Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -12139,6 +12139,7 @@ package android.content.pm { method @Nullable public android.content.IntentSender getShortcutConfigActivityIntent(@NonNull android.content.pm.LauncherActivityInfo); method public java.util.List<android.content.pm.LauncherActivityInfo> getShortcutConfigActivityList(@Nullable String, @NonNull android.os.UserHandle); method public android.graphics.drawable.Drawable getShortcutIconDrawable(@NonNull android.content.pm.ShortcutInfo, int); method @Nullable public android.app.PendingIntent getShortcutIntent(@NonNull String, @NonNull String, @Nullable android.os.Bundle, @NonNull android.os.UserHandle); method @Nullable public java.util.List<android.content.pm.ShortcutInfo> getShortcuts(@NonNull android.content.pm.LauncherApps.ShortcutQuery, @NonNull android.os.UserHandle); method @Nullable public android.os.Bundle getSuspendedPackageLauncherExtras(String, android.os.UserHandle); method public boolean hasShortcutHostPermission(); core/java/android/content/pm/ILauncherApps.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ interface ILauncherApps { String callingPackage, String packageName, in UserHandle user); IntentSender getShortcutConfigActivityIntent(String callingPackage, in ComponentName component, in UserHandle user); PendingIntent getShortcutIntent(String callingPackage, String packageName, String shortcutId, in Bundle opts, in UserHandle user); // Unregister is performed using package installer void registerPackageInstallerCallback(String callingPackage, Loading core/java/android/content/pm/LauncherApps.java +24 −0 Original line number Diff line number Diff line Loading @@ -842,6 +842,30 @@ public class LauncherApps { } } /** * Returns PendingIntent associated with specified shortcut. * * @param packageName The packageName of the shortcut * @param shortcutId The id of the shortcut * @param opts Options to pass to the PendingIntent * @param user The UserHandle of the profile */ @Nullable public PendingIntent getShortcutIntent(@NonNull final String packageName, @NonNull final String shortcutId, @Nullable final Bundle opts, @NonNull final UserHandle user) { logErrorForInvalidProfileAccess(user); if (DEBUG) { Log.i(TAG, "GetShortcutIntent " + packageName + "/" + shortcutId + " " + user); } try { return mService.getShortcutIntent( mContext.getPackageName(), packageName, shortcutId, opts, user); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Retrieves a list of config activities for creating {@link ShortcutInfo}. * Loading services/core/java/com/android/server/pm/LauncherAppsService.java +45 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.pm; import static android.app.ActivityOptions.KEY_SPLASH_SCREEN_THEME; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_MUTABLE; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.pm.LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS; Loading Loading @@ -648,6 +649,43 @@ public class LauncherAppsService extends SystemService { } } /** * Returns the intents for a specific shortcut. */ @Nullable @Override public PendingIntent getShortcutIntent(@NonNull final String callingPackage, @NonNull final String packageName, @NonNull final String shortcutId, @Nullable final Bundle opts, @NonNull final UserHandle user) throws RemoteException { Objects.requireNonNull(callingPackage); Objects.requireNonNull(packageName); Objects.requireNonNull(shortcutId); Objects.requireNonNull(user); ensureShortcutPermission(callingPackage); if (!canAccessProfile(user.getIdentifier(), "Cannot get shortcuts")) { return null; } final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( getCallingUserId(), callingPackage, packageName, shortcutId, user.getIdentifier(), injectBinderCallingPid(), injectBinderCallingUid()); if (intents == null || intents.length == 0) { return null; } final long ident = Binder.clearCallingIdentity(); try { return injectCreatePendingIntent(mContext.createPackageContextAsUser(packageName, 0, user), 0 /* requestCode */, intents, FLAG_MUTABLE, opts, user); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "Cannot create pending intent from shortcut " + shortcutId, e); } finally { Binder.restoreCallingIdentity(ident); } return null; } @Override public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user) throws RemoteException { Loading Loading @@ -756,6 +794,13 @@ public class LauncherAppsService extends SystemService { callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } @VisibleForTesting PendingIntent injectCreatePendingIntent(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) { return PendingIntent.getActivitiesAsUser(context, requestCode, intents, flags, options, user); } @Override public ParceledListSlice getShortcuts(@NonNull final String callingPackage, @NonNull final ShortcutQueryWrapper query, @NonNull final UserHandle targetUser) { Loading services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +15 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.IUidObserver; import android.app.PendingIntent; import android.app.Person; import android.app.admin.DevicePolicyManager; import android.app.appsearch.AppSearchBatchResult; Loading @@ -60,6 +61,7 @@ import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; Loading Loading @@ -197,6 +199,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return this; } @Override public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) throws PackageManager.NameNotFoundException { // ignore. return this; } @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler) { Loading Loading @@ -620,6 +629,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { boolean injectHasInteractAcrossUsersFullPermission(int callingPid, int callingUid) { return false; } @Override PendingIntent injectCreatePendingIntent(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) { return new PendingIntent(mock(IIntentSender.class)); } } protected class LauncherAppsTestable extends LauncherApps { Loading Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -12139,6 +12139,7 @@ package android.content.pm { method @Nullable public android.content.IntentSender getShortcutConfigActivityIntent(@NonNull android.content.pm.LauncherActivityInfo); method public java.util.List<android.content.pm.LauncherActivityInfo> getShortcutConfigActivityList(@Nullable String, @NonNull android.os.UserHandle); method public android.graphics.drawable.Drawable getShortcutIconDrawable(@NonNull android.content.pm.ShortcutInfo, int); method @Nullable public android.app.PendingIntent getShortcutIntent(@NonNull String, @NonNull String, @Nullable android.os.Bundle, @NonNull android.os.UserHandle); method @Nullable public java.util.List<android.content.pm.ShortcutInfo> getShortcuts(@NonNull android.content.pm.LauncherApps.ShortcutQuery, @NonNull android.os.UserHandle); method @Nullable public android.os.Bundle getSuspendedPackageLauncherExtras(String, android.os.UserHandle); method public boolean hasShortcutHostPermission();
core/java/android/content/pm/ILauncherApps.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,8 @@ interface ILauncherApps { String callingPackage, String packageName, in UserHandle user); IntentSender getShortcutConfigActivityIntent(String callingPackage, in ComponentName component, in UserHandle user); PendingIntent getShortcutIntent(String callingPackage, String packageName, String shortcutId, in Bundle opts, in UserHandle user); // Unregister is performed using package installer void registerPackageInstallerCallback(String callingPackage, Loading
core/java/android/content/pm/LauncherApps.java +24 −0 Original line number Diff line number Diff line Loading @@ -842,6 +842,30 @@ public class LauncherApps { } } /** * Returns PendingIntent associated with specified shortcut. * * @param packageName The packageName of the shortcut * @param shortcutId The id of the shortcut * @param opts Options to pass to the PendingIntent * @param user The UserHandle of the profile */ @Nullable public PendingIntent getShortcutIntent(@NonNull final String packageName, @NonNull final String shortcutId, @Nullable final Bundle opts, @NonNull final UserHandle user) { logErrorForInvalidProfileAccess(user); if (DEBUG) { Log.i(TAG, "GetShortcutIntent " + packageName + "/" + shortcutId + " " + user); } try { return mService.getShortcutIntent( mContext.getPackageName(), packageName, shortcutId, opts, user); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Retrieves a list of config activities for creating {@link ShortcutInfo}. * Loading
services/core/java/com/android/server/pm/LauncherAppsService.java +45 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.server.pm; import static android.app.ActivityOptions.KEY_SPLASH_SCREEN_THEME; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_MUTABLE; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.pm.LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS; Loading Loading @@ -648,6 +649,43 @@ public class LauncherAppsService extends SystemService { } } /** * Returns the intents for a specific shortcut. */ @Nullable @Override public PendingIntent getShortcutIntent(@NonNull final String callingPackage, @NonNull final String packageName, @NonNull final String shortcutId, @Nullable final Bundle opts, @NonNull final UserHandle user) throws RemoteException { Objects.requireNonNull(callingPackage); Objects.requireNonNull(packageName); Objects.requireNonNull(shortcutId); Objects.requireNonNull(user); ensureShortcutPermission(callingPackage); if (!canAccessProfile(user.getIdentifier(), "Cannot get shortcuts")) { return null; } final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( getCallingUserId(), callingPackage, packageName, shortcutId, user.getIdentifier(), injectBinderCallingPid(), injectBinderCallingUid()); if (intents == null || intents.length == 0) { return null; } final long ident = Binder.clearCallingIdentity(); try { return injectCreatePendingIntent(mContext.createPackageContextAsUser(packageName, 0, user), 0 /* requestCode */, intents, FLAG_MUTABLE, opts, user); } catch (PackageManager.NameNotFoundException e) { Slog.e(TAG, "Cannot create pending intent from shortcut " + shortcutId, e); } finally { Binder.restoreCallingIdentity(ident); } return null; } @Override public boolean isPackageEnabled(String callingPackage, String packageName, UserHandle user) throws RemoteException { Loading Loading @@ -756,6 +794,13 @@ public class LauncherAppsService extends SystemService { callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; } @VisibleForTesting PendingIntent injectCreatePendingIntent(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) { return PendingIntent.getActivitiesAsUser(context, requestCode, intents, flags, options, user); } @Override public ParceledListSlice getShortcuts(@NonNull final String callingPackage, @NonNull final ShortcutQueryWrapper query, @NonNull final UserHandle targetUser) { Loading
services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +15 −0 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.IUidObserver; import android.app.PendingIntent; import android.app.Person; import android.app.admin.DevicePolicyManager; import android.app.appsearch.AppSearchBatchResult; Loading @@ -60,6 +61,7 @@ import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; Loading Loading @@ -197,6 +199,13 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { return this; } @Override public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) throws PackageManager.NameNotFoundException { // ignore. return this; } @Override public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler) { Loading Loading @@ -620,6 +629,12 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { boolean injectHasInteractAcrossUsersFullPermission(int callingPid, int callingUid) { return false; } @Override PendingIntent injectCreatePendingIntent(Context context, int requestCode, @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) { return new PendingIntent(mock(IIntentSender.class)); } } protected class LauncherAppsTestable extends LauncherApps { Loading