Scan at boot time to detect newly-present full backup candidates
OTA or similar might have caused an app to appear without the usual notifications being sent. Make sure we pick up those apps as appropriate for full-data backup. Bug 19462310 Change-Id: Ic17bc72b14cc7599ae8ea540548fda932606b8f2
This commit is contained in:
committed by
Chris Tate
parent
770e98953e
commit
62d1e1ef7e
@@ -88,13 +88,13 @@ import android.util.Slog;
|
|||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.StringBuilderPrinter;
|
import android.util.StringBuilderPrinter;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.backup.IBackupTransport;
|
import com.android.internal.backup.IBackupTransport;
|
||||||
import com.android.internal.backup.IObbBackupService;
|
import com.android.internal.backup.IObbBackupService;
|
||||||
import com.android.server.AppWidgetBackupBridge;
|
import com.android.server.AppWidgetBackupBridge;
|
||||||
import com.android.server.EventLogTags;
|
import com.android.server.EventLogTags;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
|
import com.android.server.backup.PackageManagerBackupAgent.Metadata;
|
||||||
import com.android.server.pm.PackageManagerService;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
@@ -589,8 +589,12 @@ public class BackupManagerService {
|
|||||||
|
|
||||||
File mFullBackupScheduleFile;
|
File mFullBackupScheduleFile;
|
||||||
// If we're running a schedule-driven full backup, this is the task instance doing it
|
// If we're running a schedule-driven full backup, this is the task instance doing it
|
||||||
PerformFullTransportBackupTask mRunningFullBackupTask; // inside mQueueLock
|
|
||||||
ArrayList<FullBackupEntry> mFullBackupQueue; // inside mQueueLock
|
@GuardedBy("mQueueLock")
|
||||||
|
PerformFullTransportBackupTask mRunningFullBackupTask;
|
||||||
|
|
||||||
|
@GuardedBy("mQueueLock")
|
||||||
|
ArrayList<FullBackupEntry> mFullBackupQueue;
|
||||||
|
|
||||||
// Utility: build a new random integer token
|
// Utility: build a new random integer token
|
||||||
int generateToken() {
|
int generateToken() {
|
||||||
@@ -1229,8 +1233,10 @@ public class BackupManagerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (mQueueLock) {
|
||||||
// Resume the full-data backup queue
|
// Resume the full-data backup queue
|
||||||
mFullBackupQueue = readFullBackupSchedule();
|
mFullBackupQueue = readFullBackupSchedule();
|
||||||
|
}
|
||||||
|
|
||||||
// Register for broadcasts about package install, etc., so we can
|
// Register for broadcasts about package install, etc., so we can
|
||||||
// update the provider list.
|
// update the provider list.
|
||||||
@@ -1248,8 +1254,11 @@ public class BackupManagerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<FullBackupEntry> readFullBackupSchedule() {
|
private ArrayList<FullBackupEntry> readFullBackupSchedule() {
|
||||||
|
boolean changed = false;
|
||||||
ArrayList<FullBackupEntry> schedule = null;
|
ArrayList<FullBackupEntry> schedule = null;
|
||||||
synchronized (mQueueLock) {
|
List<PackageInfo> apps =
|
||||||
|
PackageManagerBackupAgent.getStorableApplications(mPackageManager);
|
||||||
|
|
||||||
if (mFullBackupScheduleFile.exists()) {
|
if (mFullBackupScheduleFile.exists()) {
|
||||||
FileInputStream fstream = null;
|
FileInputStream fstream = null;
|
||||||
BufferedInputStream bufStream = null;
|
BufferedInputStream bufStream = null;
|
||||||
@@ -1265,15 +1274,22 @@ public class BackupManagerService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
int N = in.readInt();
|
final int N = in.readInt();
|
||||||
schedule = new ArrayList<FullBackupEntry>(N);
|
schedule = new ArrayList<FullBackupEntry>(N);
|
||||||
|
|
||||||
|
// HashSet instead of ArraySet specifically because we want the eventual
|
||||||
|
// lookups against O(hundreds) of entries to be as fast as possible, and
|
||||||
|
// we discard the set immediately after the scan so the extra memory
|
||||||
|
// overhead is transient.
|
||||||
|
HashSet<String> foundApps = new HashSet<String>(N);
|
||||||
|
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
String pkgName = in.readUTF();
|
String pkgName = in.readUTF();
|
||||||
long lastBackup = in.readLong();
|
long lastBackup = in.readLong();
|
||||||
|
foundApps.add(pkgName); // all apps that we've addressed already
|
||||||
try {
|
try {
|
||||||
PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0);
|
PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0);
|
||||||
if (appGetsFullBackup(pkg)
|
if (appGetsFullBackup(pkg) && appIsEligibleForBackup(pkg.applicationInfo)) {
|
||||||
&& appIsEligibleForBackup(pkg.applicationInfo)) {
|
|
||||||
schedule.add(new FullBackupEntry(pkgName, lastBackup));
|
schedule.add(new FullBackupEntry(pkgName, lastBackup));
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@@ -1288,6 +1304,21 @@ public class BackupManagerService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New apps can arrive "out of band" via OTA and similar, so we also need to
|
||||||
|
// scan to make sure that we're tracking all full-backup candidates properly
|
||||||
|
for (PackageInfo app : apps) {
|
||||||
|
if (appGetsFullBackup(app) && appIsEligibleForBackup(app.applicationInfo)) {
|
||||||
|
if (!foundApps.contains(app.packageName)) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.i(TAG, "New full backup app " + app.packageName + " found");
|
||||||
|
}
|
||||||
|
schedule.add(new FullBackupEntry(app.packageName, 0));
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Collections.sort(schedule);
|
Collections.sort(schedule);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Slog.e(TAG, "Unable to read backup schedule", e);
|
Slog.e(TAG, "Unable to read backup schedule", e);
|
||||||
@@ -1303,18 +1334,17 @@ public class BackupManagerService {
|
|||||||
if (schedule == null) {
|
if (schedule == null) {
|
||||||
// no prior queue record, or unable to read it. Set up the queue
|
// no prior queue record, or unable to read it. Set up the queue
|
||||||
// from scratch.
|
// from scratch.
|
||||||
List<PackageInfo> apps =
|
changed = true;
|
||||||
PackageManagerBackupAgent.getStorableApplications(mPackageManager);
|
schedule = new ArrayList<FullBackupEntry>(apps.size());
|
||||||
final int N = apps.size();
|
for (PackageInfo info : apps) {
|
||||||
schedule = new ArrayList<FullBackupEntry>(N);
|
|
||||||
for (int i = 0; i < N; i++) {
|
|
||||||
PackageInfo info = apps.get(i);
|
|
||||||
if (appGetsFullBackup(info) && appIsEligibleForBackup(info.applicationInfo)) {
|
if (appGetsFullBackup(info) && appIsEligibleForBackup(info.applicationInfo)) {
|
||||||
schedule.add(new FullBackupEntry(info.packageName, 0));
|
schedule.add(new FullBackupEntry(info.packageName, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeFullBackupScheduleAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
writeFullBackupScheduleAsync();
|
||||||
}
|
}
|
||||||
return schedule;
|
return schedule;
|
||||||
}
|
}
|
||||||
@@ -4313,8 +4343,10 @@ public class BackupManagerService {
|
|||||||
|
|
||||||
// This is also slow but easy for modest numbers of apps: work backwards
|
// This is also slow but easy for modest numbers of apps: work backwards
|
||||||
// from the end of the queue until we find an item whose last backup
|
// from the end of the queue until we find an item whose last backup
|
||||||
// time was before this one, then insert this new entry after it.
|
// time was before this one, then insert this new entry after it. If we're
|
||||||
int which;
|
// adding something new we don't bother scanning, and just prepend.
|
||||||
|
int which = -1;
|
||||||
|
if (lastBackedUp > 0) {
|
||||||
for (which = mFullBackupQueue.size() - 1; which >= 0; which--) {
|
for (which = mFullBackupQueue.size() - 1; which >= 0; which--) {
|
||||||
final FullBackupEntry entry = mFullBackupQueue.get(which);
|
final FullBackupEntry entry = mFullBackupQueue.get(which);
|
||||||
if (entry.lastBackup <= lastBackedUp) {
|
if (entry.lastBackup <= lastBackedUp) {
|
||||||
@@ -4322,6 +4354,7 @@ public class BackupManagerService {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (which < 0) {
|
if (which < 0) {
|
||||||
// this one is earlier than any existing one, so prepend
|
// this one is earlier than any existing one, so prepend
|
||||||
mFullBackupQueue.add(0, newEntry);
|
mFullBackupQueue.add(0, newEntry);
|
||||||
|
|||||||
Reference in New Issue
Block a user