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