From 552f340ddaf3d93bfb08ee1fc152341bc92d9cfb Mon Sep 17 00:00:00 2001 From: Yanting Yang Date: Thu, 20 Aug 2020 00:29:45 +0800 Subject: [PATCH] Resolve tiles intent before prompting a dialog for profile selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symptom: Once the work profile component of the tile is disabled after Settings preloaded tiles, Settings will crash when the user clicks the work option from the profile selection dialog. Root cause: Settings just checks the users from the preloaded tiles to prompt profile selection dialog. It doesn’t check the activity for the work profile user before launching. Solution: Resolve the activity by intent as users before launching if the work profile is enabled. Directly start activity if only one user is resolvable, otherwise prompt a dialog for profile selection. Fixes: 162227425 Test: make RunSettingsRoboTests Change-Id: Idcc4e5a266ab2a2252db30bb97d4be002212c677 --- .../DashboardFeatureProviderImpl.java | 27 ++++++++++++++----- .../DashboardFeatureProviderImplTest.java | 24 +++++++++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java index 4378d6b669e..40d26f7a036 100644 --- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java @@ -398,26 +398,41 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider { return; } ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile); + mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory); if (tile.userHandle == null || tile.isPrimaryProfileOnly()) { - mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory); activity.startActivityForResult(intent, 0); } else if (tile.userHandle.size() == 1) { - mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory); activity.startActivityForResultAsUser(intent, 0, tile.userHandle.get(0)); } else { - mMetricsFeatureProvider.logStartedIntent(intent, sourceMetricCategory); final UserHandle userHandle = intent.getParcelableExtra(EXTRA_USER); if (userHandle != null && tile.userHandle.contains(userHandle)) { activity.startActivityForResultAsUser(intent, 0, userHandle); - } else { - ProfileSelectDialog.show(activity.getSupportFragmentManager(), tile, - sourceMetricCategory); + return; } + + final List resolvableUsers = getResolvableUsers(intent, tile); + if (resolvableUsers.size() == 1) { + activity.startActivityForResultAsUser(intent, 0, resolvableUsers.get(0)); + return; + } + + ProfileSelectDialog.show(activity.getSupportFragmentManager(), tile, + sourceMetricCategory); } } private boolean isIntentResolvable(Intent intent) { return mPackageManager.resolveActivity(intent, 0) != null; } + + private List getResolvableUsers(Intent intent, Tile tile) { + final ArrayList eligibleUsers = new ArrayList<>(); + for (UserHandle user : tile.userHandle) { + if (mPackageManager.resolveActivityAsUser(intent, 0, user.getIdentifier()) != null) { + eligibleUsers.add(user); + } + } + return eligibleUsers; + } } diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java index 3f2b7c39a97..b5b0f30bb25 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java @@ -583,4 +583,28 @@ public class DashboardFeatureProviderImplTest { .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class)); verify(mActivity).getSupportFragmentManager(); } + + @Test + public void openTileIntent_profileSelectionDialog_unresolvableWorkProfileIntentShouldNotShow() { + final int userId = 10; + ShadowUserManager.getShadow().addUser(userId, "Someone", 0); + final UserHandle userHandle = new UserHandle(userId); + final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); + final ArrayList handles = new ArrayList<>(); + handles.add(new UserHandle(0)); + handles.add(userHandle); + tile.userHandle = handles; + when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), eq(0))) + .thenReturn(new ResolveInfo()); + when(mPackageManager.resolveActivityAsUser(any(Intent.class), anyInt(), eq(userId))) + .thenReturn(null); + + mImpl.openTileIntent(mActivity, tile); + + final ArgumentCaptor argument = ArgumentCaptor.forClass(UserHandle.class); + verify(mActivity) + .startActivityForResultAsUser(any(Intent.class), anyInt(), argument.capture()); + assertThat(argument.getValue().getIdentifier()).isEqualTo(0); + verify(mActivity, never()).getSupportFragmentManager(); + } }