Watch out for deleted user when exiting async task

Fixes a problem where the async task can take a while to execute
and in the meantime the user can be removed. On exiting the async
task and updating the UI, make sure the user hasn't been deleted.

Bug: 18411181
Change-Id: I1831f3e53084c49e27557cb7aacec78c753a611b
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index e687beb..dc9e8a2 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -1023,4 +1023,21 @@
         return null;
     }
 
+    /**
+     * Queries for the UserInfo of a user. Returns null if the user doesn't exist (was removed).
+     * @param userManager Instance of UserManager
+     * @param checkUser The user to check the existence of.
+     * @return UserInfo of the user or null for non-existent user.
+     */
+    public static UserInfo getExistingUser(UserManager userManager, UserHandle checkUser) {
+        final List<UserInfo> users = userManager.getUsers(true /* excludeDying */);
+        final int checkUserId = checkUser.getIdentifier();
+        for (UserInfo user : users) {
+            if (user.id == checkUserId) {
+                return user;
+            }
+        }
+        return null;
+    }
+
 }
diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java
index 6fa5a79..4d91184 100644
--- a/src/com/android/settings/users/AppRestrictionsFragment.java
+++ b/src/com/android/settings/users/AppRestrictionsFragment.java
@@ -58,6 +58,7 @@
 
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.Utils;
 import com.android.settings.drawable.CircleFramedDrawable;
 
 import java.util.ArrayList;
@@ -643,75 +644,81 @@
         if (context == null) return;
         final PackageManager pm = mPackageManager;
         final IPackageManager ipm = mIPm;
+        final int userId = mUser.getIdentifier();
 
+        // Check if the user was removed in the meantime.
+        if (Utils.getExistingUser(mUserManager, mUser) == null) {
+            return;
+        }
         mAppList.removeAll();
         Intent restrictionsIntent = new Intent(Intent.ACTION_GET_RESTRICTION_ENTRIES);
         final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(restrictionsIntent, 0);
         int i = 0;
-        if (mVisibleApps.size() > 0) {
-            for (SelectableAppInfo app : mVisibleApps) {
-                String packageName = app.packageName;
-                if (packageName == null) continue;
-                final boolean isSettingsApp = packageName.equals(context.getPackageName());
-                AppRestrictionsPreference p = new AppRestrictionsPreference(context, this);
-                final boolean hasSettings = resolveInfoListHasPackage(receivers, packageName);
-                p.setIcon(app.icon != null ? app.icon.mutate() : null);
-                p.setChecked(false);
-                p.setTitle(app.activityName);
-                if (app.masterEntry != null) {
-                    p.setSummary(context.getString(R.string.user_restrictions_controlled_by,
-                            app.masterEntry.activityName));
-                }
-                p.setKey(getKeyForPackage(packageName));
-                p.setSettingsEnabled((hasSettings || isSettingsApp) && app.masterEntry == null);
-                p.setPersistent(false);
-                p.setOnPreferenceChangeListener(this);
-                p.setOnPreferenceClickListener(this);
-                PackageInfo pi = null;
-                try {
-                    pi = ipm.getPackageInfo(packageName,
-                            PackageManager.GET_UNINSTALLED_PACKAGES
-                            | PackageManager.GET_SIGNATURES, mUser.getIdentifier());
-                } catch (RemoteException e) {
-                }
-                if (pi != null && (pi.requiredForAllUsers || isPlatformSigned(pi))) {
-                    p.setChecked(true);
-                    p.setImmutable(true);
-                    // If the app is required and has no restrictions, skip showing it
-                    if (!hasSettings && !isSettingsApp) continue;
-                    // Get and populate the defaults, since the user is not going to be
-                    // able to toggle this app ON (it's ON by default and immutable).
-                    // Only do this for restricted profiles, not single-user restrictions
-                    // Also don't do this for slave icons
-                    if (hasSettings && app.masterEntry == null) {
-                        requestRestrictionsForApp(packageName, p, false);
-                    }
-                } else if (!mNewUser && isAppEnabledForUser(pi)) {
-                    p.setChecked(true);
-                }
-                if (mRestrictedProfile
-                        && pi.requiredAccountType != null && pi.restrictedAccountType == null) {
-                    p.setChecked(false);
-                    p.setImmutable(true);
-                    p.setSummary(R.string.app_not_supported_in_limited);
-                }
-                if (mRestrictedProfile && pi.restrictedAccountType != null) {
-                    p.setSummary(R.string.app_sees_restricted_accounts);
-                }
-                if (app.masterEntry != null) {
-                    p.setImmutable(true);
-                    p.setChecked(mSelectedPackages.get(packageName));
-                }
-                mAppList.addPreference(p);
-                if (isSettingsApp) {
-                    p.setOrder(MAX_APP_RESTRICTIONS * 1);
-                } else {
-                    p.setOrder(MAX_APP_RESTRICTIONS * (i + 2));
-                }
-                mSelectedPackages.put(packageName, p.isChecked());
-                mAppListChanged = true;
-                i++;
+        for (SelectableAppInfo app : mVisibleApps) {
+            String packageName = app.packageName;
+            if (packageName == null) continue;
+            final boolean isSettingsApp = packageName.equals(context.getPackageName());
+            AppRestrictionsPreference p = new AppRestrictionsPreference(context, this);
+            final boolean hasSettings = resolveInfoListHasPackage(receivers, packageName);
+            p.setIcon(app.icon != null ? app.icon.mutate() : null);
+            p.setChecked(false);
+            p.setTitle(app.activityName);
+            if (app.masterEntry != null) {
+                p.setSummary(context.getString(R.string.user_restrictions_controlled_by,
+                        app.masterEntry.activityName));
             }
+            p.setKey(getKeyForPackage(packageName));
+            p.setSettingsEnabled((hasSettings || isSettingsApp) && app.masterEntry == null);
+            p.setPersistent(false);
+            p.setOnPreferenceChangeListener(this);
+            p.setOnPreferenceClickListener(this);
+            PackageInfo pi = null;
+            try {
+                pi = ipm.getPackageInfo(packageName,
+                        PackageManager.GET_UNINSTALLED_PACKAGES
+                        | PackageManager.GET_SIGNATURES, userId);
+            } catch (RemoteException e) {
+            }
+            if (pi == null) {
+                continue;
+            }
+            if (pi.requiredForAllUsers || isPlatformSigned(pi)) {
+                p.setChecked(true);
+                p.setImmutable(true);
+                // If the app is required and has no restrictions, skip showing it
+                if (!hasSettings && !isSettingsApp) continue;
+                // Get and populate the defaults, since the user is not going to be
+                // able to toggle this app ON (it's ON by default and immutable).
+                // Only do this for restricted profiles, not single-user restrictions
+                // Also don't do this for slave icons
+                if (hasSettings && app.masterEntry == null) {
+                    requestRestrictionsForApp(packageName, p, false);
+                }
+            } else if (!mNewUser && isAppEnabledForUser(pi)) {
+                p.setChecked(true);
+            }
+            if (mRestrictedProfile
+                    && pi.requiredAccountType != null && pi.restrictedAccountType == null) {
+                p.setChecked(false);
+                p.setImmutable(true);
+                p.setSummary(R.string.app_not_supported_in_limited);
+            }
+            if (mRestrictedProfile && pi.restrictedAccountType != null) {
+                p.setSummary(R.string.app_sees_restricted_accounts);
+            }
+            if (app.masterEntry != null) {
+                p.setImmutable(true);
+                p.setChecked(mSelectedPackages.get(packageName));
+            }
+            mAppList.addPreference(p);
+            if (isSettingsApp) {
+                p.setOrder(MAX_APP_RESTRICTIONS * 1);
+            } else {
+                p.setOrder(MAX_APP_RESTRICTIONS * (i + 2));
+            }
+            mSelectedPackages.put(packageName, p.isChecked());
+            mAppListChanged = true;
+            i++;
         }
         // If this is the first time for a new profile, install/uninstall default apps for profile
         // to avoid taking the hit in onPause(), which can cause race conditions on user switch.
diff --git a/src/com/android/settings/users/RestrictedProfileSettings.java b/src/com/android/settings/users/RestrictedProfileSettings.java
index 8db911c..c0e8cb7 100644
--- a/src/com/android/settings/users/RestrictedProfileSettings.java
+++ b/src/com/android/settings/users/RestrictedProfileSettings.java
@@ -87,7 +87,7 @@
         super.onResume();
 
         // Check if user still exists
-        UserInfo info = getExistingUser(mUser);
+        UserInfo info = Utils.getExistingUser(mUserManager, mUser);
         if (info == null) {
             finishFragment();
         } else {
@@ -97,16 +97,6 @@
         }
     }
 
-    private UserInfo getExistingUser(UserHandle thisUser) {
-        final List<UserInfo> users = mUserManager.getUsers(true); // Only get non-dying
-        for (UserInfo user : users) {
-            if (user.id == thisUser.getIdentifier()) {
-                return user;
-            }
-        }
-        return null;
-    }
-
     @Override
     public void startActivityForResult(Intent intent, int requestCode) {
         mEditUserInfoController.startingActivityForResult();