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

Commit c6955626 authored by Bernardo Rufino's avatar Bernardo Rufino Committed by Android (Google) Code Review
Browse files

Merge "Increase PerformBackupTask unit coverage"

parents 09fa6568 c1b6ca05
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.IBackupAgent;
import android.app.PendingIntent;
import android.app.backup.BackupAgent;
import android.app.backup.BackupManager;
import android.app.backup.BackupManagerMonitor;
import android.app.backup.FullBackup;
@@ -704,7 +705,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
     * process-local non-lifecycle agent instance, so we manually set up the context
     * topology for it.
     */
    public PackageManagerBackupAgent makeMetadataAgent() {
    public BackupAgent makeMetadataAgent() {
        PackageManagerBackupAgent pmAgent = new PackageManagerBackupAgent(mPackageManager);
        pmAgent.attach(mContext);
        pmAgent.onCreate();
@@ -784,7 +785,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
    }

    @VisibleForTesting
    BackupManagerService(
    public BackupManagerService(
            Context context,
            Trampoline parent,
            HandlerThread backupThread,
@@ -1749,6 +1750,16 @@ public class BackupManagerService implements BackupManagerServiceInterface {
        }
    }

    public void putOperation(int token, Operation operation) {
        if (MORE_DEBUG) {
            Slog.d(TAG, "Adding operation token=" + Integer.toHexString(token) + ", operation type="
                    + operation.type);
        }
        synchronized (mCurrentOpLock) {
            mCurrentOperations.put(token, operation);
        }
    }

    public void removeOperation(int token) {
        if (MORE_DEBUG) {
            Slog.d(TAG, "Removing operation token=" + Integer.toHexString(token));
+4 −5
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTOR
import android.annotation.Nullable;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupManager;
@@ -205,11 +206,9 @@ public class PerformBackupTask implements BackupRestoreTask {
     * Put this task in the repository of running tasks.
     */
    private void registerTask() {
        synchronized (backupManagerService.getCurrentOpLock()) {
            backupManagerService.getCurrentOperations().put(
        backupManagerService.putOperation(
                mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
    }
    }

    /**
     * Remove this task from repository of running tasks.
@@ -358,7 +357,7 @@ public class PerformBackupTask implements BackupRestoreTask {
            // The package manager doesn't have a proper <application> etc, but since it's running
            // here in the system process we can just set up its agent directly and use a synthetic
            // BackupRequest.
            PackageManagerBackupAgent pmAgent = backupManagerService.makeMetadataAgent();
            BackupAgent pmAgent = backupManagerService.makeMetadataAgent();
            mStatus = invokeAgentForBackup(
                    PACKAGE_MANAGER_SENTINEL,
                    IBackupAgent.Stub.asInterface(pmAgent.onBind()));
+2 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERA


import android.app.IBackupAgent;
import android.app.backup.BackupAgent;
import android.app.backup.IFullBackupRestoreObserver;
import android.content.pm.ApplicationInfo;
import android.content.pm.Signature;
@@ -76,7 +77,7 @@ public class PerformAdbRestoreTask implements Runnable {
    private final String mCurrentPassword;
    private final String mDecryptPassword;
    private final AtomicBoolean mLatchObject;
    private final PackageManagerBackupAgent mPackageManagerBackupAgent;
    private final BackupAgent mPackageManagerBackupAgent;
    private final RestoreDeleteObserver mDeleteObserver = new RestoreDeleteObserver();

    private IFullBackupRestoreObserver mObserver;
+113 −0
Original line number Diff line number Diff line
/*
 * 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.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * 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
 */

package android.app.backup;

import android.content.Context;
import android.os.ParcelFileDescriptor;

import java.io.File;
import java.io.IOException;

/**
 * Useful for spying in {@link BackupAgent} instances since their {@link BackupAgent#onBind()} is
 * final and always points to the original instance, instead of the spy.
 *
 * <p>To use, construct a spy of the desired {@link BackupAgent}, spying on the methods of interest.
 * Then, where you need to pass the agent, use {@link ForwardingBackupAgent#forward(BackupAgent)}
 * with the spy.
 */
public class ForwardingBackupAgent extends BackupAgent {
    /** Returns a {@link BackupAgent} that forwards method calls to {@code backupAgent}. */
    public static BackupAgent forward(BackupAgent backupAgent) {
        return new ForwardingBackupAgent(backupAgent);
    }

    private final BackupAgent mBackupAgent;

    private ForwardingBackupAgent(BackupAgent backupAgent) {
        mBackupAgent = backupAgent;
    }

    @Override
    public void onCreate() {
        mBackupAgent.onCreate();
    }

    @Override
    public void onDestroy() {
        mBackupAgent.onDestroy();
    }

    @Override
    public void onBackup(
            ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)
            throws IOException {
        mBackupAgent.onBackup(oldState, data, newState);
    }

    @Override
    public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
            throws IOException {
        mBackupAgent.onRestore(data, appVersionCode, newState);
    }

    @Override
    public void onRestore(BackupDataInput data, long appVersionCode, ParcelFileDescriptor newState)
            throws IOException {
        mBackupAgent.onRestore(data, appVersionCode, newState);
    }

    @Override
    public void onFullBackup(FullBackupDataOutput data) throws IOException {
        mBackupAgent.onFullBackup(data);
    }

    @Override
    public void onQuotaExceeded(long backupDataBytes, long quotaBytes) {
        mBackupAgent.onQuotaExceeded(backupDataBytes, quotaBytes);
    }

    @Override
    public void onRestoreFile(
            ParcelFileDescriptor data, long size, File destination, int type, long mode, long mtime)
            throws IOException {
        mBackupAgent.onRestoreFile(data, size, destination, type, mode, mtime);
    }

    @Override
    protected void onRestoreFile(
            ParcelFileDescriptor data,
            long size,
            int type,
            String domain,
            String path,
            long mode,
            long mtime)
            throws IOException {
        mBackupAgent.onRestoreFile(data, size, type, domain, path, mode, mtime);
    }

    @Override
    public void onRestoreFinished() {
        mBackupAgent.onRestoreFinished();
    }

    @Override
    public void attach(Context context) {
        mBackupAgent.attach(context);
    }
}
+12 −28
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.server.backup;

import static com.android.server.backup.testing.BackupManagerServiceTestUtils.startBackupThread;
import static com.android.server.backup.testing.BackupManagerServiceTestUtils.startSilentBackupThread;
import static com.android.server.backup.testing.TransportData.backupTransport;
import static com.android.server.backup.testing.TransportData.d2dTransport;
import static com.android.server.backup.testing.TransportData.localTransport;
@@ -46,6 +46,7 @@ import android.os.PowerSaveState;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import com.android.server.backup.internal.BackupRequest;
import com.android.server.backup.testing.BackupManagerServiceTestUtils;
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.transport.TransportNotRegisteredException;
@@ -68,7 +69,6 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowContextWrapper;
import org.robolectric.shadows.ShadowLog;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowSettings;
@@ -104,7 +104,10 @@ public class BackupManagerServiceTest {
        mTransport = backupTransport();
        mTransportName = mTransport.transportName;

        mBackupThread = startBackupThread(this::uncaughtException);
        // Unrelated exceptions are thrown in the backup thread. Until we mock everything properly
        // we should not fail tests because of this. This is not flakiness, the exceptions thrown
        // don't interfere with the tests.
        mBackupThread = startSilentBackupThread(TAG);
        mShadowBackupLooper = shadowOf(mBackupThread.getLooper());

        ContextWrapper context = RuntimeEnvironment.application;
@@ -113,8 +116,10 @@ public class BackupManagerServiceTest {
        mShadowContext = shadowOf(context);

        File cacheDir = mContext.getCacheDir();
        mBaseStateDir = new File(cacheDir, "base_state_dir");
        mDataDir = new File(cacheDir, "data_dir");
        // Corresponds to /data/backup
        mBaseStateDir = new File(cacheDir, "base_state");
        // Corresponds to /cache/backup_stage
        mDataDir = new File(cacheDir, "data");

        ShadowBackupPolicyEnforcer.setMandatoryBackupTransport(null);
    }
@@ -126,13 +131,6 @@ public class BackupManagerServiceTest {
        ShadowBackupPolicyEnforcer.setMandatoryBackupTransport(null);
    }

    private void uncaughtException(Thread thread, Throwable e) {
        // Unrelated exceptions are thrown in the backup thread. Until we mock everything properly
        // we should not fail tests because of this. This is not flakiness, the exceptions thrown
        // don't interfere with the tests.
        ShadowLog.e(TAG, "Uncaught exception in test thread " + thread.getName(), e);
    }

    /* Tests for destination string */

    @Test
@@ -864,22 +862,8 @@ public class BackupManagerServiceTest {
    }

    private BackupManagerService createInitializedBackupManagerService() {
        BackupManagerService backupManagerService =
                new BackupManagerService(
                        mContext,
                        new Trampoline(mContext),
                        mBackupThread,
                        mBaseStateDir,
                        mDataDir,
                        mTransportManager);
        mShadowBackupLooper.runToEndOfTasks();
        // Handler instances have their own clock, so advancing looper (with runToEndOfTasks())
        // above does NOT advance the handlers' clock, hence whenever a handler post messages with
        // specific time to the looper the time of those messages will be before the looper's time.
        // To fix this we advance SystemClock as well since that is from where the handlers read
        // time.
        ShadowSystemClock.setCurrentTimeMillis(mShadowBackupLooper.getScheduler().getCurrentTime());
        return backupManagerService;
        return BackupManagerServiceTestUtils.createInitializedBackupManagerService(
                mContext, mBackupThread, mBaseStateDir, mDataDir, mTransportManager);
    }

    private void setUpPowerManager(BackupManagerService backupManagerService) {
Loading