88 Commits

Author SHA1 Message Date
Christopher Tate
21ab6a5bdb Disallow concurrent backups; consult transport requestBackupTime()
* We now check for in-progress backups when asked to perform one, and don't
  bother firing off another one concurrently (nor do we adjust the scheduling;
  after all, someone asked to do a backup "now" and we're doing one, so we are
  in line with expectations).  We also defer backup passes while a restore is
  in flight, and abort attempts to perform a restore during a backup pass.

* When a backup attempt fails, we now ask the transport how far in the future we
  should put our retry.  Previously we were simply not bothering to consult with
  the transport, so we would wind up retrying backup while network connectivity
  was known to be down, etc.

Change-Id: Ic7758010b74e06e90c50d46b7b0dd01b17af7c90
2009-09-24 19:54:46 -07:00
Christopher Tate
4cc86e1ae8 Clear the device's data from the transport when backup is disabled
Turning off backup in the Settings UI constitutes an opt-out of the whole
mechanism.  For privacy reasons we instruct the backend to wipe all of the data
belonging to this device when the user does this.  If the attempt fails it is
rescheduled in the future based on the transport's requestBackupTime()
suggestion.  If network connectivity changes prompt the transport to indicate a
backup pass is appropriate "now," any pending init operation is processed before
the backup schedule is resumed.

The broadcasts used internally to the backup manager are now fully protected;
third party apps can neither send nor receive them.

(Also a minor logging change; don't log 'appropriate' EOF encountered during
parsing of a backup data stream.)
2009-09-24 11:19:04 -07:00
Christopher Tate
b03b3bbd68 If backup fails, reenqueue all of the affected packages for next time. 2009-09-22 14:14:10 -07:00
Dan Egnor
313b29faaf Add parameter for the restore set (device id) data is being restored from to the restore_start event 2009-09-22 10:44:10 -07:00
Dan Egnor
0144516e19 Make IBackupTransport.finishBackup() also return an int code, since it too can
return TRANSPORT_NOT_INITIALIZED (in fact that's typically how it comes).

For consistency, make other IBackupTransport methods return int instead of
boolean, and handle accordingly.

Make initializeDevice() its own method instead of a flag on performBackup().
This will be needed when un-checking the settings box anyway, and is
conceptually unrelated to whatever happens to be the first post-initialization
backup we perform.  (Note that even if the init is sent separately from the
backup operation, the server will remember that an init has been done and
will *not* return NOT_INITIALIZED for the subsequent backup.)

Fix LocalTransport accordingly (trivial changes).

Handle failures more robustly in BackupManagerService -- most notably,
doQueuedBackups() was ignoring the result code of processOneBackup(), so
a NOT_INITIALIZED error would go past unseen (at least until the next
backup pass).  Keep track of error code returns more universally now.
(This includes finishBackup(), of course.)
2009-09-21 17:04:05 -07:00
Christopher Tate
d55e18acbe Reset backup tracking in response to transport data-wipe notification
When attempting a backup, the transport may inform us that the backend is in an
uninitialized state.  This typically means that the device's data has been wiped
after a period [e.g. 90 days] of inactivity.  This means that we need to
re-store all data subject to backup, and all of our incremental state tracking
on the device is now stale.

In response, we wipe all of our recorded backup state and restart the backup
pass on all participants.
2009-09-21 10:19:17 -07:00
Christopher Tate
90967f4f0d Fix up the first-backup-ever tracking
This changes a couple of bits of the Backup Manager's logic around
first-backup-ever handling.  First, it uses the same "what we've ever backed up"
handling as the rest of the system for purposes of instructing the backend to do
a wipe when the metadata is initialized for the device, instead of looking at
the presence of the @pm@ file.  Secondly, for the time being we won't be using
the saved state produced by agents' doRestore() logic.  Until the server is
migrating each restored package's data over to the new dataset, this was
resulting in the client holding an agent state blob for which no data existed on
the server under this device's identity but which the device thought was fully
up to date.
2009-09-20 15:33:35 -07:00
Christopher Tate
25a747f5c4 Add an 'init everything' operation to the first backup pass
IBackupTransport.performBackup() now takes a flag "wipeAllFirst", which if set
will result in the entire restore set for the current device/account being wiped
clean prior to the storage of the provided package.  This ensures that a device
on which backup has just been enabled will not confront potentially-stale
information, nor will the restore set potentially contain mismatched data from
orphaned packages.

The Backup Manager has also been revised to pass this flag when first backing up
its master metadata block (and never pass it thereafter unless something has
caused the backup state tracking to be erased, e.g. the user has opted out of
backup and then later re-enabled it).
2009-09-20 12:43:58 -07:00
Dan Egnor
83861e74c3 Inefficient but correct fix for 2122381: call finishBackup after every performBackup 2009-09-17 16:19:02 -07:00
Christopher Tate
b8eb1cb79b Be sure to include shared lib path info when dealing with agents
In particular, this ensures that on the client side the full classpath is known
and used by the class loader during execution of the agent.
2009-09-16 17:58:45 -07:00
Christopher Tate
5e1ab335e6 Expand apps' control over the settings restore process
Applications can now specify two more aspects of the restore process:  whether
they need to run with their own custom Application subclass rather than being
launched in the usual restricted mode during restore, and whether it's okay for
the backup manager to kill the app process once restore has completed.  The new
manifest attributes for these are, respectively, android:restoreNeedsApplication
and android:killAfterRestore.

If unspecified in the manifest, restoreNeedsApplication is false, and
killAfterRestore is true.

In order to support kill-after-restore cleanly, this change also adds a new
system-process-only interface to the Activity Manager, which will schedule a
"commit suicide" event on the target app's main thread looper.

The framework backup agents have been given the appropriate new backup
attributes as well.
2009-09-01 20:59:36 -07:00
Christopher Tate
0749dcd193 Backup participants must now hold the BACKUP_DATA permission
Packages that do not use android.permission.BACKUP_DATA will neither be backed
up nor restored.  That permission is currently signature-only.  In the future if
access to the backup/restore infrastructure is made available to arbitrary 3rd
party applications, the permission checks (and indeed, the permission itself)
can simply be removed.
2009-08-13 15:15:55 -07:00
Christopher Tate
0e0b4ae5bc Don't let bmgr leave a restore session hanging on error
Specifically, don't wait for the RestoreObserver to be informed that the restore
has completed unless performRestore() ran.  We were winding up in a case where
bmgr was hanging forever waiting on a nonexistent restore process instead of
calling endRestoreSession().

Also improve the documentation, explicitly calling out the need to call
endRestoreSession() even if previous operations on the session were
unsuccessful.
2009-08-11 17:25:12 -07:00
Christopher Tate
f2c321aeff Print restore tokens in hex 2009-08-10 15:43:36 -07:00
Amith Yamasani
2e6bca6901 Temporarily rollback a change that's causing SetupWizard failures during restore. #2042337
Don't kill the process of the package that's being restored. This is causing a chain
reaction of killing a provider needed by the setup process.
2009-08-07 20:28:33 -07:00
Christopher Tate
9dfdac5b08 Clear app data via the Activity Manager, not Package Manager
This is because doing it through the Activity Manager also makes sure that the
app has been shut down first, which is quite a desirable invariant for restore
handling.
2009-08-06 14:57:53 -07:00
Christopher Tate
aa93b0418f Correct the backup manager's identity around wakelock use 2009-08-05 18:21:40 -07:00
Christopher Tate
dfec20b10b Bootstrap the ever-backed-up bookkeeping properly 2009-08-04 10:45:37 -07:00
Dan Egnor
0084da561e Allow zero-length lists in EventLog entries.
(I'm verifying that the consumers of EventLog -- logcat, checkin -- are OK with this.)
Improve the error handling in RestoreSession.
2009-07-29 12:57:16 -07:00
Dan Egnor
bb9001c69a clean up error recovery; log events tracking backup activity 2009-07-27 17:48:50 -07:00
Joe Onorato
ab9a2a52c5 Backup manager should default to not "provisioned" so backups don't start until the setup wizard is
done.
2009-07-27 08:56:39 -07:00
Christopher Tate
1531dc80e6 Don't leave restore data lying around after the operation 2009-07-24 16:37:43 -07:00
Joe Onorato
5933a49722 Need to be able to call the backup manager from the system process. 2009-07-23 18:29:27 -04:00
Christopher Tate
9673304964 Clean up when an attempted restore throws
When a restore agent throws an exception back into the framework, assume that it
may have left the app's data in an inconsistent state and clear the data for
that app (again -- it was cleared just prior to the attempted restore, too).
2009-07-20 14:49:13 -07:00
Christopher Tate
e97e807a46 The rest of ever-backed-up tracking
When a package is uninstalled we now remove our notion of its having been backed
up, thereby forcing a backup pass if it is reinstalled at some point in the
future.  Removal from the log means rewriting it and doing an atomic rename to
the canonical version.  The temporary existence used during the rewrite is *not*
written synchronously; there's no need and it keeps the load on the flash part
much lower.

Because we might crash & reboot in the middle of the rewrite operation, there's
now code during init that sanity-checks the contents of the ever-backed-up log
and ensures that it's in a coherent state.
2009-07-15 16:50:24 -07:00
Christopher Tate
73e025296f Ensure that everything gets backed up at least once
We now schedule a backup pass for any new application we see (at boot or
package-install time) for which we have never performed a backup.  The
bookkeeping is a log file with the names of all the packages we've successfully
completed a backup pass on, maintained with synchronous journal-type behavior.

Also, make a bunch of private fields package-scoped to permit cheaper access
from the various worker / binder threads that run under the Backup Manager's
aegis.
2009-07-15 14:18:26 -07:00
Christopher Tate
de83ab9fce Grant adb the BACKUP permission
This also means we should no longer do explicit calling-identity fiddling in
dump(), relying instead on the usual permission enforcement mechanism to handle
things.
2009-07-14 15:38:07 -07:00
Christopher Tate
433830452d Don't NPE if a restore session is requested for an invalid transport 2009-07-13 15:17:13 -07:00
Christopher Tate
b407f22c9d Don't invoke the transport if doBackup supplied no data
If there's no data to be backed up, we no longer invoke the transport.  We *DO*
still require that the agent have emitted a valid new state file, however.

This change also finally uncomments the code that removes the backup data file
after it has been sent to the transport, so there will be no more
packagename.data files lying around in the staging area.
2009-07-08 13:52:50 -07:00
Christopher Tate
22b60d8fd0 Remove a lot of debug-log verbosity
We now log in dataChanged() only when an app is added to the backup set (and
*not* if it redundantly asks to be added after it's already there) and on error.
2009-07-07 16:36:02 -07:00
Christopher Tate
a7de384550 Only write to the pending-backup journal when necessary
We now only commit to the pending-backup journal on disk the first time that a
given package is added to the backup set.  This avoids a lot of write thrashing
of the disk, particularly since Settings tends to call dataChanged() a great
many times during boot, while the Settings UI is in use, etc.
2009-07-07 14:50:26 -07:00
Christopher Tate
3d7cd13e77 Fix the metadata-available test during restore 2009-07-07 14:23:07 -07:00
Christopher Tate
8031a3df2f Make enable/provisioning of the backup service a two-step process
This CL adds the concept of 'provisioned' to the backup manager.  No backups
will be scheduled until the user has indicated that backups are to be enabled
*and* has clicked all the way through the setup wizard.

When the user first turns on the backup system, the delay before the initial
backup pass is different from the periodic backup interval.  Currently that
initial delay is 12 hours.  The intent here is to guess at a less-active time
for performing that first backup pass.

NOTE: currently the backup service defaults to 'provisioned'.  Once the real
code goes live in Setup Wizard, this will be changed to default to
not-provisioned until the user has confirmed all the relevant UI.
2009-07-06 17:43:03 -07:00
Christopher Tate
34ebd0e1bb Fix up permissions for 'dumpsys backup' 2009-07-06 15:44:54 -07:00
Christopher Tate
b6787f2ee5 Hold a wakelock during backup/restore/clear operations
We need to make sure we stay alive for the duration of a backup or (especially)
restore operation.  The existing Handler-based timing system was simply not
properly functional, so it's been retooled to use a repeating alarm delivering a
broastcast PendingIntent to our registered receiver.

We acquire a partial wake lock in the broadcast receiver [i.e. while the Alarm
Manager is holding one for the duration of broadcast delivery] and pass the
wakelock object to the backup thread, which eventually releases it when it's
finsihed operations.  A similar pattern is used for the threads handling restore
and clear.
2009-07-06 11:49:49 -07:00
Christopher Tate
8c0324752a If we can't get the restore set's metadata, don't continue
Without the metadata we can't verify the version number or the signatures of the
apps whose data we'd be trying to restore against the apps present on device.
This is not acceptable; we need to refuse to give data to an unauthenticated
app.
2009-07-02 14:28:47 -07:00
Christopher Tate
4e3e50cfa7 Clean up the last two literal permission string usages 2009-07-02 12:14:05 -07:00
Christopher Tate
ee0e78af5a Add a "clear backed-up data" method to the backup mechanism
It's now possible to ask that the backup manager wipe the saved data for a given
application from the backing store.  LocalTransport implements this now but the
Google backend does not yet.  When the data is wiped, the on-device backup state
is also wiped to ensure that the next backup pushes all necessary data.

Bmgr has not yet been modified to actually call into this method, but it will
be soon.
2009-07-02 11:30:29 -07:00
Dianne Hackborn
cf098294da Move backup state to settings, change permission checks to use symbol.
This changes the backup service to use the settings provider instead
of system properties, correspondingly making it off by default and
allowing specific devices to define the transport.  Also tweaks
the permission checks to use the permission symbol instead of raw
strings.

This requires some corresponding changes in the vendor projects.
2009-07-01 20:12:36 -07:00
Joe Onorato
9a5e3e115f Less logging in some places. More in others. 2009-07-01 21:04:03 -04:00
Christopher Tate
49401ddb9a Revamp backup scheduling policy
We now schedule a periodic check of pending backups; if any apps have requested
a backup since the last check, we perform all of the pending backups.  The
periodic backup scheduling matches the enable/disable state of the backup
manager; while backups are disabled entirely there are no periodic wakeups.

The period is set here to one hour.  If an external caller (transport, the
'bmgr' command line tool, etc) requests an immediate backup pass, that is
performed and then the periodic backup check is rescheduled using that pass as
the starting point of a new interval.
2009-07-01 12:38:06 -07:00
Christopher Tate
ce0bf069fe Use secure settings for backup enable / transport selection 2009-07-01 11:45:57 -07:00
Christopher Tate
7958834e0e Run backups at background priority 2009-06-30 16:11:49 -07:00
Christopher Tate
6ef58a1509 Implement persistent enable/disable of the backup manager
Backup & restore is still enabled by default, but with the expectation that it
will be enabled during the course of the Setup Wizard or some other privileged
entity that has notified the user about the ramifications.  While disabled,
data-changed notices will still be collected, but no backup pass will be
scheduled.  When the backup manager is later enabled, any pending data-changed
notices will then be processed and the apps invoked for backup.
2009-06-29 15:33:27 -07:00
Christopher Tate
9171749700 Use system properties to track the current transport
This change retools the transport selection mechanism a fair bit.  Transports
are now specified by name rather than by numeric ID, and the name of the
currently selected transport is stored in a persistent system property under the
name "persist.service.bkup.trans".

The name -> IBackupTransport translation is now handled by maintaining a map
from the names to the live IBackupTransport objects that correspond.  The Google
transport service observer now registers and unregisters the transport as the
service goes up and down.

The bmgr command has been expanded to include real transport interrogation and
selection by name, and some documentation has been written for it.
2009-06-26 21:14:41 -07:00
Christopher Tate
f7c886b4fe Respect android:allowClearUserData=false during restore
Ordinarily we wipe the data of apps we are restoring.  This is problematic for
packages that expect that their data can never be wiped back to nothing,
especially system packages, so we now respect the android:allowClearUserData
manifest attribute.
2009-06-26 15:34:09 -07:00
Christopher Tate
466ef345d1 Trim some superfluous imports. 2009-06-26 14:41:57 -07:00
Dan Egnor
156411df46 Use a long for restore token 2009-06-26 13:25:27 -07:00
Christopher Tate
7d562ec393 Add a new IRestoreObserver callback class to the restore process
The observer is told when restore begins how many packages are being restored.
It then gets an onUpdate() call telling it that the Nth package is now
undergoing restore.  Ultimately, its restoreFinished() callback is invoked,
passing a simple success/fail error code, to let it know that the restore
operation has concluded.
2009-06-25 18:09:28 -07:00
Christopher Tate
5cb400bd72 Keep track of backup state independently for each transport
Backup transports now provide the Backup Manager with a suggested name with
which it can disambiguate any transport-specific bookkeeping that it needs to
maintain.  The Manager keeps separate application backup 'state blobs' for each
transport now, preventing things from getting out of step if the device is
switched among multiple transports.

Also, the metadata backup agent is always invoked now on each backup pass.  This
is cheap when there is nothing to do, but also strongly ensures that we never
wind up in a situation where a given transport destination has not been given
all of the metadata necessary for the backup set.
2009-06-25 16:09:03 -07:00