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