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

Commit 76d95f20 authored by Ruslan Tkhakokhov's avatar Ruslan Tkhakokhov Committed by Android (Google) Code Review
Browse files

Merge "Use new manifest flag to gate clearing data during restore"

parents f90b5b0d aee28fd4
Loading
Loading
Loading
Loading
+44 −12
Original line number Original line Diff line number Diff line
@@ -70,6 +70,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.database.ContentObserver;
import android.net.Uri;
import android.net.Uri;
import android.os.Binder;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
@@ -1484,19 +1485,50 @@ public class UserBackupManagerService {
    }
    }


    /**
    /**
     * Clear an application's data, blocking until the operation completes or times out. If {@code
     * Clear an application's data after a failed restore, blocking until the operation completes or
     * keepSystemState} is {@code true}, we intentionally do not clear system state that would
     * times out.
     * ordinarily also be cleared, because we aren't actually wiping the app back to empty; we're
     * bringing it into the actual expected state related to the already-restored notification state
     * etc.
     */
     */
    public void clearApplicationDataSynchronous(String packageName, boolean keepSystemState) {
    public void clearApplicationDataAfterRestoreFailure(String packageName) {
        // Don't wipe packages marked allowClearUserData=false
        clearApplicationDataSynchronous(packageName, true, false);
    }

    /**
     * Clear an application's data before restore, blocking until the operation completes or times
     * out.
     */
    public void clearApplicationDataBeforeRestore(String packageName) {
        clearApplicationDataSynchronous(packageName, false, true);
    }

    /**
     * Clear an application's data, blocking until the operation completes or times out.
     *
     * @param checkFlagAllowClearUserDataOnFailedRestore if {@code true} uses
     *    {@link ApplicationInfo#PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE} to decide if
     *    clearing data is allowed after a failed restore.
     *
     * @param keepSystemState if {@code true}, we don't clear system state such as already restored
     *    notification settings, permission grants, etc.
     */
    private void clearApplicationDataSynchronous(String packageName,
            boolean checkFlagAllowClearUserDataOnFailedRestore, boolean keepSystemState) {
        try {
        try {
            PackageInfo info = mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId);
            ApplicationInfo applicationInfo = mPackageManager.getPackageInfoAsUser(
            if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
                    packageName, 0, mUserId).applicationInfo;

            boolean shouldClearData;
            if (checkFlagAllowClearUserDataOnFailedRestore
                    && applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q) {
                shouldClearData = (applicationInfo.privateFlags
                    & ApplicationInfo.PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE) != 0;
            } else {
                shouldClearData =
                    (applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) != 0;
            }

            if (!shouldClearData) {
                if (MORE_DEBUG) {
                if (MORE_DEBUG) {
                    Slog.i(TAG, "allowClearUserData=false so not wiping "
                    Slog.i(TAG, "Clearing app data is not allowed so not wiping "
                            + packageName);
                            + packageName);
                }
                }
                return;
                return;
@@ -1511,8 +1543,8 @@ public class UserBackupManagerService {
        synchronized (mClearDataLock) {
        synchronized (mClearDataLock) {
            mClearingData = true;
            mClearingData = true;
            try {
            try {
                mActivityManager.clearApplicationUserData(
                mActivityManager.clearApplicationUserData(packageName, keepSystemState, observer,
                        packageName, keepSystemState, observer, mUserId);
                        mUserId);
            } catch (RemoteException e) {
            } catch (RemoteException e) {
                // can't happen because the activity manager is in this process
                // can't happen because the activity manager is in this process
            }
            }
+1 −1
Original line number Original line Diff line number Diff line
@@ -352,7 +352,7 @@ public class FullRestoreEngine extends RestoreEngine {
                                        Slog.d(TAG,
                                        Slog.d(TAG,
                                                "Clearing app data preparatory to full restore");
                                                "Clearing app data preparatory to full restore");
                                    }
                                    }
                                    mBackupManagerService.clearApplicationDataSynchronous(pkg, true);
                                    mBackupManagerService.clearApplicationDataBeforeRestore(pkg);
                                } else {
                                } else {
                                    if (MORE_DEBUG) {
                                    if (MORE_DEBUG) {
                                        Slog.d(TAG, "backup agent ("
                                        Slog.d(TAG, "backup agent ("
+3 −3
Original line number Original line Diff line number Diff line
@@ -988,8 +988,8 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {


                    // We also need to wipe the current target's data, as it's probably
                    // We also need to wipe the current target's data, as it's probably
                    // in an incoherent state.
                    // in an incoherent state.
                    backupManagerService.clearApplicationDataSynchronous(
                    backupManagerService.clearApplicationDataAfterRestoreFailure(
                            mCurrentPackage.packageName, false);
                            mCurrentPackage.packageName);


                    // Schedule the next state based on the nature of our failure
                    // Schedule the next state based on the nature of our failure
                    if (status == BackupTransport.TRANSPORT_ERROR) {
                    if (status == BackupTransport.TRANSPORT_ERROR) {
@@ -1114,7 +1114,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
        // If the agent fails restore, it might have put the app's data
        // If the agent fails restore, it might have put the app's data
        // into an incoherent state.  For consistency we wipe its data
        // into an incoherent state.  For consistency we wipe its data
        // again in this case before continuing with normal teardown
        // again in this case before continuing with normal teardown
        backupManagerService.clearApplicationDataSynchronous(mCurrentPackage.packageName, false);
        backupManagerService.clearApplicationDataAfterRestoreFailure(mCurrentPackage.packageName);
        keyValueAgentCleanup();
        keyValueAgentCleanup();
    }
    }