Home | History | Annotate | Download | only in backup
      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.  Wallpapers are now handled by a
     39  * separate package, but we still process restores from legacy datasets here.
     40  */
     41 public class SystemBackupAgent extends BackupAgentHelper {
     42     private static final String TAG = "SystemBackupAgent";
     43 
     44     // Names of the helper tags within the dataset.  Changing one of these names will
     45     // break the ability to restore from datasets that predate the change.
     46     private static final String WALLPAPER_HELPER = "wallpaper";
     47     private static final String SYNC_SETTINGS_HELPER = "account_sync_settings";
     48     private static final String PREFERRED_HELPER = "preferred_activities";
     49     private static final String NOTIFICATION_HELPER = "notifications";
     50     private static final String PERMISSION_HELPER = "permissions";
     51     private static final String USAGE_STATS_HELPER = "usage_stats";
     52     private static final String SHORTCUT_MANAGER_HELPER = "shortcut_manager";
     53     private static final String ACCOUNT_MANAGER_HELPER = "account_manager";
     54     private static final String SLICES_HELPER = "slices";
     55 
     56     // These paths must match what the WallpaperManagerService uses.  The leaf *_FILENAME
     57     // are also used in the full-backup file format, so must not change unless steps are
     58     // taken to support the legacy backed-up datasets.
     59     private static final String WALLPAPER_IMAGE_FILENAME = "wallpaper";
     60     private static final String WALLPAPER_INFO_FILENAME = "wallpaper_info.xml";
     61 
     62     // TODO: Will need to change if backing up non-primary user's wallpaper
     63     // TODO: http://b/22388012
     64     private static final String WALLPAPER_IMAGE_DIR =
     65             Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath();
     66     public static final String WALLPAPER_IMAGE =
     67             new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
     68                     "wallpaper").getAbsolutePath();
     69 
     70     // TODO: Will need to change if backing up non-primary user's wallpaper
     71     // TODO: http://b/22388012
     72     private static final String WALLPAPER_INFO_DIR =
     73             Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM).getAbsolutePath();
     74     public static final String WALLPAPER_INFO =
     75             new File(Environment.getUserSystemDirectory(UserHandle.USER_SYSTEM),
     76                     "wallpaper_info.xml").getAbsolutePath();
     77     // Use old keys to keep legacy data compatibility and avoid writing two wallpapers
     78     private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;
     79 
     80     private WallpaperBackupHelper mWallpaperHelper = null;
     81 
     82     @Override
     83     public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
     84             ParcelFileDescriptor newState) throws IOException {
     85         addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
     86         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
     87         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
     88         addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
     89         addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
     90         addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
     91         addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
     92         addHelper(SLICES_HELPER, new SliceBackupHelper(this));
     93         super.onBackup(oldState, data, newState);
     94     }
     95 
     96     @Override
     97     public void onFullBackup(FullBackupDataOutput data) throws IOException {
     98         // At present we don't back up anything
     99     }
    100 
    101     @Override
    102     public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
    103             throws IOException {
    104         // Slot in a restore helper for the older wallpaper backup schema to support restore
    105         // from devices still generating data in that format.
    106         mWallpaperHelper = new WallpaperBackupHelper(this,
    107                 new String[] { WALLPAPER_IMAGE_KEY} );
    108         addHelper(WALLPAPER_HELPER, mWallpaperHelper);
    109 
    110         // On restore, we also support a long-ago wallpaper data schema "system_files"
    111         addHelper("system_files", new WallpaperBackupHelper(this,
    112                 new String[] { WALLPAPER_IMAGE_KEY} ));
    113 
    114         addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
    115         addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
    116         addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
    117         addHelper(PERMISSION_HELPER, new PermissionBackupHelper());
    118         addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
    119         addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
    120         addHelper(ACCOUNT_MANAGER_HELPER, new AccountManagerBackupHelper());
    121         addHelper(SLICES_HELPER, new SliceBackupHelper(this));
    122 
    123         super.onRestore(data, appVersionCode, newState);
    124     }
    125 
    126     /**
    127      * Support for 'adb restore' of legacy archives
    128      */
    129     @Override
    130     public void onRestoreFile(ParcelFileDescriptor data, long size,
    131             int type, String domain, String path, long mode, long mtime)
    132             throws IOException {
    133         Slog.i(TAG, "Restoring file domain=" + domain + " path=" + path);
    134 
    135         // Bits to indicate postprocessing we may need to perform
    136         boolean restoredWallpaper = false;
    137 
    138         File outFile = null;
    139         // Various domain+files we understand a priori
    140         if (domain.equals(FullBackup.ROOT_TREE_TOKEN)) {
    141             if (path.equals(WALLPAPER_INFO_FILENAME)) {
    142                 outFile = new File(WALLPAPER_INFO);
    143                 restoredWallpaper = true;
    144             } else if (path.equals(WALLPAPER_IMAGE_FILENAME)) {
    145                 outFile = new File(WALLPAPER_IMAGE);
    146                 restoredWallpaper = true;
    147             }
    148         }
    149 
    150         try {
    151             if (outFile == null) {
    152                 Slog.w(TAG, "Skipping unrecognized system file: [ " + domain + " : " + path + " ]");
    153             }
    154             FullBackup.restoreFile(data, size, type, mode, mtime, outFile);
    155 
    156             if (restoredWallpaper) {
    157                 IWallpaperManager wallpaper =
    158                         (IWallpaperManager)ServiceManager.getService(
    159                                 Context.WALLPAPER_SERVICE);
    160                 if (wallpaper != null) {
    161                     try {
    162                         wallpaper.settingsRestored();
    163                     } catch (RemoteException re) {
    164                         Slog.e(TAG, "Couldn't restore settings\n" + re);
    165                     }
    166                 }
    167             }
    168         } catch (IOException e) {
    169             if (restoredWallpaper) {
    170                 // Make sure we wind up in a good state
    171                 (new File(WALLPAPER_IMAGE)).delete();
    172                 (new File(WALLPAPER_INFO)).delete();
    173             }
    174         }
    175     }
    176 }
    177