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

Commit 101f60b7 authored by Chandan Nath's avatar Chandan Nath Committed by Android (Google) Code Review
Browse files

Merge "Dump information for all users running backup in backup dumpsys."

parents b6a58506 5d51c314
Loading
Loading
Loading
Loading
+21 −6
Original line number Diff line number Diff line
@@ -1452,6 +1452,11 @@ public class BackupManagerService extends IBackupManager.Stub {
        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) {
            return;
        }
        dumpWithoutCheckingPermission(fd, pw, args);
    }

    @VisibleForTesting
    void dumpWithoutCheckingPermission(FileDescriptor fd, PrintWriter pw, String[] args) {
        int userId = binderGetCallingUserId();
        if (!isUserReadyForBackup(userId)) {
            pw.println("Inactive");
@@ -1460,7 +1465,16 @@ public class BackupManagerService extends IBackupManager.Stub {

        if (args != null) {
            for (String arg : args) {
                if ("users".equals(arg.toLowerCase())) {
                if ("-h".equals(arg)) {
                    pw.println("'dumpsys backup' optional arguments:");
                    pw.println("  -h       : this help text");
                    pw.println("  a[gents] : dump information about defined backup agents");
                    pw.println("  transportclients : dump information about transport clients");
                    pw.println("  transportstats : dump transport statts");
                    pw.println("  users    : dump the list of users for which backup service "
                            + "is running");
                    return;
                } else if ("users".equals(arg.toLowerCase())) {
                    pw.print(DUMP_RUNNING_USERS_MESSAGE);
                    for (int i = 0; i < mUserServices.size(); i++) {
                        pw.print(" " + mUserServices.keyAt(i));
@@ -1471,13 +1485,14 @@ public class BackupManagerService extends IBackupManager.Stub {
            }
        }

        for (int i = 0; i < mUserServices.size(); i++) {
            UserBackupManagerService userBackupManagerService =
                getServiceForUserIfCallerHasPermission(UserHandle.USER_SYSTEM, "dump()");

                    getServiceForUserIfCallerHasPermission(mUserServices.keyAt(i), "dump()");
            if (userBackupManagerService != null) {
                userBackupManagerService.dump(fd, pw, args);
            }
        }
    }

    /**
     * Used by the {@link JobScheduler} to run a full backup when conditions are right. The model we
+14 −19
Original line number Diff line number Diff line
@@ -3545,14 +3545,7 @@ public class UserBackupManagerService {
        try {
            if (args != null) {
                for (String arg : args) {
                    if ("-h".equals(arg)) {
                        pw.println("'dumpsys backup' optional arguments:");
                        pw.println("  -h       : this help text");
                        pw.println("  a[gents] : dump information about defined backup agents");
                        pw.println("  users    : dump the list of users for which backup service "
                                + "is running");
                        return;
                    } else if ("agents".startsWith(arg)) {
                    if ("agents".startsWith(arg)) {
                        dumpAgents(pw);
                        return;
                    } else if ("transportclients".equals(arg.toLowerCase())) {
@@ -3583,8 +3576,10 @@ public class UserBackupManagerService {
    }

    private void dumpInternal(PrintWriter pw) {
        // Add prefix for only non-system users so that system user dumpsys is the same as before
        String userPrefix = mUserId == UserHandle.USER_SYSTEM ? "" : "User " + mUserId + ":";
        synchronized (mQueueLock) {
            pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
            pw.println(userPrefix + "Backup Manager is " + (mEnabled ? "enabled" : "disabled")
                    + " / " + (!mSetupComplete ? "not " : "") + "setup complete / "
                    + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
            pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
@@ -3594,13 +3589,13 @@ public class UserBackupManagerService {
                    + " (now = " + System.currentTimeMillis() + ')');
            pw.println("  next scheduled: " + KeyValueBackupJob.nextScheduled(mUserId));

            pw.println("Transport whitelist:");
            pw.println(userPrefix + "Transport whitelist:");
            for (ComponentName transport : mTransportManager.getTransportWhitelist()) {
                pw.print("    ");
                pw.println(transport.flattenToShortString());
            }

            pw.println("Available transports:");
            pw.println(userPrefix + "Available transports:");
            final String[] transports = listAllTransports();
            if (transports != null) {
                for (String t : transports) {
@@ -3626,18 +3621,18 @@ public class UserBackupManagerService {

            mTransportManager.dumpTransportClients(pw);

            pw.println("Pending init: " + mPendingInits.size());
            pw.println(userPrefix + "Pending init: " + mPendingInits.size());
            for (String s : mPendingInits) {
                pw.println("    " + s);
            }

            pw.print("Ancestral: ");
            pw.print(userPrefix + "Ancestral: ");
            pw.println(Long.toHexString(mAncestralToken));
            pw.print("Current:   ");
            pw.print(userPrefix + "Current:   ");
            pw.println(Long.toHexString(mCurrentToken));

            int numPackages = mBackupParticipants.size();
            pw.println("Participants:");
            pw.println(userPrefix + "Participants:");
            for (int i = 0; i < numPackages; i++) {
                int uid = mBackupParticipants.keyAt(i);
                pw.print("  uid: ");
@@ -3648,7 +3643,7 @@ public class UserBackupManagerService {
                }
            }

            pw.println("Ancestral packages: "
            pw.println(userPrefix + "Ancestral packages: "
                    + (mAncestralPackages == null ? "none" : mAncestralPackages.size()));
            if (mAncestralPackages != null) {
                for (String pkg : mAncestralPackages) {
@@ -3657,17 +3652,17 @@ public class UserBackupManagerService {
            }

            Set<String> processedPackages = mProcessedPackagesJournal.getPackagesCopy();
            pw.println("Ever backed up: " + processedPackages.size());
            pw.println(userPrefix + "Ever backed up: " + processedPackages.size());
            for (String pkg : processedPackages) {
                pw.println("    " + pkg);
            }

            pw.println("Pending key/value backup: " + mPendingBackups.size());
            pw.println(userPrefix + "Pending key/value backup: " + mPendingBackups.size());
            for (BackupRequest req : mPendingBackups.values()) {
                pw.println("    " + req);
            }

            pw.println("Full backup queue:" + mFullBackupQueue.size());
            pw.println(userPrefix + "Full backup queue:" + mFullBackupQueue.size());
            for (FullBackupEntry entry : mFullBackupQueue) {
                pw.print("    ");
                pw.print(entry.lastBackup);
+40 −1
Original line number Diff line number Diff line
@@ -81,7 +81,10 @@ import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowPackageManager;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

/**
@@ -1238,13 +1241,49 @@ public class UserBackupManagerServiceTest {
        assertThat(service.getAncestralSerialNumber()).isEqualTo(testSerialNumber2);
    }

    /**
     * Test that {@link UserBackupManagerService#dump()} for system user does not prefix dump with
     * "User 0:".
     */
    @Test
    public void testDump_forSystemUser_DoesNotHaveUserPrefix() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        UserBackupManagerService service =
                BackupManagerServiceTestUtils.createUserBackupManagerServiceAndRunTasks(
                        UserHandle.USER_SYSTEM,
                        mContext,
                        mBackupThread,
                        mBaseStateDir,
                        mDataDir,
                        mTransportManager);

        StringWriter dump = new StringWriter();
        service.dump(new FileDescriptor(), new PrintWriter(dump), new String[0]);

        assertThat(dump.toString()).startsWith("Backup Manager is ");
    }

    /**
     * Test that {@link UserBackupManagerService#dump()} for non-system user prefixes dump with
     * "User <userid>:".
     */
    @Test
    public void testDump_forNonSystemUser_HasUserPrefix() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        UserBackupManagerService service = createUserBackupManagerServiceAndRunTasks();

        StringWriter dump = new StringWriter();
        service.dump(new FileDescriptor(), new PrintWriter(dump), new String[0]);

        assertThat(dump.toString()).startsWith("User " + USER_ID + ":" + "Backup Manager is ");
    }

    private File createTestFile() throws IOException {
        File testFile = new File(mContext.getFilesDir(), "test");
        testFile.createNewFile();
        return testFile;
    }


    /**
     * We can't mock the void method {@link #schedule(Context, long, BackupManagerConstants)} so we
     * extend {@link ShadowKeyValueBackupJob} and throw an exception at the end of the method.
+25 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static junit.framework.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -59,6 +60,7 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@@ -83,6 +85,8 @@ public class BackupManagerServiceTest {
    @Mock
    private UserBackupManagerService mUserBackupManagerService;
    @Mock
    private UserBackupManagerService mNonSystemUserBackupManagerService;
    @Mock
    private Context mContextMock;
    @Mock
    private PrintWriter mPrintWriterMock;
@@ -105,7 +109,7 @@ public class BackupManagerServiceTest {

        mUserServices = new SparseArray<>();
        mUserServices.append(UserHandle.USER_SYSTEM, mUserBackupManagerService);
        mUserServices.append(NON_USER_SYSTEM, mUserBackupManagerService);
        mUserServices.append(NON_USER_SYSTEM, mNonSystemUserBackupManagerService);

        when(mUserManagerMock.getUserInfo(UserHandle.USER_SYSTEM)).thenReturn(mUserInfoMock);
        when(mUserManagerMock.getUserInfo(NON_USER_SYSTEM)).thenReturn(mUserInfoMock);
@@ -512,6 +516,26 @@ public class BackupManagerServiceTest {
        mService.dump(mFileDescriptorStub, mPrintWriterMock, new String[0]);

        verifyNoMoreInteractions(mUserBackupManagerService);
        verifyNoMoreInteractions(mNonSystemUserBackupManagerService);
    }

    /**
     * Test that {@link BackupManagerService#dump()} dumps system user information before non-system
     * user information.
     */

    @Test
    public void testDump_systemUserFirst() {
        String[] args = new String[0];
        mService.dumpWithoutCheckingPermission(mFileDescriptorStub, mPrintWriterMock, args);

        InOrder inOrder =
                inOrder(mUserBackupManagerService, mNonSystemUserBackupManagerService);
        inOrder.verify(mUserBackupManagerService)
                .dump(mFileDescriptorStub, mPrintWriterMock, args);
        inOrder.verify(mNonSystemUserBackupManagerService)
                .dump(mFileDescriptorStub, mPrintWriterMock, args);
        inOrder.verifyNoMoreInteractions();
    }

    @Test