diff options
5 files changed, 349 insertions, 172 deletions
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java index 78e85180f3d2..efcd54f623ee 100644 --- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java @@ -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, @@ -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) { @@ -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, @@ -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 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 ce71bebfc455..6d0e58bc89be 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -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; @@ -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(); @@ -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)); @@ -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(); @@ -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(); @@ -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"); @@ -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]; @@ -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); @@ -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)); + } } 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 a68b59086d42..363551bc92fc 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -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; @@ -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; @@ -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 { @@ -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(); } @@ -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; @@ -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; + } + }; } } } diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java index 5f4194aa51e3..a7bf48858e42 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java @@ -18,16 +18,16 @@ 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.matches; -import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static com.android.internal.app.MatcherUtils.first; import static com.android.internal.app.ResolverDataProvider.createPackageManagerMockedInfo; -import static com.android.internal.app.ResolverDataProvider.createResolvedComponentInfoWithOtherId; import static com.android.internal.app.ResolverWrapperActivity.sOverrides; import static org.hamcrest.CoreMatchers.allOf; @@ -56,9 +56,6 @@ import com.android.internal.app.ResolverListAdapter.ActivityInfoPresentationGett import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; import com.android.internal.widget.ResolverDrawerLayout; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.hamcrest.Matcher; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; @@ -224,17 +221,14 @@ public class ResolverActivityTest { 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 = createSendImageIntent(); - List<ResolvedComponentInfo> resolvedComponentInfos = - createResolvedComponentsForTestWithOtherProfile(2); - ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); - - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); + ResolveInfo toChoose = personalResolvedComponentInfos.get(1).getResolveInfoAt(0); + Intent sendIntent = createSendImageIntent(); final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); Espresso.registerIdlingResources(activity.getAdapter().getLabelIdlingResource()); waitForIdle(); @@ -249,8 +243,9 @@ public class ResolverActivityTest { }; // Make a stable copy of the components as the original list may be modified List<ResolvedComponentInfo> stableCopy = - createResolvedComponentsForTestWithOtherProfile(2); - onView(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)) + createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10); + // We pick the first one as there is another one in the work profile side + onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name))) .perform(click()); onView(withId(R.id.button_once)) .perform(click()); @@ -415,18 +410,14 @@ public class ResolverActivityTest { } @Test - public void testWorkTab_workTabListEmptyBeforeGoingToTab() { + public void testWorkTab_workTabListPopulatedBeforeGoingToTab() throws InterruptedException { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; List<ResolvedComponentInfo> personalResolvedComponentInfos = - createResolvedComponentsForTest(3); + createResolvedComponentsForTestWithOtherProfile(3, /* userId = */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(personalResolvedComponentInfos); - when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + setupResolverControllers(personalResolvedComponentInfos, + new ArrayList<>(workResolvedComponentInfos)); Intent sendIntent = createSendImageIntent(); markWorkProfileUserAvailable(); @@ -434,8 +425,8 @@ public class ResolverActivityTest { waitForIdle(); assertThat(activity.getCurrentUserHandle().getIdentifier(), is(0)); - // The work list adapter must only be filled when we open the work tab - assertThat(activity.getWorkListAdapter().getCount(), is(0)); + // The work list adapter must be populated in advance before tapping the other tab + assertThat(activity.getWorkListAdapter().getCount(), is(4)); } @Test @@ -445,17 +436,7 @@ public class ResolverActivityTest { List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(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 = createSendImageIntent(); markWorkProfileUserAvailable(); @@ -474,34 +455,7 @@ public class ResolverActivityTest { List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - when(sOverrides.resolverListController.getResolversForIntentAsUser( - Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); - when(sOverrides.resolverListController.getResolversForIntentAsUser( - Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(sOverrides.workProfileUserHandle))) - .thenReturn(new ArrayList<>(workResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(sOverrides.workProfileUserHandle))) - .thenReturn(new ArrayList<>(workResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))) - .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); - + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendImageIntent(); markWorkProfileUserAvailable(); @@ -521,18 +475,7 @@ public class ResolverActivityTest { List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - 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 = createSendImageIntent(); final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); @@ -552,18 +495,7 @@ public class ResolverActivityTest { List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(3, /* userId */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - 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 = createSendImageIntent(); ResolveInfo[] chosen = new ResolveInfo[1]; sOverrides.onSafelyStartCallback = targetInfo -> { @@ -597,35 +529,7 @@ public class ResolverActivityTest { List<ResolvedComponentInfo> personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(1); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - - when(sOverrides.resolverListController.getResolversForIntentAsUser( - Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); - when(sOverrides.resolverListController.getResolversForIntentAsUser( - Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(sOverrides.workProfileUserHandle))) - .thenReturn(new ArrayList<>(workResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(sOverrides.workProfileUserHandle))) - .thenReturn(new ArrayList<>(workResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(new ArrayList<>(workResolvedComponentInfos)); - when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))) - .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); - when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class), - eq(UserHandle.SYSTEM))).thenReturn(new ArrayList<>(personalResolvedComponentInfos)); - + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendImageIntent(); final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent); @@ -644,10 +548,10 @@ public class ResolverActivityTest { // enable the work tab feature flag ResolverActivity.ENABLE_TABBED_VIEW = true; markWorkProfileUserAvailable(); + List<ResolvedComponentInfo> personalResolvedComponentInfos = + createResolvedComponentsForTestWithOtherProfile(3, /* userId= */ 10); List<ResolvedComponentInfo> workResolvedComponentInfos = createResolvedComponentsForTest(4); - when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), - Mockito.anyBoolean(), - Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); + setupResolverControllers(personalResolvedComponentInfos, workResolvedComponentInfos); Intent sendIntent = createSendImageIntent(); ResolveInfo[] chosen = new ResolveInfo[1]; sOverrides.onSafelyStartCallback = targetInfo -> { @@ -672,6 +576,82 @@ public class ResolverActivityTest { 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 = createSendImageIntent(); + sendIntent.setType("TestType"); + + mActivityRule.launchActivity(sendIntent); + 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 = createSendImageIntent(); + sendIntent.setType("TestType"); + + mActivityRule.launchActivity(sendIntent); + 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 = createSendImageIntent(); + sendIntent.setType("TestType"); + + mActivityRule.launchActivity(sendIntent); + 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 createSendImageIntent() { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); @@ -722,4 +702,21 @@ public class ResolverActivityTest { private void markWorkProfileUserAvailable() { ResolverWrapperActivity.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(workResolvedComponentInfos); + when(sOverrides.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/ResolverWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java index 36c8724e522e..208710498e1c 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java @@ -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(); } @@ -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; @@ -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 |