summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java24
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java33
-rw-r--r--services/backup/java/com/android/server/backup/Trampoline.java15
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerFiles.java11
4 files changed, 74 insertions, 9 deletions
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 98ab6665958c..680ccfc57ddf 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -112,6 +112,11 @@ public class Bmgr {
return;
}
+ if ("activated".equals(op)) {
+ doActivated(userId);
+ return;
+ }
+
if (!isBackupActive(userId)) {
return;
}
@@ -200,6 +205,21 @@ public class Bmgr {
return true;
}
+ private String activatedToString(boolean activated) {
+ return activated ? "activated" : "deactivated";
+ }
+
+ private void doActivated(@UserIdInt int userId) {
+ try {
+ System.out.println("Backup Manager currently "
+ + activatedToString(mBmgr.isBackupServiceActive(userId)));
+ } catch (RemoteException e) {
+ System.err.println(e.toString());
+ System.err.println(BMGR_NOT_RUNNING_ERR);
+ }
+
+ }
+
private String enableToString(boolean enabled) {
return enabled ? "enabled" : "disabled";
}
@@ -907,6 +927,7 @@ public class Bmgr {
System.err.println(" bmgr cancel backups");
System.err.println(" bmgr init TRANSPORT...");
System.err.println(" bmgr activate BOOL");
+ System.err.println(" bmgr activated");
System.err.println("");
System.err.println("The '--user' option specifies the user on which the operation is run.");
System.err.println("It must be the first argument before the operation.");
@@ -978,6 +999,9 @@ public class Bmgr {
System.err.println("If the argument is 'true' it will be activated, otherwise it will be");
System.err.println("deactivated. When deactivated, the service will not be running and no");
System.err.println("operations can be performed until activation.");
+ System.err.println("");
+ System.err.println("The 'activated' command reports the current activated/deactivated");
+ System.err.println("state of the backup mechanism.");
}
private static class BackupMonitor extends IBackupManagerMonitor.Stub {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 7106664d0699..79afe8e4de72 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -31,11 +31,14 @@ import android.app.backup.ISelectBackupTransportCallback;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Binder;
+import android.os.FileUtils;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -49,6 +52,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
+import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Collections;
@@ -86,6 +90,18 @@ public class BackupManagerService {
private Set<ComponentName> mTransportWhitelist;
+ private final BroadcastReceiver mUserRemovedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
+ int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+ if (userId > 0) { // for only non system users
+ onRemovedNonSystemUser(userId);
+ }
+ }
+ }
+ };
+
/** Instantiate a new instance of {@link BackupManagerService}. */
public BackupManagerService(
Context context, Trampoline trampoline, HandlerThread backupThread) {
@@ -99,6 +115,23 @@ public class BackupManagerService {
if (mTransportWhitelist == null) {
mTransportWhitelist = Collections.emptySet();
}
+
+ mContext.registerReceiver(mUserRemovedReceiver,
+ new IntentFilter(Intent.ACTION_USER_REMOVED));
+ }
+
+ /**
+ * Remove backup state for non system {@code userId} when the user is removed from the device.
+ * For non system users, backup state is stored in both the user's own dir and the system dir.
+ * When the user is removed, the user's own dir gets removed by the OS. This method ensures that
+ * the part of the user backup state which is in the system dir also gets removed.
+ */
+ private void onRemovedNonSystemUser(int userId) {
+ Slog.i(TAG, "Removing state for non system user " + userId);
+ File dir = UserBackupManagerFiles.getStateDirInSystemDir(userId);
+ if (!FileUtils.deleteContentsAndDir(dir)) {
+ Slog.w(TAG, "Failed to delete state dir for removed user: " + userId);
+ }
}
/**
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index bb0aba0c2e88..a9b292b37903 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -47,7 +47,6 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.DumpUtils;
-import com.android.server.backup.utils.FileUtils;
import com.android.server.backup.utils.RandomAccessFileUtils;
import java.io.File;
@@ -95,7 +94,7 @@ public class Trampoline extends IBackupManager.Stub {
* Name of file for non-system users that remembers whether backup was explicitly activated or
* deactivated with a call to setBackupServiceActive.
*/
- private static final String REMEMBER_ACTIVATED_FILENAME_PREFIX = "backup-remember-activated";
+ private static final String REMEMBER_ACTIVATED_FILENAME = "backup-remember-activated";
// Product-level suppression of backup/restore.
private static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable";
@@ -143,8 +142,7 @@ public class Trampoline extends IBackupManager.Stub {
/** Stored in the system user's directory and the file is indexed by the user it refers to. */
protected File getRememberActivatedFileForNonSystemUser(int userId) {
- return FileUtils.createNewFile(UserBackupManagerFiles.getStateFileInSystemDir(
- REMEMBER_ACTIVATED_FILENAME_PREFIX, userId));
+ return UserBackupManagerFiles.getStateFileInSystemDir(REMEMBER_ACTIVATED_FILENAME, userId);
}
/** Stored in the system user's directory and the file is indexed by the user it refers to. */
@@ -336,8 +334,13 @@ public class Trampoline extends IBackupManager.Stub {
// action since we need to remember that a permissioned call was made irrespective of
// whether the call changes the state or not.
if (userId != UserHandle.USER_SYSTEM) {
- RandomAccessFileUtils.writeBoolean(getRememberActivatedFileForNonSystemUser(userId),
- makeActive);
+ try {
+ File rememberFile = getRememberActivatedFileForNonSystemUser(userId);
+ createFile(rememberFile);
+ RandomAccessFileUtils.writeBoolean(rememberFile, makeActive);
+ } catch (IOException e) {
+ Slog.e(TAG, "Unable to persist backup service activity", e);
+ }
}
if (mGlobalDisable) {
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
index 4638ac63de4a..8e605426d0c9 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
@@ -49,8 +49,13 @@ final class UserBackupManagerFiles {
return new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR);
}
- /** Stored in the system user's directory and the file is indexed by the user it refers to. */
- static File getStateFileInSystemDir(String prefix, int userId) {
- return new File(getBaseStateDir(UserHandle.USER_SYSTEM), prefix + "-" + userId);
+ /** A user specific dir within the system user's directory. */
+ static File getStateDirInSystemDir(int userId) {
+ return new File(getBaseStateDir(UserHandle.USER_SYSTEM), "" + userId);
+ }
+
+ /** Stored in a user specific dir within the system user's directory. */
+ static File getStateFileInSystemDir(String filename, int userId) {
+ return new File(getStateDirInSystemDir(userId), filename);
}
}