From 2bcb37a7ab145dd910cdfcec438d721155201a1a Mon Sep 17 00:00:00 2001 From: Nick Chameyev Date: Fri, 6 May 2022 17:28:42 +0000 Subject: [PATCH] [Partial screen sharing] App selector initial version Adds an activity that inherits ChooserActivity to select an app in the partial screen sharing flow under a feature flag. It doesn't have a proper visual design, analytics, enterprise policies handling. Bug: 218314434 Test: start partial screen sharing Change-Id: Ia7d9ae07e2ef35d33f85530f26cab4e6cdc1f94a --- .../internal/app/ResolverListAdapter.java | 8 ++ .../internal/app/ResolverListController.java | 6 +- .../internal/app/ChooserActivityTest.java | 47 +++++++ .../internal/app/ResolverActivityTest.java | 12 ++ .../app/ResolverListControllerTest.java | 124 +++++++++++++++++- packages/SystemUI/AndroidManifest.xml | 11 ++ packages/SystemUI/res/values/styles.xml | 4 + .../systemui/dagger/SystemUIModule.java | 2 + .../MediaProjectionAppSelectorActivity.kt | 119 +++++++++++++++++ .../MediaProjectionPermissionActivity.java | 40 +++++- .../media/dagger/MediaProjectionModule.kt | 35 +++++ .../systemui/util/AsyncActivityLauncher.kt | 89 +++++++++++++ 12 files changed, 486 insertions(+), 11 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt create mode 100644 packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt create mode 100644 packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java index 2ed0f981692e3..737d5e348249b 100644 --- a/core/java/com/android/internal/app/ResolverListAdapter.java +++ b/core/java/com/android/internal/app/ResolverListAdapter.java @@ -265,6 +265,7 @@ public class ResolverListAdapter extends BaseAdapter { return mResolverListController.getResolversForIntent( /* shouldGetResolvedFilter= */ true, mResolverListCommunicator.shouldGetActivityMetadata(), + mResolverListCommunicator.shouldGetOnlyDefaultActivities(), mIntents); } } @@ -727,6 +728,7 @@ public class ResolverListAdapter extends BaseAdapter { protected List getResolversForUser(UserHandle userHandle) { return mResolverListController.getResolversForIntentAsUser(true, mResolverListCommunicator.shouldGetActivityMetadata(), + mResolverListCommunicator.shouldGetOnlyDefaultActivities(), mIntents, userHandle); } @@ -820,6 +822,12 @@ public class ResolverListAdapter extends BaseAdapter { boolean shouldGetActivityMetadata(); + /** + * @return true to filter only apps that can handle + * {@link android.content.Intent#CATEGORY_DEFAULT} intents + */ + default boolean shouldGetOnlyDefaultActivities() { return true; }; + Intent getTargetIntent(); void onHandlePackagesChanged(ResolverListAdapter listAdapter); diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java index 27573631b2ce7..100fcd8178126 100644 --- a/core/java/com/android/internal/app/ResolverListController.java +++ b/core/java/com/android/internal/app/ResolverListController.java @@ -110,17 +110,19 @@ public class ResolverListController { public List getResolversForIntent( boolean shouldGetResolvedFilter, boolean shouldGetActivityMetadata, + boolean shouldGetOnlyDefaultActivities, List intents) { return getResolversForIntentAsUser(shouldGetResolvedFilter, shouldGetActivityMetadata, - intents, mUserHandle); + shouldGetOnlyDefaultActivities, intents, mUserHandle); } public List getResolversForIntentAsUser( boolean shouldGetResolvedFilter, boolean shouldGetActivityMetadata, + boolean shouldGetOnlyDefaultActivities, List intents, UserHandle userHandle) { - int baseFlags = PackageManager.MATCH_DEFAULT_ONLY + int baseFlags = (shouldGetOnlyDefaultActivities ? PackageManager.MATCH_DEFAULT_ONLY : 0) | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0) 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 82148422aabf1..e8c7ce0b312b2 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java @@ -264,6 +264,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -287,6 +288,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -307,6 +309,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -327,6 +330,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -350,6 +354,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -376,6 +381,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -401,6 +407,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -422,6 +429,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -476,6 +484,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -516,6 +525,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -550,6 +560,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -585,6 +596,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -647,6 +659,7 @@ public class ChooserActivityTest { ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -686,6 +699,7 @@ public class ChooserActivityTest { ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -718,6 +732,7 @@ public class ChooserActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -745,6 +760,7 @@ public class ChooserActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -774,6 +790,7 @@ public class ChooserActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -844,6 +861,7 @@ public class ChooserActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -920,6 +938,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -956,6 +975,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -995,6 +1015,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1089,6 +1110,7 @@ public class ChooserActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -1122,6 +1144,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1155,6 +1178,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1187,6 +1211,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1216,6 +1241,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1248,6 +1274,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1282,6 +1309,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1321,6 +1349,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1363,6 +1392,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1407,6 +1437,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1483,6 +1514,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1564,6 +1596,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1636,6 +1669,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -1743,6 +1777,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2058,6 +2093,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2140,6 +2176,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2227,6 +2264,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2296,6 +2334,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2444,6 +2483,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2473,6 +2513,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2526,6 +2567,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -2663,6 +2705,7 @@ public class ChooserActivityTest { createResolvedComponentsForTest(4); when(ChooserActivityOverrideData.getInstance().resolverListController.getResolversForIntent( Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); @@ -3055,6 +3098,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -3064,6 +3108,7 @@ public class ChooserActivityTest { .getInstance() .workResolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) @@ -3073,6 +3118,7 @@ public class ChooserActivityTest { .getInstance() .workResolverListController .getResolversForIntentAsUser( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class), @@ -3129,6 +3175,7 @@ public class ChooserActivityTest { .getInstance() .resolverListController .getResolversForIntent( + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) 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 43fba529182eb..92c05b0fe9fcf 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java @@ -95,6 +95,7 @@ public class ResolverActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -126,6 +127,7 @@ public class ResolverActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); waitForIdle(); @@ -170,6 +172,7 @@ public class ResolverActivityTest { List resolvedComponentInfos = createResolvedComponentsForTest(2); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); waitForIdle(); @@ -202,6 +205,7 @@ public class ResolverActivityTest { ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); when(sOverrides.resolverListController.getLastChosen()) @@ -272,6 +276,7 @@ public class ResolverActivityTest { ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); @@ -316,6 +321,7 @@ public class ResolverActivityTest { ResolveInfo toChoose = resolvedComponentInfos.get(1).getResolveInfoAt(0); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); when(sOverrides.resolverListController.getLastChosen()) @@ -806,6 +812,7 @@ public class ResolverActivityTest { List personalResolvedComponentInfos = createResolvedComponentsForTestWithOtherProfile(2, /* userId */ 10); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); @@ -830,6 +837,7 @@ public class ResolverActivityTest { List personalResolvedComponentInfos = createResolvedComponentsForTest(1); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); @@ -887,6 +895,7 @@ public class ResolverActivityTest { createResolvedComponentsForTest(2); when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(resolvedComponentInfos); when(sOverrides.resolverListController.getLastChosen()) @@ -964,13 +973,16 @@ public class ResolverActivityTest { List personalResolvedComponentInfos, List workResolvedComponentInfos) { when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))) .thenReturn(new ArrayList<>(personalResolvedComponentInfos)); when(sOverrides.workResolverListController.getResolversForIntent(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class))).thenReturn(workResolvedComponentInfos); when(sOverrides.workResolverListController.getResolversForIntentAsUser(Mockito.anyBoolean(), + Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.isA(List.class), eq(UserHandle.SYSTEM))) diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java index e16d44854516f..42593f60094b9 100644 --- a/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java +++ b/core/tests/coretests/src/com/android/internal/app/ResolverListControllerTest.java @@ -20,11 +20,14 @@ import static junit.framework.Assert.assertEquals; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.ArgumentMatchers.intThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.usage.IUsageStatsManager; @@ -48,6 +51,7 @@ import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; @@ -78,6 +82,8 @@ public class ResolverListControllerTest { Configuration config = new Configuration(); config.locale = Locale.getDefault(); List services = new ArrayList<>(); + mUsm = new UsageStatsManager(mMockContext, mMockService); + when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm); when(mMockPackageManager.queryIntentServices(any(), anyInt())).thenReturn(services); when(mMockResources.getConfiguration()).thenReturn(config); when(mMockContext.getResources()).thenReturn(mMockResources); @@ -112,8 +118,6 @@ public class ResolverListControllerTest { doAnswer(answer).when(mMockService).reportChooserSelection( anyString(), anyInt(), anyString(), any(), anyString()); when(mMockContext.getOpPackageName()).thenReturn(refererPackage); - mUsm = new UsageStatsManager(mMockContext, mMockService); - when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm); mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent, refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM); mController.sort(new ArrayList()); @@ -129,8 +133,6 @@ public class ResolverListControllerTest { Intent sendIntent = createSendImageIntent(annotation); String refererPackage = "test_referer_package"; List resolvedComponents = createResolvedComponentsForTest(10); - mUsm = new UsageStatsManager(mMockContext, mMockService); - when(mMockContext.getSystemService(Context.USAGE_STATS_SERVICE)).thenReturn(mUsm); mController = new ResolverListController(mMockContext, mMockPackageManager, sendIntent, refererPackage, UserHandle.USER_CURRENT, /* userHandle */ UserHandle.SYSTEM); List topKList = new ArrayList<>(resolvedComponents); @@ -151,6 +153,102 @@ public class ResolverListControllerTest { sortList, topKList); } + @Test + public void getResolversForIntent_usesResultsFromPackageManager() { + mockStats(); + List infos = new ArrayList<>(); + infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT)); + when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), + any(UserHandle.class))).thenReturn(infos); + mController = new ResolverListController(mMockContext, mMockPackageManager, + createSendImageIntent("test"), null, UserHandle.USER_CURRENT, + /* userHandle= */ UserHandle.SYSTEM); + List intents = new ArrayList<>(); + intents.add(createActionMainIntent()); + + List resolvers = mController + .getResolversForIntent( + /* shouldGetResolvedFilter= */ true, + /* shouldGetActivityMetadata= */ true, + /* shouldGetOnlyDefaultActivities= */ true, + intents); + + assertThat(resolvers, hasSize(1)); + assertThat(resolvers.get(0).getResolveInfoAt(0), is(infos.get(0))); + } + + @Test + public void getResolversForIntent_shouldGetOnlyDefaultActivitiesTrue_addsFlag() { + mockStats(); + List infos = new ArrayList<>(); + infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT)); + when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), + any(UserHandle.class))).thenReturn(infos); + mController = new ResolverListController(mMockContext, mMockPackageManager, + createSendImageIntent("test"), null, UserHandle.USER_CURRENT, + /* userHandle= */ UserHandle.SYSTEM); + List intents = new ArrayList<>(); + intents.add(createActionMainIntent()); + + mController + .getResolversForIntent( + /* shouldGetResolvedFilter= */ true, + /* shouldGetActivityMetadata= */ true, + /* shouldGetOnlyDefaultActivities= */ true, + intents); + + verify(mMockPackageManager).queryIntentActivitiesAsUser(any(), + containsFlag(PackageManager.MATCH_DEFAULT_ONLY), any()); + } + + @Test + public void getResolversForIntent_shouldGetOnlyDefaultActivitiesFalse_doesNotAddFlag() { + mockStats(); + List infos = new ArrayList<>(); + infos.add(ResolverDataProvider.createResolveInfo(0, UserHandle.USER_CURRENT)); + when(mMockPackageManager.queryIntentActivitiesAsUser(any(), anyInt(), + any(UserHandle.class))).thenReturn(infos); + mController = new ResolverListController(mMockContext, mMockPackageManager, + createSendImageIntent("test"), null, UserHandle.USER_CURRENT, + /* userHandle= */ UserHandle.SYSTEM); + List intents = new ArrayList<>(); + intents.add(createActionMainIntent()); + + mController + .getResolversForIntent( + /* shouldGetResolvedFilter= */ true, + /* shouldGetActivityMetadata= */ true, + /* shouldGetOnlyDefaultActivities= */ false, + intents); + + verify(mMockPackageManager).queryIntentActivitiesAsUser(any(), + doesNotContainFlag(PackageManager.MATCH_DEFAULT_ONLY), any()); + } + + private int containsFlag(int flag) { + return intThat(new FlagMatcher(flag, /* contains= */ true)); + } + + private int doesNotContainFlag(int flag) { + return intThat(new FlagMatcher(flag, /* contains= */ false)); + } + + public static class FlagMatcher implements ArgumentMatcher { + + private final int mFlag; + private final boolean mContains; + + public FlagMatcher(int flag, boolean contains) { + mFlag = flag; + mContains = contains; + } + + @Override + public boolean matches(Integer integer) { + return ((integer & mFlag) != 0) == mContains; + } + } + private UsageStats initStats(String packageName, String action, String annotation, int count) { ArrayMap> chooserCounts = new ArrayMap<>(); @@ -174,6 +272,24 @@ public class ResolverListControllerTest { return sendIntent; } + private Intent createActionMainIntent() { + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_MAIN); + sendIntent.addCategory(Intent.CATEGORY_LAUNCHER); + return sendIntent; + } + + private void mockStats() { + final List slices = new ArrayList<>(); + ParceledListSlice stats = new ParceledListSlice<>(slices); + try { + when(mMockService.queryUsageStats(anyInt(), anyLong(), anyLong(), anyString(), + anyInt())).thenReturn(stats); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + private Integer getCount( UsageStatsManager usm, String packageName, String action, String annotation) { if (usm == null) { diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 1c13b1660e315..6edf13addbca8 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -618,6 +618,17 @@ android:excludeFromRecents="true" android:visibleToInstantApps="true"/> + + + +