SystemBackupAgent.java revision 11ae768cf1b8348e761ad9c09e98788da1e591b1
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 17package com.android.server.backup; 18 19 20import android.app.ActivityManagerNative; 21import android.app.IWallpaperManager; 22import android.app.backup.BackupDataInput; 23import android.app.backup.BackupDataOutput; 24import android.app.backup.BackupAgentHelper; 25import android.app.backup.FullBackup; 26import android.app.backup.FullBackupDataOutput; 27import android.app.backup.RecentsBackupHelper; 28import android.app.backup.WallpaperBackupHelper; 29import android.content.Context; 30import android.os.Environment; 31import android.os.ParcelFileDescriptor; 32import android.os.RemoteException; 33import android.os.ServiceManager; 34import android.os.UserHandle; 35import android.util.Slog; 36 37import java.io.File; 38import java.io.IOException; 39 40/** 41 * Backup agent for various system-managed data, currently just the system wallpaper 42 */ 43public class SystemBackupAgent extends BackupAgentHelper { 44 private static final String TAG = "SystemBackupAgent"; 45 46 // These paths must match what the WallpaperManagerService uses. The leaf *_FILENAME 47 // are also used in the full-backup file format, so must not change unless steps are 48 // taken to support the legacy backed-up datasets. 49 private static final String WALLPAPER_IMAGE_FILENAME = "wallpaper"; 50 private static final String WALLPAPER_INFO_FILENAME = "wallpaper_info.xml"; 51 52 // TODO: Will need to change if backing up non-primary user's wallpaper 53 private static final String WALLPAPER_IMAGE_DIR = 54 Environment.getUserSystemDirectory(UserHandle.USER_OWNER).getAbsolutePath(); 55 private static final String WALLPAPER_IMAGE = WallpaperBackupHelper.WALLPAPER_IMAGE; 56 57 // TODO: Will need to change if backing up non-primary user's wallpaper 58 private static final String WALLPAPER_INFO_DIR = 59 Environment.getUserSystemDirectory(UserHandle.USER_OWNER).getAbsolutePath(); 60 private static final String WALLPAPER_INFO = WallpaperBackupHelper.WALLPAPER_INFO; 61 // Use old keys to keep legacy data compatibility and avoid writing two wallpapers 62 private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY; 63 private static final String WALLPAPER_INFO_KEY = WallpaperBackupHelper.WALLPAPER_INFO_KEY; 64 65 @Override 66 public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, 67 ParcelFileDescriptor newState) throws IOException { 68 // We only back up the data under the current "wallpaper" schema with metadata 69 IWallpaperManager wallpaper = (IWallpaperManager)ServiceManager.getService( 70 Context.WALLPAPER_SERVICE); 71 String[] files = new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }; 72 String[] keys = new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY }; 73 if (wallpaper != null) { 74 try { 75 final String wallpaperName = wallpaper.getName(); 76 if (wallpaperName != null && wallpaperName.length() > 0) { 77 // When the wallpaper has a name, back up the info by itself. 78 // TODO: Don't rely on the innards of the service object like this! 79 // TODO: Send a delete for any stored wallpaper image in this case? 80 files = new String[] { WALLPAPER_INFO }; 81 keys = new String[] { WALLPAPER_INFO_KEY }; 82 } 83 } catch (RemoteException re) { 84 Slog.e(TAG, "Couldn't get wallpaper name\n" + re); 85 } 86 } 87 addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, files, keys)); 88 addHelper("recents", new RecentsBackupHelper(SystemBackupAgent.this)); 89 addHelper("account_sync_settings", 90 new AccountSyncSettingsBackupHelper(SystemBackupAgent.this)); 91 92 super.onBackup(oldState, data, newState); 93 } 94 95 @Override 96 public void onFullBackup(FullBackupDataOutput data) throws IOException { 97 // At present we back up only the wallpaper 98 fullWallpaperBackup(data); 99 } 100 101 private void fullWallpaperBackup(FullBackupDataOutput output) { 102 // Back up the data files directly. We do them in this specific order -- 103 // info file followed by image -- because then we need take no special 104 // steps during restore; the restore will happen properly when the individual 105 // files are restored piecemeal. 106 FullBackup.backupToTar(getPackageName(), FullBackup.ROOT_TREE_TOKEN, null, 107 WALLPAPER_INFO_DIR, WALLPAPER_INFO, output); 108 FullBackup.backupToTar(getPackageName(), FullBackup.ROOT_TREE_TOKEN, null, 109 WALLPAPER_IMAGE_DIR, WALLPAPER_IMAGE, output); 110 } 111 112 @Override 113 public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) 114 throws IOException { 115 // On restore, we also support a previous data schema "system_files" 116 addHelper("wallpaper", new WallpaperBackupHelper(SystemBackupAgent.this, 117 new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }, 118 new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} )); 119 addHelper("system_files", new WallpaperBackupHelper(SystemBackupAgent.this, 120 new String[] { WALLPAPER_IMAGE }, 121 new String[] { WALLPAPER_IMAGE_KEY} )); 122 addHelper("recents", new RecentsBackupHelper(SystemBackupAgent.this)); 123 addHelper("account_sync_settings", 124 new AccountSyncSettingsBackupHelper(SystemBackupAgent.this)); 125 126 try { 127 super.onRestore(data, appVersionCode, newState); 128 129 IWallpaperManager wallpaper = (IWallpaperManager) ServiceManager.getService( 130 Context.WALLPAPER_SERVICE); 131 if (wallpaper != null) { 132 try { 133 wallpaper.settingsRestored(); 134 } catch (RemoteException re) { 135 Slog.e(TAG, "Couldn't restore settings\n" + re); 136 } 137 } 138 } catch (IOException ex) { 139 // If there was a failure, delete everything for the wallpaper, this is too aggressive, 140 // but this is hopefully a rare failure. 141 Slog.d(TAG, "restore failed", ex); 142 (new File(WALLPAPER_IMAGE)).delete(); 143 (new File(WALLPAPER_INFO)).delete(); 144 } 145 } 146 147 @Override 148 public void onRestoreFile(ParcelFileDescriptor data, long size, 149 int type, String domain, String path, long mode, long mtime) 150 throws IOException { 151 Slog.i(TAG, "Restoring file domain=" + domain + " path=" + path); 152 153 // Bits to indicate postprocessing we may need to perform 154 boolean restoredWallpaper = false; 155 156 File outFile = null; 157 // Various domain+files we understand a priori 158 if (domain.equals(FullBackup.ROOT_TREE_TOKEN)) { 159 if (path.equals(WALLPAPER_INFO_FILENAME)) { 160 outFile = new File(WALLPAPER_INFO); 161 restoredWallpaper = true; 162 } else if (path.equals(WALLPAPER_IMAGE_FILENAME)) { 163 outFile = new File(WALLPAPER_IMAGE); 164 restoredWallpaper = true; 165 } 166 } 167 168 try { 169 if (outFile == null) { 170 Slog.w(TAG, "Skipping unrecognized system file: [ " + domain + " : " + path + " ]"); 171 } 172 FullBackup.restoreFile(data, size, type, mode, mtime, outFile); 173 174 if (restoredWallpaper) { 175 IWallpaperManager wallpaper = 176 (IWallpaperManager)ServiceManager.getService( 177 Context.WALLPAPER_SERVICE); 178 if (wallpaper != null) { 179 try { 180 wallpaper.settingsRestored(); 181 } catch (RemoteException re) { 182 Slog.e(TAG, "Couldn't restore settings\n" + re); 183 } 184 } 185 } 186 } catch (IOException e) { 187 if (restoredWallpaper) { 188 // Make sure we wind up in a good state 189 (new File(WALLPAPER_IMAGE)).delete(); 190 (new File(WALLPAPER_INFO)).delete(); 191 } 192 } 193 } 194 195 @Override 196 public void onRestoreFinished() { 197 try { 198 ActivityManagerNative.getDefault().systemBackupRestored(); 199 } catch (RemoteException e) { 200 // Not possible since this code is running in the system process. 201 } 202 } 203} 204