diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 32d72b37b8afc..c18a70c5dd2ab 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -138,3 +138,39 @@ java_genrule { "done && " + "$(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res", } + +// In addition to running as part of FrameworksCoreTests, we run (a subclass of) +// ChooserActivityTest against the unbundled ChooserActivity implementation in +// //packages/modules/IntentResolver/. The following library provides the +// minimum dependencies required to build that test in the unbundled package. +android_library { + name: "ChooserActivityTestsLib", + visibility: ["//packages/modules/IntentResolver/java/tests:__pkg__"], + + srcs: [ + "src/com/android/internal/app/ChooserActivityLoggerFake.java", + "src/com/android/internal/app/ChooserActivityOverrideData.java", + "src/com/android/internal/app/ChooserActivityTest.java", + "src/com/android/internal/app/ChooserWrapperActivity.java", + "src/com/android/internal/app/IChooserWrapper.java", + "src/com/android/internal/app/MatcherUtils.java", + "src/com/android/internal/app/ResolverDataProvider.java", + ], + + static_libs: [ + "androidx.test.espresso.core", + "androidx.test.ext.junit", + "androidx.test.runner", + "androidx.test.rules", + "mockito-target-minus-junit4", + "truth-prebuilt", + ], + + libs: [ + "android.test.runner", + "android.test.base", + "android.test.mock", + "framework", + "framework-res", + ], +} \ No newline at end of file diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java new file mode 100644 index 0000000000000..499f7a55996b0 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityOverrideData.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2021 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.internal.app; + +import static org.mockito.Mockito.mock; + +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.os.UserHandle; + +import com.android.internal.app.chooser.TargetInfo; +import com.android.internal.logging.MetricsLogger; + +import java.util.List; +import java.util.function.Function; + +/** + * Singleton providing overrides to be applied by any {@code IChooserWrapper} used in testing. + * We cannot directly mock the activity created since instrumentation creates it, so instead we use + * this singleton to modify behavior. + */ +public class ChooserActivityOverrideData { + private static ChooserActivityOverrideData sInstance = null; + + public static ChooserActivityOverrideData getInstance() { + if (sInstance == null) { + sInstance = new ChooserActivityOverrideData(); + } + return sInstance; + } + + @SuppressWarnings("Since15") + public Function createPackageManager; + public Function onSafelyStartCallback; + public Function onQueryDirectShareTargets; + public ResolverListController resolverListController; + public ResolverListController workResolverListController; + public Boolean isVoiceInteraction; + public boolean isImageType; + public Cursor resolverCursor; + public boolean resolverForceException; + public Bitmap previewThumbnail; + public MetricsLogger metricsLogger; + public ChooserActivityLogger chooserActivityLogger; + public int alternateProfileSetting; + public Resources resources; + public UserHandle workProfileUserHandle; + public boolean hasCrossProfileIntents; + public boolean isQuietModeEnabled; + public boolean isWorkProfileUserRunning; + public boolean isWorkProfileUserUnlocked; + public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; + public PackageManager packageManager; + + public void reset() { + onSafelyStartCallback = null; + onQueryDirectShareTargets = null; + isVoiceInteraction = null; + createPackageManager = null; + previewThumbnail = null; + isImageType = false; + resolverCursor = null; + resolverForceException = false; + resolverListController = mock(ResolverListController.class); + workResolverListController = mock(ResolverListController.class); + metricsLogger = mock(MetricsLogger.class); + chooserActivityLogger = new ChooserActivityLoggerFake(); + alternateProfileSetting = 0; + resources = null; + workProfileUserHandle = null; + hasCrossProfileIntents = true; + isQuietModeEnabled = false; + isWorkProfileUserRunning = true; + isWorkProfileUserUnlocked = true; + packageManager = null; + multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { + @Override + public boolean hasCrossProfileIntents(List intents, int sourceUserId, + int targetUserId) { + return hasCrossProfileIntents; + } + + @Override + public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { + return isQuietModeEnabled; + } + + @Override + public void requestQuietModeEnabled(boolean enabled, + UserHandle workProfileUserHandle) { + isQuietModeEnabled = enabled; + } + }; + } + + private ChooserActivityOverrideData() {} +} + diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java index 45504c0b4a34d..c69cb4b7e302a 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -34,7 +34,6 @@ import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FRO import static com.android.internal.app.ChooserActivity.TARGET_TYPE_SHORTCUTS_FROM_SHORTCUT_MANAGER; import static com.android.internal.app.ChooserListAdapter.CALLER_TARGET_SCORE_BOOST; import static com.android.internal.app.ChooserListAdapter.SHORTCUT_TARGET_SCORE_BOOST; -import static com.android.internal.app.ChooserWrapperActivity.sOverrides; import static com.android.internal.app.MatcherUtils.first; import static junit.framework.Assert.assertFalse; @@ -82,6 +81,7 @@ import android.os.UserHandle; import android.provider.DeviceConfig; import android.service.chooser.ChooserTarget; +import androidx.annotation.CallSuper; import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.rule.ActivityTestRule; @@ -111,11 +111,29 @@ import java.util.Map; import java.util.function.Function; /** - * Chooser activity instrumentation tests + * Instrumentation tests for chooser activities that derive from the system + * {@code com.android.internal.ChooserActivity}. This class is used directly to test the system + * implementation, but clients can inherit from this test to apply the same suite of chooser tests + * to their own ChooserActivity implementations. Clients should override + * #getConcreteIntentForLaunch() to configure an intent that will launch their concrete + * ChooserActivity subtype. Tests will assume that this subtype implements the IChooserWrapper + * interface, which is only appropriate for testing. Clients will typically create their own + * "ChooserWrapperActivity" by copy-and-pasting the system implementation, parenting to their own + * ChooserActivity subclass instead of directly to the system implementation. Code comments in this + * file provide direction for developers creating derived test suites, and eventually for removing + * the extra complexity once we no longer need to support parallel ChooserActivity implementations. */ @RunWith(Parameterized.class) public class ChooserActivityTest { + /* -------- + * 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 Function DEFAULT_PM = pm -> pm; private static final Function NO_APP_PREDICTION_SERVICE_PM = pm -> { @@ -132,6 +150,66 @@ public class ChooserActivityTest { }); } + /* -------- + * 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() { + cleanOverrideData(); + } + + /** + * 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.internal.app.ChooserActivity (for our ActivityTestRule), and + * must also implement the android.internal.app.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.internal.app.ChooserWrapperActivity.class); + return clientIntent; + } + + /* -------- + * The code in this section is unorthodox and can be simplified/reverted when we no longer need + * to support the parallel chooser implementations. + * -------- + */ + + // 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 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. + * -------- + */ + private static final String TEST_MIME_TYPE = "application/TestType"; private static final int CONTENT_PREVIEW_IMAGE = 1; @@ -140,10 +218,6 @@ public class ChooserActivityTest { private Function mPackageManagerOverride; private int mTestNum; - @Rule - public ActivityTestRule mActivityRule = - new ActivityTestRule<>(ChooserWrapperActivity.class, false, - false); public ChooserActivityTest( int testNum, @@ -153,10 +227,9 @@ public class ChooserActivityTest { mTestNum = testNum; } - @Before public void cleanOverrideData() { - sOverrides.reset(); - sOverrides.createPackageManager = mPackageManagerOverride; + ChooserActivityOverrideData.getInstance().reset(); + ChooserActivityOverrideData.getInstance().createPackageManager = mPackageManagerOverride; DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.APPLY_SHARING_APP_LIMITS_IN_SYSUI, Boolean.toString(true), @@ -168,10 +241,16 @@ public class ChooserActivityTest { Intent viewIntent = createViewTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule.launchActivity( + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); + final IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity( Intent.createChooser(viewIntent, "chooser test")); waitForIdle(); @@ -185,9 +264,15 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, "chooser test")); waitForIdle(); onView(withId(R.id.title)).check(matches(withText(R.string.whichSendApplication))); @@ -198,9 +283,15 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.title)) @@ -212,9 +303,15 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntentWithPreview(null, null); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_title)).check(matches(not(isDisplayed()))); @@ -227,9 +324,15 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntentWithPreview(previewTitle, null); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_title)).check(matches(isDisplayed())); @@ -244,9 +347,15 @@ public class ChooserActivityTest { Uri.parse("tel:(+49)12345789")); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_title)).check(matches(isDisplayed())); @@ -259,12 +368,18 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntentWithPreview(previewTitle, Uri.parse("android.resource://com.android.frameworks.coretests/" + com.android.frameworks.coretests.R.drawable.test320x240)); - sOverrides.previewThumbnail = createBitmap(); + ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_title)).check(matches(isDisplayed())); @@ -276,19 +391,25 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); assertThat(activity.getAdapter().getCount(), is(2)); onView(withId(R.id.profile_button)).check(doesNotExist()); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -324,19 +445,25 @@ public class ChooserActivityTest { } resolvedComponentInfos.addAll(infosToStack); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); // expect 1 unique targets + 1 group + 4 ranked app targets assertThat(activity.getAdapter().getCount(), is(6)); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -358,27 +485,33 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); UsageStatsManager usm = activity.getUsageStatsManager(); - verify(sOverrides.resolverListController, times(1)) + verify(ChooserActivityOverrideData.getInstance().resolverListController, times(1)) .topK(any(List.class), anyInt()); assertThat(activity.getIsSelected(), is(false)); - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { return true; }; ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0); onView(withText(toChoose.activityInfo.name)) .perform(click()); waitForIdle(); - verify(sOverrides.resolverListController, times(1)) + verify(ChooserActivityOverrideData.getInstance().resolverListController, times(1)) .updateChooserCounts(Mockito.anyString(), anyInt(), Mockito.anyString()); - verify(sOverrides.resolverListController, times(1)) + verify(ChooserActivityOverrideData.getInstance().resolverListController, times(1)) .updateModel(toChoose.activityInfo.getComponentName()); assertThat(activity.getIsSelected(), is(true)); } @@ -386,19 +519,27 @@ public class ChooserActivityTest { @Ignore // b/148158199 @Test public void noResultsFromPackageManager() { - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(null); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(null); Intent sendIntent = createSendTextIntent(); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper wrapper = (IChooserWrapper) activity; + waitForIdle(); assertThat(activity.isFinishing(), is(false)); onView(withId(R.id.empty)).check(matches(isDisplayed())); onView(withId(R.id.profile_pager)).check(matches(not(isDisplayed()))); InstrumentationRegistry.getInstrumentation().runOnMainSync( - () -> activity.getAdapter().handlePackagesChanged() + () -> wrapper.getAdapter().handlePackagesChanged() ); // backward compatibility. looks like we finish when data is empty after package change assertThat(activity.isFinishing(), is(true)); @@ -407,19 +548,25 @@ public class ChooserActivityTest { @Test public void autoLaunchSingleResult() throws InterruptedException { ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; List resolvedComponentInfos = createResolvedComponentsForTest(1); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); Intent sendIntent = createSendTextIntent(); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); assertThat(chosen[0], is(resolvedComponentInfos.get(0).getResolveInfoAt(0))); @@ -438,15 +585,15 @@ public class ChooserActivityTest { ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0); Intent sendIntent = createSendTextIntent(); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); // The other entry is filtered to the other profile slot assertThat(activity.getAdapter().getCount(), is(1)); ResolveInfo[] chosen = new ResolveInfo[1]; - ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -473,22 +620,22 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(3); ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - when(ChooserWrapperActivity.sOverrides.resolverListController.getLastChosen()) + when(ChooserActivityOverrideData.getInstance().resolverListController.getLastChosen()) .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0)); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); // The other entry is filtered to the other profile slot assertThat(activity.getAdapter().getCount(), is(2)); ResolveInfo[] chosen = new ResolveInfo[1]; - ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -512,20 +659,20 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(3); ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); // The other entry is filtered to the last used slot assertThat(activity.getAdapter().getCount(), is(2)); ResolveInfo[] chosen = new ResolveInfo[1]; - ChooserWrapperActivity.sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -544,13 +691,13 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed())); @@ -571,16 +718,15 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed())); @@ -600,13 +746,13 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.chooser_nearby_button)).check(matches(isDisplayed())); @@ -664,18 +810,18 @@ public class ChooserActivityTest { Uri.parse("android.resource://com.android.frameworks.coretests/" + com.android.frameworks.coretests.R.drawable.test320x240)); - sOverrides.previewThumbnail = createBitmap(); - sOverrides.isImageType = true; + ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap(); + ChooserActivityOverrideData.getInstance().isImageType = true; List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.chooser_edit_button)).check(matches(isDisplayed())); @@ -735,14 +881,20 @@ public class ChooserActivityTest { uris.add(uri); Intent sendIntent = createSendUriIntentWithPreview(uris); - sOverrides.previewThumbnail = createBitmap(); - sOverrides.isImageType = true; + ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap(); + ChooserActivityOverrideData.getInstance().isImageType = true; List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed())); @@ -761,14 +913,20 @@ public class ChooserActivityTest { uris.add(uri); Intent sendIntent = createSendUriIntentWithPreview(uris); - sOverrides.previewThumbnail = createBitmap(); - sOverrides.isImageType = true; + ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap(); + ChooserActivityOverrideData.getInstance().isImageType = true; List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed())); @@ -790,14 +948,20 @@ public class ChooserActivityTest { uris.add(uri); Intent sendIntent = createSendUriIntentWithPreview(uris); - sOverrides.previewThumbnail = createBitmap(); - sOverrides.isImageType = true; + ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap(); + ChooserActivityOverrideData.getInstance().isImageType = true; List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_image_1_large)).check(matches(isDisplayed())); @@ -811,7 +975,7 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test")); waitForIdle(); @@ -836,8 +1000,9 @@ public class ChooserActivityTest { public void testOnCreateLoggingFromWorkProfile() { Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - sOverrides.alternateProfileSetting = MetricsEvent.MANAGED_PROFILE; - MetricsLogger mockLogger = sOverrides.metricsLogger; + ChooserActivityOverrideData.getInstance().alternateProfileSetting = + MetricsEvent.MANAGED_PROFILE; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); mActivityRule.launchActivity(Intent.createChooser(sendIntent, "logger test")); waitForIdle(); @@ -862,7 +1027,7 @@ public class ChooserActivityTest { public void testEmptyPreviewLogging() { Intent sendIntent = createSendTextIntentWithPreview(null, null); - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); mActivityRule.launchActivity(Intent.createChooser(sendIntent, "empty preview logger test")); waitForIdle(); @@ -877,12 +1042,12 @@ public class ChooserActivityTest { public void testTitlePreviewLogging() { Intent sendIntent = createSendTextIntentWithPreview("TestTitle", null); - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -906,16 +1071,22 @@ public class ChooserActivityTest { uris.add(uri); Intent sendIntent = createSendUriIntentWithPreview(uris); - sOverrides.previewThumbnail = createBitmap(); - sOverrides.isImageType = true; + ChooserActivityOverrideData.getInstance().previewThumbnail = createBitmap(); + ChooserActivityOverrideData.getInstance().isImageType = true; List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); @@ -938,9 +1109,15 @@ public class ChooserActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed())); @@ -962,9 +1139,15 @@ public class ChooserActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.content_preview_filename)).check(matches(isDisplayed())); @@ -982,11 +1165,17 @@ public class ChooserActivityTest { Intent sendIntent = createSendUriIntentWithPreview(uris); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - sOverrides.resolverForceException = true; + ChooserActivityOverrideData.getInstance().resolverForceException = true; mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); @@ -1006,9 +1195,15 @@ public class ChooserActivityTest { Intent sendIntent = createSendUriIntentWithPreview(uris); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); Cursor cursor = mock(Cursor.class); when(cursor.getCount()).thenReturn(1); @@ -1016,7 +1211,7 @@ public class ChooserActivityTest { when(cursor.moveToFirst()).thenReturn(true); when(cursor.getColumnIndex(Mockito.anyString())).thenReturn(-1); - sOverrides.resolverCursor = cursor; + ChooserActivityOverrideData.getInstance().resolverCursor = cursor; mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); @@ -1032,14 +1227,24 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); - when(sOverrides.resolverListController.getScore(Mockito.isA(DisplayResolveInfo.class))) + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getScore(Mockito.isA(DisplayResolveInfo.class))) .thenReturn(testBaseScore); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); final DisplayResolveInfo testDri = @@ -1066,12 +1271,18 @@ public class ChooserActivityTest { public void testIsAppPredictionServiceAvailable() { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); if (activity.getPackageManager().getAppPredictionServicePackageName() == null) { @@ -1079,8 +1290,13 @@ public class ChooserActivityTest { } else { assertThat(activity.isAppPredictionServiceAvailable(), is(true)); - sOverrides.resources = Mockito.spy(activity.getResources()); - when(sOverrides.resources.getString(R.string.config_defaultAppPredictionService)) + ChooserActivityOverrideData.getInstance().resources = + Mockito.spy(activity.getResources()); + when( + ChooserActivityOverrideData + .getInstance() + .resources + .getString(R.string.config_defaultAppPredictionService)) .thenReturn("ComponentNameThatDoesNotExist"); assertThat(activity.isAppPredictionServiceAvailable(), is(false)); @@ -1091,12 +1307,18 @@ public class ChooserActivityTest { public void testConvertToChooserTarget_predictionService() { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); List shortcuts = createShortcuts(activity); @@ -1127,12 +1349,18 @@ public class ChooserActivityTest { public void testConvertToChooserTarget_shortcutManager() { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); List shortcuts = createShortcuts(activity); @@ -1165,20 +1393,26 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); // We need app targets for direct targets to get displayed List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); // Set up resources - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); // Create direct share target List serviceTargets = createDirectShareTargets(1, ""); ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0); // Start activity - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); // Insert the direct share target Map directShareToShortcutInfos = new HashMap<>(); @@ -1235,12 +1469,18 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); // We need app targets for direct targets to get displayed List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); // Set up resources - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); // Create direct share target List serviceTargets = createDirectShareTargets(1, @@ -1248,8 +1488,8 @@ public class ChooserActivityTest { ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0); // Start activity - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); // Insert the direct share target Map directShareToShortcutInfos = new HashMap<>(); @@ -1298,24 +1538,35 @@ public class ChooserActivityTest { @Test @Ignore public void testShortcutTargetWithApplyAppLimits() throws InterruptedException { // Set up resources - sOverrides.resources = Mockito.spy( + ChooserActivityOverrideData.getInstance().resources = Mockito.spy( InstrumentationRegistry.getInstrumentation().getContext().getResources()); - when(sOverrides.resources.getInteger(R.integer.config_maxShortcutTargetsPerApp)) + when( + ChooserActivityOverrideData + .getInstance() + .resources + .getInteger(R.integer.config_maxShortcutTargetsPerApp)) .thenReturn(1); Intent sendIntent = createSendTextIntent(); // We need app targets for direct targets to get displayed List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); // Create direct share target List serviceTargets = createDirectShareTargets(2, resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName); ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0); // Start activity - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper wrapper = (IChooserWrapper) activity; // Insert the direct share target Map directShareToShortcutInfos = new HashMap<>(); @@ -1325,8 +1576,8 @@ public class ChooserActivityTest { directShareToShortcutInfos.put(serviceTargets.get(1), shortcutInfos.get(1).getShortcutInfo()); InstrumentationRegistry.getInstrumentation().runOnMainSync( - () -> activity.getAdapter().addServiceResults( - activity.createTestDisplayResolveInfo(sendIntent, + () -> wrapper.getAdapter().addServiceResults( + wrapper.createTestDisplayResolveInfo(sendIntent, ri, "testLabel", "testInfo", @@ -1342,13 +1593,13 @@ public class ChooserActivityTest { Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS); assertThat("Chooser should have 3 targets (2 apps, 1 direct)", - activity.getAdapter().getCount(), is(3)); + wrapper.getAdapter().getCount(), is(3)); assertThat("Chooser should have exactly one selectable direct target", - activity.getAdapter().getSelectableServiceTargetCount(), is(1)); + wrapper.getAdapter().getSelectableServiceTargetCount(), is(1)); assertThat("The resolver info must match the resolver info used to create the target", - activity.getAdapter().getItem(0).getResolveInfo(), is(ri)); + wrapper.getAdapter().getItem(0).getResolveInfo(), is(ri)); assertThat("The display label must match", - activity.getAdapter().getItem(0).getDisplayLabel(), is("testTitle0")); + wrapper.getAdapter().getItem(0).getDisplayLabel(), is("testTitle0")); } @Test @Ignore @@ -1358,24 +1609,35 @@ public class ChooserActivityTest { Boolean.toString(false), true /* makeDefault*/); // Set up resources - sOverrides.resources = Mockito.spy( + ChooserActivityOverrideData.getInstance().resources = Mockito.spy( InstrumentationRegistry.getInstrumentation().getContext().getResources()); - when(sOverrides.resources.getInteger(R.integer.config_maxShortcutTargetsPerApp)) + when( + ChooserActivityOverrideData + .getInstance() + .resources + .getInteger(R.integer.config_maxShortcutTargetsPerApp)) .thenReturn(1); Intent sendIntent = createSendTextIntent(); // We need app targets for direct targets to get displayed List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); // Create direct share target List serviceTargets = createDirectShareTargets(2, resolvedComponentInfos.get(0).getResolveInfoAt(0).activityInfo.packageName); ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0); // Start activity - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final ChooserActivity activity = + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper wrapper = (IChooserWrapper) activity; // Insert the direct share target Map directShareToShortcutInfos = new HashMap<>(); @@ -1385,8 +1647,8 @@ public class ChooserActivityTest { directShareToShortcutInfos.put(serviceTargets.get(1), shortcutInfos.get(1).getShortcutInfo()); InstrumentationRegistry.getInstrumentation().runOnMainSync( - () -> activity.getAdapter().addServiceResults( - activity.createTestDisplayResolveInfo(sendIntent, + () -> wrapper.getAdapter().addServiceResults( + wrapper.createTestDisplayResolveInfo(sendIntent, ri, "testLabel", "testInfo", @@ -1402,15 +1664,15 @@ public class ChooserActivityTest { Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS); assertThat("Chooser should have 4 targets (2 apps, 2 direct)", - activity.getAdapter().getCount(), is(4)); + wrapper.getAdapter().getCount(), is(4)); assertThat("Chooser should have exactly two selectable direct target", - activity.getAdapter().getSelectableServiceTargetCount(), is(2)); + wrapper.getAdapter().getSelectableServiceTargetCount(), is(2)); assertThat("The resolver info must match the resolver info used to create the target", - activity.getAdapter().getItem(0).getResolveInfo(), is(ri)); + wrapper.getAdapter().getItem(0).getResolveInfo(), is(ri)); assertThat("The display label must match", - activity.getAdapter().getItem(0).getDisplayLabel(), is("testTitle0")); + wrapper.getAdapter().getItem(0).getDisplayLabel(), is("testTitle0")); assertThat("The display label must match", - activity.getAdapter().getItem(1).getDisplayLabel(), is("testTitle1")); + wrapper.getAdapter().getItem(1).getDisplayLabel(), is("testTitle1")); } // This test is too long and too slow and should not be taken as an example for future tests. @@ -1434,19 +1696,30 @@ public class ChooserActivityTest { .getResources().getConfiguration()); configuration.orientation = orientation; - sOverrides.resources = Mockito.spy( + ChooserActivityOverrideData.getInstance().resources = Mockito.spy( InstrumentationRegistry.getInstrumentation().getContext().getResources()); - when(sOverrides.resources.getConfiguration()).thenReturn(configuration); + when( + ChooserActivityOverrideData + .getInstance() + .resources + .getConfiguration()) + .thenReturn(configuration); Intent sendIntent = createSendTextIntent(); // We need app targets for direct targets to get displayed List resolvedComponentInfos = createResolvedComponentsForTest(15); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); // Set up resources - MetricsLogger mockLogger = sOverrides.metricsLogger; + MetricsLogger mockLogger = ChooserActivityOverrideData.getInstance().metricsLogger; ArgumentCaptor logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class); // Create direct share target List serviceTargets = createDirectShareTargets(1, @@ -1454,14 +1727,15 @@ public class ChooserActivityTest { ResolveInfo ri = ResolverDataProvider.createResolveInfo(16, 0); // Start activity - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper wrapper = (IChooserWrapper) activity; // Insert the direct share target Map directShareToShortcutInfos = new HashMap<>(); directShareToShortcutInfos.put(serviceTargets.get(0), null); InstrumentationRegistry.getInstrumentation().runOnMainSync( - () -> activity.getAdapter().addServiceResults( - activity.createTestDisplayResolveInfo(sendIntent, + () -> wrapper.getAdapter().addServiceResults( + wrapper.createTestDisplayResolveInfo(sendIntent, ri, "testLabel", "testInfo", @@ -1479,11 +1753,11 @@ public class ChooserActivityTest { assertThat( String.format("Chooser should have %d targets (%d apps, 1 direct, 15 A-Z)", appTargetsExpected + 16, appTargetsExpected), - activity.getAdapter().getCount(), is(appTargetsExpected + 16)); + wrapper.getAdapter().getCount(), is(appTargetsExpected + 16)); assertThat("Chooser should have exactly one selectable direct target", - activity.getAdapter().getSelectableServiceTargetCount(), is(1)); + wrapper.getAdapter().getSelectableServiceTargetCount(), is(1)); assertThat("The resolver info must match the resolver info used to create the target", - activity.getAdapter().getItem(0).getResolveInfo(), is(ri)); + wrapper.getAdapter().getItem(0).getResolveInfo(), is(ri)); // Click on the direct target String name = serviceTargets.get(0).getTitle().toString(); @@ -1546,7 +1820,7 @@ public class ChooserActivityTest { sendIntent.setType(TEST_MIME_TYPE); markWorkProfileUserAvailable(); - final ChooserWrapperActivity activity = + final IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); @@ -1571,7 +1845,7 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - final ChooserWrapperActivity activity = + final IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withText(R.string.resolver_work_tab)).perform(click()); @@ -1594,7 +1868,7 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -1625,13 +1899,12 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); - sOverrides.hasCrossProfileIntents = false; + ChooserActivityOverrideData.getInstance().hasCrossProfileIntents = false; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - final ChooserWrapperActivity activity = - mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); @@ -1651,14 +1924,13 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); - sOverrides.isQuietModeEnabled = true; + ChooserActivityOverrideData.getInstance().isQuietModeEnabled = true; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); ResolverActivity.ENABLE_TABBED_VIEW = true; - final ChooserWrapperActivity activity = - mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); @@ -1682,8 +1954,7 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - final ChooserWrapperActivity activity = - mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); + mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); @@ -1704,8 +1975,8 @@ public class ChooserActivityTest { List workResolvedComponentInfos = createResolvedComponentsForTest(0); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); - sOverrides.isQuietModeEnabled = true; - sOverrides.hasCrossProfileIntents = false; + ChooserActivityOverrideData.getInstance().isQuietModeEnabled = true; + ChooserActivityOverrideData.getInstance().hasCrossProfileIntents = false; Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); @@ -1730,7 +2001,7 @@ public class ChooserActivityTest { List workResolvedComponentInfos = createResolvedComponentsForTest(0); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); - sOverrides.isQuietModeEnabled = true; + ChooserActivityOverrideData.getInstance().isQuietModeEnabled = true; Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); @@ -1750,19 +2021,25 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); assertThat(activity.getAdapter().getCount(), is(2)); onView(withId(R.id.profile_button)).check(doesNotExist()); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -1821,9 +2098,15 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); // We need app targets for direct targets to get displayed List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); // Create direct share target List serviceTargets = createDirectShareTargets(1, @@ -1831,8 +2114,8 @@ public class ChooserActivityTest { ResolveInfo ri = ResolverDataProvider.createResolveInfo(3, 0); // Start activity - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); // Insert the direct share target Map directShareToShortcutInfos = new HashMap<>(); @@ -1901,13 +2184,19 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); // We need app targets for direct targets to get displayed List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); // Start activity - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); // Thread.sleep shouldn't be a thing in an integration test but it's // necessary here because of the way the code is structured @@ -1962,13 +2251,18 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); List resolvedComponentInfos = createResolvedComponentsForTest(2); - when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( - Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(resolvedComponentInfos); - final ChooserWrapperActivity activity = mActivityRule - .launchActivity(Intent.createChooser(sendIntent, null)); + final IChooserWrapper activity = (IChooserWrapper) + mActivityRule.launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); onView(withId(R.id.chooser_copy_button)).check(matches(isDisplayed())); @@ -2032,7 +2326,7 @@ public class ChooserActivityTest { Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - final ChooserWrapperActivity activity = + final IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withText(R.string.resolver_work_tab)).perform(click()); @@ -2108,14 +2402,19 @@ public class ChooserActivityTest { ResolverActivity.ENABLE_TABBED_VIEW = false; List personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))) + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -2132,14 +2431,19 @@ public class ChooserActivityTest { ResolverActivity.ENABLE_TABBED_VIEW = false; List personalResolvedComponentInfos = createResolvedComponentsForTest(1); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))) + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -2161,11 +2465,11 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10); List workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); - sOverrides.hasCrossProfileIntents = false; + ChooserActivityOverrideData.getInstance().hasCrossProfileIntents = false; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; @@ -2180,27 +2484,37 @@ public class ChooserActivityTest { public void testOneInitialIntent_noAutolaunch() { List personalResolvedComponentInfos = createResolvedComponentsForTest(1); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))) + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); Intent chooserIntent = createChooserIntent(createSendTextIntent(), new Intent[] {new Intent("action.fake")}); ResolveInfo[] chosen = new ResolveInfo[1]; - sOverrides.onSafelyStartCallback = targetInfo -> { + ChooserActivityOverrideData.getInstance().onSafelyStartCallback = targetInfo -> { chosen[0] = targetInfo.getResolveInfo(); return true; }; - sOverrides.packageManager = mock(PackageManager.class); + ChooserActivityOverrideData.getInstance().packageManager = mock(PackageManager.class); ResolveInfo ri = createFakeResolveInfo(); - when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(ri); + when( + ChooserActivityOverrideData + .getInstance().packageManager + .resolveActivity(any(Intent.class), anyInt())) + .thenReturn(ri); waitForIdle(); - ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent); + IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity(chooserIntent); waitForIdle(); assertNull(chosen[0]); - assertThat(activity.getPersonalListAdapter().getCallerTargetCount(), is(1)); + assertThat(activity + .getPersonalListAdapter().getCallerTargetCount(), is(1)); } @Test @@ -2219,12 +2533,16 @@ public class ChooserActivityTest { new Intent("action.fake2") }; Intent chooserIntent = createChooserIntent(createSendTextIntent(), initialIntents); - sOverrides.packageManager = mock(PackageManager.class); - when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())) + ChooserActivityOverrideData.getInstance().packageManager = mock(PackageManager.class); + when( + ChooserActivityOverrideData + .getInstance() + .packageManager + .resolveActivity(any(Intent.class), anyInt())) .thenReturn(createFakeResolveInfo()); waitForIdle(); - ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent); + IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity(chooserIntent); waitForIdle(); assertThat(activity.getPersonalListAdapter().getCallerTargetCount(), is(2)); @@ -2241,18 +2559,22 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); - sOverrides.hasCrossProfileIntents = false; + ChooserActivityOverrideData.getInstance().hasCrossProfileIntents = false; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent[] initialIntents = { new Intent("action.fake1"), new Intent("action.fake2") }; Intent chooserIntent = createChooserIntent(new Intent(), initialIntents); - sOverrides.packageManager = mock(PackageManager.class); - when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())) + ChooserActivityOverrideData.getInstance().packageManager = mock(PackageManager.class); + when( + ChooserActivityOverrideData + .getInstance() + .packageManager + .resolveActivity(any(Intent.class), anyInt())) .thenReturn(createFakeResolveInfo()); - final ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent); + mActivityRule.launchActivity(chooserIntent); waitForIdle(); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); @@ -2278,8 +2600,12 @@ public class ChooserActivityTest { new Intent("action.fake2") }; Intent chooserIntent = createChooserIntent(new Intent(), initialIntents); - sOverrides.packageManager = mock(PackageManager.class); - when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())) + ChooserActivityOverrideData.getInstance().packageManager = mock(PackageManager.class); + when( + ChooserActivityOverrideData + .getInstance() + .packageManager + .resolveActivity(any(Intent.class), anyInt())) .thenReturn(createFakeResolveInfo()); mActivityRule.launchActivity(chooserIntent); @@ -2298,20 +2624,26 @@ public class ChooserActivityTest { // Create 4 ranked app targets. List personalResolvedComponentInfos = createResolvedComponentsForTest(4); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), - Mockito.isA(List.class))) + Mockito.anyBoolean(), + Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); // Create caller target which is duplicate with one of app targets Intent chooserIntent = createChooserIntent(createSendTextIntent(), new Intent[] {new Intent("action.fake")}); - sOverrides.packageManager = mock(PackageManager.class); + ChooserActivityOverrideData.getInstance().packageManager = mock(PackageManager.class); ResolveInfo ri = ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT); - when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(ri); + when( + ChooserActivityOverrideData + .getInstance() + .packageManager + .resolveActivity(any(Intent.class), anyInt())) + .thenReturn(ri); waitForIdle(); - ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent); + IChooserWrapper activity = (IChooserWrapper) mActivityRule.launchActivity(chooserIntent); waitForIdle(); // Total 4 targets (1 caller target, 3 ranked targets) @@ -2330,13 +2662,14 @@ public class ChooserActivityTest { List workResolvedComponentInfos = createResolvedComponentsForTest(3); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); - sOverrides.isQuietModeEnabled = true; + ChooserActivityOverrideData.getInstance().isQuietModeEnabled = true; boolean[] isQueryDirectShareCalledOnWorkProfile = new boolean[] { false }; - sOverrides.onQueryDirectShareTargets = chooserListAdapter -> { - isQueryDirectShareCalledOnWorkProfile[0] = - (chooserListAdapter.getUserHandle().getIdentifier() == 10); - return null; - }; + ChooserActivityOverrideData.getInstance().onQueryDirectShareTargets = + chooserListAdapter -> { + isQueryDirectShareCalledOnWorkProfile[0] = + (chooserListAdapter.getUserHandle().getIdentifier() == 10); + return null; + }; Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); @@ -2361,13 +2694,14 @@ public class ChooserActivityTest { List workResolvedComponentInfos = createResolvedComponentsForTest(3); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); - sOverrides.isWorkProfileUserRunning = false; + ChooserActivityOverrideData.getInstance().isWorkProfileUserRunning = false; boolean[] isQueryDirectShareCalledOnWorkProfile = new boolean[] { false }; - sOverrides.onQueryDirectShareTargets = chooserListAdapter -> { - isQueryDirectShareCalledOnWorkProfile[0] = - (chooserListAdapter.getUserHandle().getIdentifier() == 10); - return null; - }; + ChooserActivityOverrideData.getInstance().onQueryDirectShareTargets = + chooserListAdapter -> { + isQueryDirectShareCalledOnWorkProfile[0] = + (chooserListAdapter.getUserHandle().getIdentifier() == 10); + return null; + }; Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); @@ -2394,17 +2728,18 @@ public class ChooserActivityTest { setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - sOverrides.isWorkProfileUserRunning = false; + ChooserActivityOverrideData.getInstance().isWorkProfileUserRunning = false; - final ChooserWrapperActivity activity = + final ChooserActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); + final IChooserWrapper wrapper = (IChooserWrapper) activity; waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); - assertEquals(3, activity.getWorkListAdapter().getCount()); + assertEquals(3, wrapper.getWorkListAdapter().getCount()); } @Test @@ -2417,13 +2752,14 @@ public class ChooserActivityTest { List workResolvedComponentInfos = createResolvedComponentsForTest(3); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); - sOverrides.isWorkProfileUserUnlocked = false; + ChooserActivityOverrideData.getInstance().isWorkProfileUserUnlocked = false; boolean[] isQueryDirectShareCalledOnWorkProfile = new boolean[] { false }; - sOverrides.onQueryDirectShareTargets = chooserListAdapter -> { - isQueryDirectShareCalledOnWorkProfile[0] = - (chooserListAdapter.getUserHandle().getIdentifier() == 10); - return null; - }; + ChooserActivityOverrideData.getInstance().onQueryDirectShareTargets = + chooserListAdapter -> { + isQueryDirectShareCalledOnWorkProfile[0] = + (chooserListAdapter.getUserHandle().getIdentifier() == 10); + return null; + }; Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); @@ -2450,17 +2786,18 @@ public class ChooserActivityTest { setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType(TEST_MIME_TYPE); - sOverrides.isWorkProfileUserUnlocked = false; + ChooserActivityOverrideData.getInstance().isWorkProfileUserUnlocked = false; - final ChooserWrapperActivity activity = + final ChooserActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); + final IChooserWrapper wrapper = (IChooserWrapper) activity; waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); - assertEquals(3, activity.getWorkListAdapter().getCount()); + assertEquals(3, wrapper.getWorkListAdapter().getCount()); } private Intent createChooserIntent(Intent intent, Intent[] initialIntents) { @@ -2671,23 +3008,39 @@ public class ChooserActivityTest { } private void markWorkProfileUserAvailable() { - sOverrides.workProfileUserHandle = UserHandle.of(10); + ChooserActivityOverrideData.getInstance().workProfileUserHandle = UserHandle.of(10); } private void setupResolverControllers( List personalResolvedComponentInfos, List workResolvedComponentInfos) { - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))) + when( + ChooserActivityOverrideData + .getInstance() + .resolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(UserHandle.SYSTEM))) + when( + ChooserActivityOverrideData + .getInstance() + .workResolverListController + .getResolversForIntent( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class))) + .thenReturn(new ArrayList<>(workResolvedComponentInfos)); + when( + ChooserActivityOverrideData + .getInstance() + .workResolverListController + .getResolversForIntentAsUser( + Mockito.anyBoolean(), + Mockito.anyBoolean(), + Mockito.isA(List.class), + eq(UserHandle.SYSTEM))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); } } diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java index 6b3d657f9450d..d4f08ba5d65df 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -16,7 +16,6 @@ package com.android.internal.app; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.annotation.Nullable; @@ -41,13 +40,15 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.List; -import java.util.function.Function; -public class ChooserWrapperActivity extends ChooserActivity { - /* - * Simple wrapper around chooser activity to be able to initiate it under test - */ - static final OverrideData sOverrides = new OverrideData(); +/** + * Simple wrapper around chooser activity to be able to initiate it under test with overrides + * specified in the {@code ChooserActivityOverrideData} singleton. This should be copy-and-pasted + * verbatim to test other {@code ChooserActivity} subclasses (updating only the `extends` to match + * the concrete activity under test). + */ +public class ChooserWrapperActivity extends ChooserActivity implements IChooserWrapper { + static final ChooserActivityOverrideData sOverrides = ChooserActivityOverrideData.getInstance(); private UsageStatsManager mUsm; @Override @@ -72,16 +73,19 @@ public class ChooserWrapperActivity extends ChooserActivity { getChooserActivityLogger()); } - ChooserListAdapter getAdapter() { + @Override + public ChooserListAdapter getAdapter() { return mChooserMultiProfilePagerAdapter.getActiveListAdapter(); } - ChooserListAdapter getPersonalListAdapter() { + @Override + public ChooserListAdapter getPersonalListAdapter() { return ((ChooserGridAdapter) mMultiProfilePagerAdapter.getAdapterForIndex(0)) .getListAdapter(); } - ChooserListAdapter getWorkListAdapter() { + @Override + public ChooserListAdapter getWorkListAdapter() { if (mMultiProfilePagerAdapter.getInactiveListAdapter() == null) { return null; } @@ -89,7 +93,10 @@ public class ChooserWrapperActivity extends ChooserActivity { .getListAdapter(); } - boolean getIsSelected() { return mIsSuccessfullySelected; } + @Override + public boolean getIsSelected() { + return mIsSuccessfullySelected; + } @Override protected ComponentName getNearbySharingComponent() { @@ -103,7 +110,8 @@ public class ChooserWrapperActivity extends ChooserActivity { return new ChooserWrapperActivity.EmptyTargetInfo(); } - UsageStatsManager getUsageStatsManager() { + @Override + public UsageStatsManager getUsageStatsManager() { if (mUsm == null) { mUsm = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); } @@ -172,7 +180,7 @@ public class ChooserWrapperActivity extends ChooserActivity { } @Override - protected ChooserActivityLogger getChooserActivityLogger() { + public ChooserActivityLogger getChooserActivityLogger() { return sOverrides.chooserActivityLogger; } @@ -197,6 +205,7 @@ public class ChooserWrapperActivity extends ChooserActivity { return super.isWorkProfile(); } + @Override public DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) { @@ -209,7 +218,8 @@ public class ChooserWrapperActivity extends ChooserActivity { return sOverrides.workProfileUserHandle; } - protected UserHandle getCurrentUserHandle() { + @Override + public UserHandle getCurrentUserHandle() { return mMultiProfilePagerAdapter.getCurrentUserHandle(); } @@ -248,75 +258,4 @@ public class ChooserWrapperActivity extends ChooserActivity { } return sOverrides.isWorkProfileUserUnlocked; } - - /** - * We cannot directly mock the activity created since instrumentation creates it. - *

- * Instead, we use static instances of this object to modify behavior. - */ - static class OverrideData { - @SuppressWarnings("Since15") - public Function createPackageManager; - public Function onSafelyStartCallback; - public Function onQueryDirectShareTargets; - public ResolverListController resolverListController; - public ResolverListController workResolverListController; - public Boolean isVoiceInteraction; - public boolean isImageType; - public Cursor resolverCursor; - public boolean resolverForceException; - public Bitmap previewThumbnail; - public MetricsLogger metricsLogger; - public ChooserActivityLogger chooserActivityLogger; - public int alternateProfileSetting; - public Resources resources; - public UserHandle workProfileUserHandle; - public boolean hasCrossProfileIntents; - public boolean isQuietModeEnabled; - public boolean isWorkProfileUserRunning; - public boolean isWorkProfileUserUnlocked; - public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; - public PackageManager packageManager; - - public void reset() { - onSafelyStartCallback = null; - onQueryDirectShareTargets = null; - isVoiceInteraction = null; - createPackageManager = null; - previewThumbnail = null; - isImageType = false; - resolverCursor = null; - resolverForceException = false; - resolverListController = mock(ResolverListController.class); - workResolverListController = mock(ResolverListController.class); - metricsLogger = mock(MetricsLogger.class); - chooserActivityLogger = new ChooserActivityLoggerFake(); - alternateProfileSetting = 0; - resources = null; - workProfileUserHandle = null; - hasCrossProfileIntents = true; - isQuietModeEnabled = false; - isWorkProfileUserRunning = true; - isWorkProfileUserUnlocked = true; - packageManager = null; - multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { - @Override - public boolean hasCrossProfileIntents(List intents, int sourceUserId, - int targetUserId) { - return hasCrossProfileIntents; - } - - @Override - public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { - return isQuietModeEnabled; - } - - @Override - public void requestQuietModeEnabled(boolean enabled, - UserHandle workProfileUserHandle) { - isQuietModeEnabled = enabled; - } - }; - } - } } diff --git a/core/tests/coretests/src/com/android/internal/app/IChooserWrapper.java b/core/tests/coretests/src/com/android/internal/app/IChooserWrapper.java new file mode 100644 index 0000000000000..05f82529e760f --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/app/IChooserWrapper.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 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.internal.app; + +import android.annotation.Nullable; +import android.app.usage.UsageStatsManager; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.os.UserHandle; + +import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; +import com.android.internal.app.chooser.DisplayResolveInfo; + +/** + * Test-only extended API capabilities that an instrumented ChooserActivity subclass provides in + * order to expose the internals for override/inspection. Implementations should apply the overrides + * specified by the {@code ChooserActivityOverrideData} singleton. + */ +public interface IChooserWrapper { + ChooserListAdapter getAdapter(); + ChooserListAdapter getPersonalListAdapter(); + ChooserListAdapter getWorkListAdapter(); + boolean getIsSelected(); + UsageStatsManager getUsageStatsManager(); + DisplayResolveInfo createTestDisplayResolveInfo(Intent originalIntent, ResolveInfo pri, + CharSequence pLabel, CharSequence pInfo, Intent replacementIntent, + @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter); + UserHandle getCurrentUserHandle(); + ChooserActivityLogger getChooserActivityLogger(); +}