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
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 @@
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 @@
synchronized (mAppWidgetServices) {
AppWidgetServiceImpl impl = mAppWidgetServices.get(userId);
mAppWidgetServices.remove(userId);
-
+
if (impl == null) {
AppWidgetServiceImpl.getSettingsFile(userId).delete();
} else {
@@ -212,7 +210,15 @@
}
}
- 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 @@
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 @@
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 @@
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 @@
}
}
- 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 @@
-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<UserInfo> partials = new ArrayList<UserInfo>();
for (int i = 0; i < mUsers.size(); i++) {
UserInfo ui = mUsers.valueAt(i);
@@ -459,7 +459,7 @@
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 @@
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;