Reset RunningState on user related changes

RunningState now listens to user-related broadcasts and resets its state if
necessary.

Previously, user entry was visible even after the user had been removed.

Bug:18696308
Change-Id: I499956c434d0d05bfa2a99b5e3e71ac73fe83297
This commit is contained in:
Fyodor Kupolov
2015-01-21 10:33:52 -08:00
parent 08309d2072
commit 5c22ab9781

View File

@@ -19,8 +19,11 @@ package com.android.settings.applications;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.app.ActivityManagerNative; import android.app.ActivityManagerNative;
import android.app.ActivityThread; import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageItemInfo; import android.content.pm.PackageItemInfo;
@@ -28,8 +31,6 @@ import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo; import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState; import android.graphics.drawable.Drawable.ConstantState;
import android.os.Handler; import android.os.Handler;
@@ -45,7 +46,6 @@ import android.util.SparseArray;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils; import com.android.settings.Utils;
import com.android.settings.drawable.CircleFramedDrawable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -124,9 +124,6 @@ public class RunningState {
// representing all items that would be put in mUserBackgroundItems for that user. // representing all items that would be put in mUserBackgroundItems for that user.
final SparseArray<MergedItem> mOtherUserBackgroundItems = new SparseArray<MergedItem>(); final SparseArray<MergedItem> mOtherUserBackgroundItems = new SparseArray<MergedItem>();
// Tracking of information about users.
final SparseArray<UserState> mUsers = new SparseArray<UserState>();
static class AppProcessInfo { static class AppProcessInfo {
final ActivityManager.RunningAppProcessInfo info; final ActivityManager.RunningAppProcessInfo info;
boolean hasServices; boolean hasServices;
@@ -286,6 +283,42 @@ public class RunningState {
} }
}; };
private final class UserManagerBroadcastReceiver extends BroadcastReceiver {
private volatile boolean usersChanged;
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
if (mResumed) {
mHaveData = false;
mBackgroundHandler.removeMessages(MSG_RESET_CONTENTS);
mBackgroundHandler.sendEmptyMessage(MSG_RESET_CONTENTS);
mBackgroundHandler.removeMessages(MSG_UPDATE_CONTENTS);
mBackgroundHandler.sendEmptyMessage(MSG_UPDATE_CONTENTS);
} else {
usersChanged = true;
}
}
}
public boolean checkUsersChangedLocked() {
boolean oldValue = usersChanged;
usersChanged = false;
return oldValue;
}
void register(Context context) {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_STOPPED);
filter.addAction(Intent.ACTION_USER_STARTED);
filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
context.registerReceiverAsUser(this, UserHandle.ALL, filter, null, null);
}
}
private final UserManagerBroadcastReceiver mUmBroadcastReceiver =
new UserManagerBroadcastReceiver();
// ----- DATA STRUCTURES ----- // ----- DATA STRUCTURES -----
static interface OnRefreshUiListener { static interface OnRefreshUiListener {
@@ -752,15 +785,17 @@ public class RunningState {
mBackgroundThread = new HandlerThread("RunningState:Background"); mBackgroundThread = new HandlerThread("RunningState:Background");
mBackgroundThread.start(); mBackgroundThread.start();
mBackgroundHandler = new BackgroundHandler(mBackgroundThread.getLooper()); mBackgroundHandler = new BackgroundHandler(mBackgroundThread.getLooper());
mUmBroadcastReceiver.register(mApplicationContext);
} }
void resume(OnRefreshUiListener listener) { void resume(OnRefreshUiListener listener) {
synchronized (mLock) { synchronized (mLock) {
mResumed = true; mResumed = true;
mRefreshUiListener = listener; mRefreshUiListener = listener;
// TODO: The set of users may have changed too, so we should probably recompute it boolean usersChanged = mUmBroadcastReceiver.checkUsersChangedLocked();
// each time, but that might be costly. See http://b/18696308 boolean configChanged =
if (mInterestingConfigChanges.applyNewConfig(mApplicationContext.getResources())) { mInterestingConfigChanges.applyNewConfig(mApplicationContext.getResources());
if (usersChanged || configChanged) {
mHaveData = false; mHaveData = false;
mBackgroundHandler.removeMessages(MSG_RESET_CONTENTS); mBackgroundHandler.removeMessages(MSG_RESET_CONTENTS);
mBackgroundHandler.removeMessages(MSG_UPDATE_CONTENTS); mBackgroundHandler.removeMessages(MSG_UPDATE_CONTENTS);
@@ -826,7 +861,6 @@ public class RunningState {
mRunningProcesses.clear(); mRunningProcesses.clear();
mProcessItems.clear(); mProcessItems.clear();
mAllProcessItems.clear(); mAllProcessItems.clear();
mUsers.clear();
} }
private void addOtherUserItem(Context context, ArrayList<MergedItem> newMergedItems, private void addOtherUserItem(Context context, ArrayList<MergedItem> newMergedItems,
@@ -834,9 +868,7 @@ public class RunningState {
MergedItem userItem = userItems.get(newItem.mUserId); MergedItem userItem = userItems.get(newItem.mUserId);
boolean first = userItem == null || userItem.mCurSeq != mSequence; boolean first = userItem == null || userItem.mCurSeq != mSequence;
if (first) { if (first) {
UserState userState = mUsers.get(newItem.mUserId); UserInfo info = mUm.getUserInfo(newItem.mUserId);
UserInfo info = userState != null
? userState.mInfo : mUm.getUserInfo(newItem.mUserId);
if (info == null) { if (info == null) {
// The user no longer exists, skip // The user no longer exists, skip
return; return;
@@ -851,12 +883,10 @@ public class RunningState {
userItem.mChildren.clear(); userItem.mChildren.clear();
} }
userItem.mCurSeq = mSequence; userItem.mCurSeq = mSequence;
if (userState == null) { userItem.mUser = new UserState();
userItem.mUser = new UserState(); userItem.mUser.mInfo = info;
userItem.mUser.mInfo = info; userItem.mUser.mIcon = Utils.getUserIcon(context, mUm, info);
userItem.mUser.mIcon = Utils.getUserIcon(context, mUm, info); userItem.mUser.mLabel = Utils.getUserLabel(context, info);
userItem.mUser.mLabel = Utils.getUserLabel(context, info);
}
newMergedItems.add(userItem); newMergedItems.add(userItem);
} }
userItem.mChildren.add(newItem); userItem.mChildren.add(newItem);
@@ -1405,12 +1435,6 @@ public class RunningState {
return changed; return changed;
} }
ArrayList<BaseItem> getCurrentItems() {
synchronized (mLock) {
return mItems;
}
}
void setWatchingBackgroundItems(boolean watching) { void setWatchingBackgroundItems(boolean watching) {
synchronized (mLock) { synchronized (mLock) {
mWatchingBackgroundItems = watching; mWatchingBackgroundItems = watching;