Loading services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java +8 −9 Original line number Diff line number Diff line Loading @@ -254,7 +254,8 @@ class ShortcutRequestPinProcessor { // Next, validate the incoming shortcut, etc. final PinItemRequest request; if (inShortcut != null) { request = requestPinShortcutLocked(inShortcut, resultIntent, confirmActivity); request = requestPinShortcutLocked(inShortcut, resultIntent, confirmActivity.first.getPackageName(), confirmActivity.second); } else { int launcherUid = mService.injectGetPackageUid( confirmActivity.first.getPackageName(), launcherUserId); Loading @@ -275,7 +276,7 @@ class ShortcutRequestPinProcessor { public Intent createShortcutResultIntent(@NonNull ShortcutInfo inShortcut, int userId) { // Find the default launcher activity final int launcherUserId = mService.getParentOrSelfUserId(userId); final ComponentName defaultLauncher = mService.getDefaultLauncher(launcherUserId); final String defaultLauncher = mService.getDefaultLauncher(launcherUserId); if (defaultLauncher == null) { Log.e(TAG, "Default launcher not found."); return null; Loading @@ -286,8 +287,8 @@ class ShortcutRequestPinProcessor { mService.throwIfUserLockedL(launcherUserId); // Next, validate the incoming shortcut, etc. final PinItemRequest request = requestPinShortcutLocked(inShortcut, null, Pair.create(defaultLauncher, launcherUserId)); final PinItemRequest request = requestPinShortcutLocked(inShortcut, null, defaultLauncher, launcherUserId); return new Intent().putExtra(LauncherApps.EXTRA_PIN_ITEM_REQUEST, request); } Loading @@ -296,7 +297,7 @@ class ShortcutRequestPinProcessor { */ @NonNull private PinItemRequest requestPinShortcutLocked(ShortcutInfo inShortcut, IntentSender resultIntentOriginal, Pair<ComponentName, Integer> confirmActivity) { IntentSender resultIntentOriginal, String launcherPackage, int launcherUserId) { final ShortcutPackage ps = mService.getPackageShortcutsForPublisherLocked( inShortcut.getPackage(), inShortcut.getUserId()); Loading @@ -313,8 +314,6 @@ class ShortcutRequestPinProcessor { // This is the shortcut that'll be sent to the launcher. final ShortcutInfo shortcutForLauncher; final String launcherPackage = confirmActivity.first.getPackageName(); final int launcherUserId = confirmActivity.second; IntentSender resultIntentToSend = resultIntentOriginal; Loading Loading @@ -419,14 +418,14 @@ class ShortcutRequestPinProcessor { int callingUserId, int requestType) { // Find the default launcher. final int launcherUserId = mService.getParentOrSelfUserId(callingUserId); final ComponentName defaultLauncher = mService.getDefaultLauncher(launcherUserId); final String defaultLauncher = mService.getDefaultLauncher(launcherUserId); if (defaultLauncher == null) { Log.e(TAG, "Default launcher not found."); return null; } final ComponentName activity = mService.injectGetPinConfirmationActivity( defaultLauncher.getPackageName(), launcherUserId, requestType); defaultLauncher, launcherUserId, requestType); return (activity == null) ? null : Pair.create(activity, launcherUserId); } Loading services/core/java/com/android/server/pm/ShortcutService.java +76 −129 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.app.AppGlobals; import android.app.IUidObserver; import android.app.IUriGrantsManager; import android.app.UriGrantsManager; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; Loading Loading @@ -108,7 +110,6 @@ import com.android.internal.util.Preconditions; import com.android.internal.util.StatLogger; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemService.TargetUser; import com.android.server.pm.ShortcutUser.PackageWithUser; import com.android.server.uri.UriGrantsManagerInternal; Loading Loading @@ -347,6 +348,7 @@ public class ShortcutService extends IShortcutService.Stub { private final IUriGrantsManager mUriGrantsManager; private final UriGrantsManagerInternal mUriGrantsManagerInternal; private final IBinder mUriPermissionOwner; private final RoleManager mRoleManager; private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor; private final ShortcutBitmapSaver mShortcutBitmapSaver; Loading Loading @@ -464,10 +466,11 @@ public class ShortcutService extends IShortcutService.Stub { mActivityManagerInternal = Objects.requireNonNull( LocalServices.getService(ActivityManagerInternal.class)); mUriGrantsManager = UriGrantsManager.getService(); mUriGrantsManager = Objects.requireNonNull(UriGrantsManager.getService()); mUriGrantsManagerInternal = Objects.requireNonNull( LocalServices.getService(UriGrantsManagerInternal.class)); mUriPermissionOwner = mUriGrantsManagerInternal.newUriPermissionOwner(TAG); mRoleManager = Objects.requireNonNull(mContext.getSystemService(RoleManager.class)); mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock); mShortcutBitmapSaver = new ShortcutBitmapSaver(this); Loading @@ -491,12 +494,6 @@ public class ShortcutService extends IShortcutService.Stub { mContext.registerReceiverAsUser(mPackageMonitor, UserHandle.ALL, packageFilter, null, mHandler); final IntentFilter preferedActivityFilter = new IntentFilter(); preferedActivityFilter.addAction(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); preferedActivityFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiverAsUser(mPackageMonitor, UserHandle.ALL, preferedActivityFilter, null, mHandler); final IntentFilter localeFilter = new IntentFilter(); localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED); localeFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); Loading @@ -505,6 +502,8 @@ public class ShortcutService extends IShortcutService.Stub { injectRegisterUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE); injectRegisterRoleHoldersListener(mOnRoleHoldersChangedListener); } long getStatStartTime() { Loading @@ -520,6 +519,31 @@ public class ShortcutService extends IShortcutService.Stub { return LocaleList.getDefault().toLanguageTags(); } private final OnRoleHoldersChangedListener mOnRoleHoldersChangedListener = new OnRoleHoldersChangedListener() { @Override public void onRoleHoldersChanged(String roleName, UserHandle user) { if (RoleManager.ROLE_HOME.equals(roleName)) { injectPostToHandler(() -> handleOnDefaultLauncherChanged(user.getIdentifier())); } } }; void handleOnDefaultLauncherChanged(int userId) { if (DEBUG) { Slog.v(TAG, "Default launcher changed for user: " + userId); } // Default launcher is removed or changed, revoke all URI permissions. mUriGrantsManagerInternal.revokeUriPermissionFromOwner(mUriPermissionOwner, null, ~0, 0); synchronized (mLock) { // Clear the launcher cache for this user. It will be set again next time the default // launcher is read from RoleManager. getUserShortcutsLocked(userId).setCachedLauncher(null); } } final private IUidObserver mUidObserver = new IUidObserver.Stub() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { Loading Loading @@ -2681,35 +2705,21 @@ public class ShortcutService extends IShortcutService.Stub { synchronized (mLock) { throwIfUserLockedL(userId); final ShortcutUser user = getUserShortcutsLocked(userId); // Always trust the cached component. final ComponentName cached = user.getCachedLauncher(); if (cached != null) { if (cached.getPackageName().equals(packageName)) { return true; } } // If the cached one doesn't match, then go ahead final ComponentName detected = getDefaultLauncher(userId); final String defaultLauncher = getDefaultLauncher(userId); // Update the cache. user.setLauncher(detected); if (detected != null) { if (defaultLauncher != null) { if (DEBUG) { Slog.v(TAG, "Detected launcher: " + detected); Slog.v(TAG, "Detected launcher: " + defaultLauncher + " user: " + userId); } return detected.getPackageName().equals(packageName); return defaultLauncher.equals(packageName); } else { // Default launcher not found. return false; } } } @Nullable ComponentName getDefaultLauncher(@UserIdInt int userId) { String getDefaultLauncher(@UserIdInt int userId) { final long start = getStatStartTime(); final long token = injectClearCallingIdentity(); try { Loading @@ -2717,64 +2727,27 @@ public class ShortcutService extends IShortcutService.Stub { throwIfUserLockedL(userId); final ShortcutUser user = getUserShortcutsLocked(userId); String cachedLauncher = user.getCachedLauncher(); if (cachedLauncher != null) { return cachedLauncher; } final List<ResolveInfo> allHomeCandidates = new ArrayList<>(); // Default launcher from package manager. final long startGetHomeActivitiesAsUser = getStatStartTime(); final ComponentName defaultLauncher = mPackageManagerInternal .getHomeActivitiesAsUser(allHomeCandidates, userId); logDurationStat(Stats.GET_DEFAULT_HOME, startGetHomeActivitiesAsUser); // Default launcher from role manager. final long startGetHomeRoleHoldersAsUser = getStatStartTime(); final String defaultLauncher = injectGetHomeRoleHolderAsUser(userId); logDurationStat(Stats.GET_DEFAULT_HOME, startGetHomeRoleHoldersAsUser); ComponentName detected = null; if (defaultLauncher != null) { detected = defaultLauncher; if (DEBUG) { Slog.v(TAG, "Default launcher from PM: " + detected); } } else { detected = user.getLastKnownLauncher(); if (detected != null) { if (injectIsActivityEnabledAndExported(detected, userId)) { if (DEBUG) { Slog.v(TAG, "Cached launcher: " + detected); Slog.v(TAG, "Default launcher from RoleManager: " + defaultLauncher + " user: " + userId); } user.setCachedLauncher(defaultLauncher); } else { Slog.w(TAG, "Cached launcher " + detected + " no longer exists"); detected = null; user.clearLauncher(); } } Slog.e(TAG, "Default launcher not found." + " user: " + userId); } if (detected == null) { // If we reach here, that means it's the first check since the user was created, // and there's already multiple launchers and there's no default set. // Find the system one with the highest priority. // (We need to check the priority too because of FallbackHome in Settings.) // If there's no system launcher yet, then no one can access shortcuts, until // the user explicitly final int size = allHomeCandidates.size(); int lastPriority = Integer.MIN_VALUE; for (int i = 0; i < size; i++) { final ResolveInfo ri = allHomeCandidates.get(i); if (!ri.activityInfo.applicationInfo.isSystemApp()) { continue; } if (DEBUG) { Slog.d(TAG, String.format("hasShortcutPermissionInner: pkg=%s prio=%d", ri.activityInfo.getComponentName(), ri.priority)); } if (ri.priority < lastPriority) { continue; } detected = ri.activityInfo.getComponentName(); lastPriority = ri.priority; } } return detected; return defaultLauncher; } } finally { injectRestoreCallingIdentity(token); Loading Loading @@ -3351,11 +3324,11 @@ public class ShortcutService extends IShortcutService.Stub { Objects.requireNonNull(callingPackage); final int userId = UserHandle.getUserId(callingUid); final ComponentName defaultLauncher = getDefaultLauncher(userId); final String defaultLauncher = getDefaultLauncher(userId); if (defaultLauncher == null) { return false; } if (!callingPackage.equals(defaultLauncher.getPackageName())) { if (!callingPackage.equals(defaultLauncher)) { return false; } synchronized (mLock) { Loading Loading @@ -3426,22 +3399,6 @@ public class ShortcutService extends IShortcutService.Stub { } return; } // Whenever we get one of those package broadcasts, or get // ACTION_PREFERRED_ACTIVITY_CHANGED, we purge the default launcher cache. final ShortcutUser user = getUserShortcutsLocked(userId); user.clearLauncher(); } if (Intent.ACTION_PREFERRED_ACTIVITY_CHANGED.equals(action)) { final ShortcutUser user = getUserShortcutsLocked(userId); final ComponentName lastLauncher = user.getLastKnownLauncher(); final ComponentName currentLauncher = getDefaultLauncher(userId); if (currentLauncher == null || !currentLauncher.equals(lastLauncher)) { // Default launcher is removed or changed, revoke all URI permissions. mUriGrantsManagerInternal.revokeUriPermissionFromOwner(mUriPermissionOwner, null, ~0, 0); } return; } final Uri intentUri = intent.getData(); Loading Loading @@ -4629,9 +4586,6 @@ public class ShortcutService extends IShortcutService.Stub { case "reset-config": handleResetConfig(); break; case "clear-default-launcher": handleClearDefaultLauncher(); break; case "get-default-launcher": handleGetDefaultLauncher(); break; Loading Loading @@ -4672,11 +4626,10 @@ public class ShortcutService extends IShortcutService.Stub { pw.println("cmd shortcut reset-config"); pw.println(" Reset the configuration set with \"update-config\""); pw.println(); pw.println("cmd shortcut clear-default-launcher [--user USER_ID]"); pw.println(" Clear the cached default launcher"); pw.println(); pw.println("cmd shortcut get-default-launcher [--user USER_ID]"); pw.println("[Deprecated] cmd shortcut get-default-launcher [--user USER_ID]"); pw.println(" Show the default launcher"); pw.println(" Note: This command is deprecated. Callers should query the default" + " launcher directly from RoleManager instead."); pw.println(); pw.println("cmd shortcut unload-user [--user USER_ID]"); pw.println(" Unload a user from the memory"); Loading Loading @@ -4723,36 +4676,17 @@ public class ShortcutService extends IShortcutService.Stub { } } private void clearLauncher() { synchronized (mLock) { getUserShortcutsLocked(mUserId).forceClearLauncher(); } } private void showLauncher() { synchronized (mLock) { // This ensures to set the cached launcher. Package name doesn't matter. hasShortcutHostPermissionInner("-", mUserId); getOutPrintWriter().println("Launcher: " + getUserShortcutsLocked(mUserId).getLastKnownLauncher()); } } private void handleClearDefaultLauncher() throws CommandException { synchronized (mLock) { parseOptionsLocked(/* takeUser =*/ true); clearLauncher(); } } // This method is used by various cts modules to get the current default launcher. Tests // should query this information directly from RoleManager instead. Keeping the old behavior // by returning the result from package manager. private void handleGetDefaultLauncher() throws CommandException { synchronized (mLock) { parseOptionsLocked(/* takeUser =*/ true); clearLauncher(); showLauncher(); final List<ResolveInfo> allHomeCandidates = new ArrayList<>(); // Default launcher from package manager. final ComponentName defaultLauncher = mPackageManagerInternal .getHomeActivitiesAsUser(allHomeCandidates, mUserId); getOutPrintWriter().println("Launcher: " + defaultLauncher); } } Loading Loading @@ -4881,6 +4815,19 @@ public class ShortcutService extends IShortcutService.Stub { } } @VisibleForTesting void injectRegisterRoleHoldersListener(OnRoleHoldersChangedListener listener) { mRoleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), listener, UserHandle.ALL); } @VisibleForTesting String injectGetHomeRoleHolderAsUser(int userId) { List<String> roleHolders = mRoleManager.getRoleHoldersAsUser( RoleManager.ROLE_HOME, UserHandle.of(userId)); return roleHolders.isEmpty() ? null : roleHolders.get(0); } File getUserBitmapFilePath(@UserIdInt int userId) { return new File(injectUserDataPath(userId), DIRECTORY_BITMAPS); } Loading services/core/java/com/android/server/pm/ShortcutUser.java +4 −55 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.pm.ShortcutManager; import android.metrics.LogMaker; import android.os.FileUtils; Loading Loading @@ -119,15 +118,8 @@ class ShortcutUser { private final ArrayMap<PackageWithUser, ShortcutLauncher> mLaunchers = new ArrayMap<>(); /** * Last known launcher. It's used when the default launcher isn't set in PM -- i.e. * when getHomeActivitiesAsUser() return null. We need it so that in this situation the * previously default launcher can still access shortcuts. */ private ComponentName mLastKnownLauncher; /** In-memory-cached default launcher. */ private ComponentName mCachedLauncher; private String mCachedLauncher; private String mKnownLocales; Loading Loading @@ -350,8 +342,6 @@ class ShortcutUser { mLastAppScanOsFingerprint); ShortcutService.writeAttr(out, ATTR_RESTORE_SOURCE_FINGERPRINT, mRestoreFromOsFingerprint); ShortcutService.writeTagValue(out, TAG_LAUNCHER, mLastKnownLauncher); } else { ShortcutService.writeAttr(out, ATTR_RESTORE_SOURCE_FINGERPRINT, mService.injectBuildFingerprint()); Loading Loading @@ -448,11 +438,6 @@ class ShortcutUser { if (depth == outerDepth + 1) { switch (tag) { case TAG_LAUNCHER: { ret.mLastKnownLauncher = ShortcutService.parseComponentNameAttribute( parser, ATTR_VALUE); continue; } case ShortcutPackage.TAG_ROOT: { final ShortcutPackage shortcuts = ShortcutPackage.loadFromXml( s, ret, parser, fromBackup); Loading Loading @@ -515,41 +500,11 @@ class ShortcutUser { } } public ComponentName getLastKnownLauncher() { return mLastKnownLauncher; } public void setLauncher(ComponentName launcherComponent) { setLauncher(launcherComponent, /* allowPurgeLastKnown */ false); } /** Clears the launcher information without clearing the last known one */ public void clearLauncher() { setLauncher(null); } /** * Clears the launcher information *with(* clearing the last known one; we do this witl * "cmd shortcut clear-default-launcher". */ public void forceClearLauncher() { setLauncher(null, /* allowPurgeLastKnown */ true); } private void setLauncher(ComponentName launcherComponent, boolean allowPurgeLastKnown) { mCachedLauncher = launcherComponent; // Always update the in-memory cache. if (Objects.equals(mLastKnownLauncher, launcherComponent)) { return; } if (!allowPurgeLastKnown && launcherComponent == null) { return; } mLastKnownLauncher = launcherComponent; mService.scheduleSaveUser(mUserId); public void setCachedLauncher(String launcher) { mCachedLauncher = launcher; } public ComponentName getCachedLauncher() { public String getCachedLauncher() { return mCachedLauncher; } Loading Loading @@ -640,16 +595,10 @@ class ShortcutUser { pw.print(mRestoreFromOsFingerprint); pw.println(); pw.print(prefix); pw.print("Cached launcher: "); pw.print(mCachedLauncher); pw.println(); pw.print(prefix); pw.print("Last known launcher: "); pw.print(mLastKnownLauncher); pw.println(); } for (int i = 0; i < mLaunchers.size(); i++) { Loading services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +38 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +5 −15 Original line number Diff line number Diff line Loading @@ -3810,9 +3810,6 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals(2, mManager.getRemainingCallCount()); }); mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM).setLauncher( new ComponentName("pkg1", "class")); // Restore. mService.saveDirtyInfo(); initService(); Loading Loading @@ -3843,9 +3840,6 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals("title2-2", getCallerShortcut("s2").getTitle()); }); assertEquals("pkg1", mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM) .getLastKnownLauncher().getPackageName()); // Start another user mService.handleUnlockUser(USER_10); Loading @@ -3860,7 +3854,6 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals("title10-1-1", getCallerShortcut("s1").getTitle()); assertEquals("title10-1-2", getCallerShortcut("s2").getTitle()); }); assertNull(mService.getShortcutsForTest().get(USER_10).getLastKnownLauncher()); // Try stopping the user mService.handleStopUser(USER_10); Loading Loading @@ -6440,7 +6433,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); // Prepare for requestPinShortcut(). setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_1, USER_0)); setDefaultLauncher(USER_0, LAUNCHER_1); mPinConfirmActivityFetcher = (packageName, userId) -> new ComponentName(packageName, PIN_CONFIRM_ACTIVITY_CLASS); Loading @@ -6465,7 +6458,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); // Now, change the launcher to launcher2, and request pin again. setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_2, USER_0)); setDefaultLauncher(USER_0, LAUNCHER_2); reset(mServiceContext); Loading Loading @@ -8514,10 +8507,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } public void testIsForegroundDefaultLauncher_true() { final ComponentName defaultLauncher = new ComponentName("default", "launcher"); final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, defaultLauncher); setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); makeUidForeground(uid); assertTrue(mInternal.isForegroundDefaultLauncher("default", uid)); Loading @@ -8525,20 +8517,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { public void testIsForegroundDefaultLauncher_defaultButNotForeground() { final ComponentName defaultLauncher = new ComponentName("default", "launcher"); final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, defaultLauncher); setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); makeUidBackground(uid); assertFalse(mInternal.isForegroundDefaultLauncher("default", uid)); } public void testIsForegroundDefaultLauncher_foregroundButNotDefault() { final ComponentName defaultLauncher = new ComponentName("default", "launcher"); final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, defaultLauncher); setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); makeUidForeground(uid); assertFalse(mInternal.isForegroundDefaultLauncher("another", uid)); Loading Loading
services/core/java/com/android/server/pm/ShortcutRequestPinProcessor.java +8 −9 Original line number Diff line number Diff line Loading @@ -254,7 +254,8 @@ class ShortcutRequestPinProcessor { // Next, validate the incoming shortcut, etc. final PinItemRequest request; if (inShortcut != null) { request = requestPinShortcutLocked(inShortcut, resultIntent, confirmActivity); request = requestPinShortcutLocked(inShortcut, resultIntent, confirmActivity.first.getPackageName(), confirmActivity.second); } else { int launcherUid = mService.injectGetPackageUid( confirmActivity.first.getPackageName(), launcherUserId); Loading @@ -275,7 +276,7 @@ class ShortcutRequestPinProcessor { public Intent createShortcutResultIntent(@NonNull ShortcutInfo inShortcut, int userId) { // Find the default launcher activity final int launcherUserId = mService.getParentOrSelfUserId(userId); final ComponentName defaultLauncher = mService.getDefaultLauncher(launcherUserId); final String defaultLauncher = mService.getDefaultLauncher(launcherUserId); if (defaultLauncher == null) { Log.e(TAG, "Default launcher not found."); return null; Loading @@ -286,8 +287,8 @@ class ShortcutRequestPinProcessor { mService.throwIfUserLockedL(launcherUserId); // Next, validate the incoming shortcut, etc. final PinItemRequest request = requestPinShortcutLocked(inShortcut, null, Pair.create(defaultLauncher, launcherUserId)); final PinItemRequest request = requestPinShortcutLocked(inShortcut, null, defaultLauncher, launcherUserId); return new Intent().putExtra(LauncherApps.EXTRA_PIN_ITEM_REQUEST, request); } Loading @@ -296,7 +297,7 @@ class ShortcutRequestPinProcessor { */ @NonNull private PinItemRequest requestPinShortcutLocked(ShortcutInfo inShortcut, IntentSender resultIntentOriginal, Pair<ComponentName, Integer> confirmActivity) { IntentSender resultIntentOriginal, String launcherPackage, int launcherUserId) { final ShortcutPackage ps = mService.getPackageShortcutsForPublisherLocked( inShortcut.getPackage(), inShortcut.getUserId()); Loading @@ -313,8 +314,6 @@ class ShortcutRequestPinProcessor { // This is the shortcut that'll be sent to the launcher. final ShortcutInfo shortcutForLauncher; final String launcherPackage = confirmActivity.first.getPackageName(); final int launcherUserId = confirmActivity.second; IntentSender resultIntentToSend = resultIntentOriginal; Loading Loading @@ -419,14 +418,14 @@ class ShortcutRequestPinProcessor { int callingUserId, int requestType) { // Find the default launcher. final int launcherUserId = mService.getParentOrSelfUserId(callingUserId); final ComponentName defaultLauncher = mService.getDefaultLauncher(launcherUserId); final String defaultLauncher = mService.getDefaultLauncher(launcherUserId); if (defaultLauncher == null) { Log.e(TAG, "Default launcher not found."); return null; } final ComponentName activity = mService.injectGetPinConfirmationActivity( defaultLauncher.getPackageName(), launcherUserId, requestType); defaultLauncher, launcherUserId, requestType); return (activity == null) ? null : Pair.create(activity, launcherUserId); } Loading
services/core/java/com/android/server/pm/ShortcutService.java +76 −129 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import android.app.AppGlobals; import android.app.IUidObserver; import android.app.IUriGrantsManager; import android.app.UriGrantsManager; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; Loading Loading @@ -108,7 +110,6 @@ import com.android.internal.util.Preconditions; import com.android.internal.util.StatLogger; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.SystemService.TargetUser; import com.android.server.pm.ShortcutUser.PackageWithUser; import com.android.server.uri.UriGrantsManagerInternal; Loading Loading @@ -347,6 +348,7 @@ public class ShortcutService extends IShortcutService.Stub { private final IUriGrantsManager mUriGrantsManager; private final UriGrantsManagerInternal mUriGrantsManagerInternal; private final IBinder mUriPermissionOwner; private final RoleManager mRoleManager; private final ShortcutRequestPinProcessor mShortcutRequestPinProcessor; private final ShortcutBitmapSaver mShortcutBitmapSaver; Loading Loading @@ -464,10 +466,11 @@ public class ShortcutService extends IShortcutService.Stub { mActivityManagerInternal = Objects.requireNonNull( LocalServices.getService(ActivityManagerInternal.class)); mUriGrantsManager = UriGrantsManager.getService(); mUriGrantsManager = Objects.requireNonNull(UriGrantsManager.getService()); mUriGrantsManagerInternal = Objects.requireNonNull( LocalServices.getService(UriGrantsManagerInternal.class)); mUriPermissionOwner = mUriGrantsManagerInternal.newUriPermissionOwner(TAG); mRoleManager = Objects.requireNonNull(mContext.getSystemService(RoleManager.class)); mShortcutRequestPinProcessor = new ShortcutRequestPinProcessor(this, mLock); mShortcutBitmapSaver = new ShortcutBitmapSaver(this); Loading @@ -491,12 +494,6 @@ public class ShortcutService extends IShortcutService.Stub { mContext.registerReceiverAsUser(mPackageMonitor, UserHandle.ALL, packageFilter, null, mHandler); final IntentFilter preferedActivityFilter = new IntentFilter(); preferedActivityFilter.addAction(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED); preferedActivityFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiverAsUser(mPackageMonitor, UserHandle.ALL, preferedActivityFilter, null, mHandler); final IntentFilter localeFilter = new IntentFilter(); localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED); localeFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); Loading @@ -505,6 +502,8 @@ public class ShortcutService extends IShortcutService.Stub { injectRegisterUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE); injectRegisterRoleHoldersListener(mOnRoleHoldersChangedListener); } long getStatStartTime() { Loading @@ -520,6 +519,31 @@ public class ShortcutService extends IShortcutService.Stub { return LocaleList.getDefault().toLanguageTags(); } private final OnRoleHoldersChangedListener mOnRoleHoldersChangedListener = new OnRoleHoldersChangedListener() { @Override public void onRoleHoldersChanged(String roleName, UserHandle user) { if (RoleManager.ROLE_HOME.equals(roleName)) { injectPostToHandler(() -> handleOnDefaultLauncherChanged(user.getIdentifier())); } } }; void handleOnDefaultLauncherChanged(int userId) { if (DEBUG) { Slog.v(TAG, "Default launcher changed for user: " + userId); } // Default launcher is removed or changed, revoke all URI permissions. mUriGrantsManagerInternal.revokeUriPermissionFromOwner(mUriPermissionOwner, null, ~0, 0); synchronized (mLock) { // Clear the launcher cache for this user. It will be set again next time the default // launcher is read from RoleManager. getUserShortcutsLocked(userId).setCachedLauncher(null); } } final private IUidObserver mUidObserver = new IUidObserver.Stub() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { Loading Loading @@ -2681,35 +2705,21 @@ public class ShortcutService extends IShortcutService.Stub { synchronized (mLock) { throwIfUserLockedL(userId); final ShortcutUser user = getUserShortcutsLocked(userId); // Always trust the cached component. final ComponentName cached = user.getCachedLauncher(); if (cached != null) { if (cached.getPackageName().equals(packageName)) { return true; } } // If the cached one doesn't match, then go ahead final ComponentName detected = getDefaultLauncher(userId); final String defaultLauncher = getDefaultLauncher(userId); // Update the cache. user.setLauncher(detected); if (detected != null) { if (defaultLauncher != null) { if (DEBUG) { Slog.v(TAG, "Detected launcher: " + detected); Slog.v(TAG, "Detected launcher: " + defaultLauncher + " user: " + userId); } return detected.getPackageName().equals(packageName); return defaultLauncher.equals(packageName); } else { // Default launcher not found. return false; } } } @Nullable ComponentName getDefaultLauncher(@UserIdInt int userId) { String getDefaultLauncher(@UserIdInt int userId) { final long start = getStatStartTime(); final long token = injectClearCallingIdentity(); try { Loading @@ -2717,64 +2727,27 @@ public class ShortcutService extends IShortcutService.Stub { throwIfUserLockedL(userId); final ShortcutUser user = getUserShortcutsLocked(userId); String cachedLauncher = user.getCachedLauncher(); if (cachedLauncher != null) { return cachedLauncher; } final List<ResolveInfo> allHomeCandidates = new ArrayList<>(); // Default launcher from package manager. final long startGetHomeActivitiesAsUser = getStatStartTime(); final ComponentName defaultLauncher = mPackageManagerInternal .getHomeActivitiesAsUser(allHomeCandidates, userId); logDurationStat(Stats.GET_DEFAULT_HOME, startGetHomeActivitiesAsUser); // Default launcher from role manager. final long startGetHomeRoleHoldersAsUser = getStatStartTime(); final String defaultLauncher = injectGetHomeRoleHolderAsUser(userId); logDurationStat(Stats.GET_DEFAULT_HOME, startGetHomeRoleHoldersAsUser); ComponentName detected = null; if (defaultLauncher != null) { detected = defaultLauncher; if (DEBUG) { Slog.v(TAG, "Default launcher from PM: " + detected); } } else { detected = user.getLastKnownLauncher(); if (detected != null) { if (injectIsActivityEnabledAndExported(detected, userId)) { if (DEBUG) { Slog.v(TAG, "Cached launcher: " + detected); Slog.v(TAG, "Default launcher from RoleManager: " + defaultLauncher + " user: " + userId); } user.setCachedLauncher(defaultLauncher); } else { Slog.w(TAG, "Cached launcher " + detected + " no longer exists"); detected = null; user.clearLauncher(); } } Slog.e(TAG, "Default launcher not found." + " user: " + userId); } if (detected == null) { // If we reach here, that means it's the first check since the user was created, // and there's already multiple launchers and there's no default set. // Find the system one with the highest priority. // (We need to check the priority too because of FallbackHome in Settings.) // If there's no system launcher yet, then no one can access shortcuts, until // the user explicitly final int size = allHomeCandidates.size(); int lastPriority = Integer.MIN_VALUE; for (int i = 0; i < size; i++) { final ResolveInfo ri = allHomeCandidates.get(i); if (!ri.activityInfo.applicationInfo.isSystemApp()) { continue; } if (DEBUG) { Slog.d(TAG, String.format("hasShortcutPermissionInner: pkg=%s prio=%d", ri.activityInfo.getComponentName(), ri.priority)); } if (ri.priority < lastPriority) { continue; } detected = ri.activityInfo.getComponentName(); lastPriority = ri.priority; } } return detected; return defaultLauncher; } } finally { injectRestoreCallingIdentity(token); Loading Loading @@ -3351,11 +3324,11 @@ public class ShortcutService extends IShortcutService.Stub { Objects.requireNonNull(callingPackage); final int userId = UserHandle.getUserId(callingUid); final ComponentName defaultLauncher = getDefaultLauncher(userId); final String defaultLauncher = getDefaultLauncher(userId); if (defaultLauncher == null) { return false; } if (!callingPackage.equals(defaultLauncher.getPackageName())) { if (!callingPackage.equals(defaultLauncher)) { return false; } synchronized (mLock) { Loading Loading @@ -3426,22 +3399,6 @@ public class ShortcutService extends IShortcutService.Stub { } return; } // Whenever we get one of those package broadcasts, or get // ACTION_PREFERRED_ACTIVITY_CHANGED, we purge the default launcher cache. final ShortcutUser user = getUserShortcutsLocked(userId); user.clearLauncher(); } if (Intent.ACTION_PREFERRED_ACTIVITY_CHANGED.equals(action)) { final ShortcutUser user = getUserShortcutsLocked(userId); final ComponentName lastLauncher = user.getLastKnownLauncher(); final ComponentName currentLauncher = getDefaultLauncher(userId); if (currentLauncher == null || !currentLauncher.equals(lastLauncher)) { // Default launcher is removed or changed, revoke all URI permissions. mUriGrantsManagerInternal.revokeUriPermissionFromOwner(mUriPermissionOwner, null, ~0, 0); } return; } final Uri intentUri = intent.getData(); Loading Loading @@ -4629,9 +4586,6 @@ public class ShortcutService extends IShortcutService.Stub { case "reset-config": handleResetConfig(); break; case "clear-default-launcher": handleClearDefaultLauncher(); break; case "get-default-launcher": handleGetDefaultLauncher(); break; Loading Loading @@ -4672,11 +4626,10 @@ public class ShortcutService extends IShortcutService.Stub { pw.println("cmd shortcut reset-config"); pw.println(" Reset the configuration set with \"update-config\""); pw.println(); pw.println("cmd shortcut clear-default-launcher [--user USER_ID]"); pw.println(" Clear the cached default launcher"); pw.println(); pw.println("cmd shortcut get-default-launcher [--user USER_ID]"); pw.println("[Deprecated] cmd shortcut get-default-launcher [--user USER_ID]"); pw.println(" Show the default launcher"); pw.println(" Note: This command is deprecated. Callers should query the default" + " launcher directly from RoleManager instead."); pw.println(); pw.println("cmd shortcut unload-user [--user USER_ID]"); pw.println(" Unload a user from the memory"); Loading Loading @@ -4723,36 +4676,17 @@ public class ShortcutService extends IShortcutService.Stub { } } private void clearLauncher() { synchronized (mLock) { getUserShortcutsLocked(mUserId).forceClearLauncher(); } } private void showLauncher() { synchronized (mLock) { // This ensures to set the cached launcher. Package name doesn't matter. hasShortcutHostPermissionInner("-", mUserId); getOutPrintWriter().println("Launcher: " + getUserShortcutsLocked(mUserId).getLastKnownLauncher()); } } private void handleClearDefaultLauncher() throws CommandException { synchronized (mLock) { parseOptionsLocked(/* takeUser =*/ true); clearLauncher(); } } // This method is used by various cts modules to get the current default launcher. Tests // should query this information directly from RoleManager instead. Keeping the old behavior // by returning the result from package manager. private void handleGetDefaultLauncher() throws CommandException { synchronized (mLock) { parseOptionsLocked(/* takeUser =*/ true); clearLauncher(); showLauncher(); final List<ResolveInfo> allHomeCandidates = new ArrayList<>(); // Default launcher from package manager. final ComponentName defaultLauncher = mPackageManagerInternal .getHomeActivitiesAsUser(allHomeCandidates, mUserId); getOutPrintWriter().println("Launcher: " + defaultLauncher); } } Loading Loading @@ -4881,6 +4815,19 @@ public class ShortcutService extends IShortcutService.Stub { } } @VisibleForTesting void injectRegisterRoleHoldersListener(OnRoleHoldersChangedListener listener) { mRoleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), listener, UserHandle.ALL); } @VisibleForTesting String injectGetHomeRoleHolderAsUser(int userId) { List<String> roleHolders = mRoleManager.getRoleHoldersAsUser( RoleManager.ROLE_HOME, UserHandle.of(userId)); return roleHolders.isEmpty() ? null : roleHolders.get(0); } File getUserBitmapFilePath(@UserIdInt int userId) { return new File(injectUserDataPath(userId), DIRECTORY_BITMAPS); } Loading
services/core/java/com/android/server/pm/ShortcutUser.java +4 −55 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.pm.ShortcutManager; import android.metrics.LogMaker; import android.os.FileUtils; Loading Loading @@ -119,15 +118,8 @@ class ShortcutUser { private final ArrayMap<PackageWithUser, ShortcutLauncher> mLaunchers = new ArrayMap<>(); /** * Last known launcher. It's used when the default launcher isn't set in PM -- i.e. * when getHomeActivitiesAsUser() return null. We need it so that in this situation the * previously default launcher can still access shortcuts. */ private ComponentName mLastKnownLauncher; /** In-memory-cached default launcher. */ private ComponentName mCachedLauncher; private String mCachedLauncher; private String mKnownLocales; Loading Loading @@ -350,8 +342,6 @@ class ShortcutUser { mLastAppScanOsFingerprint); ShortcutService.writeAttr(out, ATTR_RESTORE_SOURCE_FINGERPRINT, mRestoreFromOsFingerprint); ShortcutService.writeTagValue(out, TAG_LAUNCHER, mLastKnownLauncher); } else { ShortcutService.writeAttr(out, ATTR_RESTORE_SOURCE_FINGERPRINT, mService.injectBuildFingerprint()); Loading Loading @@ -448,11 +438,6 @@ class ShortcutUser { if (depth == outerDepth + 1) { switch (tag) { case TAG_LAUNCHER: { ret.mLastKnownLauncher = ShortcutService.parseComponentNameAttribute( parser, ATTR_VALUE); continue; } case ShortcutPackage.TAG_ROOT: { final ShortcutPackage shortcuts = ShortcutPackage.loadFromXml( s, ret, parser, fromBackup); Loading Loading @@ -515,41 +500,11 @@ class ShortcutUser { } } public ComponentName getLastKnownLauncher() { return mLastKnownLauncher; } public void setLauncher(ComponentName launcherComponent) { setLauncher(launcherComponent, /* allowPurgeLastKnown */ false); } /** Clears the launcher information without clearing the last known one */ public void clearLauncher() { setLauncher(null); } /** * Clears the launcher information *with(* clearing the last known one; we do this witl * "cmd shortcut clear-default-launcher". */ public void forceClearLauncher() { setLauncher(null, /* allowPurgeLastKnown */ true); } private void setLauncher(ComponentName launcherComponent, boolean allowPurgeLastKnown) { mCachedLauncher = launcherComponent; // Always update the in-memory cache. if (Objects.equals(mLastKnownLauncher, launcherComponent)) { return; } if (!allowPurgeLastKnown && launcherComponent == null) { return; } mLastKnownLauncher = launcherComponent; mService.scheduleSaveUser(mUserId); public void setCachedLauncher(String launcher) { mCachedLauncher = launcher; } public ComponentName getCachedLauncher() { public String getCachedLauncher() { return mCachedLauncher; } Loading Loading @@ -640,16 +595,10 @@ class ShortcutUser { pw.print(mRestoreFromOsFingerprint); pw.println(); pw.print(prefix); pw.print("Cached launcher: "); pw.print(mCachedLauncher); pw.println(); pw.print(prefix); pw.print("Last known launcher: "); pw.print(mLastKnownLauncher); pw.println(); } for (int i = 0; i < mLaunchers.size(); i++) { Loading
services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +38 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java +5 −15 Original line number Diff line number Diff line Loading @@ -3810,9 +3810,6 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals(2, mManager.getRemainingCallCount()); }); mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM).setLauncher( new ComponentName("pkg1", "class")); // Restore. mService.saveDirtyInfo(); initService(); Loading Loading @@ -3843,9 +3840,6 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals("title2-2", getCallerShortcut("s2").getTitle()); }); assertEquals("pkg1", mService.getShortcutsForTest().get(UserHandle.USER_SYSTEM) .getLastKnownLauncher().getPackageName()); // Start another user mService.handleUnlockUser(USER_10); Loading @@ -3860,7 +3854,6 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { assertEquals("title10-1-1", getCallerShortcut("s1").getTitle()); assertEquals("title10-1-2", getCallerShortcut("s2").getTitle()); }); assertNull(mService.getShortcutsForTest().get(USER_10).getLastKnownLauncher()); // Try stopping the user mService.handleStopUser(USER_10); Loading Loading @@ -6440,7 +6433,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); // Prepare for requestPinShortcut(). setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_1, USER_0)); setDefaultLauncher(USER_0, LAUNCHER_1); mPinConfirmActivityFetcher = (packageName, userId) -> new ComponentName(packageName, PIN_CONFIRM_ACTIVITY_CLASS); Loading @@ -6465,7 +6458,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { }); // Now, change the launcher to launcher2, and request pin again. setDefaultLauncher(USER_0, mMainActivityFetcher.apply(LAUNCHER_2, USER_0)); setDefaultLauncher(USER_0, LAUNCHER_2); reset(mServiceContext); Loading Loading @@ -8514,10 +8507,9 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { } public void testIsForegroundDefaultLauncher_true() { final ComponentName defaultLauncher = new ComponentName("default", "launcher"); final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, defaultLauncher); setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); makeUidForeground(uid); assertTrue(mInternal.isForegroundDefaultLauncher("default", uid)); Loading @@ -8525,20 +8517,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { public void testIsForegroundDefaultLauncher_defaultButNotForeground() { final ComponentName defaultLauncher = new ComponentName("default", "launcher"); final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, defaultLauncher); setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); makeUidBackground(uid); assertFalse(mInternal.isForegroundDefaultLauncher("default", uid)); } public void testIsForegroundDefaultLauncher_foregroundButNotDefault() { final ComponentName defaultLauncher = new ComponentName("default", "launcher"); final int uid = 1024; setDefaultLauncher(UserHandle.USER_SYSTEM, defaultLauncher); setDefaultLauncher(UserHandle.USER_SYSTEM, "default"); makeUidForeground(uid); assertFalse(mInternal.isForegroundDefaultLauncher("another", uid)); Loading