Merge "[Multi-user] Make backup and initialize receivers per user"

This commit is contained in:
Annie Meng
2019-01-09 13:48:28 +00:00
committed by Android (Google) Code Review
3 changed files with 127 additions and 76 deletions

View File

@@ -503,26 +503,46 @@ public class UserBackupManagerService {
mBackupPasswordManager = new BackupPasswordManager(mContext, mBaseStateDir, mRng);
// Alarm receivers for scheduled backups & initialization operations
BroadcastReceiver mRunBackupReceiver = new RunBackupReceiver(this);
// Receivers for scheduled backups and transport initialization operations.
BroadcastReceiver runBackupReceiver = new RunBackupReceiver(this);
IntentFilter filter = new IntentFilter();
filter.addAction(RUN_BACKUP_ACTION);
context.registerReceiver(mRunBackupReceiver, filter,
android.Manifest.permission.BACKUP, null);
context.registerReceiverAsUser(
runBackupReceiver,
UserHandle.of(userId),
filter,
android.Manifest.permission.BACKUP,
/* scheduler */ null);
BroadcastReceiver mRunInitReceiver = new RunInitializeReceiver(this);
BroadcastReceiver runInitReceiver = new RunInitializeReceiver(this);
filter = new IntentFilter();
filter.addAction(RUN_INITIALIZE_ACTION);
context.registerReceiver(mRunInitReceiver, filter,
android.Manifest.permission.BACKUP, null);
context.registerReceiverAsUser(
runInitReceiver,
UserHandle.of(userId),
filter,
android.Manifest.permission.BACKUP,
/* scheduler */ null);
Intent backupIntent = new Intent(RUN_BACKUP_ACTION);
backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mRunBackupIntent = PendingIntent.getBroadcast(context, 0, backupIntent, 0);
mRunBackupIntent =
PendingIntent.getBroadcastAsUser(
context,
/* requestCode */ 0,
backupIntent,
/* flags */ 0,
UserHandle.of(userId));
Intent initIntent = new Intent(RUN_INITIALIZE_ACTION);
initIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mRunInitIntent = PendingIntent.getBroadcast(context, 0, initIntent, 0);
mRunInitIntent =
PendingIntent.getBroadcastAsUser(
context,
/* requestCode */ 0,
initIntent,
/* flags */ 0,
UserHandle.of(userId));
// Set up the backup-request journaling
mJournalDir = new File(mBaseStateDir, "pending");

View File

@@ -26,62 +26,84 @@ import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Slog;
import com.android.server.backup.UserBackupManagerService;
/**
* A {@link BroadcastReceiver} for the action {@link UserBackupManagerService#RUN_BACKUP_ACTION}
* that runs an immediate backup operation if eligible.
*/
public class RunBackupReceiver extends BroadcastReceiver {
private final UserBackupManagerService mUserBackupManagerService;
private UserBackupManagerService backupManagerService;
public RunBackupReceiver(UserBackupManagerService backupManagerService) {
this.backupManagerService = backupManagerService;
public RunBackupReceiver(UserBackupManagerService userBackupManagerService) {
mUserBackupManagerService = userBackupManagerService;
}
/**
* Run a backup pass if we're eligible. We're eligible if the following conditions are met:
*
* <ul>
* <li>No transports are pending initialization (otherwise we kick off an initialization
* operation instead).
* <li>Backup is enabled for the user.
* <li>The user has completed setup.
* <li>No backup operation is currently running for the user.
* </ul>
*/
public void onReceive(Context context, Intent intent) {
if (RUN_BACKUP_ACTION.equals(intent.getAction())) {
synchronized (backupManagerService.getQueueLock()) {
if (backupManagerService.getPendingInits().size() > 0) {
// If there are pending init operations, we process those
// and then settle into the usual periodic backup schedule.
if (MORE_DEBUG) {
Slog.v(TAG, "Init pending at scheduled backup");
}
try {
backupManagerService.getAlarmManager().cancel(
backupManagerService.getRunInitIntent());
backupManagerService.getRunInitIntent().send();
} catch (PendingIntent.CanceledException ce) {
Slog.e(TAG, "Run init intent cancelled");
// can't really do more than bail here
}
} else {
// Don't run backups now if we're disabled or not yet
// fully set up.
if (backupManagerService.isEnabled()
&& backupManagerService.isSetupComplete()) {
if (!backupManagerService.isBackupRunning()) {
if (DEBUG) {
Slog.v(TAG, "Running a backup pass");
}
if (!RUN_BACKUP_ACTION.equals(intent.getAction())) {
return;
}
// Acquire the wakelock and pass it to the backup thread. it will
// be released once backup concludes.
backupManagerService.setBackupRunning(true);
backupManagerService.getWakelock().acquire();
Message msg = backupManagerService.getBackupHandler().obtainMessage(
MSG_RUN_BACKUP);
backupManagerService.getBackupHandler().sendMessage(msg);
} else {
Slog.i(TAG, "Backup time but one already running");
}
} else {
Slog.w(TAG, "Backup pass but enabled=" + backupManagerService.isEnabled()
+ " setupComplete=" + backupManagerService.isSetupComplete());
}
synchronized (mUserBackupManagerService.getQueueLock()) {
if (mUserBackupManagerService.getPendingInits().size() > 0) {
// If there are pending init operations, we process those and then settle into the
// usual periodic backup schedule.
if (MORE_DEBUG) {
Slog.v(TAG, "Init pending at scheduled backup");
}
try {
PendingIntent runInitIntent = mUserBackupManagerService.getRunInitIntent();
mUserBackupManagerService.getAlarmManager().cancel(runInitIntent);
runInitIntent.send();
} catch (PendingIntent.CanceledException ce) {
Slog.w(TAG, "Run init intent cancelled");
}
} else {
// Don't run backups if we're disabled or not yet set up.
if (!mUserBackupManagerService.isEnabled()
|| !mUserBackupManagerService.isSetupComplete()) {
Slog.w(
TAG,
"Backup pass but enabled="
+ mUserBackupManagerService.isEnabled()
+ " setupComplete="
+ mUserBackupManagerService.isSetupComplete());
return;
}
// Don't run backups if one is already running.
if (mUserBackupManagerService.isBackupRunning()) {
Slog.i(TAG, "Backup time but one already running");
return;
}
if (DEBUG) {
Slog.v(TAG, "Running a backup pass");
}
// Acquire the wakelock and pass it to the backup thread. It will be released once
// backup concludes.
mUserBackupManagerService.setBackupRunning(true);
mUserBackupManagerService.getWakelock().acquire();
Handler backupHandler = mUserBackupManagerService.getBackupHandler();
Message message = backupHandler.obtainMessage(MSG_RUN_BACKUP);
backupHandler.sendMessage(message);
}
}
}

View File

@@ -24,41 +24,50 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.ArraySet;
import android.util.Slog;
import com.android.server.backup.UserBackupManagerService;
public class RunInitializeReceiver extends BroadcastReceiver {
private final UserBackupManagerService mBackupManagerService;
import java.util.Set;
public RunInitializeReceiver(UserBackupManagerService backupManagerService) {
mBackupManagerService = backupManagerService;
/**
* A {@link BroadcastReceiver} for the action {@link UserBackupManagerService#RUN_INITIALIZE_ACTION}
* that runs an initialization operation on all pending transports.
*/
public class RunInitializeReceiver extends BroadcastReceiver {
private final UserBackupManagerService mUserBackupManagerService;
public RunInitializeReceiver(UserBackupManagerService userBackupManagerService) {
mUserBackupManagerService = userBackupManagerService;
}
public void onReceive(Context context, Intent intent) {
if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
synchronized (mBackupManagerService.getQueueLock()) {
final ArraySet<String> pendingInits = mBackupManagerService.getPendingInits();
if (DEBUG) {
Slog.v(TAG, "Running a device init; " + pendingInits.size() + " pending");
}
if (!RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
return;
}
if (pendingInits.size() > 0) {
final String[] transports =
pendingInits.toArray(new String[pendingInits.size()]);
synchronized (mUserBackupManagerService.getQueueLock()) {
Set<String> pendingInits = mUserBackupManagerService.getPendingInits();
if (DEBUG) {
Slog.v(TAG, "Running a device init; " + pendingInits.size() + " pending");
}
mBackupManagerService.clearPendingInits();
if (pendingInits.size() > 0) {
String[] transports = pendingInits.toArray(new String[pendingInits.size()]);
PowerManager.WakeLock wakelock = mBackupManagerService.getWakelock();
wakelock.acquire();
OnTaskFinishedListener listener = caller -> wakelock.release();
mUserBackupManagerService.clearPendingInits();
Runnable task =
new PerformInitializeTask(
mBackupManagerService, transports, null, listener);
mBackupManagerService.getBackupHandler().post(task);
}
PowerManager.WakeLock wakelock = mUserBackupManagerService.getWakelock();
wakelock.acquire();
OnTaskFinishedListener listener = caller -> wakelock.release();
Runnable task =
new PerformInitializeTask(
mUserBackupManagerService,
transports,
/* observer */ null,
listener);
mUserBackupManagerService.getBackupHandler().post(task);
}
}
}