Loading core/java/android/app/ApplicationPackageManager.java +21 −7 Original line number Diff line number Diff line Loading @@ -1386,22 +1386,36 @@ public class ApplicationPackageManager extends PackageManager { @Override public ResolveInfo resolveActivity(Intent intent, ResolveInfoFlags flags) { return resolveActivityAsUser(intent, flags, getUserId()); return resolveActivityAsUser(intent, /* resolvedType= */ null, flags, getUserId()); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { return resolveActivityAsUser(intent, ResolveInfoFlags.of(flags), userId); return resolveActivityAsUser(intent, /* resolvedType= */ null, ResolveInfoFlags.of(flags), userId); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, ResolveInfoFlags flags, int userId) { return resolveActivityAsUser(intent, /* resolvedType= */ null, flags, userId); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId) { return resolveActivityAsUser(intent, resolvedType, ResolveInfoFlags.of(flags), userId); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, String resolvedType, ResolveInfoFlags flags, int userId) { try { return mPM.resolveIntent( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), updateFlagsForComponent(flags.getValue(), userId, intent), userId); return mPM.resolveIntent(intent, resolvedType == null ? intent.resolveTypeIfNeeded(mContext.getContentResolver()) : resolvedType, updateFlagsForComponent(flags.getValue(), userId, intent), userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading core/java/android/content/pm/PackageManager.java +29 −1 Original line number Diff line number Diff line Loading @@ -6871,8 +6871,16 @@ public abstract class PackageManager { * Intent.resolveActivity(PackageManager)} do. * </p> * * Use {@link #resolveActivityAsUser(Intent, String, ResolveInfoFlags, int)} * when long flags are needed. * * @param intent An intent containing all of the desired specification * (action, data, type, category, and/or component). * @param resolvedType A nullable resolved type for the intent's data. * Specified explicitly when the data type contained in the * intent cannot be trusted. If null is provided, the type will * be obtained from the intent using * {@link Intent#resolveTypeIfNeeded}. * @param flags Additional option flags to modify the data returned. The * most important is {@link #MATCH_DEFAULT_ONLY}, to limit the * resolution to only those activities that support the Loading @@ -6887,6 +6895,26 @@ public abstract class PackageManager { * @deprecated Use {@link #resolveActivityAsUser(Intent, ResolveInfoFlags, int)} instead. */ @Deprecated @Nullable public ResolveInfo resolveActivityAsUser(@NonNull Intent intent, @Nullable String resolvedType, int flags, @UserIdInt int userId) { return resolveActivityAsUser(intent, resolvedType, ResolveInfoFlags.of(flags), userId); } /** * See {@link #resolveActivityAsUser(Intent, String, int, int)}. * @hide */ @Nullable public ResolveInfo resolveActivityAsUser(@NonNull Intent intent, @Nullable String resolvedType, @NonNull ResolveInfoFlags flags, @UserIdInt int userId) { throw new UnsupportedOperationException( "resolveActivityAsUser not implemented in subclass"); } /** * See {@link #resolveActivityAsUser(Intent, String, int, int)}. * @hide */ @SuppressWarnings("HiddenAbstractMethod") @Nullable @UnsupportedAppUsage Loading @@ -6894,7 +6922,7 @@ public abstract class PackageManager { int flags, @UserIdInt int userId); /** * See {@link #resolveActivityAsUser(Intent, int, int)}. * See {@link #resolveActivityAsUser(Intent, String, int, int)}. * @hide */ @Nullable Loading core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +1 −1 Original line number Diff line number Diff line Loading @@ -535,7 +535,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { ContentResolver contentResolver = mContext.getContentResolver(); for (Intent intent : intents) { if (IntentForwarderActivity.canForward(intent, source, target, packageManager, contentResolver) != null) { intent.resolveTypeIfNeeded(contentResolver)) != null) { return true; } } Loading core/java/com/android/internal/app/IntentForwarderActivity.java +27 −8 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.app.AppGlobals; import android.app.admin.DevicePolicyManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.IPackageManager; Loading Loading @@ -133,8 +132,9 @@ public class IntentForwarderActivity extends Activity { } final int callingUserId = getUserId(); String resolvedType = intentReceived.resolveTypeIfNeeded(getContentResolver()); final Intent newIntent = canForward(intentReceived, getUserId(), targetUserId, mInjector.getIPackageManager(), getContentResolver()); mInjector.getIPackageManager(), resolvedType); if (newIntent == null) { Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user " Loading @@ -145,7 +145,12 @@ public class IntentForwarderActivity extends Activity { newIntent.prepareToLeaveUser(callingUserId); final CompletableFuture<ResolveInfo> targetResolveInfoFuture = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, targetUserId); mInjector.resolveActivityAsUser( newIntent, resolvedType, MATCH_DEFAULT_ONLY, targetUserId); targetResolveInfoFuture .thenApplyAsync(targetResolveInfo -> { if (isResolverActivityResolveInfo(targetResolveInfo)) { Loading Loading @@ -248,6 +253,9 @@ public class IntentForwarderActivity extends Activity { ? targetUserId : callingUserId; int selectedProfile = findSelectedProfile(className); sanitizeIntent(intentReceived); if (intentReceived.getSelector() != null) { sanitizeIntent(intentReceived.getSelector()); } intentReceived.putExtra(EXTRA_SELECTED_PROFILE, selectedProfile); intentReceived.putExtra(EXTRA_CALLING_USER, UserHandle.of(callingUserId)); startActivityAsCaller(intentReceived, null, false, userId); Loading Loading @@ -313,20 +321,20 @@ public class IntentForwarderActivity extends Activity { * forwarding if it can be forwarded, {@code null} otherwise. */ static Intent canForward(Intent incomingIntent, int sourceUserId, int targetUserId, IPackageManager packageManager, ContentResolver contentResolver) { IPackageManager packageManager, String resolvedType) { Intent forwardIntent = new Intent(incomingIntent); forwardIntent.addFlags( Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); sanitizeIntent(forwardIntent); if (!canForwardInner(forwardIntent, sourceUserId, targetUserId, packageManager, contentResolver)) { resolvedType)) { return null; } if (forwardIntent.getSelector() != null) { sanitizeIntent(forwardIntent.getSelector()); if (!canForwardInner(forwardIntent.getSelector(), sourceUserId, targetUserId, packageManager, contentResolver)) { packageManager, resolvedType)) { return null; } } Loading @@ -334,11 +342,10 @@ public class IntentForwarderActivity extends Activity { } private static boolean canForwardInner(Intent intent, int sourceUserId, int targetUserId, IPackageManager packageManager, ContentResolver contentResolver) { IPackageManager packageManager, String resolvedType) { if (Intent.ACTION_CHOOSER.equals(intent.getAction())) { return false; } String resolvedType = intent.resolveTypeIfNeeded(contentResolver); try { if (packageManager.canForwardTo( intent, resolvedType, sourceUserId, targetUserId)) { Loading Loading @@ -419,6 +426,15 @@ public class IntentForwarderActivity extends Activity { return IntentForwarderActivity.this.getPackageManager(); } @Override @Nullable public CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId) { return CompletableFuture.supplyAsync( () -> getPackageManager().resolveActivityAsUser(intent, resolvedType, flags, userId)); } @Override @Nullable public CompletableFuture<ResolveInfo> resolveActivityAsUser( Loading @@ -440,6 +456,9 @@ public class IntentForwarderActivity extends Activity { PackageManager getPackageManager(); CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId); CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, int flags, int userId); void showToast(String message, int duration); Loading core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java +19 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -267,9 +268,19 @@ public class IntentForwarderActivityTest { IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mIPm).canForwardTo( InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mIPm, times(2)).canForwardTo( intentCaptor.capture(), nullable(String.class), anyInt(), anyInt()); assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); List<Intent> capturedIntents = intentCaptor.getAllValues(); // Verify root intent is checked and sanitized assertEquals(Intent.ACTION_MAIN, capturedIntents.get(0).getAction()); assertNull(capturedIntents.get(0)); assertNull(capturedIntents.get(0).getPackage()); // Verify selector is checked and sanitized assertEquals(Intent.ACTION_VIEW, capturedIntents.get(1).getAction()); assertNull(capturedIntents.get(1)); assertNull(capturedIntents.get(1).getPackage()); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); assertNotNull(activity.mStartActivityIntent); assertEquals(Intent.ACTION_MAIN, activity.mStartActivityIntent.getAction()); Loading Loading @@ -676,6 +687,12 @@ public class IntentForwarderActivityTest { return mPm; } @Override public CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId) { return resolveActivityAsUser(intent, flags, userId); } @Override public CompletableFuture<ResolveInfo> resolveActivityAsUser( Intent intent, int flags, int userId) { Loading Loading
core/java/android/app/ApplicationPackageManager.java +21 −7 Original line number Diff line number Diff line Loading @@ -1386,22 +1386,36 @@ public class ApplicationPackageManager extends PackageManager { @Override public ResolveInfo resolveActivity(Intent intent, ResolveInfoFlags flags) { return resolveActivityAsUser(intent, flags, getUserId()); return resolveActivityAsUser(intent, /* resolvedType= */ null, flags, getUserId()); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { return resolveActivityAsUser(intent, ResolveInfoFlags.of(flags), userId); return resolveActivityAsUser(intent, /* resolvedType= */ null, ResolveInfoFlags.of(flags), userId); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, ResolveInfoFlags flags, int userId) { return resolveActivityAsUser(intent, /* resolvedType= */ null, flags, userId); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId) { return resolveActivityAsUser(intent, resolvedType, ResolveInfoFlags.of(flags), userId); } @Override public ResolveInfo resolveActivityAsUser(Intent intent, String resolvedType, ResolveInfoFlags flags, int userId) { try { return mPM.resolveIntent( intent, intent.resolveTypeIfNeeded(mContext.getContentResolver()), updateFlagsForComponent(flags.getValue(), userId, intent), userId); return mPM.resolveIntent(intent, resolvedType == null ? intent.resolveTypeIfNeeded(mContext.getContentResolver()) : resolvedType, updateFlagsForComponent(flags.getValue(), userId, intent), userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
core/java/android/content/pm/PackageManager.java +29 −1 Original line number Diff line number Diff line Loading @@ -6871,8 +6871,16 @@ public abstract class PackageManager { * Intent.resolveActivity(PackageManager)} do. * </p> * * Use {@link #resolveActivityAsUser(Intent, String, ResolveInfoFlags, int)} * when long flags are needed. * * @param intent An intent containing all of the desired specification * (action, data, type, category, and/or component). * @param resolvedType A nullable resolved type for the intent's data. * Specified explicitly when the data type contained in the * intent cannot be trusted. If null is provided, the type will * be obtained from the intent using * {@link Intent#resolveTypeIfNeeded}. * @param flags Additional option flags to modify the data returned. The * most important is {@link #MATCH_DEFAULT_ONLY}, to limit the * resolution to only those activities that support the Loading @@ -6887,6 +6895,26 @@ public abstract class PackageManager { * @deprecated Use {@link #resolveActivityAsUser(Intent, ResolveInfoFlags, int)} instead. */ @Deprecated @Nullable public ResolveInfo resolveActivityAsUser(@NonNull Intent intent, @Nullable String resolvedType, int flags, @UserIdInt int userId) { return resolveActivityAsUser(intent, resolvedType, ResolveInfoFlags.of(flags), userId); } /** * See {@link #resolveActivityAsUser(Intent, String, int, int)}. * @hide */ @Nullable public ResolveInfo resolveActivityAsUser(@NonNull Intent intent, @Nullable String resolvedType, @NonNull ResolveInfoFlags flags, @UserIdInt int userId) { throw new UnsupportedOperationException( "resolveActivityAsUser not implemented in subclass"); } /** * See {@link #resolveActivityAsUser(Intent, String, int, int)}. * @hide */ @SuppressWarnings("HiddenAbstractMethod") @Nullable @UnsupportedAppUsage Loading @@ -6894,7 +6922,7 @@ public abstract class PackageManager { int flags, @UserIdInt int userId); /** * See {@link #resolveActivityAsUser(Intent, int, int)}. * See {@link #resolveActivityAsUser(Intent, String, int, int)}. * @hide */ @Nullable Loading
core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java +1 −1 Original line number Diff line number Diff line Loading @@ -535,7 +535,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter { ContentResolver contentResolver = mContext.getContentResolver(); for (Intent intent : intents) { if (IntentForwarderActivity.canForward(intent, source, target, packageManager, contentResolver) != null) { intent.resolveTypeIfNeeded(contentResolver)) != null) { return true; } } Loading
core/java/com/android/internal/app/IntentForwarderActivity.java +27 −8 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.app.AppGlobals; import android.app.admin.DevicePolicyManager; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.IPackageManager; Loading Loading @@ -133,8 +132,9 @@ public class IntentForwarderActivity extends Activity { } final int callingUserId = getUserId(); String resolvedType = intentReceived.resolveTypeIfNeeded(getContentResolver()); final Intent newIntent = canForward(intentReceived, getUserId(), targetUserId, mInjector.getIPackageManager(), getContentResolver()); mInjector.getIPackageManager(), resolvedType); if (newIntent == null) { Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user " Loading @@ -145,7 +145,12 @@ public class IntentForwarderActivity extends Activity { newIntent.prepareToLeaveUser(callingUserId); final CompletableFuture<ResolveInfo> targetResolveInfoFuture = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, targetUserId); mInjector.resolveActivityAsUser( newIntent, resolvedType, MATCH_DEFAULT_ONLY, targetUserId); targetResolveInfoFuture .thenApplyAsync(targetResolveInfo -> { if (isResolverActivityResolveInfo(targetResolveInfo)) { Loading Loading @@ -248,6 +253,9 @@ public class IntentForwarderActivity extends Activity { ? targetUserId : callingUserId; int selectedProfile = findSelectedProfile(className); sanitizeIntent(intentReceived); if (intentReceived.getSelector() != null) { sanitizeIntent(intentReceived.getSelector()); } intentReceived.putExtra(EXTRA_SELECTED_PROFILE, selectedProfile); intentReceived.putExtra(EXTRA_CALLING_USER, UserHandle.of(callingUserId)); startActivityAsCaller(intentReceived, null, false, userId); Loading Loading @@ -313,20 +321,20 @@ public class IntentForwarderActivity extends Activity { * forwarding if it can be forwarded, {@code null} otherwise. */ static Intent canForward(Intent incomingIntent, int sourceUserId, int targetUserId, IPackageManager packageManager, ContentResolver contentResolver) { IPackageManager packageManager, String resolvedType) { Intent forwardIntent = new Intent(incomingIntent); forwardIntent.addFlags( Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); sanitizeIntent(forwardIntent); if (!canForwardInner(forwardIntent, sourceUserId, targetUserId, packageManager, contentResolver)) { resolvedType)) { return null; } if (forwardIntent.getSelector() != null) { sanitizeIntent(forwardIntent.getSelector()); if (!canForwardInner(forwardIntent.getSelector(), sourceUserId, targetUserId, packageManager, contentResolver)) { packageManager, resolvedType)) { return null; } } Loading @@ -334,11 +342,10 @@ public class IntentForwarderActivity extends Activity { } private static boolean canForwardInner(Intent intent, int sourceUserId, int targetUserId, IPackageManager packageManager, ContentResolver contentResolver) { IPackageManager packageManager, String resolvedType) { if (Intent.ACTION_CHOOSER.equals(intent.getAction())) { return false; } String resolvedType = intent.resolveTypeIfNeeded(contentResolver); try { if (packageManager.canForwardTo( intent, resolvedType, sourceUserId, targetUserId)) { Loading Loading @@ -419,6 +426,15 @@ public class IntentForwarderActivity extends Activity { return IntentForwarderActivity.this.getPackageManager(); } @Override @Nullable public CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId) { return CompletableFuture.supplyAsync( () -> getPackageManager().resolveActivityAsUser(intent, resolvedType, flags, userId)); } @Override @Nullable public CompletableFuture<ResolveInfo> resolveActivityAsUser( Loading @@ -440,6 +456,9 @@ public class IntentForwarderActivity extends Activity { PackageManager getPackageManager(); CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId); CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, int flags, int userId); void showToast(String message, int duration); Loading
core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java +19 −2 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -267,9 +268,19 @@ public class IntentForwarderActivityTest { IntentForwarderWrapperActivity activity = mActivityRule.launchActivity(intent); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); verify(mIPm).canForwardTo( InstrumentationRegistry.getInstrumentation().waitForIdleSync(); verify(mIPm, times(2)).canForwardTo( intentCaptor.capture(), nullable(String.class), anyInt(), anyInt()); assertEquals(Intent.ACTION_VIEW, intentCaptor.getValue().getAction()); List<Intent> capturedIntents = intentCaptor.getAllValues(); // Verify root intent is checked and sanitized assertEquals(Intent.ACTION_MAIN, capturedIntents.get(0).getAction()); assertNull(capturedIntents.get(0)); assertNull(capturedIntents.get(0).getPackage()); // Verify selector is checked and sanitized assertEquals(Intent.ACTION_VIEW, capturedIntents.get(1).getAction()); assertNull(capturedIntents.get(1)); assertNull(capturedIntents.get(1).getPackage()); InstrumentationRegistry.getInstrumentation().waitForIdleSync(); assertNotNull(activity.mStartActivityIntent); assertEquals(Intent.ACTION_MAIN, activity.mStartActivityIntent.getAction()); Loading Loading @@ -676,6 +687,12 @@ public class IntentForwarderActivityTest { return mPm; } @Override public CompletableFuture<ResolveInfo> resolveActivityAsUser(Intent intent, String resolvedType, int flags, int userId) { return resolveActivityAsUser(intent, flags, userId); } @Override public CompletableFuture<ResolveInfo> resolveActivityAsUser( Intent intent, int flags, int userId) { Loading