Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05d1b4c0 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Android (Google) Code Review
Browse files

Merge "Unlock all users before moving or migrating."

parents 266bc0fa 219ec91e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3064,6 +3064,9 @@
\n\nDon\u2019t remove the <xliff:g id="name" example="SD card">^2</xliff:g> during the move.
    </string>
    <!-- Body of lock screen challenge message explaining that the given user must be unlocked before data can be moved [CHAR LIMIT=64] -->
    <string name="storage_wizard_move_unlock">To move data you need to unlock user <xliff:g id="app" example="Joey">^1</xliff:g>.</string>
    <!-- Title of wizard step showing app move progress [CHAR LIMIT=32] -->
    <string name="storage_wizard_move_progress_title">Moving <xliff:g id="app" example="Calculator">^1</xliff:g>\u2026</string>
    <!-- Body of wizard step showing app move progress [CHAR LIMIT=NONE] -->
+23 −5
Original line number Diff line number Diff line
@@ -106,6 +106,7 @@ import android.widget.TabWidget;
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 @@ public final class Utils extends com.android.settingslib.Utils {
    }

    /**
     * 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);
        }
    }

+41 −4
Original line number Diff line number Diff line
@@ -16,22 +16,28 @@

package com.android.settings.deviceinfo;

import static com.android.settings.deviceinfo.StorageSettings.TAG;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.UserManager;
import android.os.storage.DiskInfo;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.text.TextUtils;
import android.util.Log;

import android.widget.Toast;

import com.android.settings.R;
import com.android.settings.password.ChooseLockSettingsHelper;

import java.util.Objects;

import static com.android.settings.deviceinfo.StorageSettings.TAG;

public class StorageWizardMigrateConfirm extends StorageWizardBase {
    private static final int REQUEST_CREDENTIAL = 100;

    private MigrateEstimateTask mEstimate;

    @Override
@@ -75,9 +81,22 @@ public class StorageWizardMigrateConfirm extends StorageWizardBase {

    @Override
    public void onNavigateNext() {
        int moveId;
        // Ensure that all users are unlocked so that we can move their data
        if (StorageManager.isFileEncryptedNativeOrEmulated()) {
            for (UserInfo user : getSystemService(UserManager.class).getUsers()) {
                if (!StorageManager.isUserKeyUnlocked(user.id)) {
                    Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock");
                    final CharSequence description = TextUtils.expandTemplate(
                            getText(R.string.storage_wizard_move_unlock), user.name);
                    new ChooseLockSettingsHelper(this).launchConfirmationActivityForAnyUser(
                            REQUEST_CREDENTIAL, null, null, description, user.id);
                    return;
                }
            }
        }

        // We only expect exceptions from StorageManagerService#setPrimaryStorageUuid
        int moveId;
        try {
            moveId = getPackageManager().movePrimaryStorage(mVolume);
        } catch (IllegalArgumentException e) {
@@ -108,4 +127,22 @@ public class StorageWizardMigrateConfirm extends StorageWizardBase {
        startActivity(intent);
        finishAffinity();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CREDENTIAL) {
            if (resultCode == RESULT_OK) {
                // Credentials confirmed, so storage should be unlocked; let's
                // go look for the next locked user.
                onNavigateNext();
            } else {
                // User wasn't able to confirm credentials, so we're okay
                // landing back at the wizard page again, where they read
                // instructions again and tap "Next" to try again.
                Log.w(TAG, "Failed to confirm credentials");
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
}
+47 −5
Original line number Diff line number Diff line
@@ -16,20 +16,30 @@

package com.android.settings.deviceinfo;

import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.EXTRA_TITLE;
import static android.content.pm.PackageManager.EXTRA_MOVE_ID;
import static android.os.storage.VolumeInfo.EXTRA_VOLUME_ID;

import static com.android.settings.deviceinfo.StorageSettings.TAG;

import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
import android.os.Bundle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Log;

import com.android.internal.util.Preconditions;
import com.android.settings.R;

import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.EXTRA_TITLE;
import static android.content.pm.PackageManager.EXTRA_MOVE_ID;
import static android.os.storage.VolumeInfo.EXTRA_VOLUME_ID;
import com.android.settings.password.ChooseLockSettingsHelper;

public class StorageWizardMoveConfirm extends StorageWizardBase {
    private static final int REQUEST_CREDENTIAL = 100;

    private String mPackageName;
    private ApplicationInfo mApp;

@@ -66,6 +76,20 @@ public class StorageWizardMoveConfirm extends StorageWizardBase {

    @Override
    public void onNavigateNext() {
        // Ensure that all users are unlocked so that we can move their data
        if (StorageManager.isFileEncryptedNativeOrEmulated()) {
            for (UserInfo user : getSystemService(UserManager.class).getUsers()) {
                if (!StorageManager.isUserKeyUnlocked(user.id)) {
                    Log.d(TAG, "User " + user.id + " is currently locked; requesting unlock");
                    final CharSequence description = TextUtils.expandTemplate(
                            getText(R.string.storage_wizard_move_unlock), user.name);
                    new ChooseLockSettingsHelper(this).launchConfirmationActivityForAnyUser(
                            REQUEST_CREDENTIAL, null, null, description, user.id);
                    return;
                }
            }
        }

        // Kick off move before we transition
        final String appName = getPackageManager().getApplicationLabel(mApp).toString();
        final int moveId = getPackageManager().movePackage(mPackageName, mVolume);
@@ -77,4 +101,22 @@ public class StorageWizardMoveConfirm extends StorageWizardBase {
        startActivity(intent);
        finishAffinity();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CREDENTIAL) {
            if (resultCode == RESULT_OK) {
                // Credentials confirmed, so storage should be unlocked; let's
                // go look for the next locked user.
                onNavigateNext();
            } else {
                // User wasn't able to confirm credentials, so we're okay
                // landing back at the wizard page again, where they read
                // instructions again and tap "Next" to try again.
                Log.w(TAG, "Failed to confirm credentials");
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
}
+38 −6
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.os.UserManager;

import com.android.internal.annotations.VisibleForTesting;
@@ -42,6 +43,12 @@ public final class ChooseLockSettingsHelper {
    public static final String EXTRA_KEY_FOR_FINGERPRINT = "for_fingerprint";
    public static final String EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT = "for_cred_req_boot";

    /**
     * When invoked via {@link ConfirmLockPassword.InternalActivity}, this flag
     * controls if we relax the enforcement of
     * {@link Utils#enforceSameOwner(android.content.Context, int)}.
     */
    public static final String EXTRA_ALLOW_ANY_USER = "allow_any_user";

    @VisibleForTesting LockPatternUtils mLockPatternUtils;
    private Activity mActivity;
@@ -200,25 +207,47 @@ public final class ChooseLockSettingsHelper {
                external, true, challenge, Utils.enforceSameOwner(mActivity, userId));
    }

    /**
     * Variant that allows you to prompt for credentials of any user, including
     * those which aren't associated with the current user. As an example, this
     * is useful when unlocking the storage for secondary users.
     */
    public boolean launchConfirmationActivityForAnyUser(int request,
            @Nullable CharSequence title, @Nullable CharSequence header,
            @Nullable CharSequence description, int userId) {
        final Bundle extras = new Bundle();
        extras.putBoolean(EXTRA_ALLOW_ANY_USER, true);
        return launchConfirmationActivity(request, title, header, description, false,
                false, true, 0, userId, extras);
    }

    private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
            @Nullable CharSequence header, @Nullable CharSequence description,
            boolean returnCredentials, boolean external, boolean hasChallenge,
            long challenge, int userId) {
        return launchConfirmationActivity(request, title, header, description, returnCredentials,
                external, hasChallenge, challenge, userId, null /* alternateButton */);
                external, hasChallenge, challenge, userId, null /* alternateButton */, null);
    }

    private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
            @Nullable CharSequence header, @Nullable CharSequence description,
            boolean returnCredentials, boolean external, boolean hasChallenge,
            long challenge, int userId, Bundle extras) {
        return launchConfirmationActivity(request, title, header, description, returnCredentials,
                external, hasChallenge, challenge, userId, null /* alternateButton */, extras);
    }

    public boolean launchFrpConfirmationActivity(int request, @Nullable CharSequence header,
            @Nullable CharSequence description, @Nullable CharSequence alternateButton) {
        return launchConfirmationActivity(request, null /* title */, header, description,
                false /* returnCredentials */, true /* external */, false /* hasChallenge */,
                0 /* challenge */, LockPatternUtils.USER_FRP, alternateButton);
                0 /* challenge */, LockPatternUtils.USER_FRP, alternateButton, null);
    }

    private boolean launchConfirmationActivity(int request, @Nullable CharSequence title,
            @Nullable CharSequence header, @Nullable CharSequence description,
            boolean returnCredentials, boolean external, boolean hasChallenge,
            long challenge, int userId, @Nullable CharSequence alternateButton) {
            long challenge, int userId, @Nullable CharSequence alternateButton, Bundle extras) {
        final int effectiveUserId = UserManager.get(mActivity).getCredentialOwnerProfile(userId);
        boolean launched = false;

@@ -228,7 +257,7 @@ public final class ChooseLockSettingsHelper {
                        returnCredentials || hasChallenge
                                ? ConfirmLockPattern.InternalActivity.class
                                : ConfirmLockPattern.class, returnCredentials, external,
                                hasChallenge, challenge, userId, alternateButton);
                                hasChallenge, challenge, userId, alternateButton, extras);
                break;
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
@@ -240,7 +269,7 @@ public final class ChooseLockSettingsHelper {
                        returnCredentials || hasChallenge
                                ? ConfirmLockPassword.InternalActivity.class
                                : ConfirmLockPassword.class, returnCredentials, external,
                                hasChallenge, challenge, userId, alternateButton);
                                hasChallenge, challenge, userId, alternateButton, extras);
                break;
        }
        return launched;
@@ -249,7 +278,7 @@ public final class ChooseLockSettingsHelper {
    private boolean launchConfirmationActivity(int request, CharSequence title, CharSequence header,
            CharSequence message, Class<?> activityClass, boolean returnCredentials,
            boolean external, boolean hasChallenge, long challenge,
            int userId, @Nullable CharSequence alternateButton) {
            int userId, @Nullable CharSequence alternateButton, Bundle extras) {
        final boolean frp = (userId == LockPatternUtils.USER_FRP);
        final Intent intent = new Intent();
        intent.putExtra(ConfirmDeviceCredentialBaseFragment.TITLE_TEXT, title);
@@ -266,6 +295,9 @@ public final class ChooseLockSettingsHelper {
        intent.putExtra(SettingsActivity.EXTRA_HIDE_DRAWER, true);
        intent.putExtra(Intent.EXTRA_USER_ID, userId);
        intent.putExtra(KeyguardManager.EXTRA_ALTERNATE_BUTTON_LABEL, alternateButton);
        if (extras != null) {
            intent.putExtras(extras);
        }
        intent.setClassName(ConfirmDeviceCredentialBaseFragment.PACKAGE, activityClass.getName());
        if (external) {
            intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
Loading