diff options
author | Christopher Tate <ctate@google.com> | 2015-05-15 16:06:58 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2015-05-19 17:05:22 -0700 |
commit | 1a78d8c2b88fb86801937d6cdb9e4961053d898b (patch) | |
tree | 586b6d0c067c53c48f3ee2dbf154d911f76adf3b /services/backup | |
parent | 0c4729a1e468e2b0783a4234e39677d8078473b3 (diff) | |
download | frameworks_base-1a78d8c2b88fb86801937d6cdb9e4961053d898b.zip frameworks_base-1a78d8c2b88fb86801937d6cdb9e4961053d898b.tar.gz frameworks_base-1a78d8c2b88fb86801937d6cdb9e4961053d898b.tar.bz2 |
Rebind backup transports only when clearly needed
Significantly narrow the circumstances under which transports
will be re-bound. In particular, we now do not unbind + rebind
whenever any component in a bound transport's host package changes;
rather, we do so only when the transport component itself has
changed state, or when there is a state change that might cause
a new transport to become available.
Bug 19775237
Change-Id: Ib386875df19ffe9f2d3eb9f9788187338360644a
Diffstat (limited to 'services/backup')
-rw-r--r-- | services/backup/java/com/android/server/backup/BackupManagerService.java | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 6c1023c..01cc2ca 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -1725,28 +1725,68 @@ public class BackupManagerService { // At package-changed we only care about looking at new transport states if (changed) { try { + String[] components = + intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); + if (MORE_DEBUG) { Slog.i(TAG, "Package " + pkgName + " changed; rechecking"); + for (int i = 0; i < components.length; i++) { + Slog.i(TAG, " * " + components[i]); + } } - // unbind existing possibly-stale connections to that package's transports + + // In general we need to try to bind any time we see a component enable + // state change, because that change may have made a transport available. + // However, because we currently only support a single transport component + // per package, we can skip the bind attempt if the change (a) affects a + // package known to host a transport, but (b) does not affect the known + // transport component itself. + // + // In addition, if the change *is* to a known transport component, we need + // to unbind it before retrying the binding. + boolean tryBind = true; synchronized (mTransports) { TransportConnection conn = mTransportConnections.get(pkgName); if (conn != null) { + // We have a bound transport in this package; do we need to rebind it? final ServiceInfo svc = conn.mTransport; ComponentName svcName = new ComponentName(svc.packageName, svc.name); - String flatName = svcName.flattenToShortString(); - Slog.i(TAG, "Unbinding " + svcName); - - mContext.unbindService(conn); - mTransportConnections.remove(pkgName); - mTransports.remove(mTransportNames.get(flatName)); - mTransportNames.remove(flatName); + if (svc.packageName.equals(pkgName)) { + final String className = svcName.getClassName(); + if (MORE_DEBUG) { + Slog.i(TAG, "Checking need to rebind " + className); + } + // See whether it's the transport component within this package + boolean isTransport = false; + for (int i = 0; i < components.length; i++) { + if (className.equals(components[i])) { + // Okay, it's an existing transport component. + final String flatName = svcName.flattenToShortString(); + mContext.unbindService(conn); + mTransportConnections.remove(pkgName); + mTransports.remove(mTransportNames.get(flatName)); + mTransportNames.remove(flatName); + isTransport = true; + break; + } + } + if (!isTransport) { + // A non-transport component within a package that is hosting + // a bound transport + tryBind = false; + } + } + } + } + // and now (re)bind as appropriate + if (tryBind) { + if (MORE_DEBUG) { + Slog.i(TAG, "Yes, need to recheck binding"); } + PackageInfo app = mPackageManager.getPackageInfo(pkgName, 0); + checkForTransportAndBind(app); } - // and then (re)bind as appropriate - PackageInfo app = mPackageManager.getPackageInfo(pkgName, 0); - checkForTransportAndBind(app); } catch (NameNotFoundException e) { // Nope, can't find it - just ignore if (MORE_DEBUG) { |