blob: 62fba4ac52954b773c92c338182fb78e21851f26 [file] [log] [blame]
Christopher Tate9bbc21a2009-06-10 20:23:25 -07001package com.android.internal.backup;
2
3import android.backup.RestoreSet;
4import android.content.Context;
5import android.content.pm.PackageInfo;
6import android.content.pm.PackageManager;
7import android.content.pm.PackageManager.NameNotFoundException;
8import android.os.Environment;
9import android.os.ParcelFileDescriptor;
10import android.os.RemoteException;
11import android.util.Log;
12
13import java.io.File;
14import java.io.FileFilter;
15import java.io.FileInputStream;
16import java.io.FileOutputStream;
17import java.io.IOException;
18import java.util.ArrayList;
19
20/**
21 * Backup transport for stashing stuff into a known location on disk, and
22 * later restoring from there. For testing only.
23 */
24
25public class LocalTransport extends IBackupTransport.Stub {
26 private static final String TAG = "LocalTransport";
27 private static final String DATA_FILE_NAME = "data";
28
29 private Context mContext;
30 private PackageManager mPackageManager;
31 private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup");
32 private FileFilter mDirFileFilter = new FileFilter() {
33 public boolean accept(File f) {
34 return f.isDirectory();
35 }
36 };
37
38
39 public LocalTransport(Context context) {
40 mContext = context;
41 mPackageManager = context.getPackageManager();
42 }
43
44 public long requestBackupTime() throws RemoteException {
45 // any time is a good time for local backup
46 return 0;
47 }
48
49 public int startSession() throws RemoteException {
50 return 0;
51 }
52
53 public int endSession() throws RemoteException {
54 return 0;
55 }
56
57 public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data)
58 throws RemoteException {
59 File packageDir = new File(mDataDir, packageInfo.packageName);
60 File imageFileName = new File(packageDir, DATA_FILE_NAME);
61
62 //!!! TODO: process the (partial) update into the persistent restore set:
63
64 // Parse out the existing image file into the key/value map
65
66 // Parse out the backup data into the key/value updates
67
68 // Apply the backup key/value updates to the image
69
70 // Write out the image in the canonical format
71
72 return -1;
73 }
74
75 // Restore handling
76 public RestoreSet[] getAvailableRestoreSets() throws android.os.RemoteException {
77 // one hardcoded restore set
78 RestoreSet[] set = new RestoreSet[1];
79 set[0].device = "flash";
80 set[0].name = "Local disk image";
81 set[0].token = 0;
82 return set;
83 }
84
85 public PackageInfo[] getAppSet(int token) throws android.os.RemoteException {
86 // the available packages are the extant subdirs of mDatadir
87 File[] packageDirs = mDataDir.listFiles(mDirFileFilter);
88 ArrayList<PackageInfo> packages = new ArrayList<PackageInfo>();
89 for (File dir : packageDirs) {
90 try {
91 PackageInfo pkg = mPackageManager.getPackageInfo(dir.getName(),
92 PackageManager.GET_SIGNATURES);
93 if (pkg != null) {
94 packages.add(pkg);
95 }
96 } catch (NameNotFoundException e) {
97 // restore set contains data for a package not installed on the
98 // phone -- just ignore it.
99 }
100 }
101
102 Log.v(TAG, "Built app set of " + packages.size() + " entries:");
103 for (PackageInfo p : packages) {
104 Log.v(TAG, " + " + p.packageName);
105 }
106
107 PackageInfo[] result = new PackageInfo[packages.size()];
108 return packages.toArray(result);
109 }
110
111 public int getRestoreData(int token, PackageInfo packageInfo, ParcelFileDescriptor output)
112 throws android.os.RemoteException {
113 // we only support one hardcoded restore set
114 if (token != 0) return -1;
115
116 // the data for a given package is at a known location
117 File packageDir = new File(mDataDir, packageInfo.packageName);
118 File imageFile = new File(packageDir, DATA_FILE_NAME);
119
120 // restore is relatively easy: we already maintain the full data set in
121 // the canonical form understandable to the BackupAgent
122 return copyFileToFD(imageFile, output);
123 }
124
125 private int copyFileToFD(File source, ParcelFileDescriptor dest) {
126 try {
127 FileInputStream in = new FileInputStream(source);
128 FileOutputStream out = new FileOutputStream(dest.getFileDescriptor());
129 byte[] buffer = new byte[4096];
130 int bytesRead;
131 while ((bytesRead = in.read(buffer)) >= 0) {
132 out.write(buffer, 0, bytesRead);
133 }
134 } catch (IOException e) {
135 // something went wrong; claim failure
136 return -1;
137 }
138 return 0;
139 }
140}