* If the calling launcher application contains pinned shortcuts, they will still work,
* even though the caller no longer has the shortcut host permission.
*
- * <p>Returns {@code false} when the user is locked.
+ * @throws IllegalStateException when the user is locked.
*
* @see ShortcutManager
*/
* <p>Callers must be allowed to access the shortcut information, as defined in {@link
* #hasShortcutHostPermission()}.
*
- * <p>Returns am empty list when the user is locked, or when the {@code user} user
- * is locked or not running.
- *
* @param query result includes shortcuts matching this query.
* @param user The UserHandle of the profile.
*
* @return the IDs of {@link ShortcutInfo}s that match the query.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
*/
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Call will be ignored when the user is locked, or when the {@code user} user
- * is locked or not running.
- *
* @param packageName The target package name.
* @param shortcutIds The IDs of the shortcut to be pinned.
* @param user The UserHandle of the profile.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
*/
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Returns {@code null} when the user is locked, or when the user owning the shortcut
- * is locked or not running.
- *
* @param density The preferred density of the icon, zero for default density. Use
* density DPI values from {@link DisplayMetrics}.
*
* @return The drawable associated with the shortcut.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
* @see #getShortcutBadgedIconDrawable(ShortcutInfo, int)
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Returns {@code 0} when the user is locked, or when the user owning the shortcut
- * is locked or not running.
- *
* @param density Optional density for the icon, or 0 to use the default density. Use
* @return A badged icon for the shortcut.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
* @see #getShortcutIconDrawable(ShortcutInfo, int)
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Throws {@link android.content.ActivityNotFoundException}
- * when the user is locked, or when the {@code user} user
- * is locked or not running.
- *
* @param packageName The target shortcut package name.
* @param shortcutId The target shortcut ID.
* @param sourceBounds The Rect containing the source bounds of the clicked icon.
* @param startActivityOptions Options to pass to startActivity.
* @param user The UserHandle of the profile.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @throws android.content.ActivityNotFoundException failed to start shortcut. (e.g.
* the shortcut no longer exists, is disabled, the intent receiver activity doesn't exist, etc)
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Throws {@link android.content.ActivityNotFoundException}
- * when the user is locked, or when the user owning the shortcut
- * is locked or not running.
- *
* @param shortcut The target shortcut.
* @param sourceBounds The Rect containing the source bounds of the clicked icon.
* @param startActivityOptions Options to pass to startActivity.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @throws android.content.ActivityNotFoundException failed to start shortcut. (e.g.
* the shortcut no longer exists, is disabled, the intent receiver activity doesn't exist, etc)
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.SparseLongArray;
import android.util.TypedValue;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_UNINSTALLED_PACKAGES;
+ @GuardedBy("mLock")
+ final SparseBooleanArray mUnlockedUsers = new SparseBooleanArray();
+
// Stats
@VisibleForTesting
interface Stats {
Slog.d(TAG, "handleUnlockUser: user=" + userId);
}
synchronized (mLock) {
+ mUnlockedUsers.put(userId, true);
+
// Preload the user's shortcuts.
// Also see if the locale has changed.
// Note as of nyc, the locale is per-user, so the locale shouldn't change
/** lifecycle event */
void handleCleanupUser(int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, "handleCleanupUser: user=" + userId);
+ }
synchronized (mLock) {
unloadUserLocked(userId);
+
+ mUnlockedUsers.put(userId, false);
}
}
if (DEBUG) {
Slog.d(TAG, "saveDirtyInfo");
}
- synchronized (mLock) {
- for (int i = mDirtyUserIds.size() - 1; i >= 0; i--) {
- final int userId = mDirtyUserIds.get(i);
- if (userId == UserHandle.USER_NULL) { // USER_NULL for base state.
- saveBaseStateLocked();
- } else {
- saveUserLocked(userId);
+ try {
+ synchronized (mLock) {
+ for (int i = mDirtyUserIds.size() - 1; i >= 0; i--) {
+ final int userId = mDirtyUserIds.get(i);
+ if (userId == UserHandle.USER_NULL) { // USER_NULL for base state.
+ saveBaseStateLocked();
+ } else {
+ saveUserLocked(userId);
+ }
}
+ mDirtyUserIds.clear();
}
- mDirtyUserIds.clear();
+ } catch (Exception e) {
+ wtf("Exception in saveDirtyInfo", e);
}
}
}
}
- private boolean isUserUnlocked(@UserIdInt int userId) {
- final long token = injectClearCallingIdentity();
- try {
- // Weird: when SystemService.onUnlockUser() is called, the user state is still
- // unlocking, as opposed to unlocked. So we need to accept the "unlocking" state too.
- // We know when the user is unlocking, the CE storage is already unlocked.
- return mUserManager.isUserUnlockingOrUnlocked(userId);
- } finally {
- injectRestoreCallingIdentity(token);
- }
+ // Requires mLock held, but "Locked" prefix would look weired so we jsut say "L".
+ protected boolean isUserUnlockedL(@UserIdInt int userId) {
+ return mUnlockedUsers.get(userId);
}
- void throwIfUserLocked(@UserIdInt int userId) {
- if (!isUserUnlocked(userId)) {
+ // Requires mLock held, but "Locked" prefix would look weired so we jsut say "L".
+ void throwIfUserLockedL(@UserIdInt int userId) {
+ if (!isUserUnlockedL(userId)) {
throw new IllegalStateException("User " + userId + " is locked or not running");
}
}
@GuardedBy("mLock")
@NonNull
ShortcutUser getUserShortcutsLocked(@UserIdInt int userId) {
- if (!isUserUnlocked(userId)) {
+ if (!isUserUnlockedL(userId)) {
wtf("User still locked");
- return new ShortcutUser(this, userId);
}
ShortcutUser userPackages = mUsers.get(userId);
}
private void notifyListeners(@NonNull String packageName, @UserIdInt int userId) {
- final long token = injectClearCallingIdentity();
- try {
- if (!mUserManager.isUserRunning(userId)) {
- return;
- }
- } finally {
- injectRestoreCallingIdentity(token);
- }
injectPostToHandler(() -> {
- final ArrayList<ShortcutChangeListener> copy;
- synchronized (mLock) {
- copy = new ArrayList<>(mListeners);
- }
- // Note onShortcutChanged() needs to be called with the system service permissions.
- for (int i = copy.size() - 1; i >= 0; i--) {
- copy.get(i).onShortcutChanged(packageName, userId);
+ try {
+ final ArrayList<ShortcutChangeListener> copy;
+ synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ return;
+ }
+
+ copy = new ArrayList<>(mListeners);
+ }
+ // Note onShortcutChanged() needs to be called with the system service permissions.
+ for (int i = copy.size() - 1; i >= 0; i--) {
+ copy.get(i).onShortcutChanged(packageName, userId);
+ }
+ } catch (Exception ignore) {
}
});
}
public boolean setDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
final int size = newShortcuts.size();
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
public boolean updateShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
final int size = newShortcuts.size();
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
public boolean addDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
final int size = newShortcuts.size();
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
CharSequence disabledMessage, int disabledMessageResId, @UserIdInt int userId) {
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
public void enableShortcuts(String packageName, List shortcutIds, @UserIdInt int userId) {
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@UserIdInt int userId) {
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@Override
public void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
ps.deleteAllDynamicShortcuts();
public ParceledListSlice<ShortcutInfo> getDynamicShortcuts(String packageName,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
ShortcutInfo::isDynamic);
public ParceledListSlice<ShortcutInfo> getManifestShortcuts(String packageName,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
ShortcutInfo::isManifestShortcut);
public ParceledListSlice<ShortcutInfo> getPinnedShortcuts(String packageName,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
ShortcutInfo::isPinned);
@Override
public int getRemainingCallCount(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
return mMaxUpdatesPerInterval - ps.getApiCallCount();
@Override
public long getRateLimitResetTime(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getNextResetTimeLocked();
}
}
@Override
public void reportShortcutUsed(String packageName, String shortcutId, int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
Preconditions.checkNotNull(shortcutId);
}
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
void resetThrottlingInner(@UserIdInt int userId) {
synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ Log.w(TAG, "User " + userId + " is locked or not running");
+ return;
+ }
+
getUserShortcutsLocked(userId).resetThrottling();
}
scheduleSaveUser(userId);
Slog.i(TAG, "ShortcutManager: throttling counter reset for all users");
}
- void resetPackageThrottling(String packageName, int userId) {
- synchronized (mLock) {
- getPackageShortcutsLocked(packageName, userId)
- .resetRateLimitingForCommandLineNoSaving();
- saveUserLocked(userId);
- }
- }
-
@Override
public void onApplicationActive(String packageName, int userId) {
if (DEBUG) {
Slog.d(TAG, "onApplicationActive: package=" + packageName + " userid=" + userId);
}
enforceResetThrottlingPermission();
- if (!isUserUnlocked(userId)) {
- // This is called by system UI, so no need to throw. Just ignore.
- return;
+
+ synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ // This is called by system UI, so no need to throw. Just ignore.
+ return;
+ }
+
+ getPackageShortcutsLocked(packageName, userId)
+ .resetRateLimitingForCommandLineNoSaving();
+ saveUserLocked(userId);
}
- resetPackageThrottling(packageName, userId);
}
// We override this method in unit tests to do a simpler check.
// even when hasShortcutPermission() is overridden.
@VisibleForTesting
boolean hasShortcutHostPermissionInner(@NonNull String callingPackage, int userId) {
- throwIfUserLocked(userId);
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutUser user = getUserShortcutsLocked(userId);
// Always trust the in-memory cache.
@Nullable ComponentName componentName,
int queryFlags, int userId) {
final ArrayList<ShortcutInfo> ret = new ArrayList<>();
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return ret;
- }
final boolean cloneKeyFieldOnly =
((queryFlags & ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY) != 0);
}
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return false;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return null;
- }
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
final ShortcutPackage p = getUserShortcutsLocked(userId)
.getPackageShortcutsIfExists(packageName);
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkNotNull(shortcutIds, "shortcutIds");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
final ShortcutLauncher launcher =
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId);
launcher.attemptToRestoreIfNeededAndSave();
Preconditions.checkStringNotEmpty(packageName, "packageName can't be empty");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId can't be empty");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return null;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
Preconditions.checkNotNull(packageName, "packageName");
Preconditions.checkNotNull(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return 0;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
Preconditions.checkNotNull(packageName, "packageName");
Preconditions.checkNotNull(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return null;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@Override
public boolean hasShortcutHostPermission(int launcherUserId,
@NonNull String callingPackage) {
- if (!isUserUnlocked(launcherUserId)) {
- return false;
- }
return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId);
}
}
if (!mBootCompleted.get()) {
return; // Boot not completed, ignore the broadcast.
}
- if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
- handleLocaleChanged();
+ try {
+ if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+ handleLocaleChanged();
+ }
+ } catch (Exception e) {
+ wtf("Exception in mReceiver.onReceive", e);
}
}
};
}
scheduleSaveBaseState();
- final long token = injectClearCallingIdentity();
- try {
- forEachLoadedUserLocked(user -> user.detectLocaleChange());
- } finally {
- injectRestoreCallingIdentity(token);
+ synchronized (mLock) {
+ final long token = injectClearCallingIdentity();
+ try {
+ forEachLoadedUserLocked(user -> user.detectLocaleChange());
+ } finally {
+ injectRestoreCallingIdentity(token);
+ }
}
}
// but we still check it in unit tests.
final long token = injectClearCallingIdentity();
try {
-
- if (!isUserUnlocked(userId)) {
- if (DEBUG) {
- Slog.d(TAG, "Ignoring package broadcast " + action
- + " for locked/stopped user " + userId);
+ synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ if (DEBUG) {
+ Slog.d(TAG, "Ignoring package broadcast " + action
+ + " for locked/stopped user " + userId);
+ }
+ return;
}
- return;
- }
- // Whenever we get one of those package broadcasts, or get
- // ACTION_PREFERRED_ACTIVITY_CHANGED, we purge the default launcher cache.
- synchronized (mLock) {
+ // 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();
}
handlePackageDataCleared(packageName, userId);
break;
}
+ } catch (Exception e) {
+ wtf("Exception in mPackageMonitor.onReceive", e);
} finally {
injectRestoreCallingIdentity(token);
}
Slog.d(TAG, "Backing up user " + userId);
}
synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ wtf("Can't backup: user " + userId + " is locked or not running");
+ return null;
+ }
+
final ShortcutUser user = getUserShortcutsLocked(userId);
if (user == null) {
- Slog.w(TAG, "Can't backup: user not found: id=" + userId);
+ wtf("Can't backup: user not found: id=" + userId);
return null;
}
if (DEBUG) {
Slog.d(TAG, "Restoring user " + userId);
}
- final ShortcutUser user;
- final ByteArrayInputStream is = new ByteArrayInputStream(payload);
- try {
- user = loadUserInternal(userId, is, /* fromBackup */ true);
- } catch (XmlPullParserException | IOException e) {
- Slog.w(TAG, "Restoration failed.", e);
- return;
- }
synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ wtf("Can't restore: user " + userId + " is locked or not running");
+ return;
+ }
+ final ShortcutUser user;
+ final ByteArrayInputStream is = new ByteArrayInputStream(payload);
+ try {
+ user = loadUserInternal(userId, is, /* fromBackup */ true);
+ } catch (XmlPullParserException | IOException e) {
+ Slog.w(TAG, "Restoration failed.", e);
+ return;
+ }
mUsers.put(userId, user);
// Then purge all the save images.
private int mUserId = UserHandle.USER_SYSTEM;
- private void parseOptions(boolean takeUser)
+ private void parseOptionsLocked(boolean takeUser)
throws CommandException {
String opt;
while ((opt = getNextOption()) != null) {
case "--user":
if (takeUser) {
mUserId = UserHandle.parseUserArg(getNextArgRequired());
- if (!isUserUnlocked(mUserId)) {
+ if (!isUserUnlockedL(mUserId)) {
throw new CommandException(
"User " + mUserId + " is not running or locked");
}
}
private void handleResetThrottling() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- Slog.i(TAG, "cmd: handleResetThrottling: user=" + mUserId);
+ Slog.i(TAG, "cmd: handleResetThrottling: user=" + mUserId);
- resetThrottlingInner(mUserId);
+ resetThrottlingInner(mUserId);
+ }
}
private void handleResetAllThrottling() {
}
private void handleClearDefaultLauncher() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- clearLauncher();
+ clearLauncher();
+ }
}
private void handleGetDefaultLauncher() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- clearLauncher();
- showLauncher();
+ clearLauncher();
+ showLauncher();
+ }
}
private void handleUnloadUser() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- Slog.i(TAG, "cmd: handleUnloadUser: user=" + mUserId);
+ Slog.i(TAG, "cmd: handleUnloadUser: user=" + mUserId);
- ShortcutService.this.handleCleanupUser(mUserId);
+ ShortcutService.this.handleCleanupUser(mUserId);
+ }
}
private void handleClearShortcuts() throws CommandException {
- parseOptions(/* takeUser =*/ true);
- final String packageName = getNextArgRequired();
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
+ final String packageName = getNextArgRequired();
- Slog.i(TAG, "cmd: handleClearShortcuts: user" + mUserId + ", " + packageName);
+ Slog.i(TAG, "cmd: handleClearShortcuts: user" + mUserId + ", " + packageName);
- ShortcutService.this.cleanUpPackageForAllLoadedUsers(packageName, mUserId,
- /* appStillExists = */ true);
+ ShortcutService.this.cleanUpPackageForAllLoadedUsers(packageName, mUserId,
+ /* appStillExists = */ true);
+ }
}
private void handleVerifyStates() throws CommandException {