summaryrefslogtreecommitdiff
path: root/packages/WallpaperBackup
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2016-02-25 12:43:38 -0800
committerChristopher Tate <ctate@google.com>2016-04-20 14:34:07 -0700
commitd7faf53605838487cace9979e577005cc7c8cabc (patch)
tree775e47954ed2443bb60381e8f39145d3a7c57a33 /packages/WallpaperBackup
parent66e640d8b459ff285c7d9533f97990e92f9cc0da (diff)
Don't back up wallpapers that we've been told not to
In addition, now that the full uncropped wallpaper image is being backed up, we now handle that via the full-data backup path instead of key/value. Restore still knows about legacy data that gets delivered via the older key/value mechanism. This change also has the effect of removing the size limitations around wallpaper restore acceptance. Any size source imagery is valid, as crop & scale are rerun in a device-appropriate way after the restore. Bug 25453848 Bug 25727875 Change-Id: Idc64a2eaab97a8ecc9d2b8ca5dc011f29cab324d
Diffstat (limited to 'packages/WallpaperBackup')
-rw-r--r--packages/WallpaperBackup/Android.mk34
-rw-r--r--packages/WallpaperBackup/AndroidManifest.xml30
-rw-r--r--packages/WallpaperBackup/proguard.flags1
-rw-r--r--packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java164
4 files changed, 229 insertions, 0 deletions
diff --git a/packages/WallpaperBackup/Android.mk b/packages/WallpaperBackup/Android.mk
new file mode 100644
index 000000000000..cf0424966c10
--- /dev/null
+++ b/packages/WallpaperBackup/Android.mk
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+LOCAL_PACKAGE_NAME := WallpaperBackup
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := false
+
+include $(BUILD_PACKAGE)
+
+########################
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/packages/WallpaperBackup/AndroidManifest.xml b/packages/WallpaperBackup/AndroidManifest.xml
new file mode 100644
index 000000000000..b8cea20afcd4
--- /dev/null
+++ b/packages/WallpaperBackup/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2016 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wallpaperbackup"
+ android:sharedUserId="android.uid.system" >
+
+ <application android:allowClearUserData="false"
+ android:process="system"
+ android:killAfterRestore="false"
+ android:allowBackup="true"
+ android:backupAgent=".WallpaperBackupAgent"
+ android:fullBackupOnly="true" >
+ </application>
+</manifest>
diff --git a/packages/WallpaperBackup/proguard.flags b/packages/WallpaperBackup/proguard.flags
new file mode 100644
index 000000000000..247e6efb10ef
--- /dev/null
+++ b/packages/WallpaperBackup/proguard.flags
@@ -0,0 +1 @@
+-keep class com.android.wallpaperbackup.WallpaperBackupAgent
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
new file mode 100644
index 000000000000..2f79079c9188
--- /dev/null
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wallpaperbackup;
+
+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.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.UserHandle;
+import android.system.Os;
+import android.util.Slog;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class WallpaperBackupAgent extends BackupAgent {
+ private static final String TAG = "WallpaperBackup";
+ private static final boolean DEBUG = false;
+
+ // NB: must be kept in sync with WallpaperManagerService but has no
+ // compile-time visiblity.
+
+ // Target filenames within the system's wallpaper directory
+ static final String WALLPAPER = "wallpaper_orig";
+ static final String WALLPAPER_INFO = "wallpaper_info.xml";
+
+ // Names of our local-data stage files/links
+ static final String IMAGE_STAGE = "wallpaper-stage";
+ static final String INFO_STAGE = "wallpaper-info-stage";
+ static final String EMPTY_SENTINEL = "empty";
+
+ private File mWallpaperInfo; // wallpaper metadata file
+ private File mWallpaperFile; // primary wallpaper image file
+
+ private WallpaperManager mWm;
+
+ @Override
+ public void onCreate() {
+ if (DEBUG) {
+ Slog.v(TAG, "onCreate()");
+ }
+
+ File wallpaperDir = Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM);
+ mWallpaperInfo = new File(wallpaperDir, WALLPAPER_INFO);
+ mWallpaperFile = new File(wallpaperDir, WALLPAPER);
+ mWm = (WallpaperManager) getSystemService(Context.WALLPAPER_SERVICE);
+ }
+
+ @Override
+ public void onFullBackup(FullBackupDataOutput data) throws IOException {
+ // To avoid data duplication and disk churn, use links as the stage.
+ final File filesDir = getFilesDir();
+ final File infoStage = new File(filesDir, INFO_STAGE);
+ final File imageStage = new File (filesDir, IMAGE_STAGE);
+ final File empty = new File (filesDir, EMPTY_SENTINEL);
+
+ try {
+ // We always back up this 'empty' file to ensure that the absence of
+ // storable wallpaper imagery still produces a non-empty backup data
+ // stream, otherwise it'd simply be ignored in preflight.
+ FileOutputStream touch = new FileOutputStream(empty);
+ touch.close();
+ fullBackupFile(empty, data);
+
+ // 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");
+ }
+ Os.link(mWallpaperInfo.getCanonicalPath(), infoStage.getCanonicalPath());
+ fullBackupFile(infoStage, data);
+ Os.link(mWallpaperFile.getCanonicalPath(), imageStage.getCanonicalPath());
+ fullBackupFile(imageStage, data);
+ } else {
+ if (DEBUG) {
+ Slog.v(TAG, "Wallpaper not backup-eligible; writing no data");
+ }
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to back up wallpaper: " + e.getMessage());
+ } finally {
+ if (DEBUG) {
+ Slog.v(TAG, "Removing backup stage links");
+ }
+ infoStage.delete();
+ imageStage.delete();
+ }
+ }
+
+ // We use the default onRestoreFile() implementation that will recreate our stage files,
+ // then postprocess in onRestoreFinished() to move them on top of the live data.
+ //
+ // NOTE: this relies on our local files dir being on the same filesystem as the live
+ // system wallpaper data. If this is not the case then an actual copy operation will
+ // be needed.
+ @Override
+ public void onRestoreFinished() {
+ if (DEBUG) {
+ Slog.v(TAG, "onRestoreFinished()");
+ }
+ final File infoStage = new File(getFilesDir(), INFO_STAGE);
+ final File imageStage = new File (getFilesDir(), IMAGE_STAGE);
+
+ try {
+ // It is valid for the imagery to be absent; it means that we were not permitted
+ // to back up the original image on the source device.
+ if (imageStage.exists()) {
+ if (DEBUG) {
+ Slog.v(TAG, "Got restored wallpaper; renaming into place");
+ }
+ // Rename the image file into place last because that is the trigger for
+ // the wallpaper observer to generate a new crop/scale
+ Os.rename(infoStage.getCanonicalPath(), mWallpaperInfo.getCanonicalPath());
+ Os.rename(imageStage.getCanonicalPath(), mWallpaperFile.getCanonicalPath());
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to restore wallpaper: " + e.getMessage());
+ mWm.clearWallpaper(WallpaperManager.FLAG_SYSTEM, UserHandle.USER_SYSTEM);
+ } finally {
+ // These "should" not exist because of the renames, but make sure
+ // in case of errors/exceptions/etc.
+ if (DEBUG) {
+ Slog.v(TAG, "Removing restore stage files");
+ }
+ infoStage.delete();
+ imageStage.delete();
+ }
+ }
+
+ //
+ // Key/value API: abstract, so required, but not used
+ //
+
+ @Override
+ public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) throws IOException {
+ // Intentionally blank
+ }
+
+ @Override
+ public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
+ throws IOException {
+ // Intentionally blank
+ }
+} \ No newline at end of file