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

Commit 0753af02 authored by Beatrice Marchegiani's avatar Beatrice Marchegiani Committed by Android (Google) Code Review
Browse files

Merge "Fix downgrade wallpaper restore bug" into 24D1-dev

parents 576a3491 6b046e87
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -270,7 +270,8 @@ public class FullRestoreEngine extends RestoreEngine {
                            PackageManagerInternal.class);
                    RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy(
                            mBackupManagerService.getPackageManager(), allowApks, info, signatures,
                            pmi, mUserId, mBackupEligibilityRules);
                            pmi, mUserId, mBackupEligibilityRules,
                            mBackupManagerService.getContext());
                    mManifestSignatures.put(info.packageName, signatures);
                    mPackagePolicies.put(pkg, restorePolicy);
                    mPackageInstallers.put(pkg, info.installerPackageName);
+49 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_MISSING_SIGNATURE;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;

@@ -53,17 +54,22 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
import android.os.Build;
import android.os.Bundle;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;

import com.android.server.backup.FileMetadata;
import com.android.server.backup.Flags;
import com.android.server.backup.restore.RestorePolicy;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
 * Utility methods to read backup tar file.
@@ -390,7 +396,7 @@ public class TarBackupReader {
            boolean allowApks, FileMetadata info, Signature[] signatures,
            PackageManagerInternal pmi, int userId, Context context) {
        return chooseRestorePolicy(packageManager, allowApks, info, signatures, pmi, userId,
                BackupEligibilityRules.forBackup(packageManager, pmi, userId, context));
                BackupEligibilityRules.forBackup(packageManager, pmi, userId, context), context);
    }

    /**
@@ -406,7 +412,8 @@ public class TarBackupReader {
     */
    public RestorePolicy chooseRestorePolicy(PackageManager packageManager,
            boolean allowApks, FileMetadata info, Signature[] signatures,
            PackageManagerInternal pmi, int userId, BackupEligibilityRules eligibilityRules) {
            PackageManagerInternal pmi, int userId, BackupEligibilityRules eligibilityRules,
            Context context) {
        if (signatures == null) {
            return RestorePolicy.IGNORE;
        }
@@ -448,6 +455,16 @@ public class TarBackupReader {
                                    pkgInfo,
                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                                    null);
                        } else if (isAllowlistedForVToURestore(info, pkgInfo, userId, context)) {
                            Slog.i(TAG, "Performing a V to U downgrade; package: "
                                            + info.packageName
                                            + " is allowlisted");
                            policy = RestorePolicy.ACCEPT;
                            mBackupManagerMonitorEventSender.monitorEvent(
                                    LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE,
                                    pkgInfo,
                                    LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                                    null);
                        } else {
                            // The data is from a newer version of the app than
                            // is presently installed.  That means we can only
@@ -751,6 +768,36 @@ public class TarBackupReader {
        return true;
    }

    // checks the sdk of the target/source device for a B&R operation.
    // system components can opt in of V->U restore via allowlist.
    @SuppressWarnings("AndroidFrameworkCompatChange")
    private boolean isAllowlistedForVToURestore(FileMetadata backupFileInfo,
            PackageInfo installedPackageInfo,
            int userId, Context context) {
        // We assume that the package version matches the sdk (e.g. version 35 means V).
        // This is true for most of the system components ( and it is specifically true for those
        // that are in the allowlist)
        // In order to check if this is a V to U transfer we check if the package version from the
        // backup is 35 and on the target is 34.
        // We don't need to check the  V to U denylist here since a package can only make it
        // to TarBackupReader if allowed and not denied (from PerformUnifiedRestoreTask)

        String vToUAllowlist = getVToUAllowlist(context, userId);
        List<String> mVToUAllowlist = Arrays.asList(vToUAllowlist.split(","));
        return Flags.enableVToURestoreForSystemComponentsInAllowlist()
                && (installedPackageInfo.getLongVersionCode()
                == Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
                && (backupFileInfo.version > Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
                && (mVToUAllowlist.contains(installedPackageInfo.packageName));
    }

    private String getVToUAllowlist(Context context, int userId) {
        return Settings.Secure.getStringForUser(
                context.getContentResolver(),
                Settings.Secure.V_TO_U_RESTORE_ALLOWLIST,
                userId);
    }

    private static long extractRadix(byte[] data, int offset, int maxChars, int radix)
            throws IOException {
        long value = 0;
+148 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_V
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER;
import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE;

import static com.google.common.truth.Truth.assertThat;

@@ -42,17 +43,23 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.Signature;
import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import android.testing.TestableContext;

import androidx.test.InstrumentationRegistry;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.frameworks.mockingservicestests.R;
import com.android.server.backup.FileMetadata;
import com.android.server.backup.Flags;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.restore.PerformAdbRestoreTask;
import com.android.server.backup.restore.RestorePolicy;
@@ -61,6 +68,7 @@ import com.android.server.backup.testutils.PackageManagerStub;
import com.google.common.hash.Hashing;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -86,6 +94,8 @@ public class TarBackupReaderTest {
    @Mock private BytesReadListener mBytesReadListenerMock;
    @Mock private IBackupManagerMonitor mBackupManagerMonitorMock;
    @Mock private PackageManagerInternal mMockPackageManagerInternal;
    @Rule
    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    private final PackageManagerStub mPackageManagerStub = new PackageManagerStub();
    private Context mContext;
@@ -95,7 +105,7 @@ public class TarBackupReaderTest {
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        mContext = InstrumentationRegistry.getContext();
        mContext = new TestableContext(ApplicationProvider.getApplicationContext());
        mUserId = UserHandle.USER_SYSTEM;
    }

@@ -513,6 +523,107 @@ public class TarBackupReaderTest {
                LOG_EVENT_ID_VERSIONS_MATCH);
    }

    @Test
    public void
    chooseRestorePolicy_flagOnNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsIgnore()
            throws Exception {

        mSetFlagsRule.enableFlags(
                Flags.FLAG_ENABLE_V_TO_U_RESTORE_FOR_SYSTEM_COMPONENTS_IN_ALLOWLIST);

        TarBackupReader tarBackupReader = createTarBackupReader();

        Settings.Secure.putString(mContext.getContentResolver(),
                Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "test");

        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
        FileMetadata info = new FileMetadata();
        info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;

        PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
        PackageManagerStub.sPackageInfo = packageInfo;

        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
                packageInfo.packageName);
        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                false /* allowApks */, info, signatures, mMockPackageManagerInternal,
                mUserId, mContext);

        assertThat(policy).isEqualTo(RestorePolicy.ACCEPT);
        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
                LOG_EVENT_ID_V_TO_U_RESTORE_PKG_ELIGIBLE);
    }


    @Test
    public void
    chooseRestorePolicy_flagOffNotRestoreAnyVersionVToURestoreAndInAllowlist_returnsAccept()
            throws Exception {

        mSetFlagsRule.disableFlags(
                Flags.FLAG_ENABLE_V_TO_U_RESTORE_FOR_SYSTEM_COMPONENTS_IN_ALLOWLIST);

        TarBackupReader tarBackupReader = createTarBackupReader();

        Settings.Secure.putString(mContext.getContentResolver(),
                Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "test");

        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
        FileMetadata info = new FileMetadata();
        info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;

        PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
        PackageManagerStub.sPackageInfo = packageInfo;

        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
                packageInfo.packageName);
        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                false /* allowApks */, info, signatures, mMockPackageManagerInternal,
                mUserId, mContext);

        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);

    }

    @Test
    public void
    chooseRestorePolicy_flagOnNotRestoreAnyVersionVToURestoreAndNotInAllowlist_returnsIgnore()
            throws Exception {

        mSetFlagsRule.enableFlags(
                Flags.FLAG_ENABLE_V_TO_U_RESTORE_FOR_SYSTEM_COMPONENTS_IN_ALLOWLIST);

        TarBackupReader tarBackupReader = createTarBackupReader();

        Settings.Secure.putString(mContext.getContentResolver(),
                Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "pkg");

        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
        FileMetadata info = new FileMetadata();
        info.version = Build.VERSION_CODES.UPSIDE_DOWN_CAKE + 1;

        PackageInfo packageInfo = createNonRestoreAnyVersionUPackage();
        PackageManagerStub.sPackageInfo = packageInfo;

        doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1,
                packageInfo.packageName);
        RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub,
                false /* allowApks */, info, signatures, mMockPackageManagerInternal,
                mUserId, mContext);

        assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
        ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(mBackupManagerMonitorMock).onEvent(bundleCaptor.capture());
        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
    }

    @Test
    public void
    chooseRestorePolicy_notRestoreAnyVersionAndVersionMismatchButAllowApksAndHasApk_returnsAcceptIfApk()
@@ -523,6 +634,10 @@ public class TarBackupReaderTest {
                inputStream, null);
        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
                mBytesReadListenerMock, mBackupManagerMonitorMock);

        Settings.Secure.putString(mContext.getContentResolver(),
                Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "pkg");

        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
        FileMetadata info = new FileMetadata();
        info.version = 2;
@@ -564,6 +679,10 @@ public class TarBackupReaderTest {
                inputStream, null);
        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
                mBytesReadListenerMock, mBackupManagerMonitorMock);

        Settings.Secure.putString(mContext.getContentResolver(),
                Settings.Secure.V_TO_U_RESTORE_ALLOWLIST, "pkg");

        Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1};
        FileMetadata info = new FileMetadata();
        info.version = 2;
@@ -596,5 +715,33 @@ public class TarBackupReaderTest {
        assertThat(bundleCaptor.getValue().get(EXTRA_LOG_EVENT_ID)).isEqualTo(
                LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER);
    }

    private TarBackupReader createTarBackupReader() throws Exception {
        InputStream inputStream = mContext.getResources().openRawResource(
                R.raw.backup_telephony_no_password);
        InputStream tarInputStream = PerformAdbRestoreTask.parseBackupFileHeaderAndReturnTarStream(
                inputStream, null);
        TarBackupReader tarBackupReader = new TarBackupReader(tarInputStream,
                mBytesReadListenerMock, mBackupManagerMonitorMock);
        return tarBackupReader;
    }

    private PackageInfo createNonRestoreAnyVersionUPackage(){
        PackageInfo packageInfo = new PackageInfo();
        packageInfo.packageName = "test";
        packageInfo.applicationInfo = new ApplicationInfo();
        packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;
        packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
        packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID;
        packageInfo.applicationInfo.backupAgentName = null;
        packageInfo.signingInfo = new SigningInfo(
                new SigningDetails(
                        new Signature[]{FAKE_SIGNATURE_1},
                        SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                        null,
                        null));
        packageInfo.versionCode = Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
        return packageInfo;
    }
}