1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.backup;
18 
19 import android.app.WallpaperManager;
20 import android.content.Context;
21 import android.os.Environment;
22 import android.os.ParcelFileDescriptor;
23 import android.os.UserHandle;
24 import android.util.Slog;
25 
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.IOException;
29 
30 /**
31  * We no longer back up wallpapers with this helper, but we do need to process restores
32  * of legacy backup payloads.  We just take the restored image as-is and apply it as the
33  * system wallpaper using the public "set the wallpaper" API.
34  *
35  * @hide
36  */
37 public class WallpaperBackupHelper extends FileBackupHelperBase implements BackupHelper {
38     private static final String TAG = "WallpaperBackupHelper";
39     private static final boolean DEBUG = false;
40 
41     // Key that legacy wallpaper imagery was stored under
42     public static final String WALLPAPER_IMAGE_KEY =
43             "/data/data/com.android.settings/files/wallpaper";
44     public static final String WALLPAPER_INFO_KEY = "/data/system/wallpaper_info.xml";
45 
46     // Stage file that the restored imagery is stored to prior to being applied
47     // as the system wallpaper.
48     private static final String STAGE_FILE =
49             new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
50                     "wallpaper-tmp").getAbsolutePath();
51 
52     private final String[] mKeys;
53     private final WallpaperManager mWpm;
54 
55     /**
56      * Legacy wallpaper restores, from back when the imagery was stored under the
57      * "android" system package as file key/value entities.
58      *
59      * @param context
60      * @param files
61      */
WallpaperBackupHelper(Context context, String[] keys)62     public WallpaperBackupHelper(Context context, String[] keys) {
63         super(context);
64 
65         mContext = context;
66         mKeys = keys;
67 
68         mWpm = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE);
69     }
70 
71     /**
72      * Based on oldState, determine which of the files from the application's data directory
73      * need to be backed up, write them to the data stream, and fill in newState with the
74      * state as it exists now.
75      */
76     @Override
performBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)77     public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
78             ParcelFileDescriptor newState) {
79         // Intentionally no-op; we don't back up the wallpaper this way any more.
80     }
81 
82     /**
83      * Restore one absolute file entity from the restore stream.  If we're restoring the
84      * magic wallpaper file, apply it as the system wallpaper.
85      */
86     @Override
restoreEntity(BackupDataInputStream data)87     public void restoreEntity(BackupDataInputStream data) {
88         if (mWpm == null) {
89             Slog.w(TAG, "restoreEntity(): no wallpaper service");
90             return;
91         }
92         final String key = data.getKey();
93         if (isKeyInList(key, mKeys)) {
94             if (key.equals(WALLPAPER_IMAGE_KEY)) {
95                 // restore the file to the stage for inspection
96                 File stage = new File(STAGE_FILE);
97                 try {
98                     if (writeFile(stage, data)) {
99                         try (FileInputStream in = new FileInputStream(stage)) {
100                             mWpm.setStream(in);
101                         } catch (IOException e) {
102                             Slog.e(TAG, "Unable to set restored wallpaper: " + e.getMessage());
103                         }
104                     } else {
105                         Slog.e(TAG, "Unable to save restored wallpaper");
106                     }
107                 } finally {
108                     stage.delete();
109                 }
110             }
111         }
112     }
113 }
114