Loading core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +53 −4 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private Set<Integer> mLoadedPages; private final UserHandle mPersonalProfileUserHandle; private final UserHandle mWorkProfileUserHandle; private Injector mInjector; AbstractMultiProfilePagerAdapter(Context context, int currentPage, UserHandle personalProfileUserHandle, Loading @@ -70,6 +71,33 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { mLoadedPages = new HashSet<>(); mPersonalProfileUserHandle = personalProfileUserHandle; mWorkProfileUserHandle = workProfileUserHandle; UserManager userManager = context.getSystemService(UserManager.class); mInjector = new Injector() { @Override public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, int targetUserId) { return AbstractMultiProfilePagerAdapter.this .hasCrossProfileIntents(intents, sourceUserId, targetUserId); } @Override public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { return userManager.isQuietModeEnabled(workProfileUserHandle); } @Override public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) { userManager.requestQuietModeEnabled(enabled, workProfileUserHandle); } }; } /** * Overrides the default {@link Injector} for testing purposes. */ @VisibleForTesting public void setInjector(Injector injector) { mInjector = injector; } void setOnProfileSelectedListener(OnProfileSelectedListener listener) { Loading Loading @@ -252,19 +280,18 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) { UserHandle listUserHandle = activeListAdapter.getUserHandle(); UserManager userManager = mContext.getSystemService(UserManager.class); if (listUserHandle == mWorkProfileUserHandle && userManager.isQuietModeEnabled(mWorkProfileUserHandle)) { && mInjector.isQuietModeEnabled(mWorkProfileUserHandle)) { showEmptyState(activeListAdapter, R.drawable.ic_work_apps_off, R.string.resolver_turn_on_work_apps, R.string.resolver_turn_on_work_apps_explanation, (View.OnClickListener) v -> userManager.requestQuietModeEnabled(false, mWorkProfileUserHandle)); mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle)); return false; } if (UserHandle.myUserId() != listUserHandle.getIdentifier()) { if (!hasCrossProfileIntents(activeListAdapter.getIntents(), if (!mInjector.hasCrossProfileIntents(activeListAdapter.getIntents(), UserHandle.myUserId(), listUserHandle.getIdentifier())) { if (listUserHandle == mPersonalProfileUserHandle) { showEmptyState(activeListAdapter, Loading Loading @@ -366,4 +393,26 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { */ void onProfileSelected(int profileIndex); } /** * Describes an injector to be used for cross profile functionality. Overridable for testing. */ @VisibleForTesting public interface Injector { /** * Returns {@code true} if at least one of the provided {@code intents} can be forwarded * from {@code sourceUserId} to {@code targetUserId}. */ boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, int targetUserId); /** * Returns whether the given profile is in quiet mode or not. */ boolean isQuietModeEnabled(UserHandle workProfileUserHandle); /** * Enables or disables quiet mode for a managed profile. */ void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle); } } No newline at end of file core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +113 −39 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.app; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.swipeUp; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; Loading Loading @@ -355,18 +356,14 @@ public class ChooserActivityTest { public void hasOtherProfileOneOption() throws Exception { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); markWorkProfileUserAvailable(); Intent sendIntent = createSendTextIntent(); List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(2); ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0); Intent sendIntent = createSendTextIntent(); final ChooserWrapperActivity activity = mActivityRule .launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); Loading @@ -382,9 +379,11 @@ public class ChooserActivityTest { // Make a stable copy of the components as the original list may be modified List<ResolvedComponentInfo> stableCopy = createResolvedComponentsForTestWithOtherProfile(2); createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10); waitForIdle(); onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)) Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS); onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))) .perform(click()); waitForIdle(); assertThat(chosen[0], is(toChoose)); Loading Loading @@ -1218,17 +1217,7 @@ public class ChooserActivityTest { int workProfileTargets = 4; List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest( workProfileTargets); when(sOverrides.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))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); markWorkProfileUserAvailable(); Loading @@ -1245,7 +1234,7 @@ public class ChooserActivityTest { } @Test public void testWorkTab_workProfileHasExpectedNumberOfTargets() { public void testWorkTab_workProfileHasExpectedNumberOfTargets() throws InterruptedException { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); Loading @@ -1254,18 +1243,7 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); when(sOverrides.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(workResolvedComponentInfos); when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class), eq(UserHandle.SYSTEM))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); Loading @@ -1284,12 +1262,12 @@ public class ChooserActivityTest { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); int workProfileTargets = 4; List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); ResolveInfo[] chosen = new ResolveInfo[1]; Loading @@ -1312,6 +1290,85 @@ public class ChooserActivityTest { assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0))); } @Test public void testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown() { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); int workProfileTargets = 4; List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); sOverrides.hasCrossProfileIntents = false; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); final ChooserWrapperActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_cant_share_with_work_apps)) .check(matches(isDisplayed())); } @Test public void testWorkTab_workProfileDisabled_emptyStateShown() { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); int workProfileTargets = 4; List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); sOverrides.isQuietModeEnabled = true; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); final ChooserWrapperActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); onView(withText(R.string.resolver_turn_on_work_apps)) .check(matches(isDisplayed())); } @Test public void testWorkTab_noWorkTargets_emptyStateShown() { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTest(3); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(0); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); final ChooserWrapperActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); onView(withText(R.string.resolver_no_apps_available)) .check(matches(isDisplayed())); } private Intent createSendTextIntent() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); Loading Loading @@ -1486,4 +1543,21 @@ public class ChooserActivityTest { private void markWorkProfileUserAvailable() { sOverrides.workProfileUserHandle = UserHandle.of(10); } private void setupResolverControllers( List<ResolvedComponentInfo> personalResolvedComponentInfos, List<ResolvedComponentInfo> workResolvedComponentInfos) { when(sOverrides.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))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); } } core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +33 −8 Original line number Diff line number Diff line Loading @@ -16,15 +16,10 @@ package com.android.internal.app; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.annotation.Nullable; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionManager; import android.app.prediction.AppPredictor; import android.app.usage.UsageStatsManager; import android.content.ContentResolver; import android.content.Context; Loading @@ -35,7 +30,6 @@ import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.util.Size; Loading @@ -45,8 +39,7 @@ import com.android.internal.app.chooser.TargetInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import org.mockito.Mockito; import java.util.List; import java.util.function.Function; public class ChooserWrapperActivity extends ChooserActivity { Loading @@ -56,6 +49,15 @@ public class ChooserWrapperActivity extends ChooserActivity { static final OverrideData sOverrides = new OverrideData(); private UsageStatsManager mUsm; @Override protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); return multiProfilePagerAdapter; } ChooserListAdapter getAdapter() { return mChooserMultiProfilePagerAdapter.getActiveListAdapter(); } Loading Loading @@ -206,6 +208,9 @@ public class ChooserWrapperActivity extends ChooserActivity { public int alternateProfileSetting; public Resources resources; public UserHandle workProfileUserHandle; public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; public void reset() { onSafelyStartCallback = null; Loading @@ -221,6 +226,26 @@ public class ChooserWrapperActivity extends ChooserActivity { alternateProfileSetting = 0; resources = null; workProfileUserHandle = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { @Override public boolean hasCrossProfileIntents(List<Intent> 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; } }; } } } core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java +118 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java +32 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,15 @@ public class ResolverWrapperActivity extends ResolverActivity { filterLastUsed, createListController(userHandle), useLayoutForBrowsables, this); } @Override protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); return multiProfilePagerAdapter; } ResolverWrapperAdapter getAdapter() { return (ResolverWrapperAdapter) mMultiProfilePagerAdapter.getActiveListAdapter(); } Loading Loading @@ -124,6 +133,9 @@ public class ResolverWrapperActivity extends ResolverActivity { public ResolverListController workResolverListController; public Boolean isVoiceInteraction; public UserHandle workProfileUserHandle; public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; public void reset() { onSafelyStartCallback = null; Loading @@ -132,6 +144,26 @@ public class ResolverWrapperActivity extends ResolverActivity { resolverListController = mock(ResolverListController.class); workResolverListController = mock(ResolverListController.class); workProfileUserHandle = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { @Override public boolean hasCrossProfileIntents(List<Intent> 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; } }; } } } No newline at end of file Loading
core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +53 −4 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private Set<Integer> mLoadedPages; private final UserHandle mPersonalProfileUserHandle; private final UserHandle mWorkProfileUserHandle; private Injector mInjector; AbstractMultiProfilePagerAdapter(Context context, int currentPage, UserHandle personalProfileUserHandle, Loading @@ -70,6 +71,33 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { mLoadedPages = new HashSet<>(); mPersonalProfileUserHandle = personalProfileUserHandle; mWorkProfileUserHandle = workProfileUserHandle; UserManager userManager = context.getSystemService(UserManager.class); mInjector = new Injector() { @Override public boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, int targetUserId) { return AbstractMultiProfilePagerAdapter.this .hasCrossProfileIntents(intents, sourceUserId, targetUserId); } @Override public boolean isQuietModeEnabled(UserHandle workProfileUserHandle) { return userManager.isQuietModeEnabled(workProfileUserHandle); } @Override public void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle) { userManager.requestQuietModeEnabled(enabled, workProfileUserHandle); } }; } /** * Overrides the default {@link Injector} for testing purposes. */ @VisibleForTesting public void setInjector(Injector injector) { mInjector = injector; } void setOnProfileSelectedListener(OnProfileSelectedListener listener) { Loading Loading @@ -252,19 +280,18 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { private boolean rebuildTab(ResolverListAdapter activeListAdapter, boolean doPostProcessing) { UserHandle listUserHandle = activeListAdapter.getUserHandle(); UserManager userManager = mContext.getSystemService(UserManager.class); if (listUserHandle == mWorkProfileUserHandle && userManager.isQuietModeEnabled(mWorkProfileUserHandle)) { && mInjector.isQuietModeEnabled(mWorkProfileUserHandle)) { showEmptyState(activeListAdapter, R.drawable.ic_work_apps_off, R.string.resolver_turn_on_work_apps, R.string.resolver_turn_on_work_apps_explanation, (View.OnClickListener) v -> userManager.requestQuietModeEnabled(false, mWorkProfileUserHandle)); mInjector.requestQuietModeEnabled(false, mWorkProfileUserHandle)); return false; } if (UserHandle.myUserId() != listUserHandle.getIdentifier()) { if (!hasCrossProfileIntents(activeListAdapter.getIntents(), if (!mInjector.hasCrossProfileIntents(activeListAdapter.getIntents(), UserHandle.myUserId(), listUserHandle.getIdentifier())) { if (listUserHandle == mPersonalProfileUserHandle) { showEmptyState(activeListAdapter, Loading Loading @@ -366,4 +393,26 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { */ void onProfileSelected(int profileIndex); } /** * Describes an injector to be used for cross profile functionality. Overridable for testing. */ @VisibleForTesting public interface Injector { /** * Returns {@code true} if at least one of the provided {@code intents} can be forwarded * from {@code sourceUserId} to {@code targetUserId}. */ boolean hasCrossProfileIntents(List<Intent> intents, int sourceUserId, int targetUserId); /** * Returns whether the given profile is in quiet mode or not. */ boolean isQuietModeEnabled(UserHandle workProfileUserHandle); /** * Enables or disables quiet mode for a managed profile. */ void requestQuietModeEnabled(boolean enabled, UserHandle workProfileUserHandle); } } No newline at end of file
core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +113 −39 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.app; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.swipeUp; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; Loading Loading @@ -355,18 +356,14 @@ public class ChooserActivityTest { public void hasOtherProfileOneOption() throws Exception { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); markWorkProfileUserAvailable(); Intent sendIntent = createSendTextIntent(); List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(2); ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); when(ChooserWrapperActivity.sOverrides.resolverListController.getResolversForIntent( Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0); Intent sendIntent = createSendTextIntent(); final ChooserWrapperActivity activity = mActivityRule .launchActivity(Intent.createChooser(sendIntent, null)); waitForIdle(); Loading @@ -382,9 +379,11 @@ public class ChooserActivityTest { // Make a stable copy of the components as the original list may be modified List<ResolvedComponentInfo> stableCopy = createResolvedComponentsForTestWithOtherProfile(2); createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10); waitForIdle(); onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)) Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS); onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))) .perform(click()); waitForIdle(); assertThat(chosen[0], is(toChoose)); Loading Loading @@ -1218,17 +1217,7 @@ public class ChooserActivityTest { int workProfileTargets = 4; List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest( workProfileTargets); when(sOverrides.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))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); markWorkProfileUserAvailable(); Loading @@ -1245,7 +1234,7 @@ public class ChooserActivityTest { } @Test public void testWorkTab_workProfileHasExpectedNumberOfTargets() { public void testWorkTab_workProfileHasExpectedNumberOfTargets() throws InterruptedException { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); Loading @@ -1254,18 +1243,7 @@ public class ChooserActivityTest { createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); when(sOverrides.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(workResolvedComponentInfos); when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class), eq(UserHandle.SYSTEM))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); Loading @@ -1284,12 +1262,12 @@ public class ChooserActivityTest { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); int workProfileTargets = 4; List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); ResolveInfo[] chosen = new ResolveInfo[1]; Loading @@ -1312,6 +1290,85 @@ public class ChooserActivityTest { assertThat(chosen[0], is(workResolvedComponentInfos.get(0).getResolveInfoAt(0))); } @Test public void testWorkTab_crossProfileIntentsDisabled_personalToWork_emptyStateShown() { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); int workProfileTargets = 4; List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); sOverrides.hasCrossProfileIntents = false; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); final ChooserWrapperActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_cant_share_with_work_apps)) .check(matches(isDisplayed())); } @Test public void testWorkTab_workProfileDisabled_emptyStateShown() { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); int workProfileTargets = 4; List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(workProfileTargets); sOverrides.isQuietModeEnabled = true; setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); final ChooserWrapperActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); onView(withText(R.string.resolver_turn_on_work_apps)) .check(matches(isDisplayed())); } @Test public void testWorkTab_noWorkTargets_emptyStateShown() { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTest(3); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(0); setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendTextIntent(); sendIntent.setType("TestType"); final ChooserWrapperActivity activity = mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test")); waitForIdle(); onView(withId(R.id.contentPanel)) .perform(swipeUp()); onView(withText(R.string.resolver_work_tab)).perform(click()); waitForIdle(); onView(withText(R.string.resolver_no_apps_available)) .check(matches(isDisplayed())); } private Intent createSendTextIntent() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); Loading Loading @@ -1486,4 +1543,21 @@ public class ChooserActivityTest { private void markWorkProfileUserAvailable() { sOverrides.workProfileUserHandle = UserHandle.of(10); } private void setupResolverControllers( List<ResolvedComponentInfo> personalResolvedComponentInfos, List<ResolvedComponentInfo> workResolvedComponentInfos) { when(sOverrides.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))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); } }
core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +33 −8 Original line number Diff line number Diff line Loading @@ -16,15 +16,10 @@ package com.android.internal.app; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.annotation.Nullable; import android.app.prediction.AppPredictionContext; import android.app.prediction.AppPredictionManager; import android.app.prediction.AppPredictor; import android.app.usage.UsageStatsManager; import android.content.ContentResolver; import android.content.Context; Loading @@ -35,7 +30,6 @@ import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.util.Size; Loading @@ -45,8 +39,7 @@ import com.android.internal.app.chooser.TargetInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import org.mockito.Mockito; import java.util.List; import java.util.function.Function; public class ChooserWrapperActivity extends ChooserActivity { Loading @@ -56,6 +49,15 @@ public class ChooserWrapperActivity extends ChooserActivity { static final OverrideData sOverrides = new OverrideData(); private UsageStatsManager mUsm; @Override protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); return multiProfilePagerAdapter; } ChooserListAdapter getAdapter() { return mChooserMultiProfilePagerAdapter.getActiveListAdapter(); } Loading Loading @@ -206,6 +208,9 @@ public class ChooserWrapperActivity extends ChooserActivity { public int alternateProfileSetting; public Resources resources; public UserHandle workProfileUserHandle; public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; public void reset() { onSafelyStartCallback = null; Loading @@ -221,6 +226,26 @@ public class ChooserWrapperActivity extends ChooserActivity { alternateProfileSetting = 0; resources = null; workProfileUserHandle = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { @Override public boolean hasCrossProfileIntents(List<Intent> 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; } }; } } }
core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java +118 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes
core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java +32 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,15 @@ public class ResolverWrapperActivity extends ResolverActivity { filterLastUsed, createListController(userHandle), useLayoutForBrowsables, this); } @Override protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter( Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) { AbstractMultiProfilePagerAdapter multiProfilePagerAdapter = super.createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed); multiProfilePagerAdapter.setInjector(sOverrides.multiPagerAdapterInjector); return multiProfilePagerAdapter; } ResolverWrapperAdapter getAdapter() { return (ResolverWrapperAdapter) mMultiProfilePagerAdapter.getActiveListAdapter(); } Loading Loading @@ -124,6 +133,9 @@ public class ResolverWrapperActivity extends ResolverActivity { public ResolverListController workResolverListController; public Boolean isVoiceInteraction; public UserHandle workProfileUserHandle; public boolean hasCrossProfileIntents; public boolean isQuietModeEnabled; public AbstractMultiProfilePagerAdapter.Injector multiPagerAdapterInjector; public void reset() { onSafelyStartCallback = null; Loading @@ -132,6 +144,26 @@ public class ResolverWrapperActivity extends ResolverActivity { resolverListController = mock(ResolverListController.class); workResolverListController = mock(ResolverListController.class); workProfileUserHandle = null; hasCrossProfileIntents = true; isQuietModeEnabled = false; multiPagerAdapterInjector = new AbstractMultiProfilePagerAdapter.Injector() { @Override public boolean hasCrossProfileIntents(List<Intent> 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; } }; } } } No newline at end of file