summaryrefslogtreecommitdiff
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
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
-rw-r--r--core/java/android/app/IWallpaperManager.aidl8
-rw-r--r--core/java/android/app/WallpaperManager.java29
-rw-r--r--core/java/com/android/server/backup/SystemBackupAgent.java38
-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
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java78
8 files changed, 320 insertions, 62 deletions
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 2fc6533f2cd0..a42aed6fe28a 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -43,7 +43,8 @@ interface IWallpaperManager {
* new wallpaper content is ready to display.
*/
ParcelFileDescriptor setWallpaper(String name, in String callingPackage,
- in Rect cropHint, out Bundle extras, int which, IWallpaperManagerCallback completion);
+ in Rect cropHint, boolean allowBackup, out Bundle extras, int which,
+ IWallpaperManagerCallback completion);
/**
* Set the live wallpaper. This only affects the system wallpaper.
@@ -125,6 +126,11 @@ interface IWallpaperManager {
boolean isWallpaperSettingAllowed(in String callingPackage);
/*
+ * Backup: is the current system wallpaper image eligible for off-device backup?
+ */
+ boolean isWallpaperBackupEligible(int userId);
+
+ /*
* Keyguard: register a callback for being notified that lock-state relevant
* wallpaper content has changed.
*/
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 72b9318c2acd..18a559368e66 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -1,5 +1,5 @@
/*
-h * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2009 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.
@@ -875,7 +875,7 @@ public class WallpaperManager {
/* Set the wallpaper to the default values */
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(
"res:" + resources.getResourceName(resid),
- mContext.getOpPackageName(), null, result, which, completion);
+ mContext.getOpPackageName(), null, false, result, which, completion);
if (fd != null) {
FileOutputStream fos = null;
boolean ok = false;
@@ -985,7 +985,8 @@ public class WallpaperManager {
final WallpaperSetCompletion completion = new WallpaperSetCompletion();
try {
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
- mContext.getOpPackageName(), visibleCropHint, result, which, completion);
+ mContext.getOpPackageName(), visibleCropHint, allowBackup,
+ result, which, completion);
if (fd != null) {
FileOutputStream fos = null;
try {
@@ -1102,7 +1103,8 @@ public class WallpaperManager {
final WallpaperSetCompletion completion = new WallpaperSetCompletion();
try {
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
- mContext.getOpPackageName(), visibleCropHint, result, which, completion);
+ mContext.getOpPackageName(), visibleCropHint, allowBackup,
+ result, which, completion);
if (fd != null) {
FileOutputStream fos = null;
try {
@@ -1565,6 +1567,25 @@ public class WallpaperManager {
}
}
+ /**
+ * Is the current system wallpaper eligible for backup?
+ *
+ * Only the OS itself may use this method.
+ * @hide
+ */
+ public boolean isWallpaperBackupEligible() {
+ if (sGlobals.mService == null) {
+ Log.w(TAG, "WallpaperService not running");
+ return false;
+ }
+ try {
+ return sGlobals.mService.isWallpaperBackupEligible(mContext.getUserId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Exception querying wallpaper backup eligibility: " + e.getMessage());
+ }
+ return false;
+ }
+
// Private completion callback for setWallpaper() synchronization
private class WallpaperSetCompletion extends IWallpaperManagerCallback.Stub {
final CountDownLatch mLatch;
diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java
index 2d12fcda87c1..3e4530944b9e 100644
--- a/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -76,26 +76,6 @@ public class SystemBackupAgent extends BackupAgentHelper {
@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) throws IOException {
- // We only back up the data under the current "wallpaper" schema with metadata
- IWallpaperManager wallpaper = (IWallpaperManager)ServiceManager.getService(
- Context.WALLPAPER_SERVICE);
- String[] files = new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO };
- String[] keys = new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY };
- if (wallpaper != null) {
- try {
- final String wallpaperName = wallpaper.getName();
- if (wallpaperName != null && wallpaperName.length() > 0) {
- // When the wallpaper has a name, back up the info by itself.
- // TODO: Don't rely on the innards of the service object like this!
- // TODO: Send a delete for any stored wallpaper image in this case?
- files = new String[] { WALLPAPER_INFO };
- keys = new String[] { WALLPAPER_INFO_KEY };
- }
- } catch (RemoteException re) {
- Slog.e(TAG, "Couldn't get wallpaper name\n" + re);
- }
- }
- addHelper(WALLPAPER_HELPER, new WallpaperBackupHelper(this, files, keys));
addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
@@ -107,30 +87,20 @@ public class SystemBackupAgent extends BackupAgentHelper {
@Override
public void onFullBackup(FullBackupDataOutput data) throws IOException {
- // At present we back up only the wallpaper
- fullWallpaperBackup(data);
- }
-
- private void fullWallpaperBackup(FullBackupDataOutput output) {
- // Back up the data files directly. We do them in this specific order --
- // info file followed by image -- because then we need take no special
- // steps during restore; the restore will happen properly when the individual
- // files are restored piecemeal.
- FullBackup.backupToTar(getPackageName(), FullBackup.ROOT_TREE_TOKEN, null,
- WALLPAPER_INFO_DIR, WALLPAPER_INFO, output);
- FullBackup.backupToTar(getPackageName(), FullBackup.ROOT_TREE_TOKEN, null,
- WALLPAPER_IMAGE_DIR, WALLPAPER_IMAGE, output);
+ // At present we don't back up anything
}
@Override
public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
throws IOException {
+ // Slot in a restore helper for the older wallpaper backup schema to support restore
+ // from devices still generating data in that format.
mWallpaperHelper = new WallpaperBackupHelper(this,
new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO },
new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} );
addHelper(WALLPAPER_HELPER, mWallpaperHelper);
- // On restore, we also support a previous data schema "system_files"
+ // On restore, we also support a long-ago wallpaper data schema "system_files"
addHelper("system_files", new WallpaperBackupHelper(this,
new String[] { WALLPAPER_IMAGE },
new String[] { WALLPAPER_IMAGE_KEY} ));
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
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 91b6914e7621..d6ace91f64d4 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -34,7 +34,6 @@ import android.app.PendingIntent;
import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.app.admin.DevicePolicyManager;
-import android.app.backup.BackupManager;
import android.app.backup.WallpaperBackupHelper;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -61,6 +60,7 @@ import android.os.FileObserver;
import android.os.FileUtils;
import android.os.IBinder;
import android.os.IRemoteCallback;
+import android.os.Process;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
@@ -205,7 +205,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
if (path == null) {
return;
}
- final boolean written = (event == CLOSE_WRITE || event == MOVED_TO);
+ final boolean moved = (event == MOVED_TO);
+ final boolean written = (event == CLOSE_WRITE || moved);
final File changedFile = new File(mWallpaperDir, path);
// System and system+lock changes happen on the system wallpaper input file;
@@ -224,13 +225,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
+ " written=" + written);
}
synchronized (mLock) {
- if (sysWallpaperChanged || mWallpaperInfoFile.equals(changedFile)) {
- // changing the wallpaper means we'll need to back up the new one
- long origId = Binder.clearCallingIdentity();
- BackupManager bm = new BackupManager(mContext);
- bm.dataChanged();
- Binder.restoreCallingIdentity(origId);
- }
if (sysWallpaperChanged || lockWallpaperChanged) {
notifyCallbacksLocked(wallpaper);
if (wallpaper.wallpaperComponent == null
@@ -244,6 +238,14 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
if (DEBUG) {
Slog.v(TAG, "Wallpaper written; generating crop");
}
+ if (moved) {
+ // This is a restore, so generate the crop using any just-restored new
+ // crop guidelines, making sure to preserve our local dimension hints.
+ if (DEBUG) {
+ Slog.v(TAG, "moved-to, therefore restore; reloading metadata");
+ }
+ loadSettingsLocked(wallpaper.userId, true);
+ }
generateCrop(wallpaper);
if (DEBUG) {
Slog.v(TAG, "Crop done; invoking completion callback");
@@ -491,6 +493,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
IWallpaperManagerCallback setComplete;
/**
+ * Is the OS allowed to back up this wallpaper imagery?
+ */
+ boolean allowBackup;
+
+ /**
* Resource name if using a picture from the wallpaper gallery
*/
String name = "";
@@ -811,7 +818,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
mMonitor = new MyPackageMonitor();
mMonitor.register(context, null, UserHandle.ALL, true);
getWallpaperDir(UserHandle.USER_SYSTEM).mkdirs();
- loadSettingsLocked(UserHandle.USER_SYSTEM);
+ loadSettingsLocked(UserHandle.USER_SYSTEM, false);
}
private static File getWallpaperDir(int userId) {
@@ -1024,7 +1031,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
// Might need to bring it in the first time to establish our rewrite
- loadSettingsLocked(userId);
+ loadSettingsLocked(userId, false);
wallpaper = mWallpaperMap.get(userId);
}
}
@@ -1102,7 +1109,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
WallpaperData wd = mWallpaperMap.get(user.id);
if (wd == null) {
// User hasn't started yet, so load her settings to peek at the wallpaper
- loadSettingsLocked(user.id);
+ loadSettingsLocked(user.id, false);
wd = mWallpaperMap.get(user.id);
}
if (wd != null && name.equals(wd.name)) {
@@ -1235,7 +1242,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
if (wallpaper == null) {
// common case, this is the first lookup post-boot of the system or
// unified lock, so we bring up the saved state lazily now and recheck.
- loadSettingsLocked(wallpaperUserId);
+ loadSettingsLocked(wallpaperUserId, false);
wallpaper = whichSet.get(wallpaperUserId);
if (wallpaper == null) {
return null;
@@ -1304,7 +1311,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
@Override
public ParcelFileDescriptor setWallpaper(String name, String callingPackage,
- Rect cropHint, Bundle extras, int which, IWallpaperManagerCallback completion) {
+ Rect cropHint, boolean allowBackup, Bundle extras, int which,
+ IWallpaperManagerCallback completion) {
checkPermission(android.Manifest.permission.SET_WALLPAPER);
if ((which & (FLAG_LOCK|FLAG_SYSTEM)) == 0) {
@@ -1342,6 +1350,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper.whichPending = which;
wallpaper.setComplete = completion;
wallpaper.cropHint.set(cropHint);
+ if ((which & FLAG_SYSTEM) != 0) {
+ wallpaper.allowBackup = allowBackup;
+ }
}
return pfd;
} finally {
@@ -1651,6 +1662,16 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
return !um.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER);
}
+ @Override
+ public boolean isWallpaperBackupEligible(int userId) {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException("Only the system may call isWallpaperBackupEligible");
+ }
+
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId, FLAG_SYSTEM);
+ return (wallpaper != null) ? wallpaper.allowBackup : false;
+ }
+
private static JournaledFile makeJournaledFile(int userId) {
final String base = new File(getWallpaperDir(userId), WALLPAPER_INFO).getAbsolutePath();
return new JournaledFile(new File(base), new File(base + ".tmp"));
@@ -1721,6 +1742,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
out.attribute(null, "component",
wallpaper.wallpaperComponent.flattenToShortString());
}
+
+ if (wallpaper.allowBackup) {
+ out.attribute(null, "backup", "true");
+ }
+
out.endTag(null, tag);
}
@@ -1764,7 +1790,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
if (wallpaper == null) {
// common case, this is the first lookup post-boot of the system or
// unified lock, so we bring up the saved state lazily now and recheck.
- loadSettingsLocked(userId);
+ loadSettingsLocked(userId, false);
wallpaper = whichSet.get(userId);
// if it's still null here, this is a lock-only operation and there is not
// yet a lock-only wallpaper set for this user, so we need to establish
@@ -1788,7 +1814,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
return wallpaper;
}
- private void loadSettingsLocked(int userId) {
+ private void loadSettingsLocked(int userId, boolean keepDimensionHints) {
if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
JournaledFile journal = makeJournaledFile(userId);
@@ -1801,6 +1827,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
WallpaperData wallpaper = mWallpaperMap.get(userId);
if (wallpaper == null) {
wallpaper = new WallpaperData(userId, WALLPAPER, WALLPAPER_CROP);
+ wallpaper.allowBackup = true;
mWallpaperMap.put(userId, wallpaper);
if (!wallpaper.cropExists()) {
generateCrop(wallpaper);
@@ -1819,7 +1846,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
String tag = parser.getName();
if ("wp".equals(tag)) {
// Common to system + lock wallpapers
- parseWallpaperAttributes(parser, wallpaper);
+ parseWallpaperAttributes(parser, wallpaper, keepDimensionHints);
// A system wallpaper might also be a live wallpaper
String comp = parser.getAttributeValue(null, "component");
@@ -1848,7 +1875,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
WALLPAPER_LOCK_ORIG, WALLPAPER_LOCK_CROP);
mLockWallpaperMap.put(userId, lockWallpaper);
}
- parseWallpaperAttributes(parser, lockWallpaper);
+ parseWallpaperAttributes(parser, lockWallpaper, false);
}
}
} while (type != XmlPullParser.END_DOCUMENT);
@@ -1909,7 +1936,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
- private void parseWallpaperAttributes(XmlPullParser parser, WallpaperData wallpaper) {
+ private void parseWallpaperAttributes(XmlPullParser parser, WallpaperData wallpaper,
+ boolean keepDimensionHints) {
final String idString = parser.getAttributeValue(null, "id");
if (idString != null) {
final int id = wallpaper.wallpaperId = Integer.parseInt(idString);
@@ -1920,9 +1948,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper.wallpaperId = makeWallpaperIdLocked();
}
- wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
- wallpaper.height = Integer.parseInt(parser
- .getAttributeValue(null, "height"));
+ if (!keepDimensionHints) {
+ wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
+ wallpaper.height = Integer.parseInt(parser
+ .getAttributeValue(null, "height"));
+ }
wallpaper.cropHint.left = getAttributeInt(parser, "cropLeft", 0);
wallpaper.cropHint.top = getAttributeInt(parser, "cropTop", 0);
wallpaper.cropHint.right = getAttributeInt(parser, "cropRight", 0);
@@ -1932,6 +1962,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
wallpaper.padding.right = getAttributeInt(parser, "paddingRight", 0);
wallpaper.padding.bottom = getAttributeInt(parser, "paddingBottom", 0);
wallpaper.name = parser.getAttributeValue(null, "name");
+ wallpaper.allowBackup = "true".equals(parser.getAttributeValue(null, "backup"));
}
private int getMaximumSizeDimension() {
@@ -1952,9 +1983,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub {
WallpaperData wallpaper = null;
boolean success = false;
synchronized (mLock) {
- loadSettingsLocked(UserHandle.USER_SYSTEM);
+ loadSettingsLocked(UserHandle.USER_SYSTEM, false);
wallpaper = mWallpaperMap.get(UserHandle.USER_SYSTEM);
wallpaper.wallpaperId = makeWallpaperIdLocked(); // always bump id at restore
+ wallpaper.allowBackup = true; // by definition if it was restored
if (wallpaper.nextWallpaperComponent != null
&& !wallpaper.nextWallpaperComponent.equals(mImageWallpaper)) {
if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,