• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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 com.android.server.backup;
18 
19 import android.app.IWallpaperManager;
20 import android.app.backup.BackupAgentHelper;
21 import android.app.backup.BackupDataInput;
22 import android.app.backup.BackupDataOutput;
23 import android.app.backup.FullBackup;
24 import android.app.backup.FullBackupDataOutput;
25 import android.app.backup.WallpaperBackupHelper;
26 import android.content.Context;
27 import android.os.Environment;
28 import android.os.ParcelFileDescriptor;
29 import android.os.RemoteException;
30 import android.os.ServiceManager;
31 import android.os.UserHandle;
32 import android.util.Slog;
33 
34 import java.io.File;
35 import java.io.IOException;
36 
37 /**
38  * Backup agent for various system-managed data, currently just the system wallpaper
39  */
40 public class SystemBackupAgent extends BackupAgentHelper {
41     private static final String TAG = "SystemBackupAgent";
42 
43     // Names of the helper tags within the dataset.  Changing one of these names will
44     // break the ability to restore from datasets that predate the change.
45     private static final String WALLPAPER_HELPER = "wallpaper";
46     private static final String SYNC_SETTINGS_HELPER = "account_sync_settings";
47     private static final String PREFERRED_HELPER = "preferred_activities";
48     private static final String NOTIFICATION_HELPER = "notifications";
49     private static final String PERMISSION_HELPER = "permissions";
50     private static final String USAGE_STATS_HELPER = "usage_stats";
51     private static final String SHORTCUT_MANAGER_HELPER = "shortcut_manager";
52     private static final String ACCOUNT_MANAGER_HELPER = "account_manager";
53 
54     // These paths must match what the WallpaperManagerService uses.  The leaf *_FILENAME
55     // are also used in the full-backup file format, so must not change unless steps are
56     // taken to support the legacy backed-up datasets.
57     private static final String WALLPAPER_IMAGE_FILENAME = "wallpaper";
58     private static final String WALLPAPER_INFO_FILENAME = "wallpaper_info.xml";
59 
60     // TODO: Will need to change if backing up non-primary user's wallpaper
61     // TODO: http://b/22388012
62     private static final String WALLPAPER_IMAGE_DIR =
63             Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath();
64     private static final String WALLPAPER_IMAGE = WallpaperBackupHelper.WALLPAPER_IMAGE;
65 
66     // TODO: Will need to change if backing up non-primary user's wallpaper
67     // TODO: http://b/22388012
68     private static final String WALLPAPER_INFO_DIR =
69             Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath();
70     private static final String WALLPAPER_INFO = WallpaperBackupHelper.WALLPAPER_INFO;
71     // Use old keys to keep legacy data compatibility and avoid writing two wallpapers
72     private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;
73     private static final String WALLPAPER_INFO_KEY = WallpaperBackupHelper.WALLPAPER_INFO_KEY;
74 
75     private WallpaperBackupHelper mWallpaperHelper = null;
76 
77     @Override
onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)78     public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
79             ParcelFileDescriptor newState) throws IOException {
80         addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
81         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
82         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
83         addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
84         addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
85         addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
86         addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
87         super.onBackup(oldState, data, newState);
88     }
89 
90     @Override
onFullBackup(FullBackupDataOutput data)91     public void onFullBackup(FullBackupDataOutput data) throws IOException {
92         // At present we don't back up anything
93     }
94 
95     @Override
onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)96     public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
97             throws IOException {
98         // Slot in a restore helper for the older wallpaper backup schema to support restore
99         // from devices still generating data in that format.
100         mWallpaperHelper = new WallpaperBackupHelper(this,
101                 new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO },
102                 new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} );
103         addHelper(WALLPAPER_HELPER, mWallpaperHelper);
104 
105         // On restore, we also support a long-ago wallpaper data schema "system_files"
106         addHelper("system_files", new WallpaperBackupHelper(this,
107                 new String[] { WALLPAPER_IMAGE },
108                 new String[] { WALLPAPER_IMAGE_KEY} ));
109 
110         addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
111         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
112         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
113         addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
114         addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
115         addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
116         addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
117 
118         try {
119             super.onRestore(data, appVersionCode, newState);
120 
121             IWallpaperManager wallpaper = (IWallpaperManager) ServiceManager.getService(
122                     Context.WALLPAPER_SERVICE);
123             if (wallpaper != null) {
124                 try {
125                     wallpaper.settingsRestored();
126                 } catch (RemoteException re) {
127                     Slog.e(TAG, "Couldn't restore settings\n" + re);
128                 }
129             }
130         } catch (IOException ex) {
131             // If there was a failure, delete everything for the wallpaper, this is too aggressive,
132             // but this is hopefully a rare failure.
133             Slog.d(TAG, "restore failed", ex);
134             (new File(WALLPAPER_IMAGE)).delete();
135             (new File(WALLPAPER_INFO)).delete();
136         }
137     }
138 
139     @Override
onRestoreFile(ParcelFileDescriptor data, long size, int type, String domain, String path, long mode, long mtime)140     public void onRestoreFile(ParcelFileDescriptor data, long size,
141             int type, String domain, String path, long mode, long mtime)
142             throws IOException {
143         Slog.i(TAG, "Restoring file domain=" + domain + " path=" + path);
144 
145         // Bits to indicate postprocessing we may need to perform
146         boolean restoredWallpaper = false;
147 
148         File outFile = null;
149         // Various domain+files we understand a priori
150         if (domain.equals(FullBackup.ROOT_TREE_TOKEN)) {
151             if (path.equals(WALLPAPER_INFO_FILENAME)) {
152                 outFile = new File(WALLPAPER_INFO);
153                 restoredWallpaper = true;
154             } else if (path.equals(WALLPAPER_IMAGE_FILENAME)) {
155                 outFile = new File(WALLPAPER_IMAGE);
156                 restoredWallpaper = true;
157             }
158         }
159 
160         try {
161             if (outFile == null) {
162                 Slog.w(TAG, "Skipping unrecognized system file: [ " + domain + " : " + path + " ]");
163             }
164             FullBackup.restoreFile(data, size, type, mode, mtime, outFile);
165 
166             if (restoredWallpaper) {
167                 IWallpaperManager wallpaper =
168                         (IWallpaperManager)ServiceManager.getService(
169                                 Context.WALLPAPER_SERVICE);
170                 if (wallpaper != null) {
171                     try {
172                         wallpaper.settingsRestored();
173                     } catch (RemoteException re) {
174                         Slog.e(TAG, "Couldn't restore settings\n" + re);
175                     }
176                 }
177             }
178         } catch (IOException e) {
179             if (restoredWallpaper) {
180                 // Make sure we wind up in a good state
181                 (new File(WALLPAPER_IMAGE)).delete();
182                 (new File(WALLPAPER_INFO)).delete();
183             }
184         }
185     }
186 
187     @Override
onRestoreFinished()188     public void onRestoreFinished() {
189         // helper will be null following 'adb restore' or other full-data operation
190         if (mWallpaperHelper != null) {
191             mWallpaperHelper.onRestoreFinished();
192         }
193     }
194 }
195