Unlock all users before moving or migrating.

When moving apps or shared storage between storage media on FBE
devices, we need all users to be unlocked to successfully move
the data.  This change asks the user to enter the credentials for
any locked users as part of the moving/migration wizard flows.

To do this we relax Utils.enforceSameOwner() to let us prompt for the
credentials of unrelated users, but we carefully only extend this
capability to callers interacting with the "internal" activities,
which require the MANAGE_USERS permission.

Test: builds, boots, users are unlocked before moving
Bug: 29923055, 25861755
Change-Id: Ifaeb2557c4f8c4354e1d380eaa0e413768ee239f
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index cab3139..6b0a5b8 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -106,6 +106,7 @@
 import com.android.internal.app.UnlaunchableAppActivity;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.settings.password.ChooseLockSettingsHelper;
 import com.android.settings.wrapper.DevicePolicyManagerWrapper;
 import com.android.settings.wrapper.FingerprintManagerWrapper;
 
@@ -995,20 +996,37 @@
     }
 
     /**
-     * Returns the user id present in the bundle with {@link Intent#EXTRA_USER_ID} if it
-     * belongs to the current user.
+     * Returns the user id present in the bundle with
+     * {@link Intent#EXTRA_USER_ID} if it belongs to the current user.
      *
-     * @throws SecurityException if the given userId does not belong to the current user group.
+     * @throws SecurityException if the given userId does not belong to the
+     *             current user group.
      */
     public static int getUserIdFromBundle(Context context, Bundle bundle) {
+        return getUserIdFromBundle(context, bundle, false);
+    }
+
+    /**
+     * Returns the user id present in the bundle with
+     * {@link Intent#EXTRA_USER_ID} if it belongs to the current user.
+     *
+     * @param isInternal indicating if the caller is "internal" to the system,
+     *            meaning we're willing to trust extras like
+     *            {@link ChooseLockSettingsHelper#EXTRA_ALLOW_ANY_USER}.
+     * @throws SecurityException if the given userId does not belong to the
+     *             current user group.
+     */
+    public static int getUserIdFromBundle(Context context, Bundle bundle, boolean isInternal) {
         if (bundle == null) {
             return getCredentialOwnerUserId(context);
         }
+        final boolean allowAnyUser = isInternal
+                && bundle.getBoolean(ChooseLockSettingsHelper.EXTRA_ALLOW_ANY_USER, false);
         int userId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId());
         if (userId == LockPatternUtils.USER_FRP) {
-            return enforceSystemUser(context, userId);
+            return allowAnyUser ? userId : enforceSystemUser(context, userId);
         } else {
-            return enforceSameOwner(context, userId);
+            return allowAnyUser ? userId : enforceSameOwner(context, userId);
         }
     }