summaryrefslogtreecommitdiff
path: root/packages/WallpaperBackup
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2016-07-18 17:31:02 -0700
committerChristopher Tate <ctate@google.com>2016-07-18 17:38:41 -0700
commitac482ebb00c8217d86227dde08b33a37b04ece68 (patch)
tree87c4ccfc97a3355de0f70b89b7bb587c0462eb30 /packages/WallpaperBackup
parent74171f88c28fb177bd6b2777b72b0e36cead03d9 (diff)
Back up wallpapers via staged copies, not hard links
File-based encryption regimes turn out to make the zero-copy approach unworkable. We now copy the file to the local stage for backup purposes, making sure only to refresh the copy when it changes. Bug 30201058 Change-Id: Ie3f29ed63f778e3e0e00d1cf56b0bb37553b7823
Diffstat (limited to 'packages/WallpaperBackup')
-rw-r--r--packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java71
1 files changed, 49 insertions, 22 deletions
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 05207b9f6b00..402d9adf0e7c 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -16,17 +16,21 @@
package com.android.wallpaperbackup;
+import static android.app.WallpaperManager.FLAG_LOCK;
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+
import android.app.WallpaperManager;
import android.app.backup.BackupAgent;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.FullBackupDataOutput;
import android.content.Context;
+import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
-import android.system.Os;
import android.util.Slog;
import android.util.Xml;
@@ -40,7 +44,7 @@ import java.nio.charset.StandardCharsets;
public class WallpaperBackupAgent extends BackupAgent {
private static final String TAG = "WallpaperBackup";
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
// NB: must be kept in sync with WallpaperManagerService but has no
// compile-time visibility.
@@ -57,6 +61,11 @@ public class WallpaperBackupAgent extends BackupAgent {
static final String EMPTY_SENTINEL = "empty";
static final String QUOTA_SENTINEL = "quota";
+ // Not-for-backup bookkeeping
+ static final String PREFS_NAME = "wbprefs.xml";
+ static final String SYSTEM_GENERATION = "system_gen";
+ static final String LOCK_GENERATION = "lock_gen";
+
private File mWallpaperInfo; // wallpaper metadata file
private File mWallpaperFile; // primary wallpaper image file
private File mLockWallpaperFile; // lock wallpaper image file
@@ -106,27 +115,48 @@ public class WallpaperBackupAgent extends BackupAgent {
// only back up the wallpaper if we've been told it's allowed
if (mWm.isWallpaperBackupEligible()) {
if (DEBUG) {
- Slog.v(TAG, "Wallpaper is backup-eligible; linking & writing");
+ Slog.v(TAG, "Wallpaper is backup-eligible");
}
- // In case of prior muddled state
- infoStage.delete();
- imageStage.delete();
- lockImageStage.delete();
+ SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ final int lastSysGeneration = prefs.getInt(SYSTEM_GENERATION, -1);
+ final int lastLockGeneration = prefs.getInt(LOCK_GENERATION, -1);
+
+ final int sysGeneration =
+ mWm.getWallpaperIdForUser(FLAG_SYSTEM, UserHandle.USER_SYSTEM);
+ final int lockGeneration =
+ mWm.getWallpaperIdForUser(FLAG_LOCK, UserHandle.USER_SYSTEM);
+ final boolean sysChanged = (sysGeneration != lastSysGeneration);
+ final boolean lockChanged = (lockGeneration != lastLockGeneration);
+ if (DEBUG) {
+ Slog.v(TAG, "sysGen=" + sysGeneration + " : sysChanged=" + sysChanged);
+ Slog.v(TAG, "lockGen=" + lockGeneration + " : lockChanged=" + lockChanged);
+ }
if (mWallpaperInfo.exists()) {
- Os.link(mWallpaperInfo.getCanonicalPath(), infoStage.getCanonicalPath());
+ if (sysChanged || lockChanged || !infoStage.exists()) {
+ if (DEBUG) Slog.v(TAG, "New wallpaper configuration; copying");
+ FileUtils.copyFileOrThrow(mWallpaperInfo, infoStage);
+ }
fullBackupFile(infoStage, data);
}
if (mWallpaperFile.exists()) {
- Os.link(mWallpaperFile.getCanonicalPath(), imageStage.getCanonicalPath());
+ if (sysChanged || !imageStage.exists()) {
+ if (DEBUG) Slog.v(TAG, "New system wallpaper; copying");
+ FileUtils.copyFileOrThrow(mWallpaperFile, imageStage);
+ }
fullBackupFile(imageStage, data);
+ prefs.edit().putInt(SYSTEM_GENERATION, sysGeneration).apply();
}
// Don't try to store the lock image if we overran our quota last time
if (mLockWallpaperFile.exists() && !mQuotaExceeded) {
- Os.link(mLockWallpaperFile.getCanonicalPath(), lockImageStage.getCanonicalPath());
+ if (lockChanged || !lockImageStage.exists()) {
+ if (DEBUG) Slog.v(TAG, "New lock wallpaper; copying");
+ FileUtils.copyFileOrThrow(mLockWallpaperFile, lockImageStage);
+ }
fullBackupFile(lockImageStage, data);
+ prefs.edit().putInt(LOCK_GENERATION, lockGeneration).apply();
}
} else {
if (DEBUG) {
@@ -136,13 +166,6 @@ public class WallpaperBackupAgent extends BackupAgent {
} catch (Exception e) {
Slog.e(TAG, "Unable to back up wallpaper", e);
} finally {
- if (DEBUG) {
- Slog.v(TAG, "Removing backup stage links");
- }
- infoStage.delete();
- imageStage.delete();
- lockImageStage.delete();
-
// Even if this time we had to back off on attempting to store the lock image
// due to exceeding the data quota, try again next time. This will alternate
// between "try both" and "only store the primary image" until either there
@@ -189,26 +212,30 @@ public class WallpaperBackupAgent extends BackupAgent {
Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage());
} finally {
if (DEBUG) {
- Slog.v(TAG, "Removing restore stage files");
+ Slog.v(TAG, "Restore finished; clearing backup bookkeeping");
}
infoStage.delete();
imageStage.delete();
lockImageStage.delete();
+
+ SharedPreferences prefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
+ prefs.edit()
+ .putInt(SYSTEM_GENERATION, -1)
+ .putInt(LOCK_GENERATION, -1)
+ .commit();
}
}
private void restoreFromStage(File stage, File info, String hintTag, int which)
throws IOException {
if (stage.exists()) {
- if (DEBUG) {
- Slog.v(TAG, "Got restored wallpaper; applying which=" + which);
- }
// Parse the restored info file to find the crop hint. Note that this currently
// relies on a priori knowledge of the wallpaper info file schema.
Rect cropHint = parseCropHint(info, hintTag);
if (cropHint != null) {
+ Slog.i(TAG, "Got restored wallpaper; applying which=" + which);
if (DEBUG) {
- Slog.v(TAG, "Restored crop hint " + cropHint + "; now writing data");
+ Slog.v(TAG, "Restored crop hint " + cropHint);
}
try (FileInputStream in = new FileInputStream(stage)) {
mWm.setStream(in, cropHint, true, which);