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

Commit ed04879a authored by Annie Meng's avatar Annie Meng Committed by Android (Google) Code Review
Browse files

Merge "[Multi-user] Change device provisioned to per-user setup complete"

parents fb89efb4 443143af
Loading
Loading
Loading
Loading
+35 −34
Original line number Diff line number Diff line
@@ -110,9 +110,9 @@ import com.android.server.backup.internal.ClearDataObserver;
import com.android.server.backup.internal.OnTaskFinishedListener;
import com.android.server.backup.internal.Operation;
import com.android.server.backup.internal.PerformInitializeTask;
import com.android.server.backup.internal.ProvisionedObserver;
import com.android.server.backup.internal.RunBackupReceiver;
import com.android.server.backup.internal.RunInitializeReceiver;
import com.android.server.backup.internal.SetupObserver;
import com.android.server.backup.keyvalue.BackupRequest;
import com.android.server.backup.params.AdbBackupParams;
import com.android.server.backup.params.AdbParams;
@@ -261,7 +261,7 @@ public class UserBackupManagerService {
    private IBackupManager mBackupManagerBinder;

    private boolean mEnabled;   // access to this is synchronized on 'this'
    private boolean mProvisioned;
    private boolean mSetupComplete;
    private boolean mAutoRestore;

    private PendingIntent mRunBackupIntent;
@@ -315,9 +315,6 @@ public class UserBackupManagerService {

    private ActiveRestoreSession mActiveRestoreSession;

    // Watch the device provisioning operation during setup
    private ContentObserver mProvisionedObserver;

    /**
     * mCurrentOperations contains the list of currently active operations.
     *
@@ -468,15 +465,19 @@ public class UserBackupManagerService {

        // Set up our bookkeeping
        final ContentResolver resolver = context.getContentResolver();
        mProvisioned = Settings.Global.getInt(resolver,
                Settings.Global.DEVICE_PROVISIONED, 0) != 0;
        mSetupComplete =
                Settings.Secure.getIntForUser(
                        resolver, Settings.Secure.USER_SETUP_COMPLETE, 0, mUserId)
                        != 0;
        mAutoRestore = Settings.Secure.getInt(resolver,
                Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;

        mProvisionedObserver = new ProvisionedObserver(this, mBackupHandler);
        ContentObserver setupObserver = new SetupObserver(this, mBackupHandler);
        resolver.registerContentObserver(
                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
                false, mProvisionedObserver);
                Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE),
                /* notifyForDescendents */ false,
                setupObserver,
                mUserId);

        mBaseStateDir = checkNotNull(baseStateDir, "baseStateDir cannot be null");
        mBaseStateDir.mkdirs();
@@ -550,6 +551,10 @@ public class UserBackupManagerService {
        mUserBackupThread.quit();
    }

    public int getUserId() {
        return mUserId;
    }

    public BackupManagerConstants getConstants() {
        return mConstants;
    }
@@ -619,12 +624,12 @@ public class UserBackupManagerService {
        mEnabled = enabled;
    }

    public boolean isProvisioned() {
        return mProvisioned;
    public boolean isSetupComplete() {
        return mSetupComplete;
    }

    public void setProvisioned(boolean provisioned) {
        mProvisioned = provisioned;
    public void setSetupComplete(boolean setupComplete) {
        mSetupComplete = setupComplete;
    }

    public PowerManager.WakeLock getWakelock() {
@@ -1577,11 +1582,16 @@ public class UserBackupManagerService {
            throw new IllegalArgumentException("No packages are provided for backup");
        }

        if (!mEnabled || !mProvisioned) {
            Slog.i(TAG, "Backup requested but e=" + mEnabled + " p=" + mProvisioned);
        if (!mEnabled || !mSetupComplete) {
            Slog.i(
                    TAG,
                    "Backup requested but enabled="
                            + mEnabled
                            + " setupComplete="
                            + mSetupComplete);
            BackupObserverUtils.sendBackupFinished(observer,
                    BackupManager.ERROR_BACKUP_NOT_ALLOWED);
            final int logTag = mProvisioned
            final int logTag = mSetupComplete
                    ? BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED
                    : BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED;
            monitor = BackupManagerMonitorUtils.monitorEvent(monitor, logTag, null,
@@ -2016,13 +2026,13 @@ public class UserBackupManagerService {
        FullBackupEntry entry = null;
        long latency = fullBackupInterval;

        if (!mEnabled || !mProvisioned) {
        if (!mEnabled || !mSetupComplete) {
            // Backups are globally disabled, so don't proceed.  We also don't reschedule
            // the job driving automatic backups; that job will be scheduled again when
            // the user enables backup.
            if (MORE_DEBUG) {
                Slog.i(TAG, "beginFullBackup but e=" + mEnabled
                        + " p=" + mProvisioned + "; ignoring");
                Slog.i(TAG, "beginFullBackup but enabled=" + mEnabled
                        + " setupComplete=" + mSetupComplete + "; ignoring");
            }
            return false;
        }
@@ -2423,12 +2433,6 @@ public class UserBackupManagerService {
        }
    }

    /** Returns {@code true} if the system user has gone through SUW. */
    public boolean deviceIsProvisioned() {
        final ContentResolver resolver = mContext.getContentResolver();
        return (Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0);
    }

    /**
     * Used by 'adb backup' to run a backup pass for packages supplied via the command line, writing
     * the resulting data stream to the supplied {@code fd}. This method is synchronous and does not
@@ -2461,8 +2465,7 @@ public class UserBackupManagerService {

        long oldId = Binder.clearCallingIdentity();
        try {
            // Doesn't make sense to do a full backup prior to setup
            if (!deviceIsProvisioned()) {
            if (!mSetupComplete) {
                Slog.i(TAG, "Backup not supported before setup");
                return;
            }
@@ -2588,9 +2591,7 @@ public class UserBackupManagerService {
        long oldId = Binder.clearCallingIdentity();

        try {
            // Check whether the device has been provisioned -- we don't handle
            // full restores prior to completing the setup process.
            if (!deviceIsProvisioned()) {
            if (!mSetupComplete) {
                Slog.i(TAG, "Full restore not permitted before setup");
                return;
            }
@@ -2745,7 +2746,7 @@ public class UserBackupManagerService {
            }

            synchronized (mQueueLock) {
                if (enable && !wasEnabled && mProvisioned) {
                if (enable && !wasEnabled && mSetupComplete) {
                    // if we've just been enabled, start scheduling backup passes
                    KeyValueBackupJob.schedule(mContext, mConstants);
                    scheduleNextFullBackupJob(0);
@@ -2758,7 +2759,7 @@ public class UserBackupManagerService {
                    // This also constitutes an opt-out, so we wipe any data for
                    // this device from the backend.  We start that process with
                    // an alarm in order to guarantee wakelock states.
                    if (wasEnabled && mProvisioned) {
                    if (wasEnabled && mSetupComplete) {
                        // NOTE: we currently flush every registered transport, not just
                        // the currently-active one.
                        List<String> transportNames = new ArrayList<>();
@@ -3455,7 +3456,7 @@ public class UserBackupManagerService {
    private void dumpInternal(PrintWriter pw) {
        synchronized (mQueueLock) {
            pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
                    + " / " + (!mProvisioned ? "not " : "") + "provisioned / "
                    + " / " + (!mSetupComplete ? "not " : "") + "setup complete / "
                    + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
            pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
            if (mBackupRunning) pw.println("Backup currently running");
+3 −3
Original line number Diff line number Diff line
@@ -317,16 +317,16 @@ public class PerformFullTransportBackupTask extends FullBackupTask implements Ba
        int backupRunStatus = BackupManager.SUCCESS;

        try {
            if (!backupManagerService.isEnabled() || !backupManagerService.isProvisioned()) {
            if (!backupManagerService.isEnabled() || !backupManagerService.isSetupComplete()) {
                // Backups are globally disabled, so don't proceed.
                if (DEBUG) {
                    Slog.i(TAG, "full backup requested but enabled=" + backupManagerService
                            .isEnabled()
                            + " provisioned=" + backupManagerService.isProvisioned()
                            + " setupComplete=" + backupManagerService.isSetupComplete()
                            + "; ignoring");
                }
                int monitoringEvent;
                if (backupManagerService.isProvisioned()) {
                if (backupManagerService.isSetupComplete()) {
                    monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED;
                } else {
                    monitoringEvent = BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED;
+4 −3
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ public class RunBackupReceiver extends BroadcastReceiver {
                } else {
                    // Don't run backups now if we're disabled or not yet
                    // fully set up.
                    if (backupManagerService.isEnabled() && backupManagerService.isProvisioned()) {
                    if (backupManagerService.isEnabled()
                            && backupManagerService.isSetupComplete()) {
                        if (!backupManagerService.isBackupRunning()) {
                            if (DEBUG) {
                                Slog.v(TAG, "Running a backup pass");
@@ -77,8 +78,8 @@ public class RunBackupReceiver extends BroadcastReceiver {
                            Slog.i(TAG, "Backup time but one already running");
                        }
                    } else {
                        Slog.w(TAG, "Backup pass but e=" + backupManagerService.isEnabled() + " p="
                                + backupManagerService.isProvisioned());
                        Slog.w(TAG, "Backup pass but enabled=" + backupManagerService.isEnabled()
                                + " setupComplete=" + backupManagerService.isSetupComplete());
                    }
                }
            }
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -11,7 +11,7 @@
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 * limitations under the License.
 */

package com.android.server.backup.internal;
@@ -19,43 +19,71 @@ package com.android.server.backup.internal;
import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
import static com.android.server.backup.BackupManagerService.TAG;

import android.content.Context;
import android.database.ContentObserver;
import android.os.Handler;
import android.provider.Settings;
import android.util.Slog;

import com.android.server.backup.KeyValueBackupJob;
import com.android.server.backup.UserBackupManagerService;

public class ProvisionedObserver extends ContentObserver {

    private UserBackupManagerService backupManagerService;
/**
 * A {@link ContentObserver} for changes to the setting {@link Settings.Secure#USER_SETUP_COMPLETE}
 * for a particular user.
 */
public class SetupObserver extends ContentObserver {
    private final UserBackupManagerService mUserBackupManagerService;
    private final Context mContext;
    private final int mUserId;

    public ProvisionedObserver(
            UserBackupManagerService backupManagerService, Handler handler) {
    public SetupObserver(UserBackupManagerService userBackupManagerService, Handler handler) {
        super(handler);
        this.backupManagerService = backupManagerService;
        mUserBackupManagerService = userBackupManagerService;
        mContext = userBackupManagerService.getContext();
        mUserId = userBackupManagerService.getUserId();
    }

    /**
     * Callback that executes when the setting {@link Settings.Secure#USER_SETUP_COMPLETE} changes
     * for the user {@link #mUserId}. If the user is newly setup and backup is enabled, then we
     * schedule a key value and full backup job for the user. If the user was previously setup and
     * now the setting has changed to {@code false}, we don't reset the state as having gone through
     * setup is a non-reversible action.
     */
    public void onChange(boolean selfChange) {
        final boolean wasProvisioned = backupManagerService.isProvisioned();
        final boolean isProvisioned = backupManagerService.deviceIsProvisioned();
        // latch: never unprovision
        backupManagerService.setProvisioned(wasProvisioned || isProvisioned);
        boolean previousSetupComplete = mUserBackupManagerService.isSetupComplete();
        boolean newSetupComplete =
                Settings.Secure.getIntForUser(
                        mContext.getContentResolver(),
                        Settings.Secure.USER_SETUP_COMPLETE,
                        0,
                        mUserId)
                        != 0;

        boolean resolvedSetupComplete = previousSetupComplete || newSetupComplete;
        mUserBackupManagerService.setSetupComplete(resolvedSetupComplete);
        if (MORE_DEBUG) {
            Slog.d(TAG, "Provisioning change: was=" + wasProvisioned
                    + " is=" + isProvisioned + " now=" + backupManagerService.isProvisioned());
            Slog.d(
                    TAG,
                    "Setup complete change: was="
                            + previousSetupComplete
                            + " new="
                            + newSetupComplete
                            + " resolved="
                            + resolvedSetupComplete);
        }

        synchronized (backupManagerService.getQueueLock()) {
            if (backupManagerService.isProvisioned() && !wasProvisioned
                    && backupManagerService.isEnabled()) {
                // we're now good to go, so start the backup alarms
        synchronized (mUserBackupManagerService.getQueueLock()) {
            // Start backup if the user is newly setup and backup is enabled.
            if (resolvedSetupComplete
                    && !previousSetupComplete
                    && mUserBackupManagerService.isEnabled()) {
                if (MORE_DEBUG) {
                    Slog.d(TAG, "Now provisioned, so starting backups");
                    Slog.d(TAG, "Setup complete so starting backups");
                }
                KeyValueBackupJob.schedule(backupManagerService.getContext(),
                        backupManagerService.getConstants());
                backupManagerService.scheduleNextFullBackupJob(0);
                KeyValueBackupJob.schedule(mContext, mUserBackupManagerService.getConstants());
                mUserBackupManagerService.scheduleNextFullBackupJob(0);
            }
        }
    }
+4 −4
Original line number Diff line number Diff line
@@ -829,7 +829,7 @@ public class UserBackupManagerServiceTest {
    public void testRequestBackup_whenNotProvisioned() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
        backupManagerService.setProvisioned(false);
        backupManagerService.setSetupComplete(false);

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

@@ -848,7 +848,7 @@ public class UserBackupManagerServiceTest {
        setUpCurrentTransport(mTransportManager, mTransport.unregistered());
        UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
        backupManagerService.setEnabled(true);
        backupManagerService.setProvisioned(true);
        backupManagerService.setSetupComplete(true);

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

@@ -868,7 +868,7 @@ public class UserBackupManagerServiceTest {
        setUpCurrentTransport(mTransportManager, mTransport);
        UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
        backupManagerService.setEnabled(true);
        backupManagerService.setProvisioned(true);
        backupManagerService.setSetupComplete(true);
        // Haven't set PACKAGE_1 as eligible

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);
@@ -965,7 +965,7 @@ public class UserBackupManagerServiceTest {
    private UserBackupManagerService createBackupManagerServiceForRequestBackup() {
        UserBackupManagerService backupManagerService = createUserBackupManagerServiceAndRunTasks();
        backupManagerService.setEnabled(true);
        backupManagerService.setProvisioned(true);
        backupManagerService.setSetupComplete(true);
        return backupManagerService;
    }

Loading