am 4cc86e1a: Clear the device\'s data from the transport when backup is disabled
Merge commit '4cc86e1ae80eb1938500fe5fa06bbdf8b4b7b50d' into eclair-plus-aosp * commit '4cc86e1ae80eb1938500fe5fa06bbdf8b4b7b50d': Clear the device's data from the transport when backup is disabled
This commit is contained in:
@@ -52,6 +52,10 @@
|
|||||||
<protected-broadcast android:name="android.intent.action.NEW_OUTGOING_CALL" />
|
<protected-broadcast android:name="android.intent.action.NEW_OUTGOING_CALL" />
|
||||||
<protected-broadcast android:name="android.intent.action.REBOOT" />
|
<protected-broadcast android:name="android.intent.action.REBOOT" />
|
||||||
|
|
||||||
|
<protected-broadcast android:name="android.backup.intent.RUN" />
|
||||||
|
<protected-broadcast android:name="android.backup.intent.CLEAR" />
|
||||||
|
<protected-broadcast android:name="android.backup.intent.INIT" />
|
||||||
|
|
||||||
<protected-broadcast android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
|
<protected-broadcast android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
|
||||||
<protected-broadcast android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
|
<protected-broadcast android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
|
||||||
<protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
|
<protected-broadcast android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
|
||||||
|
|||||||
@@ -196,8 +196,9 @@ BackupDataReader::Status()
|
|||||||
m_done = true; \
|
m_done = true; \
|
||||||
} else { \
|
} else { \
|
||||||
m_status = errno; \
|
m_status = errno; \
|
||||||
|
LOGD("CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'", \
|
||||||
|
long(actual), long(expected), __LINE__, strerror(m_status)); \
|
||||||
} \
|
} \
|
||||||
LOGD("CHECK_SIZE failed with at line %d m_status='%s'", __LINE__, strerror(m_status)); \
|
|
||||||
return m_status; \
|
return m_status; \
|
||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import android.content.ServiceConnection;
|
|||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.IPackageDataObserver;
|
import android.content.pm.IPackageDataObserver;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PermissionInfo;
|
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.Signature;
|
import android.content.pm.Signature;
|
||||||
@@ -67,6 +66,7 @@ import com.android.server.PackageManagerBackupAgent.Metadata;
|
|||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@@ -89,11 +89,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
// the first backup pass.
|
// the first backup pass.
|
||||||
private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR;
|
private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR;
|
||||||
|
|
||||||
private static final String RUN_BACKUP_ACTION = "_backup_run_";
|
private static final String RUN_BACKUP_ACTION = "android.backup.intent.RUN";
|
||||||
|
private static final String RUN_INITIALIZE_ACTION = "android.backup.intent.INIT";
|
||||||
|
private static final String RUN_CLEAR_ACTION = "android.backup.intent.CLEAR";
|
||||||
private static final int MSG_RUN_BACKUP = 1;
|
private static final int MSG_RUN_BACKUP = 1;
|
||||||
private static final int MSG_RUN_FULL_BACKUP = 2;
|
private static final int MSG_RUN_FULL_BACKUP = 2;
|
||||||
private static final int MSG_RUN_RESTORE = 3;
|
private static final int MSG_RUN_RESTORE = 3;
|
||||||
private static final int MSG_RUN_CLEAR = 4;
|
private static final int MSG_RUN_CLEAR = 4;
|
||||||
|
private static final int MSG_RUN_INITIALIZE = 5;
|
||||||
|
|
||||||
// Event tags -- see system/core/logcat/event-log-tags
|
// Event tags -- see system/core/logcat/event-log-tags
|
||||||
private static final int BACKUP_DATA_CHANGED_EVENT = 2820;
|
private static final int BACKUP_DATA_CHANGED_EVENT = 2820;
|
||||||
@@ -123,9 +126,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
boolean mProvisioned;
|
boolean mProvisioned;
|
||||||
PowerManager.WakeLock mWakelock;
|
PowerManager.WakeLock mWakelock;
|
||||||
final BackupHandler mBackupHandler = new BackupHandler();
|
final BackupHandler mBackupHandler = new BackupHandler();
|
||||||
PendingIntent mRunBackupIntent;
|
PendingIntent mRunBackupIntent, mRunInitIntent;
|
||||||
BroadcastReceiver mRunBackupReceiver;
|
BroadcastReceiver mRunBackupReceiver, mRunInitReceiver;
|
||||||
IntentFilter mRunBackupFilter;
|
|
||||||
// map UIDs to the set of backup client services within that UID's app set
|
// map UIDs to the set of backup client services within that UID's app set
|
||||||
final SparseArray<HashSet<ApplicationInfo>> mBackupParticipants
|
final SparseArray<HashSet<ApplicationInfo>> mBackupParticipants
|
||||||
= new SparseArray<HashSet<ApplicationInfo>>();
|
= new SparseArray<HashSet<ApplicationInfo>>();
|
||||||
@@ -206,6 +208,10 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
private RandomAccessFile mEverStoredStream;
|
private RandomAccessFile mEverStoredStream;
|
||||||
HashSet<String> mEverStoredApps = new HashSet<String>();
|
HashSet<String> mEverStoredApps = new HashSet<String>();
|
||||||
|
|
||||||
|
// Persistently track the need to do a full init
|
||||||
|
static final String INIT_SENTINEL_FILE_NAME = "_need_init_";
|
||||||
|
HashSet<String> mPendingInits = new HashSet<String>(); // transport names
|
||||||
|
boolean mInitInProgress = false;
|
||||||
|
|
||||||
public BackupManagerService(Context context) {
|
public BackupManagerService(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@@ -218,23 +224,32 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
// Set up our bookkeeping
|
// Set up our bookkeeping
|
||||||
boolean areEnabled = Settings.Secure.getInt(context.getContentResolver(),
|
boolean areEnabled = Settings.Secure.getInt(context.getContentResolver(),
|
||||||
Settings.Secure.BACKUP_ENABLED, 0) != 0;
|
Settings.Secure.BACKUP_ENABLED, 0) != 0;
|
||||||
// !!! TODO: mProvisioned needs to default to 0, not 1.
|
|
||||||
mProvisioned = Settings.Secure.getInt(context.getContentResolver(),
|
mProvisioned = Settings.Secure.getInt(context.getContentResolver(),
|
||||||
Settings.Secure.BACKUP_PROVISIONED, 0) != 0;
|
Settings.Secure.BACKUP_PROVISIONED, 0) != 0;
|
||||||
mBaseStateDir = new File(Environment.getDataDirectory(), "backup");
|
mBaseStateDir = new File(Environment.getDataDirectory(), "backup");
|
||||||
mDataDir = Environment.getDownloadCacheDirectory();
|
mDataDir = Environment.getDownloadCacheDirectory();
|
||||||
|
|
||||||
|
// Alarm receivers for scheduled backups & initialization operations
|
||||||
mRunBackupReceiver = new RunBackupReceiver();
|
mRunBackupReceiver = new RunBackupReceiver();
|
||||||
mRunBackupFilter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
mRunBackupFilter.addAction(RUN_BACKUP_ACTION);
|
filter.addAction(RUN_BACKUP_ACTION);
|
||||||
context.registerReceiver(mRunBackupReceiver, mRunBackupFilter);
|
context.registerReceiver(mRunBackupReceiver, filter,
|
||||||
|
android.Manifest.permission.BACKUP, null);
|
||||||
|
|
||||||
|
mRunInitReceiver = new RunInitializeReceiver();
|
||||||
|
filter = new IntentFilter();
|
||||||
|
filter.addAction(RUN_INITIALIZE_ACTION);
|
||||||
|
context.registerReceiver(mRunInitReceiver, filter,
|
||||||
|
android.Manifest.permission.BACKUP, null);
|
||||||
|
|
||||||
Intent backupIntent = new Intent(RUN_BACKUP_ACTION);
|
Intent backupIntent = new Intent(RUN_BACKUP_ACTION);
|
||||||
// !!! TODO: restrict delivery to our receiver; the naive setClass() doesn't seem to work
|
|
||||||
//backupIntent.setClass(context, mRunBackupReceiver.getClass());
|
|
||||||
backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
|
backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
|
||||||
mRunBackupIntent = PendingIntent.getBroadcast(context, MSG_RUN_BACKUP, backupIntent, 0);
|
mRunBackupIntent = PendingIntent.getBroadcast(context, MSG_RUN_BACKUP, backupIntent, 0);
|
||||||
|
|
||||||
|
Intent initIntent = new Intent(RUN_INITIALIZE_ACTION);
|
||||||
|
backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
|
||||||
|
mRunInitIntent = PendingIntent.getBroadcast(context, MSG_RUN_INITIALIZE, initIntent, 0);
|
||||||
|
|
||||||
// Set up the backup-request journaling
|
// Set up the backup-request journaling
|
||||||
mJournalDir = new File(mBaseStateDir, "pending");
|
mJournalDir = new File(mBaseStateDir, "pending");
|
||||||
mJournalDir.mkdirs(); // creates mBaseStateDir along the way
|
mJournalDir.mkdirs(); // creates mBaseStateDir along the way
|
||||||
@@ -287,14 +302,52 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
private class RunBackupReceiver extends BroadcastReceiver {
|
private class RunBackupReceiver extends BroadcastReceiver {
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (RUN_BACKUP_ACTION.equals(intent.getAction())) {
|
if (RUN_BACKUP_ACTION.equals(intent.getAction())) {
|
||||||
if (DEBUG) Log.v(TAG, "Running a backup pass");
|
|
||||||
|
|
||||||
synchronized (mQueueLock) {
|
synchronized (mQueueLock) {
|
||||||
// acquire a wakelock and pass it to the backup thread. it will
|
if (mPendingInits.size() > 0) {
|
||||||
// be released once backup concludes.
|
// If there are pending init operations, we process those
|
||||||
|
// and then settle into the usual periodic backup schedule.
|
||||||
|
if (DEBUG) Log.v(TAG, "Init pending at scheduled backup");
|
||||||
|
try {
|
||||||
|
mAlarmManager.cancel(mRunInitIntent);
|
||||||
|
mRunInitIntent.send();
|
||||||
|
} catch (PendingIntent.CanceledException ce) {
|
||||||
|
Log.e(TAG, "Run init intent cancelled");
|
||||||
|
// can't really do more than bail here
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Don't run backups now if we're disabled, not yet
|
||||||
|
// fully set up, or racing with an initialize pass.
|
||||||
|
if (mEnabled && mProvisioned && !mInitInProgress) {
|
||||||
|
if (DEBUG) Log.v(TAG, "Running a backup pass");
|
||||||
|
|
||||||
|
// Acquire the wakelock and pass it to the backup thread. it will
|
||||||
|
// be released once backup concludes.
|
||||||
|
mWakelock.acquire();
|
||||||
|
|
||||||
|
Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
|
||||||
|
mBackupHandler.sendMessage(msg);
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned
|
||||||
|
+ " i=" + mInitInProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RunInitializeReceiver extends BroadcastReceiver {
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
if (DEBUG) Log.v(TAG, "Running a device init");
|
||||||
|
mInitInProgress = true;
|
||||||
|
|
||||||
|
// Acquire the wakelock and pass it to the init thread. it will
|
||||||
|
// be released once init concludes.
|
||||||
mWakelock.acquire();
|
mWakelock.acquire();
|
||||||
|
|
||||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
|
Message msg = mBackupHandler.obtainMessage(MSG_RUN_INITIALIZE);
|
||||||
mBackupHandler.sendMessage(msg);
|
mBackupHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -408,6 +461,37 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maintain persistent state around whether need to do an initialize operation.
|
||||||
|
// Must be called with the queue lock held.
|
||||||
|
void recordInitPendingLocked(boolean isPending, String transportName) {
|
||||||
|
if (DEBUG) Log.i(TAG, "recordInitPendingLocked: " + isPending
|
||||||
|
+ " on transport " + transportName);
|
||||||
|
try {
|
||||||
|
IBackupTransport transport = getTransport(transportName);
|
||||||
|
String transportDirName = transport.transportDirName();
|
||||||
|
File stateDir = new File(mBaseStateDir, transportDirName);
|
||||||
|
File initPendingFile = new File(stateDir, INIT_SENTINEL_FILE_NAME);
|
||||||
|
|
||||||
|
if (isPending) {
|
||||||
|
// We need an init before we can proceed with sending backup data.
|
||||||
|
// Record that with an entry in our set of pending inits, as well as
|
||||||
|
// journaling it via creation of a sentinel file.
|
||||||
|
mPendingInits.add(transportName);
|
||||||
|
try {
|
||||||
|
(new FileOutputStream(initPendingFile)).close();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// Something is badly wrong with our permissions; just try to move on
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No more initialization needed; wipe the journal and reset our state.
|
||||||
|
initPendingFile.delete();
|
||||||
|
mPendingInits.remove(transportName);
|
||||||
|
}
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// can't happen; the transport is local
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Reset all of our bookkeeping, in response to having been told that
|
// Reset all of our bookkeeping, in response to having been told that
|
||||||
// the backend data has been wiped [due to idle expiry, for example],
|
// the backend data has been wiped [due to idle expiry, for example],
|
||||||
// so we must re-upload all saved settings.
|
// so we must re-upload all saved settings.
|
||||||
@@ -430,7 +514,10 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
|
|
||||||
// Remove all the state files
|
// Remove all the state files
|
||||||
for (File sf : stateFileDir.listFiles()) {
|
for (File sf : stateFileDir.listFiles()) {
|
||||||
sf.delete();
|
// ... but don't touch the needs-init sentinel
|
||||||
|
if (!sf.getName().equals(INIT_SENTINEL_FILE_NAME)) {
|
||||||
|
sf.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue a new backup of every participant
|
// Enqueue a new backup of every participant
|
||||||
@@ -455,6 +542,29 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
if (DEBUG) Log.v(TAG, "Registering transport " + name + " = " + transport);
|
if (DEBUG) Log.v(TAG, "Registering transport " + name + " = " + transport);
|
||||||
mTransports.put(name, transport);
|
mTransports.put(name, transport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the init sentinel file exists, we need to be sure to perform the init
|
||||||
|
// as soon as practical. We also create the state directory at registration
|
||||||
|
// time to ensure it's present from the outset.
|
||||||
|
try {
|
||||||
|
String transportName = transport.transportDirName();
|
||||||
|
File stateDir = new File(mBaseStateDir, transportName);
|
||||||
|
stateDir.mkdirs();
|
||||||
|
|
||||||
|
File initSentinel = new File(stateDir, INIT_SENTINEL_FILE_NAME);
|
||||||
|
if (initSentinel.exists()) {
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
mPendingInits.add(transportName);
|
||||||
|
|
||||||
|
// TODO: pick a better starting time than now + 1 minute
|
||||||
|
long delay = 1000 * 60; // one minute, in milliseconds
|
||||||
|
mAlarmManager.set(AlarmManager.RTC_WAKEUP,
|
||||||
|
System.currentTimeMillis() + delay, mRunInitIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// can't happen, the transport is local
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----- Track installation/removal of packages -----
|
// ----- Track installation/removal of packages -----
|
||||||
@@ -581,6 +691,20 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
(new PerformClearThread(params.transport, params.packageInfo)).start();
|
(new PerformClearThread(params.transport, params.packageInfo)).start();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_RUN_INITIALIZE:
|
||||||
|
{
|
||||||
|
HashSet<String> queue;
|
||||||
|
|
||||||
|
// Snapshot the pending-init queue and work on that
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
queue = new HashSet<String>(mPendingInits);
|
||||||
|
mPendingInits.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
(new PerformInitializeThread(queue)).start();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -907,7 +1031,6 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// can't happen; the transport is local
|
// can't happen; the transport is local
|
||||||
}
|
}
|
||||||
mStateDir.mkdirs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1206,7 +1329,6 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
// can't happen; the transport is local
|
// can't happen; the transport is local
|
||||||
}
|
}
|
||||||
mStateDir.mkdirs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1552,6 +1674,80 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PerformInitializeThread extends Thread {
|
||||||
|
HashSet<String> mQueue;
|
||||||
|
|
||||||
|
PerformInitializeThread(HashSet<String> transportNames) {
|
||||||
|
mQueue = transportNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int status;
|
||||||
|
try {
|
||||||
|
for (String transportName : mQueue) {
|
||||||
|
IBackupTransport transport = getTransport(transportName);
|
||||||
|
if (transport == null) {
|
||||||
|
Log.e(TAG, "Requested init for " + transportName + " but not found");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = BackupConstants.TRANSPORT_OK;
|
||||||
|
File stateDir = null;
|
||||||
|
|
||||||
|
Log.i(TAG, "Device init on " + transport.transportDirName());
|
||||||
|
|
||||||
|
stateDir = new File(mBaseStateDir, transport.transportDirName());
|
||||||
|
|
||||||
|
status = transport.initializeDevice();
|
||||||
|
if (status != BackupConstants.TRANSPORT_OK) {
|
||||||
|
Log.e(TAG, "Error from initializeDevice: " + status);
|
||||||
|
}
|
||||||
|
if (status == BackupConstants.TRANSPORT_OK) {
|
||||||
|
status = transport.finishBackup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Okay, the wipe really happened. Clean up our local bookkeeping.
|
||||||
|
if (status == BackupConstants.TRANSPORT_OK) {
|
||||||
|
resetBackupState(stateDir);
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
recordInitPendingLocked(false, transportName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this didn't work, requeue this one and try again
|
||||||
|
// after a suitable interval
|
||||||
|
if (status != BackupConstants.TRANSPORT_OK) {
|
||||||
|
Log.i(TAG, "Device init failed");
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
recordInitPendingLocked(true, transportName);
|
||||||
|
}
|
||||||
|
// do this via another alarm to make sure of the wakelock states
|
||||||
|
long delay = transport.requestBackupTime();
|
||||||
|
if (DEBUG) Log.w(TAG, "init failed on "
|
||||||
|
+ transportName + " resched in " + delay);
|
||||||
|
mAlarmManager.set(AlarmManager.RTC_WAKEUP,
|
||||||
|
System.currentTimeMillis() + delay, mRunInitIntent);
|
||||||
|
} else {
|
||||||
|
// success!
|
||||||
|
Log.i(TAG, "Device init successful");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// can't happen; the transports are local
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Unexpected error performing init", e);
|
||||||
|
} finally {
|
||||||
|
// Done; indicate that we're finished and release the wakelock
|
||||||
|
synchronized (mQueueLock) {
|
||||||
|
mInitInProgress = false;
|
||||||
|
}
|
||||||
|
mWakelock.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----- IBackupManager binder interface -----
|
// ----- IBackupManager binder interface -----
|
||||||
|
|
||||||
@@ -1694,6 +1890,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
|
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
|
||||||
"setBackupEnabled");
|
"setBackupEnabled");
|
||||||
|
|
||||||
|
Log.i(TAG, "Backup enabled => " + enable);
|
||||||
|
|
||||||
boolean wasEnabled = mEnabled;
|
boolean wasEnabled = mEnabled;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||||
@@ -1707,7 +1905,27 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
startBackupAlarmsLocked(BACKUP_INTERVAL);
|
startBackupAlarmsLocked(BACKUP_INTERVAL);
|
||||||
} else if (!enable) {
|
} else if (!enable) {
|
||||||
// No longer enabled, so stop running backups
|
// No longer enabled, so stop running backups
|
||||||
|
if (DEBUG) Log.i(TAG, "Opting out of backup");
|
||||||
|
|
||||||
mAlarmManager.cancel(mRunBackupIntent);
|
mAlarmManager.cancel(mRunBackupIntent);
|
||||||
|
|
||||||
|
// This also constitutes an opt-out, so we wipe any data for
|
||||||
|
// this device from the backend. We start that process with
|
||||||
|
// an alarm in order to guarantee wakelock states.
|
||||||
|
if (wasEnabled && mProvisioned) {
|
||||||
|
// NOTE: we currently flush every registered transport, not just
|
||||||
|
// the currently-active one.
|
||||||
|
HashSet<String> allTransports;
|
||||||
|
synchronized (mTransports) {
|
||||||
|
allTransports = new HashSet<String>(mTransports.keySet());
|
||||||
|
}
|
||||||
|
// build the set of transports for which we are posting an init
|
||||||
|
for (String transport : allTransports) {
|
||||||
|
recordInitPendingLocked(true, transport);
|
||||||
|
}
|
||||||
|
mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
|
||||||
|
mRunInitIntent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user