From 0e19f669c3703a6c29baece731b09011e01e1790 Mon Sep 17 00:00:00 2001 From: Anthony Alridge Date: Tue, 2 May 2023 09:30:05 +0000 Subject: Remove auto-launching for single target, multiple tabs This can lead to poor UX when auto-launching across tabs. If the intent picker should be shown (e.g dev calls startActivity), and there is only a single app to handle the intent, then this has no affect. It is handled in either IntentForwarderActivity, or in ResolverActivity (mini-resolver). However, if the dev calls Intent.createChooser/ACTION_CHOOSER, without an ACTION_SEND intent (ChooserActivity), then we show something that looks like an intent picker, which has this incorrect auto-launching logic. For now we simply remove the logic because it doesn't make sesnse in an actual sharing context, and if ACTION_SEND is not used it leads to a security vulnerability and very poor UX (b/270700718). In a future release we can hopefully improve this and treat this case in-line with the intent-picker (e.g., showing the mini-resolver). Bug: 272208024 Bug: 270700718 Test: atest ResolverActivityTest Test: atest UnbundledChoserActivityTest Test: Manually tested, attached screenshots in bug Change-Id: I1a340cab94230cada1e7e805195070b032e7c5ff --- .../android/intentresolver/ResolverActivity.java | 23 ++++------------------ .../intentresolver/ResolverActivityTest.java | 5 +++-- .../UnbundledChooserActivityTest.java | 4 ++-- 3 files changed, 9 insertions(+), 23 deletions(-) (limited to 'java') diff --git a/java/src/com/android/intentresolver/ResolverActivity.java b/java/src/com/android/intentresolver/ResolverActivity.java index aea6c2c9..06a1d90c 100644 --- a/java/src/com/android/intentresolver/ResolverActivity.java +++ b/java/src/com/android/intentresolver/ResolverActivity.java @@ -1864,8 +1864,10 @@ public class ResolverActivity extends FragmentActivity implements } else if (numberOfProfiles == 2 && mMultiProfilePagerAdapter.getActiveListAdapter().isTabLoaded() && mMultiProfilePagerAdapter.getInactiveListAdapter().isTabLoaded() - && (maybeAutolaunchIfNoAppsOnInactiveTab() - || maybeAutolaunchIfCrossProfileSupported())) { + && maybeAutolaunchIfCrossProfileSupported()) { + // TODO(b/280988288): If the ChooserActivity is shown we should consider showing the + // correct intent-picker UIs (e.g., mini-resolver) if it was launched without + // ACTION_SEND. return true; } return false; @@ -1892,23 +1894,6 @@ public class ResolverActivity extends FragmentActivity implements return false; } - private boolean maybeAutolaunchIfNoAppsOnInactiveTab() { - int count = mMultiProfilePagerAdapter.getActiveListAdapter().getUnfilteredCount(); - if (count != 1) { - return false; - } - ResolverListAdapter inactiveListAdapter = - mMultiProfilePagerAdapter.getInactiveListAdapter(); - if (inactiveListAdapter.getUnfilteredCount() != 0) { - return false; - } - TargetInfo target = mMultiProfilePagerAdapter.getActiveListAdapter() - .targetInfoForPosition(0, false); - safelyStartActivity(target); - finish(); - return true; - } - /** * When we have a personal and a work profile, we auto launch in the following scenario: * - There is 1 resolved target on each profile diff --git a/java/tests/src/com/android/intentresolver/ResolverActivityTest.java b/java/tests/src/com/android/intentresolver/ResolverActivityTest.java index 5cece092..31c0a498 100644 --- a/java/tests/src/com/android/intentresolver/ResolverActivityTest.java +++ b/java/tests/src/com/android/intentresolver/ResolverActivityTest.java @@ -34,6 +34,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -741,7 +742,7 @@ public class ResolverActivityTest { } @Test - public void testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_autolaunch() { + public void testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_doesNotAutoLaunch() { markWorkProfileUserAvailable(); int workProfileTargets = 4; List personalResolvedComponentInfos = @@ -763,7 +764,7 @@ public class ResolverActivityTest { mActivityRule.launchActivity(sendIntent); waitForIdle(); - assertThat(chosen[0], is(personalResolvedComponentInfos.get(1).getResolveInfoAt(0))); + assertNull(chosen[0]); } @Test diff --git a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java index 6ba67fa7..c2212bc2 100644 --- a/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java +++ b/java/tests/src/com/android/intentresolver/UnbundledChooserActivityTest.java @@ -2341,7 +2341,7 @@ public class UnbundledChooserActivityTest { } @Test - public void testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_autolaunch() { + public void testWorkTab_onePersonalTarget_emptyStateOnWorkTarget_doesNotAutoLaunch() { markWorkProfileUserAvailable(); int workProfileTargets = 4; List personalResolvedComponentInfos = @@ -2360,7 +2360,7 @@ public class UnbundledChooserActivityTest { mActivityRule.launchActivity(Intent.createChooser(sendIntent, "Test")); waitForIdle(); - assertThat(chosen[0], is(personalResolvedComponentInfos.get(1).getResolveInfoAt(0))); + assertNull(chosen[0]); } @Test -- cgit v1.2.3-59-g8ed1b