Loading core/java/com/android/internal/app/ChooserActivity.java +45 −2 Original line number Diff line number Diff line Loading @@ -169,6 +169,17 @@ public class ChooserActivity extends ResolverActivity implements public static final String EXTRA_PRIVATE_RETAIN_IN_ON_STOP = "com.android.internal.app.ChooserActivity.EXTRA_PRIVATE_RETAIN_IN_ON_STOP"; /** * Integer extra to indicate which profile should be automatically selected. * <p>Can only be used if there is a work profile. * <p>Possible values can be either {@link #PROFILE_PERSONAL} or {@link #PROFILE_WORK}. */ static final String EXTRA_SELECTED_PROFILE = "com.android.internal.app.ChooserActivity.EXTRA_SELECTED_PROFILE"; static final int PROFILE_PERSONAL = AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL; static final int PROFILE_WORK = AbstractMultiProfilePagerAdapter.PROFILE_WORK; private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions"; private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label"; Loading Loading @@ -860,15 +871,31 @@ public class ChooserActivity extends ResolverActivity implements filterLastUsed, mUseLayoutForBrowsables, /* userHandle */ getWorkProfileUserHandle()); int selectedProfile = findSelectedProfile(); return new ChooserMultiProfilePagerAdapter( /* context */ this, personalAdapter, workAdapter, /* defaultProfile */ getCurrentProfile(), selectedProfile, getPersonalProfileUserHandle(), getWorkProfileUserHandle()); } private int findSelectedProfile() { int selectedProfile; if (getIntent().hasExtra(EXTRA_SELECTED_PROFILE)) { selectedProfile = getIntent().getIntExtra(EXTRA_SELECTED_PROFILE, /* defValue = */ -1); if (selectedProfile != PROFILE_PERSONAL && selectedProfile != PROFILE_WORK) { throw new IllegalArgumentException(EXTRA_SELECTED_PROFILE + " has invalid value " + selectedProfile + ". Must be either ChooserActivity.PROFILE_PERSONAL or " + "ChooserActivity.PROFILE_WORK."); } } else { selectedProfile = getProfileForUser(getUser()); } return selectedProfile; } @Override protected boolean postRebuildList(boolean rebuildCompleted) { updateStickyContentPreview(); Loading Loading @@ -2479,7 +2506,10 @@ public class ChooserActivity extends ResolverActivity implements gridAdapter.getMaxTargetsPerRow()); } if (mChooserMultiProfilePagerAdapter.getCurrentUserHandle() != getUser()) { UserHandle currentUserHandle = mChooserMultiProfilePagerAdapter.getCurrentUserHandle(); int currentProfile = getProfileForUser(currentUserHandle); int initialProfile = findSelectedProfile(); if (currentProfile != initialProfile) { return; } Loading Loading @@ -2576,6 +2606,19 @@ public class ChooserActivity extends ResolverActivity implements } } /** * Returns {@link #PROFILE_PERSONAL}, {@link #PROFILE_WORK}, or -1 if the given user handle * does not match either the personal or work user handle. **/ private int getProfileForUser(UserHandle currentUserHandle) { if (currentUserHandle == getPersonalProfileUserHandle()) { return PROFILE_PERSONAL; } else if (currentUserHandle == getWorkProfileUserHandle()) { return PROFILE_WORK; } return -1; } private ViewGroup getCurrentEmptyStateView() { int currentPage = mChooserMultiProfilePagerAdapter.getCurrentPage(); return mChooserMultiProfilePagerAdapter.getItem(currentPage).getEmptyStateView(); Loading core/java/com/android/internal/app/IntentForwarderActivity.java +32 −9 Original line number Diff line number Diff line Loading @@ -108,20 +108,16 @@ public class IntentForwarderActivity extends Activity { finish(); return; } if (Intent.ACTION_CHOOSER.equals(intentReceived.getAction())) { launchChooserActivityWithCorrectTab(intentReceived, className); return; } final int callingUserId = getUserId(); final Intent newIntent = canForward(intentReceived, getUserId(), targetUserId, mInjector.getIPackageManager(), getContentResolver()); if (newIntent != null) { if (Intent.ACTION_CHOOSER.equals(newIntent.getAction())) { Intent innerIntent = newIntent.getParcelableExtra(Intent.EXTRA_INTENT); // At this point, innerIntent is not null. Otherwise, canForward would have returned // false. innerIntent.prepareToLeaveUser(callingUserId); innerIntent.fixUris(callingUserId); } else { newIntent.prepareToLeaveUser(callingUserId); } final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, targetUserId); Loading Loading @@ -153,6 +149,33 @@ public class IntentForwarderActivity extends Activity { finish(); } private void launchChooserActivityWithCorrectTab(Intent intentReceived, String className) { // When showing the sharesheet, instead of forwarding to the other profile, // we launch the sharesheet in the current user and select the other tab. // This fixes b/152866292 where the user can not go back to the original profile // when cross-profile intents are disabled. int selectedProfile = findSelectedProfile(className); sanitizeIntent(intentReceived); intentReceived.putExtra(ChooserActivity.EXTRA_SELECTED_PROFILE, selectedProfile); Intent innerIntent = intentReceived.getParcelableExtra(Intent.EXTRA_INTENT); if (innerIntent == null) { Slog.wtf(TAG, "Cannot start a chooser intent with no extra " + Intent.EXTRA_INTENT); return; } sanitizeIntent(innerIntent); startActivity(intentReceived); finish(); } private int findSelectedProfile(String className) { if (className.equals(FORWARD_INTENT_TO_PARENT)) { return ChooserActivity.PROFILE_PERSONAL; } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) { return ChooserActivity.PROFILE_WORK; } return -1; } private boolean shouldShowDisclosure(@Nullable ResolveInfo ri, Intent intent) { if (!isDeviceProvisioned()) { return false; Loading core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java +9 −11 Original line number Diff line number Diff line Loading @@ -213,13 +213,9 @@ public class IntentForwarderActivityTest { } @Test public void forwardToManagedProfile_canForward_chooserIntent() throws Exception { public void launchInSameProfile_chooserIntent() { sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; // Intent can be forwarded. when(mIPm.canForwardTo( any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); // Manage profile exists. List<UserInfo> profiles = new ArrayList<>(); profiles.add(CURRENT_USER_INFO); Loading @@ -235,10 +231,6 @@ public class IntentForwarderActivityTest { intent.putExtra(Intent.EXTRA_INTENT, sendIntent); IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt()); assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction()); assertNotNull(activity.mStartActivityIntent); assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction()); assertNull(activity.mStartActivityIntent.getPackage()); Loading @@ -249,9 +241,9 @@ public class IntentForwarderActivityTest { assertEquals(Intent.ACTION_SEND, innerIntent.getAction()); assertNull(innerIntent.getComponent()); assertNull(innerIntent.getPackage()); assertEquals(CURRENT_USER_INFO.id, innerIntent.getContentUserHint()); assertEquals(UserHandle.USER_CURRENT, innerIntent.getContentUserHint()); assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn); assertEquals(CURRENT_USER_INFO.id, activity.mUserIdActivityLaunchedIn); } @Test Loading Loading @@ -655,6 +647,12 @@ public class IntentForwarderActivityTest { mUserIdActivityLaunchedIn = userId; } @Override public void startActivity(Intent intent) { mStartActivityIntent = intent; mUserIdActivityLaunchedIn = getUserId(); } @Override protected MetricsLogger getMetricsLogger() { return mMetricsLogger; Loading Loading
core/java/com/android/internal/app/ChooserActivity.java +45 −2 Original line number Diff line number Diff line Loading @@ -169,6 +169,17 @@ public class ChooserActivity extends ResolverActivity implements public static final String EXTRA_PRIVATE_RETAIN_IN_ON_STOP = "com.android.internal.app.ChooserActivity.EXTRA_PRIVATE_RETAIN_IN_ON_STOP"; /** * Integer extra to indicate which profile should be automatically selected. * <p>Can only be used if there is a work profile. * <p>Possible values can be either {@link #PROFILE_PERSONAL} or {@link #PROFILE_WORK}. */ static final String EXTRA_SELECTED_PROFILE = "com.android.internal.app.ChooserActivity.EXTRA_SELECTED_PROFILE"; static final int PROFILE_PERSONAL = AbstractMultiProfilePagerAdapter.PROFILE_PERSONAL; static final int PROFILE_WORK = AbstractMultiProfilePagerAdapter.PROFILE_WORK; private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions"; private static final String CHIP_LABEL_METADATA_KEY = "android.service.chooser.chip_label"; Loading Loading @@ -860,15 +871,31 @@ public class ChooserActivity extends ResolverActivity implements filterLastUsed, mUseLayoutForBrowsables, /* userHandle */ getWorkProfileUserHandle()); int selectedProfile = findSelectedProfile(); return new ChooserMultiProfilePagerAdapter( /* context */ this, personalAdapter, workAdapter, /* defaultProfile */ getCurrentProfile(), selectedProfile, getPersonalProfileUserHandle(), getWorkProfileUserHandle()); } private int findSelectedProfile() { int selectedProfile; if (getIntent().hasExtra(EXTRA_SELECTED_PROFILE)) { selectedProfile = getIntent().getIntExtra(EXTRA_SELECTED_PROFILE, /* defValue = */ -1); if (selectedProfile != PROFILE_PERSONAL && selectedProfile != PROFILE_WORK) { throw new IllegalArgumentException(EXTRA_SELECTED_PROFILE + " has invalid value " + selectedProfile + ". Must be either ChooserActivity.PROFILE_PERSONAL or " + "ChooserActivity.PROFILE_WORK."); } } else { selectedProfile = getProfileForUser(getUser()); } return selectedProfile; } @Override protected boolean postRebuildList(boolean rebuildCompleted) { updateStickyContentPreview(); Loading Loading @@ -2479,7 +2506,10 @@ public class ChooserActivity extends ResolverActivity implements gridAdapter.getMaxTargetsPerRow()); } if (mChooserMultiProfilePagerAdapter.getCurrentUserHandle() != getUser()) { UserHandle currentUserHandle = mChooserMultiProfilePagerAdapter.getCurrentUserHandle(); int currentProfile = getProfileForUser(currentUserHandle); int initialProfile = findSelectedProfile(); if (currentProfile != initialProfile) { return; } Loading Loading @@ -2576,6 +2606,19 @@ public class ChooserActivity extends ResolverActivity implements } } /** * Returns {@link #PROFILE_PERSONAL}, {@link #PROFILE_WORK}, or -1 if the given user handle * does not match either the personal or work user handle. **/ private int getProfileForUser(UserHandle currentUserHandle) { if (currentUserHandle == getPersonalProfileUserHandle()) { return PROFILE_PERSONAL; } else if (currentUserHandle == getWorkProfileUserHandle()) { return PROFILE_WORK; } return -1; } private ViewGroup getCurrentEmptyStateView() { int currentPage = mChooserMultiProfilePagerAdapter.getCurrentPage(); return mChooserMultiProfilePagerAdapter.getItem(currentPage).getEmptyStateView(); Loading
core/java/com/android/internal/app/IntentForwarderActivity.java +32 −9 Original line number Diff line number Diff line Loading @@ -108,20 +108,16 @@ public class IntentForwarderActivity extends Activity { finish(); return; } if (Intent.ACTION_CHOOSER.equals(intentReceived.getAction())) { launchChooserActivityWithCorrectTab(intentReceived, className); return; } final int callingUserId = getUserId(); final Intent newIntent = canForward(intentReceived, getUserId(), targetUserId, mInjector.getIPackageManager(), getContentResolver()); if (newIntent != null) { if (Intent.ACTION_CHOOSER.equals(newIntent.getAction())) { Intent innerIntent = newIntent.getParcelableExtra(Intent.EXTRA_INTENT); // At this point, innerIntent is not null. Otherwise, canForward would have returned // false. innerIntent.prepareToLeaveUser(callingUserId); innerIntent.fixUris(callingUserId); } else { newIntent.prepareToLeaveUser(callingUserId); } final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, targetUserId); Loading Loading @@ -153,6 +149,33 @@ public class IntentForwarderActivity extends Activity { finish(); } private void launchChooserActivityWithCorrectTab(Intent intentReceived, String className) { // When showing the sharesheet, instead of forwarding to the other profile, // we launch the sharesheet in the current user and select the other tab. // This fixes b/152866292 where the user can not go back to the original profile // when cross-profile intents are disabled. int selectedProfile = findSelectedProfile(className); sanitizeIntent(intentReceived); intentReceived.putExtra(ChooserActivity.EXTRA_SELECTED_PROFILE, selectedProfile); Intent innerIntent = intentReceived.getParcelableExtra(Intent.EXTRA_INTENT); if (innerIntent == null) { Slog.wtf(TAG, "Cannot start a chooser intent with no extra " + Intent.EXTRA_INTENT); return; } sanitizeIntent(innerIntent); startActivity(intentReceived); finish(); } private int findSelectedProfile(String className) { if (className.equals(FORWARD_INTENT_TO_PARENT)) { return ChooserActivity.PROFILE_PERSONAL; } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) { return ChooserActivity.PROFILE_WORK; } return -1; } private boolean shouldShowDisclosure(@Nullable ResolveInfo ri, Intent intent) { if (!isDeviceProvisioned()) { return false; Loading
core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java +9 −11 Original line number Diff line number Diff line Loading @@ -213,13 +213,9 @@ public class IntentForwarderActivityTest { } @Test public void forwardToManagedProfile_canForward_chooserIntent() throws Exception { public void launchInSameProfile_chooserIntent() { sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; // Intent can be forwarded. when(mIPm.canForwardTo( any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); // Manage profile exists. List<UserInfo> profiles = new ArrayList<>(); profiles.add(CURRENT_USER_INFO); Loading @@ -235,10 +231,6 @@ public class IntentForwarderActivityTest { intent.putExtra(Intent.EXTRA_INTENT, sendIntent); IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mIPm).canForwardTo(intentCaptor.capture(), eq(TYPE_PLAIN_TEXT), anyInt(), anyInt()); assertEquals(Intent.ACTION_SEND, intentCaptor.getValue().getAction()); assertNotNull(activity.mStartActivityIntent); assertEquals(Intent.ACTION_CHOOSER, activity.mStartActivityIntent.getAction()); assertNull(activity.mStartActivityIntent.getPackage()); Loading @@ -249,9 +241,9 @@ public class IntentForwarderActivityTest { assertEquals(Intent.ACTION_SEND, innerIntent.getAction()); assertNull(innerIntent.getComponent()); assertNull(innerIntent.getPackage()); assertEquals(CURRENT_USER_INFO.id, innerIntent.getContentUserHint()); assertEquals(UserHandle.USER_CURRENT, innerIntent.getContentUserHint()); assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn); assertEquals(CURRENT_USER_INFO.id, activity.mUserIdActivityLaunchedIn); } @Test Loading Loading @@ -655,6 +647,12 @@ public class IntentForwarderActivityTest { mUserIdActivityLaunchedIn = userId; } @Override public void startActivity(Intent intent) { mStartActivityIntent = intent; mUserIdActivityLaunchedIn = getUserId(); } @Override protected MetricsLogger getMetricsLogger() { return mMetricsLogger; Loading