)]}'
{
  "log": [
    {
      "commit": "e5f51c212cc3292a69988cd3569ce24cbb98f978",
      "tree": "3eb28f15dcc220a6cb35aada604b1c1ec64761e0",
      "parents": [
        "11f17cad62747a45d557cf2af9a16ce5f0114a1f"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Jan 27 18:17:43 2016 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jan 29 12:47:45 2016 -0800"
      },
      "message": "Stage backup/restore data in a cache subdir rather than root\n\nAlso make sure not to do the restorecon() before the file is\ncreated.\n\n(Also fix binder identity bug in the \u0027bmgr fullbackup\u0027 flow.)\n\nBug 26834865\n\nChange-Id: Ia8a59eeb55762264163c8b310caae5e303413571\n"
    },
    {
      "commit": "7200364e8d74fc105023790eeda0fc42dac3310a",
      "tree": "816afb450751d7bda5b4f2c6969f7eb91086a918",
      "parents": [
        "800133d4eb5c6bc4c88f236362e0cca4f7e2fc54",
        "872d3b6e19933af6fa9ae65214b9f6df04fc3222"
      ],
      "author": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Wed Jan 27 12:15:50 2016 +0000"
      },
      "committer": {
        "name": "Android (Google) Code Review",
        "email": "android-gerrit@google.com",
        "time": "Wed Jan 27 12:15:50 2016 +0000"
      },
      "message": "Merge \"Quota exceeded API in BackupAgent\""
    },
    {
      "commit": "339b53a8e678f18da906906f5f32ed57772102bb",
      "tree": "4bd98f17e9af36769c4847b6850dae3767cecb96",
      "parents": [
        "bae1c3482cdcd487dec7d1a754cf79d5c18a624b"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jan 22 15:05:32 2016 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jan 26 10:58:37 2016 -0800"
      },
      "message": "Prevent (and repair) poisoned full-data backup queue\n\nAn app that transitioned from full-data to key/value backup regimes\nwas being left in the full-data backup queue until next reboot.  In\nedge cases this would result in the app being inappropriately shut\ndown for backup; furthermore, it would potentially cause there to\nexist a full-data payload for the app that was considered \"newest\"\nand therefore be the one delivered at restore time on a new device\nor app (re)installation.\n\nDefense in depth: full-backup candidates are just-in-time reevaluated\nfor validity when they come up again in the queue; app update\nnotifications cause a reevaluation and removal from the queue if\nfull-data is no longer the right modality; and the common engine for\nall cloud-facing full-data backups does an additional last-ditch\nvalidation that each stated target is actually supposed to get\nfull-data backups rather than key/value, to backstop the checks on\nqueue-presence validity.\n\nBug 26744511\n\nChange-Id: I55bea3e19a2cab0150dbe5a08dd9fc550f0068c4\n"
    },
    {
      "commit": "872d3b6e19933af6fa9ae65214b9f6df04fc3222",
      "tree": "fceec9367d28d1d32502306e14d0b1f216461f2e",
      "parents": [
        "eb6c023710ebc1f07329f8623cf0b3e44d5bd538"
      ],
      "author": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Tue Jan 12 15:48:08 2016 +0100"
      },
      "committer": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Fri Jan 22 14:38:52 2016 +0100"
      },
      "message": "Quota exceeded API in BackupAgent\n\nShould be also implemented in GMS BackupTransport.\n\nBug: 25693504\nChange-Id: I6e4b2edb6d62addca0aced3e801d7629fb9394ca\n"
    },
    {
      "commit": "9448196076d5a5266b3ae7e4945216b30ee88aa7",
      "tree": "b25df433f5fac5bc865eb380b8cf5d33c929abd0",
      "parents": [
        "75fab6b8bc84bcabdbdfb2a917e2b97bdd29152b"
      ],
      "author": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Thu Jan 07 18:25:35 2016 +0100"
      },
      "committer": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Thu Jan 21 22:41:39 2016 +0100"
      },
      "message": "Add BackupManager#isAppEligibleForBackup() method to Backup API.\n\nCheck is done only in framework.\nTransport still can deny backup for the package.\n\nBug: 26443192\nChange-Id: Ifcde67a4d11725aa4b15ab4f57d740f55ab2b265\n"
    },
    {
      "commit": "d3665f1f0f2e2aefe4c5dd6b000b356dfb414783",
      "tree": "0598d8e2edbd5e57f5a3e2f733c6fec070e42902",
      "parents": [
        "3bcf800c50238ac2df19c9fc0375c303905524b0",
        "fe06bf64d204c459699b0bf6465f9fb69208345e"
      ],
      "author": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Thu Jan 21 18:55:28 2016 +0000"
      },
      "committer": {
        "name": "Android (Google) Code Review",
        "email": "android-gerrit@google.com",
        "time": "Thu Jan 21 18:55:28 2016 +0000"
      },
      "message": "Merge \"Introduce BackupManager#requestBackup \u0026 BackupObserver API\""
    },
    {
      "commit": "fe06bf64d204c459699b0bf6465f9fb69208345e",
      "tree": "9c17b7068072e9117c1b665db5d02f6b4cb17097",
      "parents": [
        "b325061b196e8bb849356c1beb09de9d18bbe97b"
      ],
      "author": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Tue Dec 15 16:26:23 2015 +0100"
      },
      "committer": {
        "name": "Sergey Poromov",
        "email": "poromov@google.com",
        "time": "Thu Jan 21 19:15:33 2016 +0100"
      },
      "message": "Introduce BackupManager#requestBackup \u0026 BackupObserver API\n\nIntroduces a way to request immediate backup for list of packages\nand receive callbacks on backup progress.\n\nBug: 25688526\nChange-Id: Ib826933d44f4ebf2b981f8be366215b2d37847e2\n"
    },
    {
      "commit": "63fec3ef1adb6c447cd505679714a8e780d18263",
      "tree": "193c2a3be9c3fddea64d4e4ac2120beb6f8ea104",
      "parents": [
        "f9bf6da6cd0666897f4b56cf0e6dee3c55243273"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Dec 11 18:35:28 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jan 14 11:03:36 2016 -0800"
      },
      "message": "Don\u0027t full-data back up apps in foreground-equivalent state\n\nWe have to kill the app and bring it up in a controlled lifecycle mode\nin order to do full-data backup, and if it\u0027s e.g. playing media, this\nis hugely disruptive.  Instead, we now check whether an app being\nconsidered for full-data backup is in a user-observable state, and\ndefer its backup if so.  We don\u0027t kick it all the way down the\ndaily-backup cycle in this situation -- we set it up to retry the\nbackup in just a few hours.\n\nBug 25960428\n\nChange-Id: I576f25c6fb07545565f59bd685624c612b9c5ffd\n"
    },
    {
      "commit": "4cfe29bdf2ee14e8316d45cfc23e4548319b3ab9",
      "tree": "21680e7de47b00ea7c8ea748317bc2000401e06b",
      "parents": [
        "9ed62e47c9df8f5a7c39ecc18127a1752c5876dc"
      ],
      "author": {
        "name": "Xiaohui Chen",
        "email": "xiaohuic@google.com",
        "time": "Fri Sep 04 13:55:23 2015 -0700"
      },
      "committer": {
        "name": "Xiaohui Chen",
        "email": "xiaohuic@google.com",
        "time": "Fri Sep 04 13:57:20 2015 -0700"
      },
      "message": "Cleanup USER_OWNER in backup service\n\nThis is just a straight constant replace.  The feature is tracked in a\nseparate bug b/22388012.\n\nBug: 19913735\nChange-Id: I7ae0953558bfdb77441e9efd749f1bb1cc77050c\n"
    },
    {
      "commit": "05a24e5b59eb378ecfd4b0fc174d2141a677b1ec",
      "tree": "428611c92e4fd7d35087343688ad18b5ff1e3972",
      "parents": [
        "3c2d1fd84be0ee58c26b194beeca772f30a5fe25",
        "a6888d6d8b912a69fad189e1d53da79746aa74ae"
      ],
      "author": {
        "name": "Chris Tate",
        "email": "ctate@android.com",
        "time": "Fri Aug 28 20:37:24 2015 +0000"
      },
      "committer": {
        "name": "Android Git Automerger",
        "email": "android-git-automerger@android.com",
        "time": "Fri Aug 28 20:37:24 2015 +0000"
      },
      "message": "am a6888d6d: am b5bcd607: am 27c5cfd7: am 9b2f9bcb: am 82d14d60: Merge \"Crashing the system process is inadvisable\" into mnc-dev\n\n* commit \u0027a6888d6d8b912a69fad189e1d53da79746aa74ae\u0027:\n  Crashing the system process is inadvisable\n"
    },
    {
      "commit": "0d446c18dc84f8db522823f24983b8e71a0b0f04",
      "tree": "26003cdb2cc2ef2ff740e2dcfb55d90fad73cbc6",
      "parents": [
        "3883e72aeda7dcc5f76eba7ad2e95ad2cb041687"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 28 10:55:14 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 28 10:59:25 2015 -0700"
      },
      "message": "Crashing the system process is inadvisable\n\nWhen asking for the set of services published by a package, it\u0027s\nquite possible that there are none, in which case the returned List\u003c\u003e\nis null rather than valid-but-empty.  Don\u0027t bother looking at it\nwhen it\u0027s null.\n\nBug 23614440\n\nChange-Id: Ibebb26b9c3f75ec810a95f1b9d2663e884cb98bc\n"
    },
    {
      "commit": "6578ad5bb493d43ae6a1f8a0b0d6dd180aa90b50",
      "tree": "d67785920a2542a4a212b2a13529fb614d1e8c61",
      "parents": [
        "7f2aba0fb9b0c9848af7756fe94a2d15918ce544",
        "905cb17f921a804fde3679a2f8887055ec7db028"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 21 01:35:49 2015 +0000"
      },
      "committer": {
        "name": "Android Git Automerger",
        "email": "android-git-automerger@android.com",
        "time": "Fri Aug 21 01:35:49 2015 +0000"
      },
      "message": "am 905cb17f: am adde39d8: am b893c1ba: am 99b252ad: am ddc2536d: Make sure to kill restore-at-install full-data targets after restore\n\n* commit \u0027905cb17f921a804fde3679a2f8887055ec7db028\u0027:\n  Make sure to kill restore-at-install full-data targets after restore\n"
    },
    {
      "commit": "ddc2536d2b6f277a7828278a066be874e4f9502e",
      "tree": "e7a47c1f7e157a18f71ce79b3f9f899dda00dfef",
      "parents": [
        "54c807e713c0d04134108b7d13e4abd467e318d5"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Aug 20 12:30:50 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Aug 20 15:08:55 2015 -0700"
      },
      "message": "Make sure to kill restore-at-install full-data targets after restore\n\nSpecifically: correctly distinguish the \"I want to restore my own data\"\ncase, in which the app is intentionally not killed, from the single-package\nrestore at install operation.\n\nBug 23357388\n\nChange-Id: Ic50ac39fe942af1f6ec9e04a32d81a39b70a0b2b\n"
    },
    {
      "commit": "1c1dd4bc8dbad8846bbc7520dfe307099a6c05d7",
      "tree": "5965101af73dd7af4aa7b4df7365d35276bcdd40",
      "parents": [
        "267ed78aadeda8ab65a273e0806ab7622e5a190a",
        "45f88e1b2c0a8433b073f69c58660db843d46d04"
      ],
      "author": {
        "name": "Chris Tate",
        "email": "ctate@android.com",
        "time": "Tue Aug 18 01:44:08 2015 +0000"
      },
      "committer": {
        "name": "Android Git Automerger",
        "email": "android-git-automerger@android.com",
        "time": "Tue Aug 18 01:44:08 2015 +0000"
      },
      "message": "am 45f88e1b: am 591b371f: am ccbb02f9: am b16cd62c: am c0a2254e: Merge \"Clean up properly if outcall for doRestoreFinished() fails\" into mnc-dev\n\n* commit \u002745f88e1b2c0a8433b073f69c58660db843d46d04\u0027:\n  Clean up properly if outcall for doRestoreFinished() fails\n"
    },
    {
      "commit": "d71d7c350c76d3494dd6688c26a837fa41ea18f8",
      "tree": "706975fe76d5ee045b3ebf6b953ffd97581b6d4c",
      "parents": [
        "ed7961eb5a1fceabf30a8f790c8dc37ae714db51"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Aug 17 12:16:19 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Aug 17 12:16:19 2015 -0700"
      },
      "message": "Clean up properly if outcall for doRestoreFinished() fails\n\nThe target app crashed at an inopportune time but this shouldn\u0027t\ninvalidate the whole ongoing restore operation; it\u0027s a problem local to\nthe specific app undergoing restore.  Recognize this, clean up the app\u0027s\npossibly-incomplete data, and continue running the restore queue as\nplanned.\n\nBug 23228982\n\nChange-Id: If9a19d2fe6a0ce5339c893630d7a61a5a5ccd9b1\n"
    },
    {
      "commit": "1ad82779bea52865055db70ead52a8a360fcdba8",
      "tree": "834ff651d99f64577c6372f6584abf48a3d46f75",
      "parents": [
        "637e4ab8372183ebe85d9ffdfe8a06d331a2d62f",
        "5f70b3b1d3360dcfa2716d610c04efa3e309521e"
      ],
      "author": {
        "name": "Chris Tate",
        "email": "ctate@android.com",
        "time": "Thu Jul 30 18:12:43 2015 +0000"
      },
      "committer": {
        "name": "Android Git Automerger",
        "email": "android-git-automerger@android.com",
        "time": "Thu Jul 30 18:12:43 2015 +0000"
      },
      "message": "am 5f70b3b1: am e5b25915: am e625b631: am 4de7b0ff: am 74a0744e: Merge \"Fix issues around process teardown after full-data restore\" into mnc-dev\n\n* commit \u00275f70b3b1d3360dcfa2716d610c04efa3e309521e\u0027:\n  Fix issues around process teardown after full-data restore\n"
    },
    {
      "commit": "2ad7e27362f682e3358b307bef23196be1c8b126",
      "tree": "6ffa38e076eaac06c5df2e025b3279dc8403793d",
      "parents": [
        "a991c66c12da30d0240ac6c98736edee93d95977"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Jul 29 19:23:58 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Jul 29 19:27:47 2015 -0700"
      },
      "message": "Fix issues around process teardown after full-data restore\n\nThe unified code path for cleanup was mistakenly looking at the\nandroid:killAfterRestore manifest attribute even for full-data restore\noperations.  That attribute is only relevant for key/value payload\nhandling.  We need to *always* kill after restore in the full-data\ncase because the app will otherwise be allowed to enter normal\ncomponent lifecycles without its correct Application / ContentProvider\nstate in force.\n\nBug 22704852\n\nChange-Id: Ia63f985a35c28084c734389cfc49d3792173e5c7\n"
    },
    {
      "commit": "7e744dfcfd916e510385ce81f794d69d13026bf3",
      "tree": "3891d70d27a878f03f238027f0f7f4e7fb56911b",
      "parents": [
        "26c60581d78657b6cadfc0229c917d5451cba4fd",
        "803b73a29004d2f8bf0234c0619480f5e639b5d6"
      ],
      "author": {
        "name": "Chris Tate",
        "email": "ctate@android.com",
        "time": "Wed Jul 29 00:49:12 2015 +0000"
      },
      "committer": {
        "name": "Android Git Automerger",
        "email": "android-git-automerger@android.com",
        "time": "Wed Jul 29 00:49:12 2015 +0000"
      },
      "message": "am 803b73a2: am f9f837fa: am 6613ec44: am 403e22b9: am 751a96a0: Merge \"Don\\\u0027t redundantly call transport.finishRestore()\" into mnc-dev\n\n* commit \u0027803b73a29004d2f8bf0234c0619480f5e639b5d6\u0027:\n  Don\u0027t redundantly call transport.finishRestore()\n"
    },
    {
      "commit": "6ab2fb61f08d87e01874114c3c204166a287e92c",
      "tree": "11f764b6ed3bb80d9efb4c43bf644bd4296a5718",
      "parents": [
        "bdbec480e8598bd959a2fc047cfad8b72c8a645b"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 28 13:59:35 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 28 14:04:04 2015 -0700"
      },
      "message": "Don\u0027t redundantly call transport.finishRestore()\n\nThe RestoreSession is no longer responsible for calling finishRestore();\nthat happens as part of tidying up after running the restore itself,\neven in failure cases.\n\nBug 22640096\n\nChange-Id: I0be52af2ae8c2c1ac685e9904ccb8120f7fcf522\n"
    },
    {
      "commit": "a848379cabab5054e65ee29da339f5a3e8ca2481",
      "tree": "9b9c9f3c1055f440ceae4bd74af239e09860ba95",
      "parents": [
        "1e8e63754a851e3183f41476278385dc7302c5e7"
      ],
      "author": {
        "name": "Kenny Guy",
        "email": "kennyguy@google.com",
        "time": "Wed Jul 15 16:44:12 2015 +0100"
      },
      "committer": {
        "name": "Kenny Guy",
        "email": "kennyguy@google.com",
        "time": "Wed Jul 15 16:44:12 2015 +0100"
      },
      "message": "Update backup todo to mentioned admin control.\n\nUpdate backup manager todo about backups for profiles\nto mention the need for DevicePolicyManager control.\n\nChange-Id: I7f17fc01a53d9608b104b70e57da7f619cb82c5f\n"
    },
    {
      "commit": "2fe00adc02cb3fdcad8374bf624118d5c3d5575e",
      "tree": "085c6689594e1f22aadf2ce392b9f05f405e2096",
      "parents": [
        "20f71891c4ae420398b96cc6a77f0c43316e6717"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 07 10:46:10 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 07 10:46:10 2015 -0700"
      },
      "message": "Clean up obsolete pending timeout after restoring package metadata\n\nBug 22040047\n\nChange-Id: I460dbcc50a45d794392beb9ff4a4358c05c87e07\n"
    },
    {
      "commit": "758de809b9e26e80b3490779f45c64aeaadf2a45",
      "tree": "ccf0bbffc945bba7e56e4594cc5ae6e7f2c9aef9",
      "parents": [
        "40dff5b47f52ffb648f51c395ae67193e3121a2c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 30 17:48:46 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 30 17:58:27 2015 -0700"
      },
      "message": "Fix dispatch of onRestoreFinished()\n\nThe agent instance wasn\u0027t properly being conveyed from the generic\nrestore engine implementation to the state machine handling the\nlifecycles.  On top of that, the lifecycle wasn\u0027t advancing to the\nrestore-finished callback phase properly in the full-data restore\ncase.\n\nBug 22194736\n\nChange-Id: Ic649d6a196adbd21a4a0f3083c7eed2fff383e52\n"
    },
    {
      "commit": "ad8a96231680fae6c49bc877074b8af3562e90f1",
      "tree": "253b468aa1c00f8149f56ed0d0f32bc07c8059ab",
      "parents": [
        "fba7f5d73cce893860faa3af9df7b4099a8565a1"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jun 05 14:17:43 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jun 05 14:22:11 2015 -0700"
      },
      "message": "Don\u0027t run backups in battery-saver mode\n\nDefer both full-data and key/value backups while in battery-saver mode.\n\nBug 21563473\n\nChange-Id: I081b7bcd19af21a4c88ebb434d2d3ef4bc93951f\n"
    },
    {
      "commit": "3d7e0d8e21e2ba706573fc43f8a7e5654814fb11",
      "tree": "2c15d117ab98c7aed3edaa8843f3b8031ba86383",
      "parents": [
        "cb81d183672a3d9858ade10a997990c5d66a1be3"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue May 12 17:06:33 2015 -0700"
      },
      "committer": {
        "name": "Chris Tate",
        "email": "ctate@android.com",
        "time": "Sat May 30 00:49:26 2015 +0000"
      },
      "message": "Adjust key/value backup scheduling\n\nWe now try to perform key/value backups only while charging, proceeding\noff-charger only after we\u0027ve waited a full day for the device to be\nplugged in.\n\nBug 21076663\n\nChange-Id: Ib32c9f8bfaf8a310f5f388907e38a28d3c54bd8e\n"
    },
    {
      "commit": "03d64a52105ce6eada02bf030e1a746c226fd8b1",
      "tree": "3298b6f5cc15d35f3e851578d56381d4b6f92b3c",
      "parents": [
        "bcec2b0cebd873f8b80c11c8653326fc638af860"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue May 26 12:57:56 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed May 27 15:06:24 2015 -0700"
      },
      "message": "Don\u0027t erase backup metadata when an app is uninstalled\n\nWe still retain the data in the backup, in order to support the flow\nin which a user has the app and its data is stored; then the app\nis uninstalled; then later the app is reinstalled.  We depend on\nhaving correct metadata for the data in the datastore in order to\nevaluate its validity for restore-at-install, so we mustn\u0027t\nforget that metadata just because the app is not currently\ninstalled.\n\nWe also now permit the sentinel pseudopackage name \"@pm@\" as an\nargument to dataChanged(), indicating specifically that the metadata\nshould be scheduled for backup without having to be piggybacked on\nanother app\u0027s requested backup pass.  That lets us now make sure to\nschedule a backup pass for metadata-update in response to app\ninstall activity.\n\nFinally, fix a \"min instead of max\" bug in full backup scheduling\nthat was causing the OS to ignore the transport\u0027s inter-package\nquiet time requirement when multiple packages were overdue for\nbackup.\n\nBug 21471973\n\nChange-Id: I1dbc260edb91b8deadd2744e273dfa9578b9ef2a\n"
    },
    {
      "commit": "62d1e1ef7e04f03c492b49e721ee9773677bba8b",
      "tree": "4e470330773a377914bc7fe56b50bb741a8b0f11",
      "parents": [
        "770e98953e27573d24578008810eeb44c0755995"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed May 20 14:49:38 2015 -0700"
      },
      "committer": {
        "name": "Chris Tate",
        "email": "ctate@android.com",
        "time": "Thu May 21 01:32:39 2015 +0000"
      },
      "message": "Scan at boot time to detect newly-present full backup candidates\n\nOTA or similar might have caused an app to appear without the usual\nnotifications being sent.  Make sure we pick up those apps as\nappropriate for full-data backup.\n\nBug 19462310\n\nChange-Id: Ic17bc72b14cc7599ae8ea540548fda932606b8f2\n"
    },
    {
      "commit": "1a78d8c2b88fb86801937d6cdb9e4961053d898b",
      "tree": "586b6d0c067c53c48f3ee2dbf154d911f76adf3b",
      "parents": [
        "0c4729a1e468e2b0783a4234e39677d8078473b3"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri May 15 16:06:58 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue May 19 17:05:22 2015 -0700"
      },
      "message": "Rebind backup transports only when clearly needed\n\nSignificantly narrow the circumstances under which transports\nwill be re-bound.  In particular, we now do not unbind + rebind\nwhenever any component in a bound transport\u0027s host package changes;\nrather, we do so only when the transport component itself has\nchanged state, or when there is a state change that might cause\na new transport to become available.\n\nBug 19775237\n\nChange-Id: Ib386875df19ffe9f2d3eb9f9788187338360644a\n"
    },
    {
      "commit": "5aba226d8ac28cbac5200ee3715a174683b1faa0",
      "tree": "5aae050fad88a7ae90f8ac230b6a48bfc44c4c18",
      "parents": [
        "261208e002775fe9a9f4e79e9f70b41852cfbe60"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed May 06 12:31:46 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed May 06 12:31:46 2015 -0700"
      },
      "message": "Fix requestRestore() of an app\u0027s own package\n\nThe BACKUP permission check was being applied over-zealously.\n\nBug 19336200\n\nChange-Id: Ia52b5c5cc0fd8d19b74ee624be85113d1b8dca7e\n"
    },
    {
      "commit": "303650c9cdb7cec88e7ec20747b161d9fff10719",
      "tree": "310f95b0e6ff91830cebfdc015ee158015fc5d27",
      "parents": [
        "ca030f8ed5fd52f2821d159b9c16d0c514dc0688"
      ],
      "author": {
        "name": "Matthew Williams",
        "email": "mjwilliams@google.com",
        "time": "Fri Apr 17 18:22:51 2015 -0700"
      },
      "committer": {
        "name": "Matthew Williams",
        "email": "mjwilliams@google.com",
        "time": "Sun May 03 16:19:27 2015 -0700"
      },
      "message": "Add full backup criteria to android manifest\n\nBUG: 20010079\nApi change: ApplicationInfo now has a fullBackupContent int\nwhere -1 is (off) 0 is (on) and \u003e0 indicates an xml\nresource that should be parsed in order for a developer\nto indicate exactly which files they want to include/exclude\nfrom the backup set.\ndd: https://docs.google.com/document/d/1dnNctwhWOI-_qtZ7I3iNRtrbShmERj2GFTzwV4xXtOk/edit#heading\u003dh.wcfw1q2pbmae\n\nChange-Id: I90273dc0aef5e9a3230c6b074a45e8f5409ed5ce\n"
    },
    {
      "commit": "511d02fcc37dce092e17354d53023db44817ebe6",
      "tree": "ab1eb93a4f7a3cbcad9d638bc3773807c413c1ed",
      "parents": [
        "7f7e1d13c0f1b7f8996f3b241d5b096c852f891c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Apr 08 20:05:30 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Apr 09 13:13:42 2015 -0700"
      },
      "message": "Add system API for querying the available restore dataset for a package\n\nBug 20123585\n\nChange-Id: Ife6e77a224b5d4175178aacdb7c285e9944b9eab\n"
    },
    {
      "commit": "e012a235569fe307d165dfd0784ae847d0b13739",
      "tree": "f60b37a641be0e89eeba32cdef7f825dedfbdd29",
      "parents": [
        "0f2974321b8109d7d4e888a8a9662b5f9813c114"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Apr 01 17:18:50 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Apr 06 17:36:25 2015 -0700"
      },
      "message": "Back up / restore preferred app configuration\n\nBug 19848104\n\nChange-Id: I84cdfcc44b48a9732984955d7eedf745b5586bdd\n"
    },
    {
      "commit": "ab06997ed5d4599f7223f3033b5c3bc77ac7044e",
      "tree": "0802d9b2192aad4153727a5114cb20260e2c9394",
      "parents": [
        "dc0078b7947e0b035dce6c61108a48a276b11034"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Mar 30 18:00:52 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Mar 30 18:00:52 2015 -0700"
      },
      "message": "Fixes to full-backup scheduling edge cases\n\nIf a scheduled full-data backup was attempted but the device had not yet\nrun the primary key/value backup pass, the full-data backup scheduler\nwould wind up in a bad state and potentially never retry until reboot.\n\nWe now properly reschedule a future retry, using the key/value\nscheduling batch quantum as a backoff to be sure to give it a chance\nto run before the next time full data is attempted.\n\nChange-Id: Ic7eb7a7940fe6380f40d04813a46fc336e95815e\n"
    },
    {
      "commit": "a7f038c9c3715bf29aec194bf079bf061502b1d9",
      "tree": "ac811fc46fc297c50a01187af817cbfbabb9aad6",
      "parents": [
        "6e6af0d34eb08a810cd399de64c1ade21fe866a9"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Mar 27 17:58:18 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Mar 27 17:58:18 2015 -0700"
      },
      "message": "Respect the transport\u0027s requestFullBackupTime() backoff\n\nWe now make sure to pause by at least requestFullBackupTime() between full-data\nbackup operations, to give the transport the ability to apply traffic control\nwhile we\u0027re running the queue of eligible packages.\n\nAlso, we now reset a package\u0027s queue position whenever a full-data backup for\nthat package is run explicitly via adb.\n\nBug 19732890\n\nChange-Id: I6cf24495ad18eebd55557f229d11c703e5b7f529\n"
    },
    {
      "commit": "11ae768cf1b8348e761ad9c09e98788da1e591b1",
      "tree": "fa4a4e9fffc83e61af98476d41df4252e3cd1323",
      "parents": [
        "e7f931c4505a6bd62e01bef5193dd724571a672b"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Mar 24 18:48:10 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Mar 26 18:57:36 2015 -0700"
      },
      "message": "Add payload-size preflight stage to full transport backup\n\nWe now peform a total-size preflight pass before committing data to the\nwire.  This is to eliminate the large superfluous network traffic that\nwould otherwise happen if the transport enforces internal quotas: we\nnow instead ask the transport up front whether it\u0027s prepared to accept\na given payload size for the package.\n\nFrom the app\u0027s perspective this preflight operation is indistinguishable\nfrom a full-data backup pass.  If the app has provided its own full-data\nhandling in a subclassed backup agent, their usual file-providing code\npath will be executed.  However, the files named for backup during this\npass are not opened and read; just measured for their total size.  As\nfar as component lifecycles, this measurement pass is simply another\ncall to the agent, immediately after it is bound, with identical\ntimeout semantics to the existing full-data backup invocation.\n\nOnce the app\u0027s file set has been measured the preflight operation\ninvokes a new method on BackupTransport, called checkFullBackupSize().\nThis method is called after performFullBackup() (which applies any\noverall whitelist/blacklist policy) but before any data is delivered\nto the transport via sendBackupData().  The return code from\ncheckFullBackupSize() is similar to the other transport methods:\nTRANSPORT_OK to permit the full backup to proceed; or\nTRANSPORT_REJECT_PACKAGE to indicate that the requested payload is\nunacceptable; or TRANSPORT_ERROR to report a more serious overall\ntransport-level problem that prevents a full-data backup operation\nfrom occurring right now.\n\nThe estimated payload currently does not include the size of the\nsource-package metadata (technically, the manifest entry in its\narchive payload) or the size of any widget metadata associated with\nthe package\u0027s install.  In practice this means the preflighted size\nunderestimates by 3 to 5 KB.  In addition, the preflight API currently\ncannot distinguish between payload sizes larger than 2 gigabytes;\nany payload estimate larger than that is passed as Integer.MAX_VALUE\nto the checkFullBackupSize() query.\n\nBug 19846750\n\nChange-Id: I44498201e2d4b07482dcb3ca8fa6935dddc467ca\n"
    },
    {
      "commit": "2c7a0cc2cfa3a0502aa23e09e6236ba09979b539",
      "tree": "d2af8cd033390cea019451a394fdddac836c258b",
      "parents": [
        "c75517c1607289ac7cbb0b81a5b1979d1aa970ad"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Mar 23 19:04:56 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Mar 24 10:41:52 2015 -0700"
      },
      "message": "Switch to new userActivity and package install APIs\n\nTracking the deprecation of older API variants and switching to the\nnew and more informative versions.  Also tidying up a few unused\nvariables along the way.\n\nChange-Id: I282a18525f9db838f4e0a77c90403b8b904e4fd7\n"
    },
    {
      "commit": "27aec3c54a0319a989f7969ab6a368e9e1ae9d28",
      "tree": "1e6502cca63497d8274ec2eaf34ae30051951b41",
      "parents": [
        "d58617b4f519e69cf8a828210f138d2bcbe4e20a"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Mar 12 18:24:30 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Mar 12 18:24:30 2015 -0700"
      },
      "message": "Don\u0027t run full backups until package metadata has been pushed\n\nBug 19692849\n\nChange-Id: I13615db7408b5c6fbc787c4773103c052e70f0b2\n"
    },
    {
      "commit": "b538d3c06f37979a617c7c23644c23cc424f3f6a",
      "tree": "71845945670d55c35813507270d5b732c3990d40",
      "parents": [
        "eb803aef3b0f55785624e6a51deae867c1a95e88"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Mar 11 14:16:15 2015 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Mar 11 16:35:12 2015 -0700"
      },
      "message": "Don\u0027t run full backups on stopped packages\n\nWe already decline to run key/value backup passes for (participating)\napps that are in the \u0027stopped\u0027 state.  Now we also properly avoid\nfull-data backup passes on such apps.\n\nBug 19684052\n\nChange-Id: Ieafc07b5531a91a243d57238c53db41ad3459140\n"
    },
    {
      "commit": "77a2d78dbf91d4799f811385b1e39ad89052e7eb",
      "tree": "1642774f727d07c731e0c4fc74cf94204d1acbc7",
      "parents": [
        "9b98afca76592b8a1dc8d17dcaa99166f3658cb8"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Mar 03 16:19:44 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Mar 05 18:04:16 2015 -0800"
      },
      "message": "Don\u0027t enqueue allowBackup\u003dfalse apps for full backup attempts\n\nWe are correctly refusing to actually process apps for backup if they have\ndeclared android:allowBackup\u003d\"false\" in their manifests, but we\u0027re still\nwasting bookkeeping \u0026 a certain amount of work in tracking them as part of\nthe full backup queue.  Fix that; now we recognize that they shouldn\u0027t be\nin the queue in the first place.\n\nWhen reinflating the queue at boot time we also re-verify the participation\nof each mentioned app so that we properly drop ones that have been uninstalled\nor altered such that they are no longer full-data backup candidates.\n\nFinally, if an app previously implemented key/value backup, so we think\nwe\u0027ll be running it in that mode in a future backup pass, but has been\nupdated to use the full-data path instead, we don\u0027t want to go ahead and\nrun a key/value pass on it.  Added a backstop check and proceed gracefully\nin this situation.\n\n(Also add bit more debug-build logging to LocalTransport)\n\nBug 19462310\n\nChange-Id: I07ab4f2e68e92766d9e8f2595fa763c91193d743\n"
    },
    {
      "commit": "73570db59f9178cf3a8affe943e96808ac404049",
      "tree": "fa500a58f47332bd66315f6c55c43eb85cdd3930",
      "parents": [
        "20d58e2af7738209b068038197db516d365d887a"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Feb 26 19:32:55 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Mar 02 18:01:28 2015 -0800"
      },
      "message": "Use scheduled job rather than periodic alarms for key/value backups\n\nInstead of a runs-forever periodic alarm that drives key/value backup\npasses, we instead schedule-on-demand a trigger job that will kick off\nthe pass after a batching interval.  The key semantic change is that\nwe now never wake for key/value backup work unless we\u0027ve been explicitly\nasked to do so.  We also use a rather longer batching interval than\nwas previously the case.\n\nBug 19536032\n\nChange-Id: Ie377562b2812c9aeda0ee73770dfa94af6017778\n"
    },
    {
      "commit": "6a873711cd1ed43c85f6cc93e8cf61fed7aeff0e",
      "tree": "40c55208d3425c0d2457c4e3c93d704674c48a7e",
      "parents": [
        "fa9ec310d8aac23bd085b0a7f0fe91fe2115181a",
        "12f783d6c6155a65a87511e200206a81798aa2ed"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Feb 25 02:30:34 2015 +0000"
      },
      "committer": {
        "name": "Android (Google) Code Review",
        "email": "android-gerrit@google.com",
        "time": "Wed Feb 25 02:30:37 2015 +0000"
      },
      "message": "Merge \"Don\u0027t crash when backup timeout races with agent completion\""
    },
    {
      "commit": "12f783d6c6155a65a87511e200206a81798aa2ed",
      "tree": "779829159d8924ecceb5632444860dcc35f14c8a",
      "parents": [
        "a1879609890640bd26639fc3ce1fa482efd17e8d"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Feb 24 17:27:09 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Feb 24 17:37:54 2015 -0800"
      },
      "message": "Don\u0027t crash when backup timeout races with agent completion\n\nThere\u0027s a narrow window of time in which an agent reporting that its\noperation has completed races with timeouts such that we wind up\nhandling the completion callback just after certain fundamental state\nhas been reset.  Detect this race and proceed gracefully instead of\ncrashing.\n\nBug 19498669\n\nChange-Id: I5a475527db1a55a8e567366ddfb10112e427682e\n"
    },
    {
      "commit": "8dd7d01c1a07d9893ce1207c90869fe3d40fbced",
      "tree": "db5ed59b6923f3674af382d629c98bafcd79d01e",
      "parents": [
        "a1879609890640bd26639fc3ce1fa482efd17e8d"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Feb 24 15:08:08 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Feb 24 15:16:57 2015 -0800"
      },
      "message": "Check DUMP permission in the backup service trampoline\n\nMake sure that even if backup is disabled outright (and hence there\nis no underlying service implementation for the trampoline to delegate\nto), the DUMP permission exception is thrown as expected.\n\nBug 19422232\n\nChange-Id: I6d1a17c5f85adcfad75af969b521920e786c05a8\n"
    },
    {
      "commit": "33d3c53da021f0d044028860ace0f4ad817273f5",
      "tree": "1ebd67dbfa35109595bd6258633abba7931f1290",
      "parents": [
        "c093955af1434a7023093acb148ab152d915e59c",
        "517e0274cb2cfd215b20622280d5e256e8282bbb"
      ],
      "author": {
        "name": "Alex Klyubin",
        "email": "klyubin@google.com",
        "time": "Wed Feb 11 12:37:12 2015 -0800"
      },
      "committer": {
        "name": "Alex Klyubin",
        "email": "klyubin@google.com",
        "time": "Wed Feb 11 12:37:12 2015 -0800"
      },
      "message": "resolved conflicts for merge of 517e0274 to lmp-mr1-dev-plus-aosp\n\nChange-Id: Ic20b6c8851458483dd73a144bd5ae6e8d141e62a\n"
    },
    {
      "commit": "b9f8a5204a1b0b3919fa921e858d04124c582828",
      "tree": "c4faa0b3e8d1db30fc8a2deb3bb13b38de5a9364",
      "parents": [
        "3fbbe396faffeec6b46796087ad1e075e9a21f0d"
      ],
      "author": {
        "name": "Alex Klyubin",
        "email": "klyubin@google.com",
        "time": "Tue Feb 03 11:12:59 2015 -0800"
      },
      "committer": {
        "name": "Alex Klyubin",
        "email": "klyubin@google.com",
        "time": "Wed Feb 11 11:06:40 2015 -0800"
      },
      "message": "Move hidden ApplicationInfo flags into a separate field.\n\nThe public API field android.content.pm.ApplicationInfo.flags can\nsupport only 32 flags. This limit has been reached. As a short term\nworkaround to enable new public flags to be added, this CL moves flags\nwhich are not public API into a separate new field privateFlags and\nrenames the affected flags constants accordingly (e.g., FLAG_PRIVILEGED\nis now PRIVATE_FLAG_PRIVILEGED).\n\nThe new privateFlags field is not public API and should not be used\nfor flags that are public API.\n\nThe flags that are moved out of ApplicationInfo.flags are:\n* FLAG_HIDDEN,\n* FLAG_CANT_SAVE_STATE,\n* FLAG_FORWARD_LOCK, and\n* FLAG_PRIVILEGED.\n\nNOTE: This changes the format of packages.xml. Prior to this CL flags\nwere stored in the \"flags\" attribute. With this CL, the public flags\nare stored in a new \"publicFlags\" attribute and private flags are\nstored in a new \"privateFlags\" attribute. The old \"flags\" attribute\nis interpreted by using the old values of hidden/private flags.\n\nChange-Id: Ie23eb8ddd5129de3c6e008c5261b639e22182ee5\n"
    },
    {
      "commit": "e77c12ba37b7358ef6b6a6010e778926cc4194b8",
      "tree": "7220c96c1f5da422c8681ffe6082c0f2fb2e4501",
      "parents": [
        "6efc3ac6d2094c72b6a2e288101a5349b017274d"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jan 29 13:17:37 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jan 29 15:47:43 2015 -0800"
      },
      "message": "Don\u0027t run full-data backups when backup is disabled\n\nIf the scheduled job fires but backup is disabled or the device is\nnot yet provisioned (i.e. has not yet finished going through setup),\nbow out gracefully without running any backup operations.  Also, even\nif a backup is directly invoked (e.g. via adb), verify again right\nbefore we start collecting app data, and abandon the operation in\nthat path as well.\n\n(This is redundant; having only the latter test would suffice, but\nthis lets us distinguish in the logging more easily.)\n\nFinally, make sure that if we were waiting on setup before permitting\nbackup operations to begin, that we startup the full-data scheduling\nas well as the [separate] key/value scheduling.\n\nBug 19197062\n\nChange-Id: I3d8fb650c50f946d8ed7ac7170df361c707f2528\n"
    },
    {
      "commit": "cf962601186a05a8818c02b690c1e7b5c15144f1",
      "tree": "1de13ba946caf9f3ba2a68ba81a4058570e4ae26",
      "parents": [
        "faf92d725649337a29312603dc8c10a3f0ee103a"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jan 15 17:26:22 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jan 15 17:37:06 2015 -0800"
      },
      "message": "Don\u0027t write widget metadata to backup unless it\u0027s new/changed\n\nRedundant backup traffic is bad.  Don\u0027t commit the widget metadata payload\n(or the deletion operation for it) unless the widget state of the app has\nactually changed since the last backup.\n\nBug 19003911\n\nChange-Id: I93819173c0e2357b030d9e2b3d2ee57f2410bb57\n"
    },
    {
      "commit": "b89e1405cf9f1da533dc0843390a1b6783abb0f4",
      "tree": "c3c9a188e6f2627c4bb04330b9fd31f7a64f3497",
      "parents": [
        "1c6014e77dfad1a7af229d642df7b7300beee721"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jan 06 15:48:33 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jan 06 15:48:33 2015 -0800"
      },
      "message": "Support single-package backup rejection by the transport\n\nWe now cleanly handle the case of the transport blacklisting specific\npackages from key/value backup.  Previously we would halt the entire\nbackup pass and reschedule if the transport returned any error from\nperformBackup(pkg).  Now, we recognize the TRANSPORT_PACKAGE_REJECTED\nresult from that invocation, and properly drop that package\u0027s work\nbut proceed with running the rest of the backup queue as expected.\n\nBug 18694053\n\nChange-Id: Id0dd6d59492bdea9f970540d776f37db0cc5d99c\n"
    },
    {
      "commit": "603ad6f7d00b6c1687102f4679314af533f18f6a",
      "tree": "ef1609bd155707caf5360503d11b4e116696b559",
      "parents": [
        "748902420d26b2868296303be7df89d0c25b7f2b"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jan 05 17:07:57 2015 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jan 05 17:07:57 2015 -0800"
      },
      "message": "Remove the \"backup_data_changed\" event log\n\nNowadays it\u0027s just spammy and uninformative, so away it goes.\n\nBug 18833115\n\nChange-Id: Ic373c596d7a892c4fedc0343e2c03dc1c295225e\n"
    },
    {
      "commit": "22192ada99691221f9ab167c046fb71c23baf723",
      "tree": "3367f0e0feeb60a64d1cacc8b00f5c8784ff7d26",
      "parents": [
        "6dfa60f33ca6018959ebff1efde82db7d2aed1e3"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Dec 04 17:20:28 2014 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Dec 04 19:38:55 2014 -0800"
      },
      "message": "Correctly parse previous PMBA state during backup\n\nBug 18628030\n\nChange-Id: Iefa23de50dd9e1b27cfa5d887f117876d57e4083\n"
    },
    {
      "commit": "a7e47d5d344674f4174919c4ac51e5b9c74b5802",
      "tree": "34b8d1f8a38225b2386d19e2b2b3a7a30ae06615",
      "parents": [
        "089f95f4483c95873cf0084c11cb23a0f5b32c3c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Dec 01 14:37:28 2014 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Dec 01 14:37:28 2014 -0800"
      },
      "message": "Don\u0027t crash if a system restore fails before constructing the PMBA\n\nIf a whole-system restore operation failed at just the wrong point,\nwe\u0027d wind up in the teardown code without a certain vital bit of it\nhaving been initialized, and crash on the null pointer.  Now we\nrecognize this failure mode and make sure not to do that.\n\nBug 18574450\n\nChange-Id: Ifa2c10ce16bb3c6bc916ed7151c5fd51b7225691\n"
    },
    {
      "commit": "201caf57f9a9699e04620eac9b1fcdaf4338d2f0",
      "tree": "0012bb1c1dc502ea15beccbdabf684a87401e1fa",
      "parents": [
        "19865ccd44958b0902b9eedd11df279a03ff74c1"
      ],
      "author": {
        "name": "Zoltan Szatmary-Ban",
        "email": "szatmz@google.com",
        "time": "Wed Nov 12 18:03:08 2014 +0000"
      },
      "committer": {
        "name": "Zoltan Szatmary-Ban",
        "email": "szatmz@google.com",
        "time": "Wed Nov 12 23:51:31 2014 +0000"
      },
      "message": "Adding method to query backup manager service activity status\n\nBug: 17367491\nChange-Id: I9920c07d56c4c0ccb1f3dce637c0fb390902d2ff\n"
    },
    {
      "commit": "bbe23b31dcd0eec8af5b5198970de7ff2a9ef79a",
      "tree": "e0f6458989ba16677e19f930fcfd128af6d11d3f",
      "parents": [
        "4b19b7aaff1d1ff972ebe68101c2107454bbe5de"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Oct 30 13:44:27 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Fri Nov 07 18:40:47 2014 +0000"
      },
      "message": "Enable runtime turndown of backup/restore services\n\nThe heavy implementation of the backup manager service is now sitting\nbehind a lightweight trampoline that actually provides the binder\ncall interface.  The indirection allows us now to tear down the\nimplementation on the fly without breaking callers who have cached\nbinder references to the backup services: these callers will simply\nsee their future invocations failing benignly.\n\nIn addition there is now an API for suitably privileged callers such\nas device policy management to effect this turndown.\n\nFinally, there is now a static system property, \"ro.backup.disable\",\nthat a product can use to outright remove backup/restore operation\nfrom the system\u0027s operation.  The public APIs will continue to be\nsafely usable on such products but no data will be moved to or\nfrom the device.\n\nBug 17367491\n\nChange-Id: I8108e386ef3b5c967938fae483366d6978fe4e04\n"
    },
    {
      "commit": "a28b5c51602ccc48f2672274dabda05d3776ccd9",
      "tree": "028943d53b964cbb0f5409cfa9214fa4a0afc109",
      "parents": [
        "60e74b4924dee6d033ca61854cac42768006ced5"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Oct 16 13:44:00 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Oct 16 13:56:45 2014 -0700"
      },
      "message": "Eliminate race condition around backup completion + resumption\n\nEnsure that the callback always sees the current-operation state in sync\nwith the various other bits of internal backup-operation state.  Previously\nonly the current-operation state was managed inside the critical section;\nthis resulted in a slim race window where a callback could see an ongoing\noperation as still valid, but after the internal state on which that\noperation depended had already been cleared.\n\nBug 17931760\n\nChange-Id: Ia032668e7a9d22f1029c57fc98db9e86484d5719\n"
    },
    {
      "commit": "0f32717a17307ee581381d7f8527b686aacb3ac4",
      "tree": "14bacccb9409dcf741f43c55e81aeeeb66175b22",
      "parents": [
        "20de619d66a594fd9e6e76a3a2cb79422aef577c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Oct 15 17:49:42 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Thu Oct 16 01:34:01 2014 +0000"
      },
      "message": "Fix spurious restore session timeouts\n\nThe restore-session idle timeout should not be ticking while we\u0027re\ndoing legitimate restore work.  We now explicitly stop the timeout\nticker [a delayed message on our handler thread] whenever we undertake\na valid restore operation.  The timer is already correctly resumed\nwhen restore operations conclude.\n\n(In practice we need to suspend the timeout tracking at exactly those\ntimes when we\u0027re entering the wakelock-protected restore flow.  The\ntimeout is reestablished when the wakelock is released; this part\nis already in the code.)\n\nBug 17990544\n\nChange-Id: I7318020ce30fd9c35bc3a644f8c101fd3d063c8b\n"
    },
    {
      "commit": "2aa1d18e3acd269ed7a5f5a4843d447735f0676c",
      "tree": "4c88e5ed43a9a8201dc04e9b6f7dc040cfdb83c0",
      "parents": [
        "2c2cb29a3d7f0a90d753b0fa9c32c1fc5cdbff32"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Oct 09 15:20:24 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Oct 09 15:20:24 2014 -0700"
      },
      "message": "Fix bug 17931760 - spurious timeout leads to mayhem\n\nWe know a priori that the PMBA metadata package\u0027s backup pass\ndoesn\u0027t need to be tracked for timeout, because it\u0027s run inline\nrather than as an asynchronous separate-process operation.\n\nChange-Id: Ifd21ab3a016917f5e557a38c1c88f8d8ac1337d2\n"
    },
    {
      "commit": "6067d79807653172de9772d8cfd5e914557207b7",
      "tree": "64259c4df9e4316f4db12fc4e6821c5e47ba00b0",
      "parents": [
        "3dd06d9005bd572a3b012b3a2b27adfa94533144"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Oct 08 11:10:49 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Wed Oct 08 18:14:02 2014 +0000"
      },
      "message": "Actually tell the widget service that restore is starting\n\nBefore beginning a full-system restore we need to tell the widget service,\nso that it can properly start remapping IDs from the ground state.\n\nBug 17869323\n\nChange-Id: I152257563f5b52cae67244e936bc2c44ced7618d\n"
    },
    {
      "commit": "ecae2116169e4cc7c109fcfc2aa9f5be1d105995",
      "tree": "b568e3afb4969c444aa26d335e4807401962fe49",
      "parents": [
        "7caa51e6ec6443d5c1fdb96f7e42508b074b4278"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Oct 03 18:26:29 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Oct 03 18:26:29 2014 -0700"
      },
      "message": "adb backup/restore fixes\n\nBug 17811327 : teach adb restore about the new widget metadata entries\n\nBug 14165872 : -nosystem should not act like -onlysystem\n\nChange-Id: I39da0ba80df7c5309a78ec1fa38016cebd80aa5f\n"
    },
    {
      "commit": "64f10efab72aa7701a8d292425f4f56f04ca556b",
      "tree": "f77d0794fe803b5219dc34e31b0f2f4d13ee48c4",
      "parents": [
        "48766577d43f708481d0def315f592659d7a51dc"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Sep 11 15:33:05 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Fri Sep 12 22:01:12 2014 +0000"
      },
      "message": "Track enable/disable of transport components\n\nFor fallback / rollback of backup transport selection we need to\nhandle live enable/disable of legacy or superseded transports.\nWe now watch for component enable state changes in packages that\nhost transports, and rebind as needed.\n\nThe semantics for selecting the current transport have also been\nadjusted.  We no longer require that the selected transport be\nlive and currently bound in order to be designated as the active\ninstance.  This prevents nondeterministic races around upgrade\nand replacement.\n\nBug 17136637\n\nChange-Id: Idaf45cf4522a23576444e6b11626ee3f7f47c36c\n"
    },
    {
      "commit": "539b217b764562964c7f11b416da8391cb7cf93f",
      "tree": "171567fd1747991d65a852d9a6889be481dcdba4",
      "parents": [
        "e8f8bc0ad6f7f2c657b4360033d2c7571c800ccb"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Sep 03 13:50:23 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Sep 03 14:12:11 2014 -0700"
      },
      "message": "The transport system API needs to manage binder identity\n\n...around writing settings.  It does its own proper permission check;\nit just needs to make sure not to accidentally crash the caller in\nstrange and wondrous ways because of failing to clear binder identity\nbefore writing the result to secure settings.\n\nBug 16542048\n\nChange-Id: I88d1f2dbeebd24eed5d86989f0ca0d834878b054\n"
    },
    {
      "commit": "674d3e750133efc4b2d575d806596d1f56bda8d9",
      "tree": "2620ebae0d5139ccb4a1df5fb9ad3a651ea2a137",
      "parents": [
        "3e97f9d48b6ef6b5ff5fa4e3c738138c0fe14edc"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Aug 27 13:54:51 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Aug 27 13:54:51 2014 -0700"
      },
      "message": "Do not require device provisioning to do restore-at-install\n\nProvisioning is a milestone used for gating *backup* operation,\nbut it\u0027s important that restores be possible during the setup\nprocess.  In particular, some applications such as home apps may\nbe deliberately pushed for install after platform restore, but\nbefore the end of the setup process.  We need to be able to do\ninstall-time restores of such apps.\n\nBug 17288313\n\nChange-Id: Iaff5d9919e6392b2ca5925be4d63a4116cd11f77\n"
    },
    {
      "commit": "915f1dc785886ecd14a5222778f7d46f0243b1f5",
      "tree": "e1419b3a431e4f62a40a7fa30618972c848b4700",
      "parents": [
        "70613dbff74544c6f537cc3a84392e07ad70859c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Aug 26 18:09:05 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Aug 26 18:32:55 2014 -0700"
      },
      "message": "Remember having done full-data as well as key/value app backups\n\nThe \"what have we ever succesfully backed up?\" log is used to determine\nwhether we can do an install-time restore from the currently-live dataset\nrather than go back to the ancestral dataset (if any).  We now track\napps that have gotten a successful full-data backup through the transport,\nnot just key/value backups.\n\nBug 17263823\n\nChange-Id: If21350a8dd8aaa4ed02fb74101617e935920e4ae\n"
    },
    {
      "commit": "b8e6838583c9d784a7e8d030999d57eb2e87a561",
      "tree": "9151e5679659f10fb6fb2c57d99db37d10d609fd",
      "parents": [
        "306908f235f9a53e8b68136ccd83cef5aad07fd2",
        "32d06732cdb7ee653a58e49a4dab13a780513db5"
      ],
      "author": {
        "name": "Paul Lawrence",
        "email": "paullawrence@google.com",
        "time": "Sat Aug 23 20:44:29 2014 +0000"
      },
      "committer": {
        "name": "Android (Google) Code Review",
        "email": "android-gerrit@google.com",
        "time": "Sat Aug 23 20:44:30 2014 +0000"
      },
      "message": "Merge \"Fix adb backup for encrypted case\" into lmp-dev"
    },
    {
      "commit": "d1c06753d045ad10e00e7aba53ee2adba0712ccc",
      "tree": "6a1103dfcc0b6db0dfc030aba6cdb4961e2a91c2",
      "parents": [
        "acb570cd84b4e3503e7e96138ea0d9d236ca9b9e"
      ],
      "author": {
        "name": "Matthew Williams",
        "email": "mjwilliams@google.com",
        "time": "Fri Aug 22 14:15:28 2014 -0700"
      },
      "committer": {
        "name": "Matthew Williams",
        "email": "mjwilliams@google.com",
        "time": "Fri Aug 22 16:08:45 2014 -0700"
      },
      "message": "Implement API review feedback for JobScheduler\n\nBUG: 17005336\n\nTook the opportunity to clean up some back-off logic\n\nChange-Id: Ibc8ae34d1d44dd064ba071e4cbad17872f7e38cf\n"
    },
    {
      "commit": "e7bbe47833160d05bc31fa33f6d2e6134f3cb8e9",
      "tree": "a1b9893f417127cf6b70211e6c518625f26bfea4",
      "parents": [
        "37e6cbae59e19bba734e7961620b6a7fb695db58",
        "5684dae9ccceb756c9b44b80931ccac9af198ea6"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 22 21:11:40 2014 +0000"
      },
      "committer": {
        "name": "Android (Google) Code Review",
        "email": "android-gerrit@google.com",
        "time": "Fri Aug 22 21:11:41 2014 +0000"
      },
      "message": "Merge \"Automatically bind to newly-installed backup transports\" into lmp-dev"
    },
    {
      "commit": "5684dae9ccceb756c9b44b80931ccac9af198ea6",
      "tree": "e92d25b5924fc580504c529b9e4f2a338bea50f7",
      "parents": [
        "b68654ce84cb80cb89bda69a170c8f69dfb3bd77"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Aug 21 15:45:47 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 22 13:29:46 2014 -0700"
      },
      "message": "Automatically bind to newly-installed backup transports\n\nThey\u0027ll be rebound automatically at boot, but need to be brought\nup immediately.  As always they can only be provided by privileged\napps.\n\nBug 16542048\n\nChange-Id: I9f121a5c111a772deb3f0c44166002a2cbb16ad5\n"
    },
    {
      "commit": "32d06732cdb7ee653a58e49a4dab13a780513db5",
      "tree": "e7915fe34e031d09fa3e746f3504b22163b7ef99",
      "parents": [
        "f9220b39533d18b6c79099c32522b3ff712ff89b"
      ],
      "author": {
        "name": "Paul Lawrence",
        "email": "paullawrence@google.com",
        "time": "Thu Aug 21 08:43:41 2014 -0700"
      },
      "committer": {
        "name": "Paul Lawrence",
        "email": "paullawrence@google.com",
        "time": "Fri Aug 22 11:22:43 2014 -0700"
      },
      "message": "Fix adb backup for encrypted case\n\nNew behavior. Backup no longer uses the encryption password. This is in\npart because that is hard with patterns, in part because it is a security\nissue - the off line backup is much easier to brute force than the phone.\n\nInstead, we simply insist on an encryption password if your device is encrypted\nand locked.\n\nBug: 17159330\nChange-Id: Ia22f84722522abf0b569a3ef1e16ead5527c726d\n"
    },
    {
      "commit": "8def5cbb3a1a68bb66fbe7ce63fcc8eadcbb238d",
      "tree": "34f99e0d39f3194f2485018a9f90da1b324eca46",
      "parents": [
        "63859536047e907fbcde87f12511ec3b35bf53dc"
      ],
      "author": {
        "name": "Brian Carlstrom",
        "email": "bdc@google.com",
        "time": "Thu Aug 21 23:15:13 2014 -0700"
      },
      "committer": {
        "name": "Brian Carlstrom",
        "email": "bdc@google.com",
        "time": "Thu Aug 21 23:15:13 2014 -0700"
      },
      "message": "Move SystemBackupAgent from services.jar to frameworks.jar\n\nBug: 17168017\nChange-Id: I89b98ca839a78eeb7fb43930e0699ee235deafad\n"
    },
    {
      "commit": "b2707afb0cbf955952d313e4c75fd3bfd3a35e98",
      "tree": "fce93b3840aae1c6d96558dcef0f7633c2e2052b",
      "parents": [
        "827296b7dd6689c14df1340f21a85e1f2f8d6844"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Aug 19 17:05:31 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Thu Aug 21 00:25:53 2014 +0000"
      },
      "message": "Maintain transport connection through package updates\n\nWhen a package is updated, existing bindings to that package\u0027s\nservices are severed and must be manually re-established.  Now\nthat the transport can be updated outside the system per se,\nmake sure that we detect these cases and rebind as needed.\n\nBug 16139912\n\nChange-Id: I5d6fa75bb86484f8f7d4f8e93c9157773995e6a7\n"
    },
    {
      "commit": "9dbba1b669eeb69316b70dbc9e457f8f8b084ea1",
      "tree": "b61db4521204e67241c2d48f95f000560bb595d4",
      "parents": [
        "dd7930354aaf2baf91810bc7a3e47543dbcc7f28"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Aug 19 18:24:06 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Aug 19 18:24:06 2014 -0700"
      },
      "message": "Don\u0027t crash good-citizen restore session clients\n\nIf an app is trying to do the right thing and end its restore sessions\ncleanly, but winds up being slow and having the session timed out from\nunder them, don\u0027t crash them with an illegal state exception for having\nappeared to end the session twice.\n\nBug 17133115\n\nChange-Id: I0a0989e2067b156569bddb6626ce045e625c6604\n"
    },
    {
      "commit": "10ab095a5be2cc45354266b8fbe642c3facafd55",
      "tree": "6ac510265f3e9ac0c9f312feef8de7d1952a5c81",
      "parents": [
        "71809ee7f63229d0ea4f6169922ddfbfee330fd2"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Aug 18 14:41:33 2014 -0700"
      },
      "committer": {
        "name": "Di Wu",
        "email": "arete@google.com",
        "time": "Mon Aug 18 22:01:43 2014 +0000"
      },
      "message": "Minor restore fixes\n\n1. We were missing a \u0027break\u0027 in the session-timeout case of\n   message dispatch, so were falling through into a different\n   case.  Oops.  Fortunately it was benign; the other case\u0027s\n   logic was merely logging \"hey it doesn\u0027t look like there\u0027s\n   anything to do here\" and cleanly exiting.\n\n2. After a restore operation finishes we were previously\n   always leaving the session timeout clock running.  However,\n   this was not appropriate in the case of restore-at-install,\n   when the restore was a one-shot kicked off by the package\n   manager rather than an operation on an ongoing RestoreSession.\n   That logic now properly tidies up the session timeout when\n   winding up the restore in either situation.\n\nBug 17080648\n\nChange-Id: I51d4a50db4feefc4c355230a3bfb926ea2fb5944\n"
    },
    {
      "commit": "a63246d6daa02c6f3e4e78d0072d991387e14c87",
      "tree": "69ad9f559a279b83aa610701a39d72a911c0e105",
      "parents": [
        "9fde9a250fffc15c6bcdfc985de12c8646a9813c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 15 11:12:13 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 15 11:22:01 2014 -0700"
      },
      "message": "Tighten restore-at-install behavior\n\nHarden the guarantee that if we\u0027re asked about a possible restore,\nwe always ALWAYS report back to the package manager.  This involved\nclosing \"should never happen\" edge cases around provisioning/auto-restore\nsetting that nevertheless were happening.\n\nAlso, on the auto-restore setting front, make sure to plumb that\nsystem API through appropriately, since going behind its back and\nmanipulating the secure setting directly would cause things to get\nout of step.\n\nBug 17060654\n\nChange-Id: I52ca9c1ffbfc0bd6b57196157500d0868bfc2989\n"
    },
    {
      "commit": "bf1a4a81ebd340a18583f4ca9b5d562a01f55674",
      "tree": "01fe035e46fd2b4f6632e9102e8bfd1e243f14c4",
      "parents": [
        "7f708ecc2f1dcebd516d9f445ec838a4385512fc"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Aug 08 15:05:48 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Sat Aug 09 00:48:47 2014 +0000"
      },
      "message": "Start using cancelFullBackup() when appropriate\n\nThe API was in place but the framework wasn\u0027t yet calling it.\n\nBug 16524520\n\nChange-Id: Ie368758c830a7d0ad11e7dd3142a0ed896069944\n"
    },
    {
      "commit": "0660244119243928a69e5f21ef5ea339c7f6d008",
      "tree": "903bb725d4767fcdd59737656f66433a62d426e0",
      "parents": [
        "f9b4c2cc6ffbcb21f8e9b015ed3bdab0501bdf65",
        "cce476034388383a6006555a225e2170f3b4dcd9"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Aug 07 20:57:59 2014 +0000"
      },
      "committer": {
        "name": "Android (Google) Code Review",
        "email": "android-gerrit@google.com",
        "time": "Thu Aug 07 15:00:45 2014 +0000"
      },
      "message": "Merge \"Sanity-check paths of files to be restored\" into lmp-dev"
    },
    {
      "commit": "4cf9f007e6b66c0a970600f66b4229c4ede73f7f",
      "tree": "1e90bfa0ef0a0a0babf3e1005453ee796c4b3f3b",
      "parents": [
        "4565ded1a29f394dffa67b0852eca15ef47bded7"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Aug 05 16:12:42 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Wed Aug 06 19:24:33 2014 +0000"
      },
      "message": "Add event logs for full backup/restore milestones\n\nBug 16689703\n\nChange-Id: If870f1b7b9cb3929ac1edc38affc688a37c2acfd\n"
    },
    {
      "commit": "46db93404b27fe5ec121ab55527712e2a6692c7a",
      "tree": "d56c5250b6cddb252b8912bc93fe413726bfd890",
      "parents": [
        "40b8ef99a5132a970903e33d3c8ee087d0502a93"
      ],
      "author": {
        "name": "Michael Wright",
        "email": "michaelwr@google.com",
        "time": "Tue Jul 29 18:28:47 2014 -0700"
      },
      "committer": {
        "name": "Michael Wright",
        "email": "michaelwr@google.com",
        "time": "Tue Aug 05 19:58:27 2014 +0000"
      },
      "message": "Ensure backup schedule file is closed.\n\nChange-Id: Ie4a62cda74815c67c62fb08e8df25a71d6102d4c\n"
    },
    {
      "commit": "cce476034388383a6006555a225e2170f3b4dcd9",
      "tree": "2475f4269260adf175fbdff03f4f9e8ceeed41ec",
      "parents": [
        "b942035837b5206b232081d724916eabb7dd4c6b"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Aug 04 14:49:26 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Aug 04 15:13:16 2014 -0700"
      },
      "message": "Sanity-check paths of files to be restored\n\nThe duplicated implementations are an artifact of an ongoing\nrefactor of the full-data restore code.  The adb-specific path\nwill be switched to use the FullRestoreEngine [as has already\nbeen done for the \u0027adb backup\u0027 path using the parallel full\nbackup engine], at which point the extra implementation here\nwill be removed, but for now we need to make sure that all\nbases are covered.\n\nBug 16298491\n\nChange-Id: I9cdb8a1c537939a620208df3cf0e921061b981ad\n"
    },
    {
      "commit": "7dfbaf52db6401ae85588e334be5af751bb813a8",
      "tree": "54d722deff37637292c25b3058a13d091874c111",
      "parents": [
        "0615026ba15d7d7a68d0a191d449da47a1ceabea"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 29 13:47:47 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Tue Jul 29 21:06:29 2014 +0000"
      },
      "message": "Make archive metadata idempotent\n\nWe want to make sure that the manifest and widget metadata\nblocks are identical, including their in-stream headers, if\nwe regenerate the archive without underlying filesystem changes.\n\nBug 15968355\n\nChange-Id: I828b264545d19e1d865d98d5723915d02fafc012\n"
    },
    {
      "commit": "c17739d112d8e7076924c7fdd98614abafd58609",
      "tree": "0c10a66c857854501da3a5c39258110896f92273",
      "parents": [
        "cfcdf1270127d9a333cda2b91646713d1f41c6ac"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jul 28 15:02:04 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Mon Jul 28 23:13:06 2014 +0000"
      },
      "message": "Provide outside-facing API for data management intent+label\n\nBug 16346320\n\nChange-Id: I3f4c2f4b700c77880ba3d8db7c92cdb404763d0d\n"
    },
    {
      "commit": "5eeb59cceb1f95813c548c1c5937f161c1ed3571",
      "tree": "7d8a657bcae2254fa0355c08c71b0846a82bbe3d",
      "parents": [
        "5c8ea084e609ecce17a038eb6b09fe118a81d700"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 22 10:50:22 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Mon Jul 28 01:21:48 2014 +0000"
      },
      "message": "Schedule full backups\n\nInitial policy:  at most daily; backups only run when the\ndevice is idle + charging + on an unmetered network.\n\nBug 16485874\n\nChange-Id: I5665d890a943bac765adcef14be79d7dba6ce078\n"
    },
    {
      "commit": "7ff106c20d403e3217f5f384e63737285e2668a2",
      "tree": "a42b9704925a46ea6e30d6ec33f1eaddc521d3c2",
      "parents": [
        "ccf9fca47149d102293668c2e81febc175e0329e"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 24 18:58:23 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 24 18:58:23 2014 -0700"
      },
      "message": "A couple of restore fixes:\n\n* Fix crasher after transport-level failure attempting to ask for\n  the name of the next package to be restored\n\n* Current-dataset single-package restore path no longer requires\n  that the package have its own backup agent.\n\nBug 16548983\n\nChange-Id: Id37f2f0e6075d53c414d9a997bf738bbf0cfff8b\n"
    },
    {
      "commit": "a4e4d68f08c1d48a3cdcf83617468370366d03d4",
      "tree": "56c91d22372026fe6810e0fe5ece025fd87b4ac6",
      "parents": [
        "8a01b05062e9ad3b262b6473a1122b2ba964210a"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 22 16:24:28 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Tue Jul 22 23:42:48 2014 +0000"
      },
      "message": "Handle single-package restores properly\n\nBug 16346405\n\nChange-Id: I69e3288f5a9d68d818fad6a2cd4b27ad45c1007e\n"
    },
    {
      "commit": "f7cbb1fc25223bbf793f7128280ee4b00d509eb0",
      "tree": "bd2fdb7c021c27112fea10861e7948b4c4519e71",
      "parents": [
        "fcd8b20e09ca066da6d2564935d8dbfff2777547"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 22 12:54:52 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 22 15:12:02 2014 -0700"
      },
      "message": "Always check restore against the latest backend metadata\n\nBug 16484934\n\nChange-Id: I472a7db89a94b9804f6ea94c25da206dd111a497\n"
    },
    {
      "commit": "89101f7fe89134a609459e80f779c1a5114e562a",
      "tree": "1f24d7a91077ef087b8bae0af7df1ca74aaebf9c",
      "parents": [
        "5f7f252b451f94bc09e2e5b880e026c28a9c2d0b"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 17 19:09:00 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 17 19:12:09 2014 -0700"
      },
      "message": "Tear down agents properly at EOD in full restore\n\nThe restore engine wasn\u0027t tearing down the bound agent after reaching\nthe end of data for the app, and furthermore was allowing the restore\noperation to resume running the queue before all data had been delivered\nto the current target.\n\nAlso make LocalTransport deliver data in 2K chunks rather than 32K,\nas a first step towards making its timing characteristics more like\nwe\u0027ll see in networked situations.\n\nFinally, added a bunch of MORE_DEBUG output for finding odd bugs\nlike this.\n\nChange-Id: Icdbe6a070af6cc7c708a938ad044108d40ebce9a\n"
    },
    {
      "commit": "5f7f252b451f94bc09e2e5b880e026c28a9c2d0b",
      "tree": "b662685b871bdf63deb2117cd3d53e6aa70e9509",
      "parents": [
        "f3e85b5bac693780c75935f0d27acf536458702d"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Jul 17 15:58:12 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Thu Jul 17 23:01:04 2014 +0000"
      },
      "message": "Properly end full restore attempt if getNextFullRestoreDataChunk() fails\n\nDon\u0027t just drop the error return on the floor and retry (forever!).\n\nChange-Id: I5f0ef2d09ea286d813add69517f865e474341b43\n"
    },
    {
      "commit": "2e40d115ca4332d88424d1b591fdd8d5f78d1831",
      "tree": "43ff38544c1b7301ce72dde50cff3bd5dcd84964",
      "parents": [
        "738177caf6a755a59ca6b17bb968be0aa4e8e10f"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 15 12:37:38 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Thu Jul 17 17:43:24 2014 +0000"
      },
      "message": "Add BackupAgent.onRestoreFinished() callback\n\nThe agent\u0027s onRestoreFinished() method is called after all available\ndata has been delivered to the app, whether via the key/value restore\nAPI or the full-data file-at-a-time API.  This gives the app a stable\nopportunity to do any postprocessing that might be appropriate.\n\nAlso fixes a lingering bug in the framework\u0027s handling of backup\nagent lifetimes.  In cases where an existing agent instances was\nbeing rebound, the framework was forgetting to notify the dependent\nthat the agent was available.  This was causing timeouts and restore\nfailure.\n\nBug 16241004\n\nChange-Id: I3f52b299312d30d38b0cba63a2cfaeb934991ef2\n"
    },
    {
      "commit": "a176d22110a1670f363ba0f745f127d2b6ca2350",
      "tree": "e29f8208c1d3de0773e7697f049e3a53f6ec8c8a",
      "parents": [
        "ac17c2a8c9ba85efdd35f0262d05a41554eb3775"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Jul 16 12:15:07 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Jul 16 13:10:58 2014 -0700"
      },
      "message": "Always call finishBackup() if performFullBackup() succeeded\n\nEven if we later get an error from sendBackupData() we need to give\nthe transport its teardown callback.  This simplifies the transport\nlogic considerably.\n\nChange-Id: Ib8c0e210d4a876ee6b083a4d619dfccc462da4e5\n"
    },
    {
      "commit": "a7835b6b6b00923b608a6bc3194e7840f67de7a8",
      "tree": "17f914d3a2e608714d3833c90d6c0cf2db6ffc7b",
      "parents": [
        "4ad58a4738048ade35f4bee91554dd84aeab3f88"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Jul 11 17:25:57 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@android.com",
        "time": "Mon Jul 14 22:56:04 2014 +0000"
      },
      "message": "Add Context.getNoBackupFilesDir()\n\nThis is an app-private filesystem space exactly like the one\nreported by Context.getFilesDir(), with one exception:  files\nplaced here are never backed up by the full-backup infrastructure.\nIf an app attempts to back up any of its contents via the normal\nAPI it\u0027s immediately ignored with a logged warning.\n\nThe restriction is also enforced on the restore side, because\napps using support libraries might wind up creating full backup\narchives containing no_backup subdirs on pre-L devices (via\nadb backup, Helium, \u0026c.).  We check for this before passing the\nrestore data to the app, and drop it if we detect the situation\nso that the app never sees the bits.\n\nBug 16240573\n\nChange-Id: I11216a391f1d32117ec7ce15aafc9cd93d0337de\n"
    },
    {
      "commit": "8f1bb3a0d47a4cb34471464dff2af932772a7ade",
      "tree": "1f6e9901c83aaf866d77f83f0966f02ac3284c17",
      "parents": [
        "8d3cd2c8cf8ec355265941a8457ffd8e2e348648"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 08 11:08:50 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jul 08 13:00:33 2014 -0700"
      },
      "message": "Fix NPE in platform restore\n\nBug 16061451\n\nChange-Id: I79d7913455886828a493a0c4ea850d259bfeeeab\n"
    },
    {
      "commit": "d746057f2414cba2bdc69257cc5be8cb681bb592",
      "tree": "d25c88f1e3e5406bdb3fa149df0cb596602a302f",
      "parents": [
        "255edb556e289a53d1c62a700028c25dab90010e"
      ],
      "author": {
        "name": "Jeff Sharkey",
        "email": "jsharkey@android.com",
        "time": "Sun Jul 06 20:44:55 2014 -0700"
      },
      "committer": {
        "name": "Jeff Sharkey",
        "email": "jsharkey@android.com",
        "time": "Tue Jul 08 00:38:57 2014 -0700"
      },
      "message": "Change new file installs to be cluster-based!\n\nNow that all the other pieces are in place, we\u0027re ready to start\ninstalling new file-based packages as a cluster (the new unified\ndirectory-based layout).  This greatly simplifies the renaming\nprocess.\n\nAlso add helper methods to ApplicationInfo to give a much clearer\nmapping between it and internal field names, since we can\u0027t change\nthe public API.\n\nAdd recursive restorecon().\n\nBug: 14975160\nChange-Id: I72a63c5ddbc594c2fec4a91dd59f73ef253fbfd7\n"
    },
    {
      "commit": "51fea57e06fcb1dab1d239a5fff6e75ba2b7cee7",
      "tree": "a11647d14f291a4f8bfcfdab2e34cff6c16e8c03",
      "parents": [
        "9a347f199284ad8bcb8a81bfbd306fe0b1a710ba"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 23 17:01:06 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 30 17:43:05 2014 -0700"
      },
      "message": "Refactor restore to deal with heterogeneous datasets\n\nTransport-based restore now handles both key/value and full-data\n(stream) data delivery.\n\nAlso: PMBA now holds metadata for *all* apps, not just those with\nbackup agents.  Since we need to consult this for every restore-\nat-install operation we cache this locally now, tagged per transport\nand per remote dataset, to avoid having to re-download it as part\nof every future restore operation.\n\nAlso fixed a bug in LocalTransport that was preventing restore of\nkey/value datasets, i.e. all of them that were nominally available\nprior to this change.\n\nNOTE: at present there is no automatic full-data backup; if for\ntesting purposes you need to create some to then use for restore,\nyou still need to use \u0027bmgr fullbackup ...\u0027 to push them.\n\nNOTE: at present the unified transport restore uses a refactored\n\"engine\" implementation to handle stream data that encapsulates\nthe existing \"adb restore\" implementation.  However, the adb\nrestore code path has not yet been refactored to wrap the newly-\nextracted engine version; it still contains its own copy of all\nthe relevant logic.  This will change in a future CL, at which\npoint offline/USB archive restore will simply wrap the same\nshared stream-restore engine implementation.\n\nBug 15330073\nBug 15989617\n\nChange-Id: Ieedb18fd7836ad31ba24656ec9feaaf69e164af8\n"
    },
    {
      "commit": "6a49dd087f29cfca82d55dfabeb97439ef84b508",
      "tree": "485b8c340470472482fa8e79ac741f9dc0803543",
      "parents": [
        "6b2df21ecacfa6826a85cabdf8d6fe0e81fe11d9"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 16 18:49:25 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Jun 17 14:29:09 2014 -0700"
      },
      "message": "Tweak restore API\n\nWe need the transport to tell the system not only what package it\u0027s going\nto deliver data for next, but also what format that data is in.\n\nChange-Id: I989cf78febf923a4208acb33ed80ccc7869356f5\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": "4dd2635bf501ad1a1adc22a6ceb4c66cd61a1a23",
      "tree": "78f87822d8aa88f5213c016feae8e4cd0d515703",
      "parents": [
        "0dcecc1cab9e0586ccc4725a2dab068e78207387"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 02 18:54:18 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Mon Jun 02 18:57:21 2014 -0700"
      },
      "message": "Add full-backup stream API to BackupTransport\n\nAlso started migrating the definition of transport success/failure constants\ninto BackupTransport to make them permanent.\n\nThe new methods are not yet plumbed in; this is just to allow forward\nprogress against a proposed stable API.\n\nBug 15329632\n\nChange-Id: I27472e09b831350c140b9fa548ebda3af334eb1a\n"
    },
    {
      "commit": "f97c63350abcc6715ba9fdc21fd3405d0f7ba716",
      "tree": "9eba371ad46dc3dd0b70e40ad494623421979fab",
      "parents": [
        "54dacbe7ca6d8a8c71d601fcf773e7b27eba3a53"
      ],
      "author": {
        "name": "Elliott Hughes",
        "email": "enh@google.com",
        "time": "Mon Apr 28 16:38:43 2014 -0700"
      },
      "committer": {
        "name": "Elliott Hughes",
        "email": "enh@google.com",
        "time": "Mon Apr 28 16:38:43 2014 -0700"
      },
      "message": "Move internal libcore.os users over to android.system.\n\nChange-Id: I84e1ace19ba3b4e58d7bb24f3ecda1bdf5dc75a5\n"
    },
    {
      "commit": "d4659698fe2c8d854089138000ec24193d8359b8",
      "tree": "3af669b5cd81c555dee196101690f2cf8c0ae004",
      "parents": [
        "121db9e8525163a867915adfd23a08cf1300d4fa"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Apr 08 16:34:06 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Apr 08 17:10:54 2014 -0700"
      },
      "message": "Don\u0027t crash on null installer package bookkeeping.\n\nBug 13906859\n\nChange-Id: I926ccc5620abae8b97bd2b7de21b82b7729e78dd\n"
    },
    {
      "commit": "a99d02170bc0e54f729b2b735571c8eea8d5034d",
      "tree": "daf6ef3f61fa93d3a638616685d6706f04c4f97d",
      "parents": [
        "118d113478a2c58e7997f926a8dd1bc5ca5f5dc8"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Apr 04 16:58:10 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Fri Apr 04 17:40:34 2014 -0700"
      },
      "message": "Back up the preferred home app, if any\n\nIf the user has stated a preference about their home app, make sure we\ncapture that so that a system restore can return them to that preferred\nsituation.  It\u0027s built into the system metadata so that we can, if\nnecessary, fast-path configuration of that home app while the rest of\nthe restore operation is in flight.\n\nChange-Id: I64dfee8f7a2a9e40f556cd19298d7b367c6aa8dc\n"
    },
    {
      "commit": "cba5941c6085dab1566bc047c1ea31f58a2dd4cf",
      "tree": "65f1da5c842078cebbc4db4d547ae80243e66271",
      "parents": [
        "4bb047fa5e6d43a027bfe1dfe23b3541e3910a31"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Apr 01 10:38:29 2014 -0700"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Apr 01 16:43:00 2014 -0700"
      },
      "message": "Rejigger the invalid-key checks at backup time\n\nBug 13732002\n\nChange-Id: Ic8f71234d1bbc7420eaa8e1762b999d09f308d46\n"
    },
    {
      "commit": "adfe8b86e9178a553b6db9722340fa4ff5201cf1",
      "tree": "2054d99dc17b0ada61693b97d9f3e306b4fe4d4a",
      "parents": [
        "aef4f6ebc8f8eb1f9fbfbe4ae2556c9f1a26a63c"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Tue Feb 04 16:23:32 2014 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Thu Mar 20 12:30:51 2014 -0700"
      },
      "message": "App widget backup/restore infrastructure\n\nBackup/restore now supports app widgets.\n\nAn application involved with app widgets, either hosting or publishing,\nnow has associated data in its backup dataset related to the state of\nwidget instantiation on the ancestral device.  That data is processed\nby the OS during restore so that the matching widget instances can be\n\"automatically\" regenerated.\n\nTo take advantage of this facility, widget-using apps need to do two\nthings:  first, implement a backup agent and store whatever widget\nstate they need to properly deal with them post-restore (e.g. the\nwidget instance size \u0026 location, for a host); and second, implement\nhandlers for new AppWidgetManager broadcasts that describe how to\ntranslate ancestral-dataset widget id numbers to the post-restore\nworld.  Note that a host or provider doesn\u0027t technically need to\nstore *any* data on its own via its agent; it just needs to opt in\nto the backup/restore process by publishing an agent.  The OS will\nthen store a small amount of data on behalf of each widget-savvy\napp within the backup dataset, and act on that data at restore time.\n\nThe broadcasts are AppWidgetManager.ACTION_APPWIDGET_RESTORED and\nACTION_APPWIDGET_HOST_RESTORED, and have three associated extras:\n\n    EXTRA_APPWIDGET_OLD_IDS\n    EXTRA_APPWIDGET_IDS\n    EXTRA_HOST_ID [for the host-side broadcast]\n\nThe first two are same-sized arrays of integer widget IDs.  The\n_OLD_IDS values are the widget IDs as known to the ancestral device.\nThe _IDS array holds the corresponding widget IDs in the new post-\nrestore environment.  The app should simply update the stored\nwidget IDs in its bookkeeping to the new values, and things are\noff and running.  The HOST_ID extra, as one might expect, is the\napp-defined host ID value of the particular host instance which\nhas just been restored.\n\nThe broadcasts are sent following the conclusion of the overall\nrestore pass.  This is because the restore might have occurred in a\ntightly restricted lifecycle environment without content providers\nor the package\u0027s custom Application class.  The _RESTORED broadcast,\nhowever, is always delivered into a normal application environment,\nso that the app can use its content provider etc as expected.\n\n*All* widget instances that were processed over the course of the\nsystem restore are indicated in the _RESTORED broadcast, even if\nthe backing provider or host is not yet installed.  The widget\nparticipant is responsible for understanding that these are\npromises that might be fulfilled later rather than necessarily\nreflecting the immediate presentable widget state.  (Remember\nthat following a cloud restore, apps may be installed piecemeal\nover a lengthy period of time.)  Telling the hosts up front\nabout all intended widget instances allows them to show placeholder\nUI or similarly useful information rather than surprising the user\nwith piecemeal unexpected appearances.\n\nThe AppWidgetProvider helper class has been updated to add a new\ncallback, onRestored(...), invoked when the _RESTORED broadcast\nis received.  The call to onRestored() is immediately followed by\nan invocation of onUpdate() for the affected widgets because\nthey will need to have their RemoteViews regenerated under the\nnew ID values.\n\nBug 10622506\nBug 10707117\n\nChange-Id: Ie0007cdf809600b880d91989c00c3c3b8a4f988b\n"
    },
    {
      "commit": "cb20740ee171de3e604c07cdd02963d4d08a5fc9",
      "tree": "9692f596099b9fcdc4a25c00051fb443f430329e",
      "parents": [
        "fd2c77ca249ec2d6746ff426d191fb3991b6ea3d"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Mar 05 17:22:25 2014 -0800"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Mar 05 17:22:25 2014 -0800"
      },
      "message": "Fix build.  Silly gits.\n\nChange-Id: I8f21b7239621da500d9a73eb17d350e06dda9b20\n"
    },
    {
      "commit": "ff8b037c10a7ce90cbb6130b49c8cb076e1e7c0f",
      "tree": "3fad37a57528bf2fcf29aef1319e368c587559d4",
      "parents": [
        "2665f6e9f5163d27608c21ed029a224d53ede43d"
      ],
      "author": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Mar 05 22:20:56 2014 +0000"
      },
      "committer": {
        "name": "Christopher Tate",
        "email": "ctate@google.com",
        "time": "Wed Mar 05 16:17:34 2014 -0800"
      },
      "message": "am 777b8a80: am 422b2656: resolved conflicts for merge of c45ff35f to klp-modular-dev\n\n* commit \u0027777b8a808ee76401429f7210ebb7194632040d45\u0027:\n  Adapt to underlying changes in the PBKDF2 implementation\n\nChange-Id: Ia68694a03e52693fceaedc6740dbd8e690e21257\n"
    }
  ],
  "next": "5c38516e83f772fe04176f72f2ab7a1094e17430"
}
