1package android.app.backup;
2
3import android.content.Context;
4import android.os.Environment;
5import android.os.ParcelFileDescriptor;
6import android.util.Slog;
7
8import java.io.File;
9
10/**
11 * Helper for saving/restoring 'recent tasks' infrastructure.
12 * @hide
13 */
14public class RecentsBackupHelper implements BackupHelper {
15    private static final String TAG = "RecentsBackup";
16    private static final boolean DEBUG = false;
17
18    // This must match TaskPersister.TASKS_DIRNAME, but that class is not accessible from here
19    private static final String RECENTS_TASK_DIR = "recent_tasks";
20
21    // Must match TaskPersister.IMAGES_DIRNAME, as above
22    private static final String RECENTS_IMAGE_DIR = "recent_images";
23
24    // At restore time, tasks/thumbnails are placed in these directories alongside
25    // the "live" recents dirs named above.
26    private static final String RECENTS_TASK_RESTORE_DIR = "restored_" + RECENTS_TASK_DIR;
27    private static final String RECENTS_IMAGE_RESTORE_DIR = "restored_" + RECENTS_IMAGE_DIR;
28
29    // Prefixes for tagging the two kinds of recents backup records that we might generate
30    private static final String RECENTS_TASK_KEY = "task:";
31    private static final String RECENTS_IMAGE_KEY = "image:";
32
33    FileBackupHelperBase mTaskFileHelper;
34
35    final File mSystemDir;
36    final File mTasksDir;
37    final File mRestoredTasksDir;
38    final File mRestoredImagesDir;
39    final String[] mRecentFiles;
40    final String[] mRecentKeys;
41
42    /**
43     * @param context The agent context in which this helper instance will run
44     */
45    public RecentsBackupHelper(Context context) {
46        mTaskFileHelper = new FileBackupHelperBase(context);
47
48        mSystemDir = new File(Environment.getDataDirectory(), "system");
49        mTasksDir = new File(mSystemDir, RECENTS_TASK_DIR);
50        mRestoredTasksDir = new File(mSystemDir, RECENTS_TASK_RESTORE_DIR);
51        mRestoredImagesDir = new File(mSystemDir, RECENTS_IMAGE_RESTORE_DIR);
52
53        // Currently we back up only the recent-task descriptions, not the thumbnails
54        File[] recentFiles = mTasksDir.listFiles();
55        if (recentFiles != null) {
56            // We explicitly proceed even if this is a zero-size array
57            final int N = recentFiles.length;
58            mRecentKeys = new String[N];
59            mRecentFiles = new String[N];
60            if (DEBUG) {
61                Slog.i(TAG, "Identifying recents for backup: " + N);
62            }
63            for (int i = 0; i < N; i++) {
64                mRecentKeys[i] = new String(RECENTS_TASK_KEY + recentFiles[i].getName());
65                mRecentFiles[i] = recentFiles[i].getAbsolutePath();
66                if (DEBUG) {
67                    Slog.i(TAG, "   " + mRecentKeys[i]);
68                }
69            }
70        } else {
71            mRecentFiles = mRecentKeys = new String[0];
72        }
73    }
74
75    /**
76     * Task-file key:  RECENTS_TASK_KEY + leaf filename
77     * Thumbnail-file key: RECENTS_IMAGE_KEY + leaf filename
78     */
79    @Override
80    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
81            ParcelFileDescriptor newState) {
82        FileBackupHelperBase.performBackup_checked(oldState, data, newState,
83                mRecentFiles, mRecentKeys);
84    }
85
86    @Override
87    public void restoreEntity(BackupDataInputStream data) {
88        final String key = data.getKey();
89        File output = null;
90        if (key.startsWith(RECENTS_TASK_KEY)) {
91            String name = key.substring(RECENTS_TASK_KEY.length());
92            output = new File(mRestoredTasksDir, name);
93            mRestoredTasksDir.mkdirs();
94        } else if (key.startsWith(RECENTS_IMAGE_KEY)) {
95            String name = key.substring(RECENTS_IMAGE_KEY.length());
96            output = new File(mRestoredImagesDir, name);
97            mRestoredImagesDir.mkdirs();
98        }
99
100        if (output != null) {
101            if (DEBUG) {
102                Slog.i(TAG, "Restoring key='"
103                        + key + "' to " + output.getAbsolutePath());
104            }
105            mTaskFileHelper.writeFile(output, data);
106        }
107    }
108
109    @Override
110    public void writeNewStateDescription(ParcelFileDescriptor newState) {
111        mTaskFileHelper.writeNewStateDescription(newState);
112    }
113
114}
115