summaryrefslogtreecommitdiff
path: root/services/backup
diff options
context:
space:
mode:
authorBernardo Rufino <brufino@google.com>2019-06-24 11:48:37 +0100
committerBernardo Rufino <brufino@google.com>2019-08-05 14:35:40 +0100
commitd1df67ef43f64ecbd9ba8ab4bcda492848a471d2 (patch)
treecfffdfb523c6e148ecb5cf542ea916b028ccdf7b /services/backup
parentf128bcc47f5bbda87c97160e2294ca6c3c82f33d (diff)
Eagerly initialize BMS in Trampoline's constructor
After multi-user BMS became a lightweight class as well, so no need to lazily initialize it. This lays the ground for unifying Trampoline and BMS. Test: atest TrampolineTest Test: adb shell bmgr backupnow <package> Bug: 135247112 Bug: 135661048 Change-Id: Ia7f69d2ed282c6dfe6443a601f27229d43802fe6
Diffstat (limited to 'services/backup')
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java50
-rw-r--r--services/backup/java/com/android/server/backup/Trampoline.java106
2 files changed, 80 insertions, 76 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d5a7c818bfb2..814f6daac43c 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -195,16 +195,20 @@ public class BackupManagerService {
}
boolean isAbleToServeUser(int userId) {
- return getServiceUsers().get(UserHandle.USER_SYSTEM) != null
- && getServiceUsers().get(userId) != null;
+ return getUserServices().get(UserHandle.USER_SYSTEM) != null
+ && getUserServices().get(userId) != null;
}
/**
- * Returns a lst of users currently unlocked that have a
- * {@link UserBackupManagerService} registered.
+ * Returns a list of users currently unlocked that have a {@link UserBackupManagerService}
+ * registered.
+ *
+ * Warning: Do NOT modify returned object as it's used inside.
+ *
+ * TODO: Return a copy or only expose read-only information through other means.
*/
@VisibleForTesting
- public SparseArray<UserBackupManagerService> getServiceUsers() {
+ public SparseArray<UserBackupManagerService> getUserServices() {
return mServiceUsers;
}
@@ -495,7 +499,8 @@ public class BackupManagerService {
/**
* Returns a {@link UserHandle} for the user that has {@code ancestralSerialNumber} as the
- * serial number of the its ancestral work profile.
+ * serial number of the its ancestral work profile or null if there is no {@link
+ * UserBackupManagerService} associated with that user.
*
* <p> The ancestral work profile is set by {@link #setAncestralSerialNumber(long)}
* and it corresponds to the profile that was used to restore to the callers profile.
@@ -504,16 +509,18 @@ public class BackupManagerService {
public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
int callingUserId = Binder.getCallingUserHandle().getIdentifier();
long oldId = Binder.clearCallingIdentity();
- int[] userIds;
+ final int[] userIds;
try {
- userIds = mContext.getSystemService(UserManager.class).getProfileIds(callingUserId,
- false);
+ userIds =
+ mContext
+ .getSystemService(UserManager.class)
+ .getProfileIds(callingUserId, false);
} finally {
Binder.restoreCallingIdentity(oldId);
}
for (int userId : userIds) {
- UserBackupManagerService userBackupManagerService = getServiceUsers().get(userId);
+ UserBackupManagerService userBackupManagerService = getUserServices().get(userId);
if (userBackupManagerService != null) {
if (userBackupManagerService.getAncestralSerialNumber() == ancestralSerialNumber) {
return UserHandle.of(userId);
@@ -880,28 +887,35 @@ public class BackupManagerService {
}
/** Implementation to receive lifecycle event callbacks for system services. */
- public static final class Lifecycle extends SystemService {
+ public static class Lifecycle extends SystemService {
public Lifecycle(Context context) {
+ this(context, new Trampoline(context));
+ }
+
+ @VisibleForTesting
+ Lifecycle(Context context, Trampoline trampoline) {
super(context);
- sInstance = new Trampoline(context);
+ sInstance = trampoline;
}
@Override
public void onStart() {
- publishBinderService(Context.BACKUP_SERVICE, sInstance);
+ publishService(Context.BACKUP_SERVICE, sInstance);
}
@Override
public void onUnlockUser(int userId) {
- if (userId == UserHandle.USER_SYSTEM) {
- sInstance.initializeService();
- }
- sInstance.unlockUser(userId);
+ sInstance.onUnlockUser(userId);
}
@Override
public void onStopUser(int userId) {
- sInstance.stopUser(userId);
+ sInstance.onStopUser(userId);
+ }
+
+ @VisibleForTesting
+ void publishService(String name, IBinder service) {
+ publishBinderService(name, service);
}
}
}
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index f4b66456c27b..210a9ef94e53 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -40,12 +40,12 @@ import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
-import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.server.backup.utils.RandomAccessFileUtils;
@@ -73,9 +73,6 @@ import java.io.PrintWriter;
* Temporary disabling is controlled by {@link #setBackupServiceActive(int, boolean)} through
* privileged callers (currently {@link DevicePolicyManager}). This is called on {@link
* UserHandle#USER_SYSTEM} and disables backup for all users.
- *
- * <p>Creation of the backup service is done when {@link UserHandle#USER_SYSTEM} is unlocked. The
- * system user is unlocked before any other users.
*/
public class Trampoline extends IBackupManager.Stub {
/**
@@ -109,7 +106,10 @@ public class Trampoline extends IBackupManager.Stub {
// TODD(b/121198006): remove this object and synchronized all methods on "this".
private final Object mStateLock = new Object();
- private volatile BackupManagerService mService;
+ // TODO: This is not marked as final because of test code. Since we'll merge BMS and Trampoline,
+ // it doesn't make sense to refactor for final. It's never null.
+ @VisibleForTesting
+ protected volatile BackupManagerService mService;
private final Handler mHandler;
public Trampoline(Context context) {
@@ -120,6 +120,13 @@ public class Trampoline extends IBackupManager.Stub {
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
mUserManager = UserManager.get(context);
+ mService = new BackupManagerService(mContext, this);
+ }
+
+ // TODO: Remove this when we implement DI by injecting in the construtor.
+ @VisibleForTesting
+ Handler getBackupHandler() {
+ return mHandler;
}
protected boolean isBackupDisabled() {
@@ -205,7 +212,7 @@ public class Trampoline extends IBackupManager.Stub {
// This method should not perform any I/O (e.g. do not call isBackupActivatedForUser),
// it's used in multiple places where I/O waits would cause system lock-ups.
private boolean isUserReadyForBackup(int userId) {
- return mService != null && mService.isAbleToServeUser(userId);
+ return mService.isAbleToServeUser(userId);
}
/**
@@ -230,68 +237,55 @@ public class Trampoline extends IBackupManager.Stub {
return mUserManager;
}
- protected BackupManagerService createBackupManagerService() {
- return new BackupManagerService(mContext, this);
- }
-
protected void postToHandler(Runnable runnable) {
mHandler.post(runnable);
}
/**
- * Called from {@link BackupManagerService.Lifecycle} when the system user is unlocked. Attempts
- * to initialize {@link BackupManagerService}. Offloads work onto the handler thread {@link
- * #mHandlerThread} to keep unlock time low.
- */
- void initializeService() {
- postToHandler(
- () -> {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backup init");
- if (mGlobalDisable) {
- Slog.i(TAG, "Backup service not supported");
- return;
- }
- synchronized (mStateLock) {
- if (mService == null) {
- mService = createBackupManagerService();
- }
- }
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- });
- }
-
- /**
* Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is unlocked.
* Starts the backup service for this user if backup is active for this user. Offloads work onto
- * the handler thread {@link #mHandlerThread} to keep unlock time low.
+ * the handler thread {@link #mHandlerThread} to keep unlock time low since backup is not
+ * essential for device functioning.
*/
- void unlockUser(int userId) {
+ void onUnlockUser(int userId) {
postToHandler(() -> startServiceForUser(userId));
}
private void startServiceForUser(int userId) {
// We know that the user is unlocked here because it is called from setBackupServiceActive
// and unlockUser which have these guarantees. So we can check if the file exists.
- if (mService != null && isBackupActivatedForUser(userId)) {
- Slog.i(TAG, "Starting service for user: " + userId);
- mService.startServiceForUser(userId);
+ if (mGlobalDisable) {
+ Slog.i(TAG, "Backup service not supported");
+ return;
}
+ if (!isBackupActivatedForUser(userId)) {
+ Slog.i(TAG, "Backup not activated for user " + userId);
+ return;
+ }
+ Slog.i(TAG, "Starting service for user: " + userId);
+ mService.startServiceForUser(userId);
}
/**
* Called from {@link BackupManagerService.Lifecycle} when a user {@code userId} is stopped.
* Offloads work onto the handler thread {@link #mHandlerThread} to keep stopping time low.
*/
- void stopUser(int userId) {
+ void onStopUser(int userId) {
postToHandler(
() -> {
- if (mService != null) {
+ if (!mGlobalDisable) {
Slog.i(TAG, "Stopping service for user: " + userId);
mService.stopServiceForUser(userId);
}
});
}
+ /** Returns {@link UserBackupManagerService} for user {@code userId}. */
+ @Nullable
+ public UserBackupManagerService getUserService(int userId) {
+ return mService.getUserServices().get(userId);
+ }
+
/**
* The system user and managed profiles can only be acted on by callers in the system or root
* processes. Other users can be acted on by callers who have both android.permission.BACKUP and
@@ -350,9 +344,6 @@ public class Trampoline extends IBackupManager.Stub {
synchronized (mStateLock) {
Slog.i(TAG, "Making backup " + (makeActive ? "" : "in") + "active");
if (makeActive) {
- if (mService == null) {
- mService = createBackupManagerService();
- }
try {
activateBackupForUserLocked(userId);
} catch (IOException e) {
@@ -380,7 +371,7 @@ public class Trampoline extends IBackupManager.Stub {
}
//TODO(b/121198006): loop through active users that have work profile and
// stop them as well.
- stopUser(userId);
+ onStopUser(userId);
}
}
}
@@ -388,8 +379,7 @@ public class Trampoline extends IBackupManager.Stub {
// IBackupManager binder API
/**
- * Querying activity state of backup service. Calling this method before initialize yields
- * undefined result.
+ * Querying activity state of backup service.
*
* @param userId The user in which the activity state of backup service is queried.
* @return true if the service is active.
@@ -397,7 +387,7 @@ public class Trampoline extends IBackupManager.Stub {
@Override
public boolean isBackupServiceActive(int userId) {
synchronized (mStateLock) {
- return mService != null && isBackupActivatedForUser(userId);
+ return !mGlobalDisable && isBackupActivatedForUser(userId);
}
}
@@ -598,8 +588,8 @@ public class Trampoline extends IBackupManager.Stub {
@Override
@Nullable
public ComponentName getCurrentTransportComponentForUser(int userId) {
- return (isUserReadyForBackup(userId)) ? mService.getCurrentTransportComponent(userId)
- : null;
+ return (isUserReadyForBackup(userId))
+ ? mService.getCurrentTransportComponent(userId) : null;
}
@Override
@@ -614,8 +604,8 @@ public class Trampoline extends IBackupManager.Stub {
@Override
public ComponentName[] listAllTransportComponentsForUser(int userId) throws RemoteException {
- return (isUserReadyForBackup(userId)) ? mService.listAllTransportComponents(userId)
- : null;
+ return (isUserReadyForBackup(userId))
+ ? mService.listAllTransportComponents(userId) : null;
}
@Override
@@ -648,8 +638,8 @@ public class Trampoline extends IBackupManager.Stub {
@Override
public String selectBackupTransportForUser(int userId, String transport)
throws RemoteException {
- return (isUserReadyForBackup(userId)) ? mService.selectBackupTransport(userId, transport)
- : null;
+ return (isUserReadyForBackup(userId))
+ ? mService.selectBackupTransport(userId, transport) : null;
}
@Override
@@ -700,8 +690,8 @@ public class Trampoline extends IBackupManager.Stub {
@Override
public Intent getDataManagementIntentForUser(int userId, String transport)
throws RemoteException {
- return isUserReadyForBackup(userId) ? mService.getDataManagementIntent(userId, transport)
- : null;
+ return isUserReadyForBackup(userId)
+ ? mService.getDataManagementIntent(userId, transport) : null;
}
@Override
@@ -784,15 +774,15 @@ public class Trampoline extends IBackupManager.Stub {
@Override
@Nullable public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
- if (mService != null) {
- return mService.getUserForAncestralSerialNumber(ancestralSerialNumber);
+ if (mGlobalDisable) {
+ return null;
}
- return null;
+ return mService.getUserForAncestralSerialNumber(ancestralSerialNumber);
}
@Override
public void setAncestralSerialNumber(long ancestralSerialNumber) {
- if (mService != null) {
+ if (!mGlobalDisable) {
mService.setAncestralSerialNumber(ancestralSerialNumber);
}
}