summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Annie Meng <anniemeng@google.com> 2018-11-30 12:09:08 +0000
committer Annie Meng <anniemeng@google.com> 2018-12-10 12:33:28 +0000
commita6d828755ee306c0e01a078530c22bd83d56f55f (patch)
tree43f9f9ff4f532e50e537846628132c64ae0a91e9
parent348c897729fef9a4c3d2f522efea0c6946071971 (diff)
[Multi-user] Create setting for multi-user backup service support
Whether the backup service supports multi-user is now configured in a Global setting: backup_multi_user_enabled This allows us to develop multi-user support hidden behind a flag. In a future CL, we'll also gate the types of users we support. Also create basic infrastructure for starting the service for a newly unlocked user (currently a no-op). Bug: 120212806 Test: 1) atest TrampolineTest 2) adb shell settings put global backup_multi_user_enabled 0; unlock system user -> verify service started; unlock user 10 -> verify service not started; 3) adb shell settings put global backup_multi_user_enabled 1; unlock system user -> verify service started; unlock user 10 -> verify service started; Change-Id: I048e017cfa6148097cebe2eb2916d1b53c53d3b0
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/proto/android/providers/settings/global.proto12
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java3
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java7
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java13
-rw-r--r--services/backup/java/com/android/server/backup/Trampoline.java53
-rw-r--r--services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java28
7 files changed, 111 insertions, 13 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3437e1d09cd4..de6afcbad9a6 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -13795,6 +13795,14 @@ public final class Settings {
"backup_agent_timeout_parameters";
/**
+ * Whether the backup system service supports multiple users (0 = disabled, 1 = enabled). If
+ * disabled, the service will only be active for the system user.
+ *
+ * @hide
+ */
+ public static final String BACKUP_MULTI_USER_ENABLED = "backup_multi_user_enabled";
+
+ /**
* Blacklist of GNSS satellites.
*
* This is a list of integers separated by commas to represent pairs of (constellation,
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index da6e20867cca..11bd43b11977 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -109,7 +109,15 @@ message GlobalSettingsProto {
}
optional Autofill autofill = 140;
- optional SettingProto backup_agent_timeout_parameters = 18;
+ reserved 18; // Used to be backup_agent_timeout_parameters
+
+ message Backup {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto backup_agent_timeout_parameters = 1;
+ optional SettingProto backup_multi_user_enabled = 2;
+ }
+ optional Backup backup = 146;
message Battery {
option (android.msg_privacy).dest = DEST_EXPLICIT;
@@ -1007,5 +1015,5 @@ message GlobalSettingsProto {
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 146;
+ // Next tag = 147;
}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 79eaab8a6e85..49a7555c2ac4 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -541,7 +541,8 @@ public class SettingsBackupTest {
Settings.Global.OVERRIDE_SETTINGS_PROVIDER_RESTORE_ANY_VERSION,
Settings.Global.CHAINED_BATTERY_ATTRIBUTION_ENABLED,
Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS,
- Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS);
+ Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS,
+ Settings.Global.BACKUP_MULTI_USER_ENABLED);
private static final Set<String> BACKUP_BLACKLISTED_SECURE_SETTINGS =
newHashSet(
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 533956f69835..e3d3d81704a8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -208,9 +208,14 @@ class SettingsProtoDumpUtil {
GlobalSettingsProto.Autofill.MAX_VISIBLE_DATASETS);
p.end(autofillToken);
+ final long backupToken = p.start(GlobalSettingsProto.BACKUP);
dumpSetting(s, p,
Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS,
- GlobalSettingsProto.BACKUP_AGENT_TIMEOUT_PARAMETERS);
+ GlobalSettingsProto.Backup.BACKUP_AGENT_TIMEOUT_PARAMETERS);
+ dumpSetting(s, p,
+ Settings.Global.BACKUP_MULTI_USER_ENABLED,
+ GlobalSettingsProto.Backup.BACKUP_MULTI_USER_ENABLED);
+ p.end(backupToken);
final long batteryToken = p.start(GlobalSettingsProto.BATTERY);
dumpSetting(s, p,
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 0b06f286441a..e62ec7ac41aa 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -184,6 +184,15 @@ public class BackupManagerService {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
+ /**
+ * Starts the backup service for user {@code userId} by creating a new instance of {@link
+ * UserBackupManagerService} and registering it with this service.
+ */
+ // TODO(b/120212806): Add UserBackupManagerService initialization logic.
+ void startServiceForUser(int userId) {
+ // Intentionally empty.
+ }
+
/*
* The following methods are implementations of IBackupManager methods called from Trampoline.
* They delegate to the appropriate per-user instance of UserBackupManagerService to perform the
@@ -626,7 +635,9 @@ public class BackupManagerService {
@Override
public void onUnlockUser(int userId) {
if (userId == UserHandle.USER_SYSTEM) {
- sInstance.unlockSystemUser();
+ sInstance.initializeServiceAndUnlockSystemUser();
+ } else {
+ sInstance.startServiceForUser(userId);
}
}
}
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 59629aac7b4d..9ca2070c7bab 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -41,6 +41,7 @@ import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -81,6 +82,12 @@ public class Trampoline extends IBackupManager.Stub {
// Product-level suppression of backup/restore.
private static final String BACKUP_DISABLE_PROPERTY = "ro.backup.disable";
+ private static final String BACKUP_THREAD = "backup";
+
+ /** Values for setting {@link Settings.Global#BACKUP_MULTI_USER_ENABLED} */
+ private static final int MULTI_USER_DISABLED = 0;
+ private static final int MULTI_USER_ENABLED = 1;
+
private final Context mContext;
@GuardedBy("mStateLock")
@@ -91,18 +98,31 @@ public class Trampoline extends IBackupManager.Stub {
private volatile BackupManagerService mService;
private HandlerThread mHandlerThread;
+ private Handler mHandler;
public Trampoline(Context context) {
mContext = context;
mGlobalDisable = isBackupDisabled();
mSuppressFile = getSuppressFile();
mSuppressFile.getParentFile().mkdirs();
+
+ mHandlerThread = new HandlerThread(BACKUP_THREAD, Process.THREAD_PRIORITY_BACKGROUND);
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
}
protected boolean isBackupDisabled() {
return SystemProperties.getBoolean(BACKUP_DISABLE_PROPERTY, false);
}
+ protected boolean isMultiUserEnabled() {
+ return Settings.Global.getInt(
+ mContext.getContentResolver(),
+ Settings.Global.BACKUP_MULTI_USER_ENABLED,
+ MULTI_USER_DISABLED)
+ == MULTI_USER_ENABLED;
+ }
+
protected int binderGetCallingUid() {
return Binder.getCallingUid();
}
@@ -147,15 +167,9 @@ public class Trampoline extends IBackupManager.Stub {
/**
* Called from {@link BackupManagerService.Lifecycle} when the system user is unlocked. Attempts
* to initialize {@link BackupManagerService} and set backup state for the system user.
- *
- * @see BackupManagerService#unlockSystemUser()
*/
- void unlockSystemUser() {
- mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
- mHandlerThread.start();
-
- Handler h = new Handler(mHandlerThread.getLooper());
- h.post(
+ void initializeServiceAndUnlockSystemUser() {
+ mHandler.post(
() -> {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup init");
initializeService(UserHandle.USER_SYSTEM);
@@ -170,6 +184,29 @@ public class Trampoline extends IBackupManager.Stub {
}
/**
+ * Called from {@link BackupManagerService.Lifecycle} when a non-system user {@code userId} is
+ * unlocked. Starts the backup service for this user if the service supports multi-user.
+ * Offloads work onto the handler thread {@link #mHandlerThread} to keep unlock time low.
+ */
+ // TODO(b/120212806): Consolidate service start for system and non-system users when system
+ // user-only logic is removed.
+ void startServiceForUser(int userId) {
+ if (!isMultiUserEnabled()) {
+ Slog.i(TAG, "Multi-user disabled, cannot start service for user: " + userId);
+ return;
+ }
+
+ mHandler.post(
+ () -> {
+ BackupManagerService service = mService;
+ if (service != null) {
+ Slog.i(TAG, "Starting service for user: " + userId);
+ service.startServiceForUser(userId);
+ }
+ });
+ }
+
+ /**
* Only privileged callers should be changing the backup state. This method only acts on {@link
* UserHandle#USER_SYSTEM} and is a no-op if passed non-system users. Deactivating backup in the
* system user also deactivates backup in all users.
diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
index 7c002995a769..fd010f1fed4f 100644
--- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
@@ -23,6 +23,7 @@ import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -43,10 +44,14 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
+import android.provider.Settings;
+import android.test.mock.MockContentResolver;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.util.test.FakeSettingsProvider;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -97,6 +102,7 @@ public class TrampolineTest {
private FileDescriptor mFileDescriptorStub = new FileDescriptor();
private TrampolineTestable mTrampoline;
+ private MockContentResolver mContentResolver;
@Before
public void setUp() {
@@ -110,6 +116,10 @@ public class TrampolineTest {
when(mSuppressFileMock.getParentFile()).thenReturn(mSuppressFileParentMock);
mTrampoline = new TrampolineTestable(mContextMock);
+
+ mContentResolver = new MockContentResolver();
+ mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ when(mContextMock.getContentResolver()).thenReturn(mContentResolver);
}
@Test
@@ -118,6 +128,24 @@ public class TrampolineTest {
}
@Test
+ public void startServiceForUser_whenMultiUserSettingDisabled_isIgnored() {
+ Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 0);
+
+ mTrampoline.startServiceForUser(10);
+
+ verify(mBackupManagerServiceMock, never()).startServiceForUser(10);
+ }
+
+ @Test
+ public void startServiceForUser_whenMultiUserSettingEnabled_callsBackupManagerService() {
+ Settings.Global.putInt(mContentResolver, Settings.Global.BACKUP_MULTI_USER_ENABLED, 1);
+
+ mTrampoline.startServiceForUser(10);
+
+ verify(mBackupManagerServiceMock).startServiceForUser(10);
+ }
+
+ @Test
public void initializeService_forUserSystem_successfullyInitialized() {
mTrampoline.initializeService(UserHandle.USER_SYSTEM);