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