Loading core/java/android/window/WindowContainerTransaction.java +55 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.app.PendingIntent; import android.app.WindowConfiguration; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; Loading Loading @@ -434,6 +435,21 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Starts activity(s) from a shortcut. * @param callingPackage The package launching the shortcut. * @param shortcutInfo Information about the shortcut to start * @param options bundle containing ActivityOptions for the task's top activity. * @hide */ @NonNull public WindowContainerTransaction startShortcut(@NonNull String callingPackage, @NonNull ShortcutInfo shortcutInfo, @Nullable Bundle options) { mHierarchyOps.add(HierarchyOp.createForStartShortcut( callingPackage, shortcutInfo, options)); return this; } /** * Creates a new TaskFragment with the given options. * @param taskFragmentOptions the options used to create the TaskFragment. Loading Loading @@ -957,11 +973,16 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_REPARENT_CHILDREN = 11; public static final int HIERARCHY_OP_TYPE_PENDING_INTENT = 12; public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 13; public static final int HIERARCHY_OP_TYPE_START_SHORTCUT = 14; // The following key(s) are for use with mLaunchOptions: // When launching a task (eg. from recents), this is the taskId to be launched. public static final String LAUNCH_KEY_TASK_ID = "android:transaction.hop.taskId"; // When starting from a shortcut, this contains the calling package. public static final String LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE = "android:transaction.hop.shortcut_calling_package"; private final int mType; // Container we are performing the operation on. Loading Loading @@ -999,6 +1020,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private PendingIntent mPendingIntent; @Nullable private ShortcutInfo mShortcutInfo; public static HierarchyOp createForReparent( @NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) { return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT) Loading Loading @@ -1058,6 +1082,17 @@ public final class WindowContainerTransaction implements Parcelable { .build(); } /** Create a hierarchy op for starting a shortcut. */ public static HierarchyOp createForStartShortcut(@NonNull String callingPackage, @NonNull ShortcutInfo shortcutInfo, @Nullable Bundle options) { final Bundle fullOptions = options == null ? new Bundle() : options; fullOptions.putString(LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE, callingPackage); return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_START_SHORTCUT) .setShortcutInfo(shortcutInfo) .setLaunchOptions(fullOptions) .build(); } /** Create a hierarchy op for setting launch adjacent flag root. */ public static HierarchyOp createForSetLaunchAdjacentFlagRoot(IBinder container, boolean clearRoot) { Loading Loading @@ -1085,6 +1120,7 @@ public final class WindowContainerTransaction implements Parcelable { mActivityIntent = copy.mActivityIntent; mTaskFragmentCreationOptions = copy.mTaskFragmentCreationOptions; mPendingIntent = copy.mPendingIntent; mShortcutInfo = copy.mShortcutInfo; } protected HierarchyOp(Parcel in) { Loading @@ -1100,6 +1136,7 @@ public final class WindowContainerTransaction implements Parcelable { mActivityIntent = in.readTypedObject(Intent.CREATOR); mTaskFragmentCreationOptions = in.readTypedObject(TaskFragmentCreationParams.CREATOR); mPendingIntent = in.readTypedObject(PendingIntent.CREATOR); mShortcutInfo = in.readTypedObject(ShortcutInfo.CREATOR); } public int getType() { Loading Loading @@ -1170,6 +1207,11 @@ public final class WindowContainerTransaction implements Parcelable { return mPendingIntent; } @Nullable public ShortcutInfo getShortcutInfo() { return mShortcutInfo; } @Override public String toString() { switch (mType) { Loading Loading @@ -1212,6 +1254,9 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS: return "{SetAdjacentTaskFragments: container=" + mContainer + " adjacentContainer=" + mReparent + "}"; case HIERARCHY_OP_TYPE_START_SHORTCUT: return "{StartShortcut: options=" + mLaunchOptions + " info=" + mShortcutInfo + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop Loading @@ -1234,6 +1279,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeTypedObject(mActivityIntent, flags); dest.writeTypedObject(mTaskFragmentCreationOptions, flags); dest.writeTypedObject(mPendingIntent, flags); dest.writeTypedObject(mShortcutInfo, flags); } @Override Loading Loading @@ -1287,6 +1333,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private PendingIntent mPendingIntent; @Nullable private ShortcutInfo mShortcutInfo; Builder(int type) { mType = type; } Loading Loading @@ -1347,6 +1396,11 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setShortcutInfo(@Nullable ShortcutInfo shortcutInfo) { mShortcutInfo = shortcutInfo; return this; } HierarchyOp build() { final HierarchyOp hierarchyOp = new HierarchyOp(mType); hierarchyOp.mContainer = mContainer; Loading @@ -1364,6 +1418,7 @@ public final class WindowContainerTransaction implements Parcelable { hierarchyOp.mActivityIntent = mActivityIntent; hierarchyOp.mPendingIntent = mPendingIntent; hierarchyOp.mTaskFragmentCreationOptions = mTaskFragmentCreationOptions; hierarchyOp.mShortcutInfo = mShortcutInfo; return hierarchyOp; } Loading services/core/java/com/android/server/pm/LauncherAppsService.java +64 −16 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ public class LauncherAppsService extends SystemService { public void onStart() { publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); mLauncherAppsImpl.registerLoadingProgressForIncrementalApps(); LocalServices.addService(LauncherAppsServiceInternal.class, mLauncherAppsImpl.mInternal); } static class BroadcastCookie { Loading @@ -137,6 +138,17 @@ public class LauncherAppsService extends SystemService { } } /** * Local system service interface. * @hide Only for use within system server */ public abstract static class LauncherAppsServiceInternal { /** Same as startShortcut except supports forwarding of caller uid/pid. */ public abstract boolean startShortcut(int callerUid, int callerPid, String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId); } @VisibleForTesting static class LauncherAppsImpl extends ILauncherApps.Stub { private static final boolean DEBUG = false; Loading Loading @@ -168,6 +180,8 @@ public class LauncherAppsService extends SystemService { private PackageInstallerService mPackageInstallerService; final LauncherAppsServiceInternal mInternal; public LauncherAppsImpl(Context context) { mContext = context; mIPM = AppGlobals.getPackageManager(); Loading @@ -189,6 +203,7 @@ public class LauncherAppsService extends SystemService { mShortcutServiceInternal.addShortcutChangeCallback(mShortcutChangeHandler); mCallbackHandler = BackgroundThread.getHandler(); mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); mInternal = new LocalService(); } @VisibleForTesting Loading Loading @@ -359,11 +374,15 @@ public class LauncherAppsService extends SystemService { * group. */ private boolean canAccessProfile(int targetUserId, String message) { final int callingUserId = injectCallingUserId(); return canAccessProfile(injectBinderCallingUid(), injectCallingUserId(), injectBinderCallingPid(), targetUserId, message); } private boolean canAccessProfile(int callingUid, int callingUserId, int callingPid, int targetUserId, String message) { if (targetUserId == callingUserId) return true; if (injectHasInteractAcrossUsersFullPermission(injectBinderCallingPid(), injectBinderCallingUid())) { if (injectHasInteractAcrossUsersFullPermission(callingPid, callingUid)) { return true; } Loading @@ -379,25 +398,29 @@ public class LauncherAppsService extends SystemService { injectRestoreCallingIdentity(ident); } return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId, return mUserManagerInternal.isProfileAccessible(callingUserId, targetUserId, message, true); } private void verifyCallingPackage(String callingPackage) { verifyCallingPackage(callingPackage, injectBinderCallingUid()); } @VisibleForTesting // We override it in unit tests void verifyCallingPackage(String callingPackage) { void verifyCallingPackage(String callingPackage, int callerUid) { int packageUid = -1; try { packageUid = mIPM.getPackageUid(callingPackage, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_UNINSTALLED_PACKAGES, UserHandle.getUserId(getCallingUid())); UserHandle.getUserId(callerUid)); } catch (RemoteException ignore) { } if (packageUid < 0) { Log.e(TAG, "Package not found: " + callingPackage); } if (packageUid != injectBinderCallingUid()) { if (packageUid != callerUid) { throw new SecurityException("Calling package name mismatch"); } } Loading Loading @@ -797,9 +820,15 @@ public class LauncherAppsService extends SystemService { } private void ensureShortcutPermission(@NonNull String callingPackage) { verifyCallingPackage(callingPackage); if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), callingPackage, injectBinderCallingPid(), injectBinderCallingUid())) { ensureShortcutPermission(injectBinderCallingUid(), injectBinderCallingPid(), callingPackage); } private void ensureShortcutPermission(int callerUid, int callerPid, @NonNull String callingPackage) { verifyCallingPackage(callingPackage, callerUid); if (!mShortcutServiceInternal.hasShortcutHostPermission(UserHandle.getUserId(callerUid), callingPackage, callerPid, callerUid)) { throw new SecurityException("Caller can't access shortcut information"); } } Loading Loading @@ -989,20 +1018,28 @@ public class LauncherAppsService extends SystemService { public boolean startShortcut(String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { verifyCallingPackage(callingPackage); return startShortcutInner(injectBinderCallingUid(), injectBinderCallingPid(), injectCallingUserId(), callingPackage, packageName, featureId, shortcutId, sourceBounds, startActivityOptions, targetUserId); } private boolean startShortcutInner(int callerUid, int callerPid, int callingUserId, String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { verifyCallingPackage(callingPackage, callerUid); if (!canAccessProfile(targetUserId, "Cannot start activity")) { return false; } // Even without the permission, pinned shortcuts are always launchable. if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), if (!mShortcutServiceInternal.isPinnedByCaller(callingUserId, callingPackage, packageName, shortcutId, targetUserId)) { ensureShortcutPermission(callingPackage); ensureShortcutPermission(callerUid, callerPid, callingPackage); } final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId, injectBinderCallingPid(), injectBinderCallingUid()); callingUserId, callingPackage, packageName, shortcutId, targetUserId, callerPid, callerUid); if (intents == null || intents.length == 0) { return false; } Loading @@ -1023,7 +1060,7 @@ public class LauncherAppsService extends SystemService { // Replace theme for splash screen final String splashScreenThemeResName = mShortcutServiceInternal.getShortcutStartingThemeResName(getCallingUserId(), mShortcutServiceInternal.getShortcutStartingThemeResName(callingUserId, callingPackage, packageName, shortcutId, targetUserId); if (splashScreenThemeResName != null && !splashScreenThemeResName.isEmpty()) { if (startActivityOptions == null) { Loading Loading @@ -1809,5 +1846,16 @@ public class LauncherAppsService extends SystemService { } } } final class LocalService extends LauncherAppsServiceInternal { @Override public boolean startShortcut(int callerUid, int callerPid, String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { return LauncherAppsImpl.this.startShortcutInner(callerUid, callerPid, UserHandle.getUserId(callerUid), callingPackage, packageName, featureId, shortcutId, sourceBounds, startActivityOptions, targetUserId); } } } } services/core/java/com/android/server/wm/WindowOrganizerController.java +19 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_SHORTCUT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED; Loading Loading @@ -79,6 +80,8 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.pm.LauncherAppsService.LauncherAppsServiceInternal; import java.util.ArrayList; import java.util.HashMap; Loading Loading @@ -785,6 +788,22 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub null /* requiredPermission */, options); break; } case HIERARCHY_OP_TYPE_START_SHORTCUT: { final Bundle launchOpts = hop.getLaunchOptions(); final String callingPackage = launchOpts.getString( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE); launchOpts.remove( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE); final LauncherAppsServiceInternal launcherApps = LocalServices.getService( LauncherAppsServiceInternal.class); launcherApps.startShortcut(caller.mUid, caller.mPid, callingPackage, hop.getShortcutInfo().getPackage(), null /* default featureId */, hop.getShortcutInfo().getId(), null /* sourceBounds */, launchOpts, hop.getShortcutInfo().getUserId()); break; } case HIERARCHY_OP_TYPE_REPARENT_CHILDREN: { final WindowContainer oldParent = WindowContainer.fromBinder(hop.getContainer()); final WindowContainer newParent = hop.getNewParent() != null Loading services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -579,7 +579,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override public void verifyCallingPackage(String callingPackage) { public void verifyCallingPackage(String callingPackage, int callerUid) { // SKIP } Loading Loading
core/java/android/window/WindowContainerTransaction.java +55 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.app.PendingIntent; import android.app.WindowConfiguration; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; Loading Loading @@ -434,6 +435,21 @@ public final class WindowContainerTransaction implements Parcelable { return this; } /** * Starts activity(s) from a shortcut. * @param callingPackage The package launching the shortcut. * @param shortcutInfo Information about the shortcut to start * @param options bundle containing ActivityOptions for the task's top activity. * @hide */ @NonNull public WindowContainerTransaction startShortcut(@NonNull String callingPackage, @NonNull ShortcutInfo shortcutInfo, @Nullable Bundle options) { mHierarchyOps.add(HierarchyOp.createForStartShortcut( callingPackage, shortcutInfo, options)); return this; } /** * Creates a new TaskFragment with the given options. * @param taskFragmentOptions the options used to create the TaskFragment. Loading Loading @@ -957,11 +973,16 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_REPARENT_CHILDREN = 11; public static final int HIERARCHY_OP_TYPE_PENDING_INTENT = 12; public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 13; public static final int HIERARCHY_OP_TYPE_START_SHORTCUT = 14; // The following key(s) are for use with mLaunchOptions: // When launching a task (eg. from recents), this is the taskId to be launched. public static final String LAUNCH_KEY_TASK_ID = "android:transaction.hop.taskId"; // When starting from a shortcut, this contains the calling package. public static final String LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE = "android:transaction.hop.shortcut_calling_package"; private final int mType; // Container we are performing the operation on. Loading Loading @@ -999,6 +1020,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private PendingIntent mPendingIntent; @Nullable private ShortcutInfo mShortcutInfo; public static HierarchyOp createForReparent( @NonNull IBinder container, @Nullable IBinder reparent, boolean toTop) { return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_REPARENT) Loading Loading @@ -1058,6 +1082,17 @@ public final class WindowContainerTransaction implements Parcelable { .build(); } /** Create a hierarchy op for starting a shortcut. */ public static HierarchyOp createForStartShortcut(@NonNull String callingPackage, @NonNull ShortcutInfo shortcutInfo, @Nullable Bundle options) { final Bundle fullOptions = options == null ? new Bundle() : options; fullOptions.putString(LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE, callingPackage); return new HierarchyOp.Builder(HIERARCHY_OP_TYPE_START_SHORTCUT) .setShortcutInfo(shortcutInfo) .setLaunchOptions(fullOptions) .build(); } /** Create a hierarchy op for setting launch adjacent flag root. */ public static HierarchyOp createForSetLaunchAdjacentFlagRoot(IBinder container, boolean clearRoot) { Loading Loading @@ -1085,6 +1120,7 @@ public final class WindowContainerTransaction implements Parcelable { mActivityIntent = copy.mActivityIntent; mTaskFragmentCreationOptions = copy.mTaskFragmentCreationOptions; mPendingIntent = copy.mPendingIntent; mShortcutInfo = copy.mShortcutInfo; } protected HierarchyOp(Parcel in) { Loading @@ -1100,6 +1136,7 @@ public final class WindowContainerTransaction implements Parcelable { mActivityIntent = in.readTypedObject(Intent.CREATOR); mTaskFragmentCreationOptions = in.readTypedObject(TaskFragmentCreationParams.CREATOR); mPendingIntent = in.readTypedObject(PendingIntent.CREATOR); mShortcutInfo = in.readTypedObject(ShortcutInfo.CREATOR); } public int getType() { Loading Loading @@ -1170,6 +1207,11 @@ public final class WindowContainerTransaction implements Parcelable { return mPendingIntent; } @Nullable public ShortcutInfo getShortcutInfo() { return mShortcutInfo; } @Override public String toString() { switch (mType) { Loading Loading @@ -1212,6 +1254,9 @@ public final class WindowContainerTransaction implements Parcelable { case HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS: return "{SetAdjacentTaskFragments: container=" + mContainer + " adjacentContainer=" + mReparent + "}"; case HIERARCHY_OP_TYPE_START_SHORTCUT: return "{StartShortcut: options=" + mLaunchOptions + " info=" + mShortcutInfo + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop Loading @@ -1234,6 +1279,7 @@ public final class WindowContainerTransaction implements Parcelable { dest.writeTypedObject(mActivityIntent, flags); dest.writeTypedObject(mTaskFragmentCreationOptions, flags); dest.writeTypedObject(mPendingIntent, flags); dest.writeTypedObject(mShortcutInfo, flags); } @Override Loading Loading @@ -1287,6 +1333,9 @@ public final class WindowContainerTransaction implements Parcelable { @Nullable private PendingIntent mPendingIntent; @Nullable private ShortcutInfo mShortcutInfo; Builder(int type) { mType = type; } Loading Loading @@ -1347,6 +1396,11 @@ public final class WindowContainerTransaction implements Parcelable { return this; } Builder setShortcutInfo(@Nullable ShortcutInfo shortcutInfo) { mShortcutInfo = shortcutInfo; return this; } HierarchyOp build() { final HierarchyOp hierarchyOp = new HierarchyOp(mType); hierarchyOp.mContainer = mContainer; Loading @@ -1364,6 +1418,7 @@ public final class WindowContainerTransaction implements Parcelable { hierarchyOp.mActivityIntent = mActivityIntent; hierarchyOp.mPendingIntent = mPendingIntent; hierarchyOp.mTaskFragmentCreationOptions = mTaskFragmentCreationOptions; hierarchyOp.mShortcutInfo = mShortcutInfo; return hierarchyOp; } Loading
services/core/java/com/android/server/pm/LauncherAppsService.java +64 −16 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ public class LauncherAppsService extends SystemService { public void onStart() { publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); mLauncherAppsImpl.registerLoadingProgressForIncrementalApps(); LocalServices.addService(LauncherAppsServiceInternal.class, mLauncherAppsImpl.mInternal); } static class BroadcastCookie { Loading @@ -137,6 +138,17 @@ public class LauncherAppsService extends SystemService { } } /** * Local system service interface. * @hide Only for use within system server */ public abstract static class LauncherAppsServiceInternal { /** Same as startShortcut except supports forwarding of caller uid/pid. */ public abstract boolean startShortcut(int callerUid, int callerPid, String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId); } @VisibleForTesting static class LauncherAppsImpl extends ILauncherApps.Stub { private static final boolean DEBUG = false; Loading Loading @@ -168,6 +180,8 @@ public class LauncherAppsService extends SystemService { private PackageInstallerService mPackageInstallerService; final LauncherAppsServiceInternal mInternal; public LauncherAppsImpl(Context context) { mContext = context; mIPM = AppGlobals.getPackageManager(); Loading @@ -189,6 +203,7 @@ public class LauncherAppsService extends SystemService { mShortcutServiceInternal.addShortcutChangeCallback(mShortcutChangeHandler); mCallbackHandler = BackgroundThread.getHandler(); mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); mInternal = new LocalService(); } @VisibleForTesting Loading Loading @@ -359,11 +374,15 @@ public class LauncherAppsService extends SystemService { * group. */ private boolean canAccessProfile(int targetUserId, String message) { final int callingUserId = injectCallingUserId(); return canAccessProfile(injectBinderCallingUid(), injectCallingUserId(), injectBinderCallingPid(), targetUserId, message); } private boolean canAccessProfile(int callingUid, int callingUserId, int callingPid, int targetUserId, String message) { if (targetUserId == callingUserId) return true; if (injectHasInteractAcrossUsersFullPermission(injectBinderCallingPid(), injectBinderCallingUid())) { if (injectHasInteractAcrossUsersFullPermission(callingPid, callingUid)) { return true; } Loading @@ -379,25 +398,29 @@ public class LauncherAppsService extends SystemService { injectRestoreCallingIdentity(ident); } return mUserManagerInternal.isProfileAccessible(injectCallingUserId(), targetUserId, return mUserManagerInternal.isProfileAccessible(callingUserId, targetUserId, message, true); } private void verifyCallingPackage(String callingPackage) { verifyCallingPackage(callingPackage, injectBinderCallingUid()); } @VisibleForTesting // We override it in unit tests void verifyCallingPackage(String callingPackage) { void verifyCallingPackage(String callingPackage, int callerUid) { int packageUid = -1; try { packageUid = mIPM.getPackageUid(callingPackage, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_UNINSTALLED_PACKAGES, UserHandle.getUserId(getCallingUid())); UserHandle.getUserId(callerUid)); } catch (RemoteException ignore) { } if (packageUid < 0) { Log.e(TAG, "Package not found: " + callingPackage); } if (packageUid != injectBinderCallingUid()) { if (packageUid != callerUid) { throw new SecurityException("Calling package name mismatch"); } } Loading Loading @@ -797,9 +820,15 @@ public class LauncherAppsService extends SystemService { } private void ensureShortcutPermission(@NonNull String callingPackage) { verifyCallingPackage(callingPackage); if (!mShortcutServiceInternal.hasShortcutHostPermission(getCallingUserId(), callingPackage, injectBinderCallingPid(), injectBinderCallingUid())) { ensureShortcutPermission(injectBinderCallingUid(), injectBinderCallingPid(), callingPackage); } private void ensureShortcutPermission(int callerUid, int callerPid, @NonNull String callingPackage) { verifyCallingPackage(callingPackage, callerUid); if (!mShortcutServiceInternal.hasShortcutHostPermission(UserHandle.getUserId(callerUid), callingPackage, callerPid, callerUid)) { throw new SecurityException("Caller can't access shortcut information"); } } Loading Loading @@ -989,20 +1018,28 @@ public class LauncherAppsService extends SystemService { public boolean startShortcut(String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { verifyCallingPackage(callingPackage); return startShortcutInner(injectBinderCallingUid(), injectBinderCallingPid(), injectCallingUserId(), callingPackage, packageName, featureId, shortcutId, sourceBounds, startActivityOptions, targetUserId); } private boolean startShortcutInner(int callerUid, int callerPid, int callingUserId, String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { verifyCallingPackage(callingPackage, callerUid); if (!canAccessProfile(targetUserId, "Cannot start activity")) { return false; } // Even without the permission, pinned shortcuts are always launchable. if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), if (!mShortcutServiceInternal.isPinnedByCaller(callingUserId, callingPackage, packageName, shortcutId, targetUserId)) { ensureShortcutPermission(callingPackage); ensureShortcutPermission(callerUid, callerPid, callingPackage); } final Intent[] intents = mShortcutServiceInternal.createShortcutIntents( getCallingUserId(), callingPackage, packageName, shortcutId, targetUserId, injectBinderCallingPid(), injectBinderCallingUid()); callingUserId, callingPackage, packageName, shortcutId, targetUserId, callerPid, callerUid); if (intents == null || intents.length == 0) { return false; } Loading @@ -1023,7 +1060,7 @@ public class LauncherAppsService extends SystemService { // Replace theme for splash screen final String splashScreenThemeResName = mShortcutServiceInternal.getShortcutStartingThemeResName(getCallingUserId(), mShortcutServiceInternal.getShortcutStartingThemeResName(callingUserId, callingPackage, packageName, shortcutId, targetUserId); if (splashScreenThemeResName != null && !splashScreenThemeResName.isEmpty()) { if (startActivityOptions == null) { Loading Loading @@ -1809,5 +1846,16 @@ public class LauncherAppsService extends SystemService { } } } final class LocalService extends LauncherAppsServiceInternal { @Override public boolean startShortcut(int callerUid, int callerPid, String callingPackage, String packageName, String featureId, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, int targetUserId) { return LauncherAppsImpl.this.startShortcutInner(callerUid, callerPid, UserHandle.getUserId(callerUid), callingPackage, packageName, featureId, shortcutId, sourceBounds, startActivityOptions, targetUserId); } } } }
services/core/java/com/android/server/wm/WindowOrganizerController.java +19 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_ACTIVITY_IN_TASK_FRAGMENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_START_SHORTCUT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED; Loading Loading @@ -79,6 +80,8 @@ import com.android.internal.protolog.common.ProtoLog; import com.android.internal.util.ArrayUtils; import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; import com.android.server.pm.LauncherAppsService.LauncherAppsServiceInternal; import java.util.ArrayList; import java.util.HashMap; Loading Loading @@ -785,6 +788,22 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub null /* requiredPermission */, options); break; } case HIERARCHY_OP_TYPE_START_SHORTCUT: { final Bundle launchOpts = hop.getLaunchOptions(); final String callingPackage = launchOpts.getString( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE); launchOpts.remove( WindowContainerTransaction.HierarchyOp.LAUNCH_KEY_SHORTCUT_CALLING_PACKAGE); final LauncherAppsServiceInternal launcherApps = LocalServices.getService( LauncherAppsServiceInternal.class); launcherApps.startShortcut(caller.mUid, caller.mPid, callingPackage, hop.getShortcutInfo().getPackage(), null /* default featureId */, hop.getShortcutInfo().getId(), null /* sourceBounds */, launchOpts, hop.getShortcutInfo().getUserId()); break; } case HIERARCHY_OP_TYPE_REPARENT_CHILDREN: { final WindowContainer oldParent = WindowContainer.fromBinder(hop.getContainer()); final WindowContainer newParent = hop.getNewParent() != null Loading
services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -579,7 +579,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { } @Override public void verifyCallingPackage(String callingPackage) { public void verifyCallingPackage(String callingPackage, int callerUid) { // SKIP } Loading