Loading services/core/java/com/android/server/pm/LauncherAppsService.java +46 −10 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -121,6 +122,21 @@ public class LauncherAppsService extends SystemService { return getCallingUid(); } final int injectCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } @VisibleForTesting long injectClearCallingIdentity() { return Binder.clearCallingIdentity(); } // Injection point. @VisibleForTesting void injectRestoreCallingIdentity(long token) { Binder.restoreCallingIdentity(token); } private int getCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } Loading Loading @@ -197,14 +213,13 @@ public class LauncherAppsService extends SystemService { /** * Checks if the caller is in the same group as the userToCheck. */ @VisibleForTesting // We override it in unit tests void ensureInUserProfiles(UserHandle userToCheck, String message) { final int callingUserId = UserHandle.getCallingUserId(); private void ensureInUserProfiles(UserHandle userToCheck, String message) { final int callingUserId = injectCallingUserId(); final int targetUserId = userToCheck.getIdentifier(); if (targetUserId == callingUserId) return; long ident = Binder.clearCallingIdentity(); long ident = injectClearCallingIdentity(); try { UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); Loading @@ -214,7 +229,7 @@ public class LauncherAppsService extends SystemService { throw new SecurityException(message); } } finally { Binder.restoreCallingIdentity(ident); injectRestoreCallingIdentity(ident); } } Loading @@ -239,12 +254,12 @@ public class LauncherAppsService extends SystemService { * Checks if the user is enabled. */ private boolean isUserEnabled(UserHandle user) { long ident = Binder.clearCallingIdentity(); long ident = injectClearCallingIdentity(); try { UserInfo targetUserInfo = mUm.getUserInfo(user.getIdentifier()); return targetUserInfo != null && targetUserInfo.isEnabled(); } finally { Binder.restoreCallingIdentity(ident); injectRestoreCallingIdentity(ident); } } Loading Loading @@ -345,6 +360,9 @@ public class LauncherAppsService extends SystemService { public ParceledListSlice getShortcuts(String callingPackage, long changedSince, String packageName, ComponentName componentName, int flags, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return new ParceledListSlice<>(new ArrayList(0)); } return new ParceledListSlice<>( mShortcutServiceInternal.getShortcuts(getCallingUserId(), Loading @@ -356,6 +374,9 @@ public class LauncherAppsService extends SystemService { public ParceledListSlice getShortcutInfo(String callingPackage, String packageName, List<String> ids, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return new ParceledListSlice<>(new ArrayList(0)); } return new ParceledListSlice<>( mShortcutServiceInternal.getShortcutInfo(getCallingUserId(), Loading @@ -366,6 +387,10 @@ public class LauncherAppsService extends SystemService { public void pinShortcuts(String callingPackage, String packageName, List<String> ids, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot pin shortcuts for disabled profile " + user); } mShortcutServiceInternal.pinShortcuts(getCallingUserId(), callingPackage, packageName, ids, user.getIdentifier()); Loading @@ -375,6 +400,9 @@ public class LauncherAppsService extends SystemService { public int getShortcutIconResId(String callingPackage, ShortcutInfo shortcut, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return 0; } return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), callingPackage, shortcut, user.getIdentifier()); Loading @@ -384,6 +412,9 @@ public class LauncherAppsService extends SystemService { public ParcelFileDescriptor getShortcutIconFd(String callingPackage, ShortcutInfo shortcut, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return null; } return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), callingPackage, shortcut, user.getIdentifier()); Loading @@ -402,6 +433,11 @@ public class LauncherAppsService extends SystemService { verifyCallingPackage(callingPackage); ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user); if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot start a shortcut for disabled profile " + user); } // Even without the permission, pinned shortcuts are always launchable. if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), callingPackage, packageName, shortcutId, user.getIdentifier())) { Loading Loading @@ -530,13 +566,13 @@ public class LauncherAppsService extends SystemService { /** Checks if user is a profile of or same as listeningUser. * and the user is enabled. */ boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, String debugMsg) { if (user.getIdentifier() == listeningUser.getIdentifier()) { if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg); return true; } long ident = Binder.clearCallingIdentity(); long ident = injectClearCallingIdentity(); try { UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); Loading @@ -557,7 +593,7 @@ public class LauncherAppsService extends SystemService { return true; } } finally { Binder.restoreCallingIdentity(ident); injectRestoreCallingIdentity(ident); } } Loading services/core/java/com/android/server/pm/ShortcutService.java +13 −0 Original line number Diff line number Diff line Loading @@ -2159,6 +2159,9 @@ public class ShortcutService extends IShortcutService.Stub { case "refresh-default-launcher": handleRefreshDefaultLauncher(); break; case "unload-user": handleUnloadUser(); break; default: return handleDefaultCommands(cmd); } Loading Loading @@ -2196,6 +2199,10 @@ public class ShortcutService extends IShortcutService.Stub { pw.println("cmd shortcut refresh-default-launcher [--user USER_ID]"); pw.println(" Refresh the cached default launcher"); pw.println(); pw.println("cmd shortcut unload-user [--user USER_ID]"); pw.println(" Unload a user from the memory"); pw.println(" (This should not affect any observable behavior)"); pw.println(); } private int handleResetThrottling() throws CommandException { Loading Loading @@ -2267,6 +2274,12 @@ public class ShortcutService extends IShortcutService.Stub { clearLauncher(); showLauncher(); } private void handleUnloadUser() throws CommandException { parseOptions(/* takeUser =*/ true); ShortcutService.this.handleCleanupUser(mUserId); } } // === Unit test support === Loading services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java +318 −60 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/pm/LauncherAppsService.java +46 −10 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -121,6 +122,21 @@ public class LauncherAppsService extends SystemService { return getCallingUid(); } final int injectCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } @VisibleForTesting long injectClearCallingIdentity() { return Binder.clearCallingIdentity(); } // Injection point. @VisibleForTesting void injectRestoreCallingIdentity(long token) { Binder.restoreCallingIdentity(token); } private int getCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } Loading Loading @@ -197,14 +213,13 @@ public class LauncherAppsService extends SystemService { /** * Checks if the caller is in the same group as the userToCheck. */ @VisibleForTesting // We override it in unit tests void ensureInUserProfiles(UserHandle userToCheck, String message) { final int callingUserId = UserHandle.getCallingUserId(); private void ensureInUserProfiles(UserHandle userToCheck, String message) { final int callingUserId = injectCallingUserId(); final int targetUserId = userToCheck.getIdentifier(); if (targetUserId == callingUserId) return; long ident = Binder.clearCallingIdentity(); long ident = injectClearCallingIdentity(); try { UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); Loading @@ -214,7 +229,7 @@ public class LauncherAppsService extends SystemService { throw new SecurityException(message); } } finally { Binder.restoreCallingIdentity(ident); injectRestoreCallingIdentity(ident); } } Loading @@ -239,12 +254,12 @@ public class LauncherAppsService extends SystemService { * Checks if the user is enabled. */ private boolean isUserEnabled(UserHandle user) { long ident = Binder.clearCallingIdentity(); long ident = injectClearCallingIdentity(); try { UserInfo targetUserInfo = mUm.getUserInfo(user.getIdentifier()); return targetUserInfo != null && targetUserInfo.isEnabled(); } finally { Binder.restoreCallingIdentity(ident); injectRestoreCallingIdentity(ident); } } Loading Loading @@ -345,6 +360,9 @@ public class LauncherAppsService extends SystemService { public ParceledListSlice getShortcuts(String callingPackage, long changedSince, String packageName, ComponentName componentName, int flags, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return new ParceledListSlice<>(new ArrayList(0)); } return new ParceledListSlice<>( mShortcutServiceInternal.getShortcuts(getCallingUserId(), Loading @@ -356,6 +374,9 @@ public class LauncherAppsService extends SystemService { public ParceledListSlice getShortcutInfo(String callingPackage, String packageName, List<String> ids, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return new ParceledListSlice<>(new ArrayList(0)); } return new ParceledListSlice<>( mShortcutServiceInternal.getShortcutInfo(getCallingUserId(), Loading @@ -366,6 +387,10 @@ public class LauncherAppsService extends SystemService { public void pinShortcuts(String callingPackage, String packageName, List<String> ids, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot pin shortcuts for disabled profile " + user); } mShortcutServiceInternal.pinShortcuts(getCallingUserId(), callingPackage, packageName, ids, user.getIdentifier()); Loading @@ -375,6 +400,9 @@ public class LauncherAppsService extends SystemService { public int getShortcutIconResId(String callingPackage, ShortcutInfo shortcut, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return 0; } return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), callingPackage, shortcut, user.getIdentifier()); Loading @@ -384,6 +412,9 @@ public class LauncherAppsService extends SystemService { public ParcelFileDescriptor getShortcutIconFd(String callingPackage, ShortcutInfo shortcut, UserHandle user) { ensureShortcutPermission(callingPackage, user); if (!isUserEnabled(user)) { return null; } return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), callingPackage, shortcut, user.getIdentifier()); Loading @@ -402,6 +433,11 @@ public class LauncherAppsService extends SystemService { verifyCallingPackage(callingPackage); ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user); if (!isUserEnabled(user)) { throw new IllegalStateException("Cannot start a shortcut for disabled profile " + user); } // Even without the permission, pinned shortcuts are always launchable. if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), callingPackage, packageName, shortcutId, user.getIdentifier())) { Loading Loading @@ -530,13 +566,13 @@ public class LauncherAppsService extends SystemService { /** Checks if user is a profile of or same as listeningUser. * and the user is enabled. */ boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, String debugMsg) { if (user.getIdentifier() == listeningUser.getIdentifier()) { if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg); return true; } long ident = Binder.clearCallingIdentity(); long ident = injectClearCallingIdentity(); try { UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); Loading @@ -557,7 +593,7 @@ public class LauncherAppsService extends SystemService { return true; } } finally { Binder.restoreCallingIdentity(ident); injectRestoreCallingIdentity(ident); } } Loading
services/core/java/com/android/server/pm/ShortcutService.java +13 −0 Original line number Diff line number Diff line Loading @@ -2159,6 +2159,9 @@ public class ShortcutService extends IShortcutService.Stub { case "refresh-default-launcher": handleRefreshDefaultLauncher(); break; case "unload-user": handleUnloadUser(); break; default: return handleDefaultCommands(cmd); } Loading Loading @@ -2196,6 +2199,10 @@ public class ShortcutService extends IShortcutService.Stub { pw.println("cmd shortcut refresh-default-launcher [--user USER_ID]"); pw.println(" Refresh the cached default launcher"); pw.println(); pw.println("cmd shortcut unload-user [--user USER_ID]"); pw.println(" Unload a user from the memory"); pw.println(" (This should not affect any observable behavior)"); pw.println(); } private int handleResetThrottling() throws CommandException { Loading Loading @@ -2267,6 +2274,12 @@ public class ShortcutService extends IShortcutService.Stub { clearLauncher(); showLauncher(); } private void handleUnloadUser() throws CommandException { parseOptions(/* takeUser =*/ true); ShortcutService.this.handleCleanupUser(mUserId); } } // === Unit test support === Loading
services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java +318 −60 File changed.Preview size limit exceeded, changes collapsed. Show changes