Exclude tasks manipulated before user setup is complete from Recents
We don't want any tasks manipulated before the user is done setting-up
their device included in the tasks list we give to the Recents activity.
However, the task can be included back in Recents if it is manipulated
after the user set-up is complete. E.g. you go into the gmail activity
during setup the task will be exclude, but if the user goes back into
gmail after setup then we start including the task.
Bug: 25959392
Change-Id: I421d48f0a9bcfc782d1ef19aa2f63e8b34a668e2
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 551f332..2f63b2d3 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -24,6 +24,7 @@
import static android.app.ActivityManager.USER_OP_SUCCESS;
import static android.content.Context.KEYGUARD_SERVICE;
import static android.os.Process.SYSTEM_UID;
+import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -45,11 +46,14 @@
import android.app.IStopUserCallback;
import android.app.IUserSwitchObserver;
import android.app.KeyguardManager;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Bundle;
@@ -66,10 +70,12 @@
import android.os.UserManager;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
+import android.provider.Settings;
import android.util.IntArray;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import com.android.internal.R;
@@ -145,6 +151,34 @@
private final LockPatternUtils mLockPatternUtils;
+ // Set of users who have completed the set-up process.
+ private final SparseBooleanArray mSetupCompletedUsers = new SparseBooleanArray();
+ private final UserSetupCompleteContentObserver mUserSetupCompleteContentObserver;
+
+ private class UserSetupCompleteContentObserver extends ContentObserver {
+ private final Uri mUserSetupComplete = Settings.Secure.getUriFor(USER_SETUP_COMPLETE);
+
+ public UserSetupCompleteContentObserver(Handler handler) {
+ super(handler);
+ }
+
+ void register(ContentResolver resolver) {
+ resolver.registerContentObserver(mUserSetupComplete, false, this, UserHandle.USER_ALL);
+ synchronized (mService) {
+ updateCurrentUserSetupCompleteLocked();
+ }
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (mUserSetupComplete.equals(uri)) {
+ synchronized (mService) {
+ updateCurrentUserSetupCompleteLocked();
+ }
+ }
+ }
+ }
+
UserController(ActivityManagerService service) {
mService = service;
mHandler = mService.mHandler;
@@ -154,6 +188,7 @@
mUserLru.add(UserHandle.USER_SYSTEM);
mLockPatternUtils = new LockPatternUtils(mService.mContext);
updateStartedUserArrayLocked();
+ mUserSetupCompleteContentObserver = new UserSetupCompleteContentObserver(mHandler);
}
void finishUserSwitch(UserState uss) {
@@ -424,6 +459,7 @@
mStartedUsers.remove(userId);
mUserLru.remove(Integer.valueOf(userId));
updateStartedUserArrayLocked();
+ mSetupCompletedUsers.delete(userId);
mService.onUserStoppedLocked(userId);
// Clean up all state and processes associated with the user.
@@ -619,6 +655,7 @@
final Integer userIdInt = userId;
mUserLru.remove(userIdInt);
mUserLru.add(userIdInt);
+ updateCurrentUserSetupCompleteLocked();
if (foreground) {
mCurrentUserId = userId;
@@ -833,6 +870,17 @@
mUserSwitchObservers.finishBroadcast();
}
+ void updateCurrentUserSetupCompleteLocked() {
+ final ContentResolver cr = mService.mContext.getContentResolver();
+ final boolean setupComplete =
+ Settings.Secure.getIntForUser(cr, USER_SETUP_COMPLETE, 0, mCurrentUserId) != 0;
+ mSetupCompletedUsers.put(mCurrentUserId, setupComplete);
+ }
+
+ boolean isUserSetupCompleteLocked(int userId) {
+ return mSetupCompletedUsers.get(userId);
+ }
+
private void stopBackgroundUsersIfEnforced(int oldUserId) {
// Never stop system user
if (oldUserId == UserHandle.USER_SYSTEM) {
@@ -1141,12 +1189,17 @@
}
}
+ void onSystemReady() {
+ updateCurrentProfileIdsLocked();
+ mUserSetupCompleteContentObserver.register(mService.mContext.getContentResolver());
+ }
+
/**
* Refreshes the list of users related to the current user when either a
* user switch happens or when a new related user is started in the
* background.
*/
- void updateCurrentProfileIdsLocked() {
+ private void updateCurrentProfileIdsLocked() {
final List<UserInfo> profiles = getUserManager().getProfiles(mCurrentUserId,
false /* enabledOnly */);
int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null