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

This commit is contained in:
Chandan Nath
2020-01-10 15:01:47 +00:00
committed by Android (Google) Code Review
4 changed files with 100 additions and 27 deletions

View File

@@ -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,11 +1485,12 @@ public class BackupManagerService extends IBackupManager.Stub {
}
}
UserBackupManagerService userBackupManagerService =
getServiceForUserIfCallerHasPermission(UserHandle.USER_SYSTEM, "dump()");
if (userBackupManagerService != null) {
userBackupManagerService.dump(fd, pw, args);
for (int i = 0; i < mUserServices.size(); i++) {
UserBackupManagerService userBackupManagerService =
getServiceForUserIfCallerHasPermission(mUserServices.keyAt(i), "dump()");
if (userBackupManagerService != null) {
userBackupManagerService.dump(fd, pw, args);
}
}
}

View File

@@ -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);

View File

@@ -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.

View File

@@ -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