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(