From 756901d82b41f50610a63b7cf4c7747a70f1f724 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Fri, 12 Oct 2012 12:30:07 -0700 Subject: Do cleanup when Stopping users Mark user 0 as initialized, otherwise it will show up as uninitialized when viewed from secondary user if never switched to user 0. Bug: 7301595 Also clean up any users that were in the process of being removed, if device crashes at a bad time. Change-Id: Ic16a6c9ccb6a64b7463725f6cc279335a821fcd5 --- .../java/com/android/server/AppWidgetService.java | 34 +++++++++++++--------- .../com/android/server/AppWidgetServiceImpl.java | 5 +++- .../android/server/WallpaperManagerService.java | 23 +++++++++++++-- .../com/android/server/pm/UserManagerService.java | 9 ++++-- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index c18fe0e..b44340f 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -98,21 +98,19 @@ class AppWidgetService extends IAppWidgetService.Stub IntentFilter userFilter = new IntentFilter(); userFilter.addAction(Intent.ACTION_USER_REMOVED); + userFilter.addAction(Intent.ACTION_USER_STOPPING); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)); + if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { + onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } else if (Intent.ACTION_USER_STOPPING.equals(intent.getAction())) { + onUserStopping(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } } }, userFilter); - - IntentFilter userStopFilter = new IntentFilter(); - userStopFilter.addAction(Intent.ACTION_USER_STOPPED); - mContext.registerReceiverAsUser(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - onUserStopped(getSendingUserId()); - } - }, UserHandle.ALL, userFilter, null, null); } /** @@ -203,7 +201,7 @@ class AppWidgetService extends IAppWidgetService.Stub synchronized (mAppWidgetServices) { AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); mAppWidgetServices.remove(userId); - + if (impl == null) { AppWidgetServiceImpl.getSettingsFile(userId).delete(); } else { @@ -212,7 +210,15 @@ class AppWidgetService extends IAppWidgetService.Stub } } - public void onUserStopped(int userId) { + public void onUserStopping(int userId) { + if (userId < 1) return; + synchronized (mAppWidgetServices) { + AppWidgetServiceImpl impl = mAppWidgetServices.get(userId); + if (impl != null) { + mAppWidgetServices.remove(userId); + impl.onUserStopping(); + } + } } private AppWidgetServiceImpl getImplForUser(int userId) { @@ -322,11 +328,11 @@ class AppWidgetService extends IAppWidgetService.Stub String action = intent.getAction(); // Slog.d(TAG, "received " + action); if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { - int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); if (userId >= 0) { getImplForUser(userId).sendInitialBroadcasts(); } else { - Slog.w(TAG, "Not user handle supplied in " + intent); + Slog.w(TAG, "Incorrect user handle supplied in " + intent); } } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { for (int i = 0; i < mAppWidgetServices.size(); i++) { diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index 9fea6f3..6a313a0 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -1778,13 +1778,16 @@ class AppWidgetServiceImpl { return new AtomicFile(settingsFile); } - void onUserRemoved() { + void onUserStopping() { // prune the ones we don't want to keep int N = mInstalledProviders.size(); for (int i = N - 1; i >= 0; i--) { Provider p = mInstalledProviders.get(i); cancelBroadcasts(p); } + } + + void onUserRemoved() { getSettingsFile(mUserId).delete(); } diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index e0f3814..a02fc8d 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -458,15 +458,21 @@ class WallpaperManagerService extends IWallpaperManager.Stub { IntentFilter userFilter = new IntentFilter(); userFilter.addAction(Intent.ACTION_USER_REMOVED); + userFilter.addAction(Intent.ACTION_USER_STOPPING); mContext.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_USER_REMOVED.equals(action)) { - removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); + onRemoveUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); + } else if (Intent.ACTION_USER_STOPPING.equals(action)) { + onStoppingUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL)); } } }, userFilter); + try { ActivityManagerNative.getDefault().registerUserSwitchObserver( new IUserSwitchObserver.Stub() { @@ -491,13 +497,24 @@ class WallpaperManagerService extends IWallpaperManager.Stub { } } - void removeUser(int userId) { + void onStoppingUser(int userId) { + if (userId < 1) return; synchronized (mLock) { WallpaperData wallpaper = mWallpaperMap.get(userId); if (wallpaper != null) { - wallpaper.wallpaperObserver.stopWatching(); + if (wallpaper.wallpaperObserver != null) { + wallpaper.wallpaperObserver.stopWatching(); + wallpaper.wallpaperObserver = null; + } mWallpaperMap.remove(userId); } + } + } + + void onRemoveUser(int userId) { + if (userId < 1) return; + synchronized (mLock) { + onStoppingUser(userId); File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER); wallpaperFile.delete(); File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO); diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java index 4f9375a..77e6c03 100644 --- a/services/java/com/android/server/pm/UserManagerService.java +++ b/services/java/com/android/server/pm/UserManagerService.java @@ -149,7 +149,7 @@ public class UserManagerService extends IUserManager.Stub { -1, -1); mUserListFile = new File(mUsersDir, USER_LIST_FILENAME); readUserListLocked(); - // Prune out any partially created users. + // Prune out any partially created/partially removed users. ArrayList partials = new ArrayList(); for (int i = 0; i < mUsers.size(); i++) { UserInfo ui = mUsers.valueAt(i); @@ -459,7 +459,7 @@ public class UserManagerService extends IUserManager.Stub { private void fallbackToSingleUserLocked() { // Create the primary user UserInfo primary = new UserInfo(0, "Primary", null, - UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); + UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED); mUsers.put(0, primary); mNextSerialNumber = MIN_USER_ID; updateUserIdsLocked(); @@ -703,6 +703,11 @@ public class UserManagerService extends IUserManager.Stub { return false; } mRemovingUserIds.add(userHandle); + // Set this to a partially created user, so that the user will be purged + // on next startup, in case the runtime stops now before stopping and + // removing the user completely. + user.partial = true; + writeUserLocked(user); } int res; -- cgit v1.1