LocalTransport.java revision 9bbc21a773cbdfbef2876a75c32bda5839647751
1package 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} 141