)]}'
{
  "log": [
    {
      "commit": "fbec21ff43c8a35e95fca9ce40351350608974e9",
      "tree": "24d58d1fa567fb10682da017b5acdb3693a3e81b",
      "parents": [
        "2f8d4ea2064940b373c96b47d6fcdefad3732ee8"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Nov 13 16:36:33 2014 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Nov 13 16:39:56 2014 -0800"
      },
      "message": "Teach bmgr that \"android\" is a valid package name\n\nBug 18379037\n\nChange-Id: I4d6da2893f83e672920bbda9447aa4cbd1ecec7b\n"
    },
    {
      "commit": "ab225b301b8b13a141053a33d5dd5eeccfc69887",
      "tree": "e79e890866f6002fb9656ade335cc6bd4b31d812",
      "parents": [
        "7218e9c6beaa066237c6b2aac6d10dd7dc84e0a2"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 24 16:28:48 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 24 16:52:09 2014 -0700"
      },
      "message": "Add \u0027fullbackup\u0027 to bmgr\u0027s usage statement\n\nAlso make it handle the list of packages to be backed up as a single\nmultiple-app argument to fullTransportBackup() rather than N calls\neach backing up one app.\n\nChange-Id: I9fe4d5caca54fafef70ffe9af4c26e3941dc5d26\n"
    },
    {
      "commit": "9ff53a7100b1a40f5d2df3eb19a2f3f2fff39a46",
      "tree": "162c23a51e116f9506e7d6801236dd2e2c8f3788",
      "parents": [
        "ad60891a6ecaf2a5815677b33e96afe7f49ee113"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 03 17:20:07 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Sun Jun 15 17:35:33 2014 -0700"
      },
      "message": "Implement full data backup through transport\n\nCurrently no timed/scheduled full-data backup operations are\nperformed by the OS, but the plumbing is now in place and can\nbe tested using \u0027adb shell bmgr fullbackup pkg [pkg2 pkg3 ...]\u0027.\n\nThe LocalTransport test transport implementation has been augmented\nto support the new full-data backup API as well.\n\nIn addition, \u0027adb backup\u0027 now takes the -compress/-nocompress\ncommand line options to control whether the resulting archive is\ncompressed before leaving the device.  Previously the archive was\nalways compressed.  (The default is still to compress, as it will\nusually reduce the archive size considerably.)\n\nInternally, the core implementation of gathering the full backup\ndata stream from the target application has been refactored into\nan \"engine\" component that is shared by both \u0027adb backup\u0027 and the\ntransport-oriented full backup task.  The archive file header\ngeneration, encryption, and compression logic are now factored out\nof the engine itself instead of being hardwired into the data\nhandling.\n\nBug 15329632\n\nChange-Id: I4a044faa4070d684ef457bd3e11771198cdf557c\n"
    },
    {
      "commit": "b0183f0ae311966cff0e10e8139c56f97288d1f2",
      "tree": "6bd0662fd8d6b0640b2da0c293882b47ff9480e6",
      "parents": [
        "c04aa87e4ac41b6c65dceb7b20d7a7f92c2efec1"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Nov 18 14:20:36 2013 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Nov 19 11:24:46 2013 -0800"
      },
      "message": "Harden against transiently unavailable backup transports\n\nThe init \u0026 clear operations are particularly important to ensure\ndelivery when at all possible, so we retry those periodically\nif the transport is unavailable when we first attempt them.\n\nNow with 100% less build break.\n\nBug 11716868\n\nChange-Id: I2af4e93788068cfac97c0a48d3568c561eefa23d\n"
    },
    {
      "commit": "d5965cb506bde84612109bf26c3fcc6712ca91e5",
      "tree": "a679a23ee7ab71d8e14aac8edcc99cb08defc408",
      "parents": [
        "8f98252afea3fd0e68693635ec21b6004a52fa69"
      ],
      "author": {
        "name": "Sascha Prueter",
        "email": "saschap@google.com",
        "time": "Tue Nov 19 06:51:21 2013 +0000"
      },
      "committer": {
        "name": "Sascha Prueter",
        "email": "saschap@google.com",
        "time": "Tue Nov 19 06:51:21 2013 +0000"
      },
      "message": "Trying to unbreak build...\n\nRevert \"Harden against transiently unavailable backup transports\"\n\nThis reverts commit 8f98252afea3fd0e68693635ec21b6004a52fa69.\n\nChange-Id: I3aabb80f1a5932d530bce6b82d4b30c6cd1cdd5a\n"
    },
    {
      "commit": "8f98252afea3fd0e68693635ec21b6004a52fa69",
      "tree": "ae1c473590c0a9d1c2022376f047f88151e3db7a",
      "parents": [
        "245408d29018fee4b1231e52f5da1edcc3283c4a"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Nov 18 14:20:36 2013 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Nov 18 16:12:38 2013 -0800"
      },
      "message": "Harden against transiently unavailable backup transports\n\nThe init \u0026 clear operations are particularly important to ensure\ndelivery when at all possible, so we retry those periodically\nif the transport is unavailable when we first attempt them.\n\nBug 11716868\n\nChange-Id: I4860fe3d4e99618b2cd194c83162bd7cbd5a83a9\n"
    },
    {
      "commit": "284f1bb4daf77f7e6b688c0936dd4a31ec2e7c74",
      "tree": "d651aa41ee14b9137285163166b391badfe4cbe2",
      "parents": [
        "1d19c18f9bd66b2b4883f8ce33c04ff5c87dd881"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 07 14:31:18 2011 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jul 08 12:28:48 2011 -0700"
      },
      "message": "Can now restore a subset of apps from historical dataset\n\nAdds the ability to filter a restore of an historical dataset so that it\nonly restores certain apps\u0027 data regardless of what is actually present\nin the dataset.  This is currently only used by the bmgr command-line tool,\nfor debugging / developer support.\n\nBug 2021590\n\nChange-Id: I7685e5d609b0f5506f71d70c26410602bb387659\n"
    },
    {
      "commit": "4a627c71ff53a4fca1f961f4b1dcc0461df18a06",
      "tree": "270190b1e030424210b6375ca886c45db10c4fb6",
      "parents": [
        "2bb51bb203c117649db10ad8bd497f199ca797b0"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Apr 01 14:43:32 2011 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue May 10 17:52:51 2011 -0700"
      },
      "message": "Full local backup infrastructure\n\nThis is the basic infrastructure for pulling a full(*) backup of the\ndevice\u0027s data over an adb(**) connection to the local device.  The\nbasic process consists of these interacting pieces:\n\n1. The framework\u0027s BackupManagerService, which coordinates the\n   collection of app data and routing to the destination.\n\n2. A new framework-provided BackupAgent implementation called\n   FullBackupAgent, which is instantiated in the target applications\u0027\n   processes in turn, and knows how to emit a datastream that contains\n   all of the app\u0027s saved data files.\n\n3. A new shell-level program called \"bu\" that is used to bridge from\n   adb to the framework\u0027s Backup Manager.\n\n4. adb itself, which now knows how to use \u0027bu\u0027 to kick off a backup\n   operation and pull the resulting data stream to the desktop host.\n\n5. A system-provided application that verifies with the user that\n   an attempted backup/restore operation is in fact expected and to\n   be allowed.\n\nThe full agent implementation is not used during normal operation of\nthe delta-based app-customized remote backup process.  Instead it\u0027s\nused during user-confirmed *full* backup of applications and all their\ndata to a local destination, e.g. via the adb connection.\n\nThe output format is \u0027tar\u0027.  This makes it very easy for the end\nuser to examine the resulting dataset, e.g. for purpose of extracting\nfiles for debug purposes; as well as making it easy to contemplate\nadding things like a direct gzip stage to the data pipeline during\nbackup/restore.  It also makes it convenient to construct and maintain\nsynthetic backup datasets for testing purposes.\n\nWithin the tar format, certain artificial conventions are used.\nAll files are stored within top-level directories according to\ntheir semantic origin:\n\napps/pkgname/a/  : Application .apk file itself\napps/pkgname/obb/: The application\u0027s associated .obb containers\napps/pkgname/f/  : The subtree rooted at the getFilesDir() location\napps/pkgname/db/ : The subtree rooted at the getDatabasePath() parent\napps/pkgname/sp/ : The subtree rooted at the getSharedPrefsFile() parent\napps/pkgname/r/  : Files stored relative to the root of the app\u0027s file tree\napps/pkgname/c/  : Reserved for the app\u0027s getCacheDir() tree; not stored.\n\nFor each package, the first entry in the tar stream is a file called\n\"_manifest\", nominally rooted at apps/pkgname.  This file contains some\nmetadata about the package whose data is stored in the archive.\n\nThe contents of shared storage can optionally be included in the tar\nstream. It is placed in the synthetic location:\n\nshared/...\n\nuid/gid are ignored; app uids are assigned at install time, and the\napp\u0027s data is handled from within its own execution environment, so\nwill automatically have the app\u0027s correct uid.\n\nForward-locked .apk files are never backed up.  System-partition\n.apk files are not backed up unless they have been overridden by a\npost-factory upgrade, in which case the current .apk *is* backed up --\ni.e. the .apk that matches the on-disk data.  The manifest preceding\neach application\u0027s portion of the tar stream provides version numbers\nand signature blocks for version checking, as well as an indication\nof whether the restore logic should expect to install the .apk before\nextracting the data.\n\nSystem packages can designate their own full backup agents.  This is\nto manage things like the settings provider which (a) cannot be shut\ndown on the fly in order to do a clean snapshot of their file trees,\nand (b) manage data that is not only irrelevant but actively hostile\nto non-identical devices -- CDMA telephony settings would seriously\nmess up a GSM device if emplaced there blind, for example.\n\nWhen a full backup or restore is initiated from adb, the system will\npresent a confirmation UI that the user must explicitly respond to\nwithin a short [~ 30 seconds] timeout.  This is to avoid the\npossibility of malicious desktop-side software secretly grabbing a copy\nof all the user\u0027s data for nefarious purposes.\n\n(*) The backup is not strictly a full mirror.  In particular, the\n    settings database is not cloned; it is handled the same way that\n    it is in cloud backup/restore.  This is because some settings\n    are actively destructive if cloned onto a different (or\n    especially a different-model) device: telephony settings and\n    AndroidID are good examples of this.\n\n(**) On the framework side it doesn\u0027t care that it\u0027s adb; it just\n    sends the tar stream to a file descriptor.  This can easily be\n    retargeted around whatever transport we might decide to use\n    in the future.\n\nKNOWN ISSUES:\n\n* the security UI is desperately ugly; no proper designs have yet\n  been done for it\n* restore is not yet implemented\n* shared storage backup is not yet implemented\n* symlinks aren\u0027t yet handled, though some infrastructure for\n  dealing with them has been put in place.\n\nChange-Id: Ia8347611e23b398af36ea22c36dff0a276b1ce91\n"
    },
    {
      "commit": "44ab8453e1c4c46790f792a46d026fa1017d8cfe",
      "tree": "9c499e6c6c1c894bd00c203e8ce6f815cf580187",
      "parents": [
        "64f1163084433952766eed31dbd26df420ba6cfb"
      ],
      "author": {
        "name": "Chris Tate",
        "email": "ctate@google.com",
        "time": "Tue Nov 16 15:10:49 2010 -0800"
      },
      "committer": {
        "name": "Chris Tate",
        "email": "ctate@google.com",
        "time": "Tue Nov 16 16:57:29 2010 -0800"
      },
      "message": "Permission fix: don\u0027t require BACKUP perm for self-restores\n\nThe public API is not supposed to require the BACKUP permission in order\nfor an application to restore its own last-known-good backup data.  However,\nas currently implemented, BackupManager.requestRestore() [the public API\nin question] depends on private Backup Manager methods that *do* enforce\nthat permission.  The net result is that the method cannot be successfully\nused by third party applications: it will throw an exception if attempted.\nThis CL restructures the permission checking involved.\n\nFirst, the underlying beginRestoreSession() operation can now be passed a\n\u0027null\u0027 transport name; if this is done, then the restore session is begun\non whatever the currently-active transport is.  Looking up the name of the\nactive transport is one of the permission-guarded actions that was required\nwith the initial implementation.\n\nSecond, a package name can now be passed to beginRestoreSession().  If\nthis is done, then the restore session can only be used to perform a\nsingle-package restore of that one application.  The BACKUP permission is\nnot required if the caller is tying the restore to its own package name.\n\nIn combination, these changes permit BackupManager.requestRestore() to\nfunction without the calling app needing to hold any special permission.\nThe no-permission case is intentionally quite narrow:  the caller must\nhold the permission unless they both (a) pass \u0027null\u0027 for the transport\nname, thereby accepting whatever the currently active transport is, and\n(b) pass their own package name to restrict the restore session only\nto their own app.\n\nExternal bug http://code.google.com/p/android/issues/detail?id\u003d10094\nInternal bug 3197202\n\nChange-Id: Ibc9d652323f2da03727d850f991b4096af6520d2\n"
    },
    {
      "commit": "7a0fc8776782a18374ec6e3b4418027c3c685b1a",
      "tree": "10c6de4405abf313c3d13cefbfd627e4d5090e60",
      "parents": [
        "de4077487dc32b3b00ec76f8f8ef11a02cccd0f2"
      ],
      "author": {
        "name": "Chris Tate",
        "email": "ctate@google.com",
        "time": "Mon Nov 01 15:50:35 2010 -0700"
      },
      "committer": {
        "name": "Chris Tate",
        "email": "ctate@google.com",
        "time": "Mon Nov 01 15:50:35 2010 -0700"
      },
      "message": "Don\u0027t crash bmgr if there are no available restore sets\n\nProperly guard against a null set of available restore sets when\nvalidating the token passed to \u0027bmgr restore TOKEN\u0027 against what\u0027s\nknown to exist on the backend.\n\nFixes bug 3153986\n\nChange-Id: I74bdd4c6242f682833c1633baa4fefccb2b165a7\n"
    },
    {
      "commit": "04686f428995fde3f6f5f5f12ccdd135f885ac84",
      "tree": "16d3da40249f7a0463b305c5aea2e0106ffe193b",
      "parents": [
        "f01a873029641da2155ca1882f311d8f4e92675a"
      ],
      "author": {
        "name": "Fabrice Di Meglio",
        "email": "fdimeglio@google.com",
        "time": "Fri Oct 01 11:16:10 2010 -0700"
      },
      "committer": {
        "name": "Fabrice Di Meglio",
        "email": "fdimeglio@google.com",
        "time": "Fri Oct 01 11:16:10 2010 -0700"
      },
      "message": "Fix bug #3055578 (\"adb shell bmgr list sets\" generates NPE and cannot be run again when device has no account setup)\n\n- fix NPE\n- code cleaning\n\nChange-Id: Ieb30b666d995de8cbd27ee6d17e2178e7ea670f6\n"
    },
    {
      "commit": "7e76ff1c409bc22e89ed09ef90161164dae40838",
      "tree": "fdb5a34ac33b3c79228bd3fb080deb396814ff7b",
      "parents": [
        "55f8209da3048768a6dc24929dec8798e8ddf077"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Jun 09 12:21:31 2010 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Jun 09 12:21:31 2010 -0700"
      },
      "message": "Fail gracefully if the user fails to supply necessary args to bmgr\n\nFixes bug #2755355\n\nChange-Id: I4690756bb5077a6b4bbbfb232cd852cad43cef77\n"
    },
    {
      "commit": "1398e27bb0f5768cbbd5b9d9fd7c8675da63ccb0",
      "tree": "91eea1fbb15f2e7a96df53d2268aa62867a81039",
      "parents": [
        "fede9aed2b1f0b6316e18cbfa58be593fa7eb14c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Apr 06 12:17:12 2010 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Apr 06 12:17:46 2010 -0700"
      },
      "message": "Fix \u0027bmgr restore\u0027\n\nZero means success.  Fixes bug #2573785\n\nChange-Id: I11bd4d85aa2b3a061aa37e085790ee8cd52d50a2\n"
    },
    {
      "commit": "2d449afe3d075020bdd1115bcc15c9383cbce122",
      "tree": "d7c71c9a74e317319de947f3e3fe3ee673f0c559",
      "parents": [
        "ae405d56215e4ab43e8210b66e741a0bf9d5edcf"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Mar 29 19:14:24 2010 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Mar 30 12:42:35 2010 -0700"
      },
      "message": "Make RestoreSession.getAvailableRestoreSets() asynchronous\n\nThis transaction can involve the transport having to query a remote backend\nover the wire, so it can take a Long Time(tm).  Make it main-thread-safe by\nmaking it asynchronous, with the results passed as a callback to the invoker\u0027s\nRestoreObserver.  We also make the IRestoreObserver callback interface\nproperly oneway.\n\nBug #2550665\nBug #2549422\n\nChange-Id: If18a233a0a3d54c7b55101715c9e6195b762c5a0\n"
    },
    {
      "commit": "9c3cee9824026764275e4d84ba9b5d9fdc5da690",
      "tree": "a68cba5a6d4dc4dc747c4089a2426dcfe5550b77",
      "parents": [
        "a3de74555120cc4dc205a3f93ef44c843b8d64a8"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Mar 25 16:06:43 2010 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Mar 26 14:26:44 2010 -0700"
      },
      "message": "API CHANGE: Backup/restore API changes requested by the API Council\n\n* @hide the android.app.backup.RestoreSession class and functionality\n\n* Provide a public method on android.app.backup.BackupManager that apps\n  can use to request a restore pass of their last-known-good dataset.\n  The new method is called requestRestore().\n\n* Provide the name of the package being restored, not just its ordinal,\n  in the RestoreObserver\u0027s onUpdate() callback.\n\nPart of bug #2545514\n\nChange-Id: I9689bf8d6e2b808b4ee412424a36a835be0a5ca8\n"
    },
    {
      "commit": "4528186e0d65fc68ef0dd1941aa2ac8aefcd55a3",
      "tree": "3f1276aef1448aad75a0d44ad1abbbd1478a4937",
      "parents": [
        "931bf89d327ecf07301231fd86b17deac535feaa"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Mar 05 15:46:30 2010 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Mar 05 16:27:15 2010 -0800"
      },
      "message": "Refactor android.backup \u003d\u003e android.app.backup\n\nChange-Id: I0b21316ff890d7f3c7d4b82837bb60670724c2e8\n"
    },
    {
      "commit": "485c3a16cef38136a821e79a5fe37df4e1779d28",
      "tree": "b8c6d546e9bb365c347ffc0f936a1f18e5ab2f3a",
      "parents": [
        "4a3c3b23d0aa87a68088976b4f397be116cd2338"
      ],
      "author": {
        "name": "Christian Sonntag",
        "email": "cxs@google.com",
        "time": "Thu Mar 04 14:59:04 2010 -0800"
      },
      "committer": {
        "name": "Christian Sonntag",
        "email": "cxs@google.com",
        "time": "Thu Mar 04 14:59:04 2010 -0800"
      },
      "message": "fix hex parsing of bmgr\n"
    },
    {
      "commit": "7d411a3b947ba82d1d57f73c0fa698c3b9c95892",
      "tree": "9fae7c4860733aaa126af64ab433c98665ff2819",
      "parents": [
        "4c904a3bf3dbe98607b5e3f706ee8ef8887ee104"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Feb 26 11:27:08 2010 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Feb 26 12:45:22 2010 -0800"
      },
      "message": "Add single-package restore to Bmgr feature set\n\nAlso sanity-check the package name on the Backup Manager side, failing gracefully\nif the given package is not a backup/restore participant.\n\nBug: 2293977\n\nChange-Id: I3575046ffcaa3cf45c1c602824baeadd64082f70\n"
    },
    {
      "commit": "8472581aa32eee1368de379c2c079ea0a66baa3c",
      "tree": "c7e71e08b7e465fa710c7e0903b8a2a74cce6fc4",
      "parents": [
        "348f7b904851e3edcf09b8362406ff2f4ae57db2"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Feb 04 15:52:40 2010 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Feb 04 16:01:09 2010 -0800"
      },
      "message": "Add single-package restore from an app\u0027s most-recent data\n\nRenamed the RestoreSession performRestore() method to restoreAll(), and\nadded a new restorePackage() method that only restores the single\nspecified app.  In order to restore an app other than itself, the\ncaller must hold the android.permission.BACKUP permission.\n\nThis change also introduces dataset tracking:  the Backup Manager\npersistently remembers both the current backup dataset\u0027s identity\nand that of the \"ancestral\" dataset, i.e. the one most recently used\nfor a whole-device restore such as performed by SetupWizard.  When a\nsingle package is restored via restorePackage(), the selection of\nmost-recent dataset to use is this:\n\n1. The data from the currently-active backup dataset, if such exists.\n   An app that has ever backed up data will therefore get its last-\n   known-good data.\n\n2. The app\u0027s data from the ancestral dataset, if such exists.  This\n   covers the case of a factory reset followed by reinstallation of\n   an app at a later time.  The app had not yet backed anything up\n   post-wipe, but the old data is in the ancestral dataset and should\n   be brought forward when the app reappears.\n\n3. If neither 1. nor 2. exist, there is no data to restore, so just\n   skip it and return failure.\n\nNote that the infrastructure to automatically attempt a restore after\nan application has been installed does not yet exist; that\u0027s coming.\n\nChange-Id: I0ba170df9885128000c46ed28d3dddda3a63a143\n"
    },
    {
      "commit": "0e0b4ae5bc5c652c8339d71ed9667e1e37baaa03",
      "tree": "42fa43521b6d394421d9f93f8191da457876ec63",
      "parents": [
        "a1cbccd7b31f3c33ea46b7fe2a287168eb672056"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Mon Aug 10 16:13:47 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Tue Aug 11 17:25:12 2009 -0700"
      },
      "message": "Don\u0027t let bmgr leave a restore session hanging on error\n\nSpecifically, don\u0027t wait for the RestoreObserver to be informed that the restore\nhas completed unless performRestore() ran.  We were winding up in a case where\nbmgr was hanging forever waiting on a nonexistent restore process instead of\ncalling endRestoreSession().\n\nAlso improve the documentation, explicitly calling out the need to call\nendRestoreSession() even if previous operations on the session were\nunsuccessful.\n"
    },
    {
      "commit": "84780f56f441deb4ff736987986daeaf64db17a4",
      "tree": "8bfa903dfd7770403b27f0a2e4fdacc33fcd8e01",
      "parents": [
        "b99ab30cbc98ec38d514bbd11197a6abf1c104b5"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Fri Aug 07 15:40:35 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Fri Aug 07 15:50:02 2009 -0700"
      },
      "message": "Don\u0027t crash if the Backup Manager returns a null RestoreSet[]\n"
    },
    {
      "commit": "77095d49f203eed6a6742f2605ca319e7360af32",
      "tree": "ba5d5cd0606f9a2ca58bffaa76ba42be16f86954",
      "parents": [
        "02d34e78f4de20fc05831c22a771fffc645c5953"
      ],
      "author": {
        "name": "Christian Sonntag",
        "email": "cxs@android.com",
        "time": "Fri Aug 07 11:16:05 2009 -0700"
      },
      "committer": {
        "name": "Christian Sonntag",
        "email": "cxs@android.com",
        "time": "Fri Aug 07 13:42:45 2009 -0700"
      },
      "message": "make restore tokens shown in hex.\n\nSince they are android ids, it is much easier to use them as hex, since we can just copy then into android inspector and learn more about the restore set.\n"
    },
    {
      "commit": "08e40b858e8a3266c5519a83fda6f7505f1c14db",
      "tree": "1d88e375aa6d464e0f221e86429a0909dec0569c",
      "parents": [
        "8851e163fc5bc17d139bf29cd2ec2f3926d342bc"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Fri Aug 07 11:35:35 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Fri Aug 07 11:35:35 2009 -0700"
      },
      "message": "Fix Bmgr\u0027s logic around restore completion\n\nThe caller needs to wait for the restore observer to be informed that the\nrestore has finished processing before it can safely shut down the restore\nsession.\n"
    },
    {
      "commit": "d23d7f2d12c20314e1e8ff206fafc8f21745ca2d",
      "tree": "4b640ba80d1820d59aea0b53fd49da8f12869d7a",
      "parents": [
        "e15df4017c3625de700e9f9953073f38898bbc89"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 02 14:37:05 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 02 14:37:50 2009 -0700"
      },
      "message": "Add a \u0027wipe\u0027 operation to Bmgr\n\n\"bmgr wipe PACKAGE\" now issues the backup transport clearBackupData() operation\nfor the given package.\n"
    },
    {
      "commit": "6ef58a1509b9d3348a33ca5686917796c2759aa5",
      "tree": "0cdfef7bf8e2085dc2888c4222aba7481683ee2f",
      "parents": [
        "3a608f829b54a7653c9cc2b3bdbda0641cca37bb"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 29 14:56:28 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 29 15:33:27 2009 -0700"
      },
      "message": "Implement persistent enable/disable of the backup manager\n\nBackup \u0026 restore is still enabled by default, but with the expectation that it\nwill be enabled during the course of the Setup Wizard or some other privileged\nentity that has notified the user about the ramifications.  While disabled,\ndata-changed notices will still be collected, but no backup pass will be\nscheduled.  When the backup manager is later enabled, any pending data-changed\nnotices will then be processed and the apps invoked for backup.\n"
    },
    {
      "commit": "9171749700853305f3e6abbcdbd9e02f3a71d459",
      "tree": "7aaa1fada6783a588d1662165730e8d3f4ef591c",
      "parents": [
        "4cb1276e143e175590c69ceefa58eb721aa52846"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jun 26 21:07:13 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jun 26 21:14:41 2009 -0700"
      },
      "message": "Use system properties to track the current transport\n\nThis change retools the transport selection mechanism a fair bit.  Transports\nare now specified by name rather than by numeric ID, and the name of the\ncurrently selected transport is stored in a persistent system property under the\nname \"persist.service.bkup.trans\".\n\nThe name -\u003e IBackupTransport translation is now handled by maintaining a map\nfrom the names to the live IBackupTransport objects that correspond.  The Google\ntransport service observer now registers and unregisters the transport as the\nservice goes up and down.\n\nThe bmgr command has been expanded to include real transport interrogation and\nselection by name, and some documentation has been written for it.\n"
    },
    {
      "commit": "156411df4627336b246db78cddca8248ed615b67",
      "tree": "e0aab41ac43c870e5c464b297418034a50e47d93",
      "parents": [
        "040441fa992bcfc11070d559bfceeb039667b382"
      ],
      "author": {
        "name": "Dan Egnor",
        "email": "egnor@google.com",
        "time": "Fri Jun 26 13:20:02 2009 -0700"
      },
      "committer": {
        "name": "Dan Egnor",
        "email": "egnor@google.com",
        "time": "Fri Jun 26 13:25:27 2009 -0700"
      },
      "message": "Use a long for restore token\n"
    },
    {
      "commit": "c73a218c2663e6ae3ec8a9ab8b9524f95702ade9",
      "tree": "ded996c56eae0df093d1d36857d38fef4870bf10",
      "parents": [
        "56bc71565ecd72bf7a3e45b5c871b0407ed9f781"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jun 26 11:41:26 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jun 26 12:20:10 2009 -0700"
      },
      "message": "Add some error reporting \u0026 info to bmgr\u0027s output\n"
    },
    {
      "commit": "4a64bded06a0299785c295a975e2818308eb53e2",
      "tree": "a24057a8f82108aae7f8e6fcb5067c2ed7fe9690",
      "parents": [
        "5e8a4b842c20dd47b82e9915f1bd730ee1b0d46d"
      ],
      "author": {
        "name": "Joe Onorato",
        "email": "joeo@android.com",
        "time": "Thu Jun 25 23:53:29 2009 -0400"
      },
      "committer": {
        "name": "Joe Onorato",
        "email": "joeo@android.com",
        "time": "Thu Jun 25 23:53:29 2009 -0400"
      },
      "message": "Add some helpful tests scripts for backup and make bmgr restore wait until the backup is done.\n"
    },
    {
      "commit": "5e8a4b842c20dd47b82e9915f1bd730ee1b0d46d",
      "tree": "7408bf959f58575cb3e991ca72b3b9a6bb39f72c",
      "parents": [
        "7d562ec393d54dd9ef387c49d1283243bfdbd2b1"
      ],
      "author": {
        "name": "Joe Onorato",
        "email": "joeo@android.com",
        "time": "Thu Jun 25 21:34:49 2009 -0400"
      },
      "committer": {
        "name": "Joe Onorato",
        "email": "joeo@android.com",
        "time": "Thu Jun 25 21:34:49 2009 -0400"
      },
      "message": "Give the bmgr command an IRestoreObserver too.\n"
    },
    {
      "commit": "abce4e8714bed26a2b37b20ad3f02cf619d71c9a",
      "tree": "274cf438fcda8dca4b13a056bc73fea61ba4dd77",
      "parents": [
        "2810f681991d1beb5ceb3515159f9fad3cc341d5"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jun 18 18:35:32 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jun 18 18:38:02 2009 -0700"
      },
      "message": "Use signatures on restore\n\nOn restore now, the backup manager gets the signature blocks corresponding to\nthe restore set from the transport.  It then validates those signatures against\nthe on-device app signatures, and refuses to restore data to an app whose\non-device sig block does not match the backup image\u0027s.\n\nAlso actually implement \u0027bmgr transport N\u0027 so that we can select the local\ntransport easily during runtime.\n"
    },
    {
      "commit": "f68eb500f99361541049e09eb7f9ddd6f4ef4efa",
      "tree": "ccb031f408b087de63baf720b13779d4d989a61d",
      "parents": [
        "5633034f79bfa67c4219f16fd6d23e962e800be2"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 16 11:02:01 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 16 13:58:17 2009 -0700"
      },
      "message": "More bmgr work; fix clear-data signalling\n\nThe \u0027list sets\u0027 and \u0027restore token#\u0027 commands from bmgr now do what they are\nsupposed to.  At this point we see the restore target\u0027s data being cleared\nproperly and its agent being launched and invoked for restore.\n"
    },
    {
      "commit": "ace7f094bf07bbd90cb998b9462e4f2d101a498c",
      "tree": "9581b7ce708b84fa8c433041722e9f730e3c0fe3",
      "parents": [
        "9908b3d820f7574ef432f22d280c7f1f5065f67f"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 15 18:07:25 2009 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 15 18:07:25 2009 -0700"
      },
      "message": "Sketch out a \u0027bmgr\u0027 command line tool\n\nNot finished, but eventually will allow adb shell access to the Backup Manager\nfor testing purposes etc.\n"
    }
  ]
}
