Loading core/java/android/app/ActivityManagerInternal.java +9 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package android.app; import android.annotation.NonNull; import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.service.voice.IVoiceInteractionSession; Loading Loading @@ -161,4 +163,11 @@ public abstract class ActivityManagerInternal { */ public abstract void updatePersistentConfigurationForUser(@NonNull Configuration values, int userId); /** * Create an {@link IIntentSender} to start an activity, as if {@code packageName} on * user {@code userId} created it. */ public abstract IIntentSender getActivityIntentSenderAsPackage(String packageName, int userId, int requestCode, Intent intent, int flags, Bundle bOptions); } core/java/android/content/pm/ILauncherApps.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ interface ILauncherApps { in List shortcutIds, in ComponentName componentName, int flags, in UserHandle user); void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds, in UserHandle user); boolean startShortcut(String callingPackage, String packageName, String id, void startShortcut(String callingPackage, String packageName, String id, in Rect sourceBounds, in Bundle startActivityOptions, int userId); int getShortcutIconResId(String callingPackage, String packageName, String id, Loading services/core/java/com/android/server/am/ActivityManagerService.java +27 −0 Original line number Diff line number Diff line Loading @@ -21724,6 +21724,33 @@ public final class ActivityManagerService extends ActivityManagerNative updateConfigurationLocked(values, null, false, true, userId); } } @Override public IIntentSender getActivityIntentSenderAsPackage( String packageName, int userId, int requestCode, Intent intent, int flags, Bundle bOptions) { String resolvedType = intent != null ? intent.resolveTypeIfNeeded( mContext.getContentResolver()) : null; // UID of the package on user userId. // "= 0" is needed because otherwise catch(RemoteException) would make it look like // packageUid may not be initialized. int packageUid = 0; try { packageUid = AppGlobals.getPackageManager().getPackageUid( packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); } catch (RemoteException e) { // Shouldn't happen. } synchronized (ActivityManagerService.this) { return getIntentSenderLocked( ActivityManager.INTENT_SENDER_ACTIVITY, packageName, packageUid, UserHandle.getUserId(packageUid), /*token*/ null, /*resultWho*/ null, requestCode, new Intent[] {intent}, new String[]{resolvedType}, flags, bOptions); } } } private final class SleepTokenImpl extends SleepToken { services/core/java/com/android/server/pm/LauncherAppsService.java +35 −8 Original line number Diff line number Diff line Loading @@ -19,9 +19,13 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; Loading Loading @@ -98,6 +102,7 @@ public class LauncherAppsService extends SystemService { private final Context mContext; private final PackageManager mPm; private final UserManager mUm; private final ActivityManagerInternal mActivityManagerInternal; private final ShortcutServiceInternal mShortcutServiceInternal; private final PackageCallbackList<IOnAppsChangedListener> mListeners = new PackageCallbackList<IOnAppsChangedListener>(); Loading @@ -110,6 +115,8 @@ public class LauncherAppsService extends SystemService { mContext = context; mPm = mContext.getPackageManager(); mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mActivityManagerInternal = Preconditions.checkNotNull( LocalServices.getService(ActivityManagerInternal.class)); mShortcutServiceInternal = Preconditions.checkNotNull( LocalServices.getService(ShortcutServiceInternal.class)); mShortcutServiceInternal.addListener(mPackageMonitor); Loading Loading @@ -432,7 +439,7 @@ public class LauncherAppsService extends SystemService { } @Override public boolean startShortcut(String callingPackage, String packageName, String shortcutId, public void startShortcut(String callingPackage, String packageName, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int userId) { verifyCallingPackage(callingPackage); ensureInUserProfiles(userId, "Cannot start activity for unrelated profile " + userId); Loading @@ -451,20 +458,40 @@ public class LauncherAppsService extends SystemService { final Intent intent = mShortcutServiceInternal.createShortcutIntent(getCallingUserId(), callingPackage, packageName, shortcutId, userId); if (intent == null) { return false; return; } // Note the target activity doesn't have to be exported. intent.setSourceBounds(sourceBounds); prepareIntentForLaunch(intent, sourceBounds); startShortcutIntentAsPublisher( intent, packageName, startActivityOptions, userId); } @VisibleForTesting protected void startShortcutIntentAsPublisher(@NonNull Intent intent, @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { try { final IIntentSender intentSender; final long ident = Binder.clearCallingIdentity(); try { mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId)); intentSender = mActivityManagerInternal.getActivityIntentSenderAsPackage( publisherPackage, userId, /* requestCode= */ 0, intent, PendingIntent.FLAG_ONE_SHOT, /* options= */ startActivityOptions); } finally { Binder.restoreCallingIdentity(ident); } return true; // Negative result means a failure. ActivityManagerNative.getDefault().sendIntentSender( intentSender, 0, null, null, null, null, null); } catch (RemoteException e) { return; } } @Override Loading services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManagerInternal; import android.app.IUidObserver; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; Loading Loading @@ -466,6 +467,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { void injectRestoreCallingIdentity(long token) { mInjectedCallingUid = (int) token; } @Override protected void startShortcutIntentAsPublisher(@NonNull Intent intent, @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { // Just forward to startActivityAsUser() during unit tests. mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId)); } } protected class LauncherAppsTestable extends LauncherApps { Loading Loading @@ -518,6 +526,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected PackageManagerInternal mMockPackageManagerInternal; protected UserManager mMockUserManager; protected UsageStatsManagerInternal mMockUsageStatsManagerInternal; protected ActivityManagerInternal mMockActivityManagerInternal; protected static final String CALLING_PACKAGE_1 = "com.android.test.1"; protected static final int CALLING_UID_1 = 10001; Loading Loading @@ -616,11 +625,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { mMockPackageManagerInternal = mock(PackageManagerInternal.class); mMockUserManager = mock(UserManager.class); mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class); mMockActivityManagerInternal = mock(ActivityManagerInternal.class); LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal); LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); LocalServices.addService(UsageStatsManagerInternal.class, mMockUsageStatsManagerInternal); LocalServices.removeServiceForTest(ActivityManagerInternal.class); LocalServices.addService(ActivityManagerInternal.class, mMockActivityManagerInternal); // Prepare injection values. Loading Loading
core/java/android/app/ActivityManagerInternal.java +9 −0 Original line number Diff line number Diff line Loading @@ -19,7 +19,9 @@ package android.app; import android.annotation.NonNull; import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.service.voice.IVoiceInteractionSession; Loading Loading @@ -161,4 +163,11 @@ public abstract class ActivityManagerInternal { */ public abstract void updatePersistentConfigurationForUser(@NonNull Configuration values, int userId); /** * Create an {@link IIntentSender} to start an activity, as if {@code packageName} on * user {@code userId} created it. */ public abstract IIntentSender getActivityIntentSenderAsPackage(String packageName, int userId, int requestCode, Intent intent, int flags, Bundle bOptions); }
core/java/android/content/pm/ILauncherApps.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ interface ILauncherApps { in List shortcutIds, in ComponentName componentName, int flags, in UserHandle user); void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds, in UserHandle user); boolean startShortcut(String callingPackage, String packageName, String id, void startShortcut(String callingPackage, String packageName, String id, in Rect sourceBounds, in Bundle startActivityOptions, int userId); int getShortcutIconResId(String callingPackage, String packageName, String id, Loading
services/core/java/com/android/server/am/ActivityManagerService.java +27 −0 Original line number Diff line number Diff line Loading @@ -21724,6 +21724,33 @@ public final class ActivityManagerService extends ActivityManagerNative updateConfigurationLocked(values, null, false, true, userId); } } @Override public IIntentSender getActivityIntentSenderAsPackage( String packageName, int userId, int requestCode, Intent intent, int flags, Bundle bOptions) { String resolvedType = intent != null ? intent.resolveTypeIfNeeded( mContext.getContentResolver()) : null; // UID of the package on user userId. // "= 0" is needed because otherwise catch(RemoteException) would make it look like // packageUid may not be initialized. int packageUid = 0; try { packageUid = AppGlobals.getPackageManager().getPackageUid( packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId); } catch (RemoteException e) { // Shouldn't happen. } synchronized (ActivityManagerService.this) { return getIntentSenderLocked( ActivityManager.INTENT_SENDER_ACTIVITY, packageName, packageUid, UserHandle.getUserId(packageUid), /*token*/ null, /*resultWho*/ null, requestCode, new Intent[] {intent}, new String[]{resolvedType}, flags, bOptions); } } } private final class SleepTokenImpl extends SleepToken {
services/core/java/com/android/server/pm/LauncherAppsService.java +35 −8 Original line number Diff line number Diff line Loading @@ -19,9 +19,13 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; Loading Loading @@ -98,6 +102,7 @@ public class LauncherAppsService extends SystemService { private final Context mContext; private final PackageManager mPm; private final UserManager mUm; private final ActivityManagerInternal mActivityManagerInternal; private final ShortcutServiceInternal mShortcutServiceInternal; private final PackageCallbackList<IOnAppsChangedListener> mListeners = new PackageCallbackList<IOnAppsChangedListener>(); Loading @@ -110,6 +115,8 @@ public class LauncherAppsService extends SystemService { mContext = context; mPm = mContext.getPackageManager(); mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE); mActivityManagerInternal = Preconditions.checkNotNull( LocalServices.getService(ActivityManagerInternal.class)); mShortcutServiceInternal = Preconditions.checkNotNull( LocalServices.getService(ShortcutServiceInternal.class)); mShortcutServiceInternal.addListener(mPackageMonitor); Loading Loading @@ -432,7 +439,7 @@ public class LauncherAppsService extends SystemService { } @Override public boolean startShortcut(String callingPackage, String packageName, String shortcutId, public void startShortcut(String callingPackage, String packageName, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int userId) { verifyCallingPackage(callingPackage); ensureInUserProfiles(userId, "Cannot start activity for unrelated profile " + userId); Loading @@ -451,20 +458,40 @@ public class LauncherAppsService extends SystemService { final Intent intent = mShortcutServiceInternal.createShortcutIntent(getCallingUserId(), callingPackage, packageName, shortcutId, userId); if (intent == null) { return false; return; } // Note the target activity doesn't have to be exported. intent.setSourceBounds(sourceBounds); prepareIntentForLaunch(intent, sourceBounds); startShortcutIntentAsPublisher( intent, packageName, startActivityOptions, userId); } @VisibleForTesting protected void startShortcutIntentAsPublisher(@NonNull Intent intent, @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { try { final IIntentSender intentSender; final long ident = Binder.clearCallingIdentity(); try { mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId)); intentSender = mActivityManagerInternal.getActivityIntentSenderAsPackage( publisherPackage, userId, /* requestCode= */ 0, intent, PendingIntent.FLAG_ONE_SHOT, /* options= */ startActivityOptions); } finally { Binder.restoreCallingIdentity(ident); } return true; // Negative result means a failure. ActivityManagerNative.getDefault().sendIntentSender( intentSender, 0, null, null, null, null, null); } catch (RemoteException e) { return; } } @Override Loading
services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +12 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManagerInternal; import android.app.IUidObserver; import android.app.usage.UsageStatsManagerInternal; import android.content.BroadcastReceiver; Loading Loading @@ -466,6 +467,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { void injectRestoreCallingIdentity(long token) { mInjectedCallingUid = (int) token; } @Override protected void startShortcutIntentAsPublisher(@NonNull Intent intent, @NonNull String publisherPackage, Bundle startActivityOptions, int userId) { // Just forward to startActivityAsUser() during unit tests. mContext.startActivityAsUser(intent, startActivityOptions, UserHandle.of(userId)); } } protected class LauncherAppsTestable extends LauncherApps { Loading Loading @@ -518,6 +526,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { protected PackageManagerInternal mMockPackageManagerInternal; protected UserManager mMockUserManager; protected UsageStatsManagerInternal mMockUsageStatsManagerInternal; protected ActivityManagerInternal mMockActivityManagerInternal; protected static final String CALLING_PACKAGE_1 = "com.android.test.1"; protected static final int CALLING_UID_1 = 10001; Loading Loading @@ -616,11 +625,14 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { mMockPackageManagerInternal = mock(PackageManagerInternal.class); mMockUserManager = mock(UserManager.class); mMockUsageStatsManagerInternal = mock(UsageStatsManagerInternal.class); mMockActivityManagerInternal = mock(ActivityManagerInternal.class); LocalServices.removeServiceForTest(PackageManagerInternal.class); LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal); LocalServices.removeServiceForTest(UsageStatsManagerInternal.class); LocalServices.addService(UsageStatsManagerInternal.class, mMockUsageStatsManagerInternal); LocalServices.removeServiceForTest(ActivityManagerInternal.class); LocalServices.addService(ActivityManagerInternal.class, mMockActivityManagerInternal); // Prepare injection values. Loading