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