Merge "[Multi-user] No-op refactor to move backup dirs and settings, which should be user-specific, to one class for each."
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 7049744..8b07db7 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -36,7 +36,6 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Binder;
-import android.os.Environment;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -50,11 +49,7 @@
import com.android.server.SystemConfig;
import com.android.server.SystemService;
-import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Set;
@@ -72,10 +67,6 @@
public static final boolean MORE_DEBUG = false;
public static final boolean DEBUG_SCHEDULING = true;
- // File containing backup-enabled state. Contains a single byte to denote enabled status.
- // Nonzero is enabled; file missing or a zero byte is disabled.
- private static final String BACKUP_ENABLE_FILE = "backup_enabled";
-
// The published binder is a singleton Trampoline object that calls through to the proper code.
// This indirection lets us turn down the heavy implementation object on the fly without
// disturbing binders that have been cached elsewhere in the system.
@@ -150,7 +141,8 @@
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup enable");
try {
// TODO(b/121198604): Make enable file per-user and clean up indirection.
- mTrampoline.setBackupEnabledForUser(userId, readBackupEnableState(userId));
+ mTrampoline.setBackupEnabledForUser(
+ userId, UserBackupManagerFilePersistedSettings.readBackupEnableState(userId));
} catch (RemoteException e) {
// Can't happen, it's a local object.
}
@@ -773,44 +765,6 @@
}
}
- private static boolean readBackupEnableState(int userId) {
- File base = new File(Environment.getDataDirectory(), "backup");
- File enableFile = new File(base, BACKUP_ENABLE_FILE);
- if (enableFile.exists()) {
- try (FileInputStream fin = new FileInputStream(enableFile)) {
- int state = fin.read();
- return state != 0;
- } catch (IOException e) {
- // can't read the file; fall through to assume disabled
- Slog.e(TAG, "Cannot read enable state; assuming disabled");
- }
- } else {
- if (DEBUG) {
- Slog.i(TAG, "isBackupEnabled() => false due to absent settings file");
- }
- }
- return false;
- }
-
- static void writeBackupEnableState(boolean enable, int userId) {
- File base = new File(Environment.getDataDirectory(), "backup");
- File enableFile = new File(base, BACKUP_ENABLE_FILE);
- File stage = new File(base, BACKUP_ENABLE_FILE + "-stage");
- try (FileOutputStream fout = new FileOutputStream(stage)) {
- fout.write(enable ? 1 : 0);
- fout.close();
- stage.renameTo(enableFile);
- // will be synced immediately by the try-with-resources call to close()
- } catch (IOException | RuntimeException e) {
- Slog.e(
- TAG,
- "Unable to record backup enable state; reverting to disabled: "
- + e.getMessage());
- enableFile.delete();
- stage.delete();
- }
- }
-
/** Implementation to receive lifecycle event callbacks for system services. */
public static final class Lifecycle extends SystemService {
public Lifecycle(Context context) {
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java
new file mode 100644
index 0000000..6a1de63
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerFilePersistedSettings.java
@@ -0,0 +1,78 @@
+/*
+ * 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 com.android.server.backup;
+
+import static com.android.server.backup.BackupManagerService.DEBUG;
+import static com.android.server.backup.BackupManagerService.TAG;
+
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/** User settings which are persisted across reboots. */
+final class UserBackupManagerFilePersistedSettings {
+ // File containing backup-enabled state. Contains a single byte to denote enabled status.
+ // Nonzero is enabled; file missing or a zero byte is disabled.
+ private static final String BACKUP_ENABLE_FILE = "backup_enabled";
+
+ static boolean readBackupEnableState(int userId) {
+ return readBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId));
+ }
+
+ static void writeBackupEnableState(int userId, boolean enable) {
+ writeBackupEnableState(UserBackupManagerFiles.getBaseStateDir(userId), enable);
+ }
+
+ private static boolean readBackupEnableState(File baseDir) {
+ File enableFile = new File(baseDir, BACKUP_ENABLE_FILE);
+ if (enableFile.exists()) {
+ try (FileInputStream fin = new FileInputStream(enableFile)) {
+ int state = fin.read();
+ return state != 0;
+ } catch (IOException e) {
+ // can't read the file; fall through to assume disabled
+ Slog.e(TAG, "Cannot read enable state; assuming disabled");
+ }
+ } else {
+ if (DEBUG) {
+ Slog.i(TAG, "isBackupEnabled() => false due to absent settings file");
+ }
+ }
+ return false;
+ }
+
+ private static void writeBackupEnableState(File baseDir, boolean enable) {
+ File enableFile = new File(baseDir, BACKUP_ENABLE_FILE);
+ File stage = new File(baseDir, BACKUP_ENABLE_FILE + "-stage");
+ try (FileOutputStream fout = new FileOutputStream(stage)) {
+ fout.write(enable ? 1 : 0);
+ fout.close();
+ stage.renameTo(enableFile);
+ // will be synced immediately by the try-with-resources call to close()
+ } catch (IOException | RuntimeException e) {
+ Slog.e(
+ TAG,
+ "Unable to record backup enable state; reverting to disabled: "
+ + e.getMessage());
+ enableFile.delete();
+ stage.delete();
+ }
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
new file mode 100644
index 0000000..a0feaf9
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerFiles.java
@@ -0,0 +1,45 @@
+/*
+ * 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 com.android.server.backup;
+
+import android.os.Environment;
+
+import java.io.File;
+
+/** Directories used for user specific backup/restore persistent state and book-keeping. */
+public final class UserBackupManagerFiles {
+ // Name of the directories the service stores bookkeeping data under.
+ private static final String BACKUP_PERSISTENT_DIR = "backup";
+ private static final String BACKUP_STAGING_DIR = "backup_stage";
+
+ static File getBaseStateDir(int userId) {
+ // TODO (b/120424138) this should be per user
+ return new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR);
+ }
+
+ static File getDataDir(int userId) {
+ // TODO (b/120424138) this should be per user
+ // This dir on /cache is managed directly in init.rc
+ return new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR);
+ }
+
+ /** Directory used by full backup engine to store state. */
+ public static File getFullBackupEngineFilesDir(int userId) {
+ // TODO (b/120424138) this should be per user
+ return new File("/data/system");
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 2e41443..6425508 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -70,7 +70,6 @@
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
-import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
@@ -164,17 +163,9 @@
/** System service that performs backup/restore operations. */
public class UserBackupManagerService {
- // File containing backup-enabled state. Contains a single byte;
- // nonzero == enabled. File missing or contains a zero byte == disabled.
- private static final String BACKUP_ENABLE_FILE = "backup_enabled";
-
// Persistently track the need to do a full init.
private static final String INIT_SENTINEL_FILE_NAME = "_need_init_";
- // Name of the directories the service stores bookkeeping data under.
- private static final String BACKUP_PERSISTENT_DIR = "backup";
- private static final String BACKUP_STAGING_DIR = "backup_stage";
-
// System-private key used for backing up an app's widget state. Must
// begin with U+FFxx by convention (we reserve all keys starting
// with U+FF00 or higher for system use).
@@ -354,9 +345,9 @@
final AtomicInteger mNextToken = new AtomicInteger();
// Where we keep our journal files and other bookkeeping.
- private File mBaseStateDir;
- private File mDataDir;
- private File mJournalDir;
+ private final File mBaseStateDir;
+ private final File mDataDir;
+ private final File mJournalDir;
@Nullable
private DataChangedJournal mJournal;
private File mFullBackupScheduleFile;
@@ -395,10 +386,8 @@
TransportManager transportManager =
new TransportManager(context, transportWhitelist, currentTransport);
- File baseStateDir = new File(Environment.getDataDirectory(), BACKUP_PERSISTENT_DIR);
-
- // This dir on /cache is managed directly in init.rc
- File dataDir = new File(Environment.getDownloadCacheDirectory(), BACKUP_STAGING_DIR);
+ File baseStateDir = UserBackupManagerFiles.getBaseStateDir(userId);
+ File dataDir = UserBackupManagerFiles.getDataDir(userId);
return createAndInitializeService(
userId, context, trampoline, backupThread, baseStateDir, dataDir, transportManager);
@@ -726,18 +715,10 @@
return mBaseStateDir;
}
- public void setBaseStateDir(File baseStateDir) {
- mBaseStateDir = baseStateDir;
- }
-
public File getDataDir() {
return mDataDir;
}
- public void setDataDir(File dataDir) {
- mDataDir = dataDir;
- }
-
@Nullable
public DataChangedJournal getJournal() {
return mJournal;
@@ -2735,8 +2716,7 @@
try {
boolean wasEnabled = mEnabled;
synchronized (this) {
- // TODO(b/118520567): Clean up writing backup enabled logic.
- BackupManagerService.writeBackupEnableState(enable, UserHandle.USER_SYSTEM);
+ UserBackupManagerFilePersistedSettings.writeBackupEnableState(mUserId, enable);
mEnabled = enable;
}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 5e92339..45ca2af 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -24,6 +24,7 @@
import static com.android.server.backup.UserBackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
+import android.annotation.UserIdInt;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
import android.app.backup.BackupTransport;
@@ -40,6 +41,7 @@
import com.android.server.AppWidgetBackupBridge;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.UserBackupManagerFiles;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.remote.RemoteCall;
import com.android.server.backup.utils.FullBackupUtils;
@@ -66,6 +68,7 @@
private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
class FullBackupRunner implements Runnable {
+ private final @UserIdInt int mUserId;
private final PackageManager mPackageManager;
private final PackageInfo mPackage;
private final IBackupAgent mAgent;
@@ -81,13 +84,15 @@
int token,
boolean includeApks)
throws IOException {
+ // TODO: http://b/22388012
+ mUserId = UserHandle.USER_SYSTEM;
mPackageManager = backupManagerService.getPackageManager();
mPackage = packageInfo;
mAgent = agent;
mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor());
mToken = token;
mIncludeApks = includeApks;
- mFilesDir = new File("/data/system");
+ mFilesDir = UserBackupManagerFiles.getFullBackupEngineFilesDir(mUserId);
}
@Override
@@ -114,10 +119,8 @@
manifestFile.delete();
// Write widget data.
- // TODO: http://b/22388012
byte[] widgetData =
- AppWidgetBackupBridge.getWidgetState(
- packageName, UserHandle.USER_SYSTEM);
+ AppWidgetBackupBridge.getWidgetState(packageName, mUserId);
if (widgetData != null && widgetData.length > 0) {
File metadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
appMetadataBackupWriter.backupWidget(