1f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato/*
2f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * Copyright (C) 2009 The Android Open Source Project
3f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato *
4f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
5f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * you may not use this file except in compliance with the License.
6f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * You may obtain a copy of the License at
7f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato *
8f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
9f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato *
10f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * Unless required by applicable law or agreed to in writing, software
11f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
12f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * See the License for the specific language governing permissions and
14f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato * limitations under the License.
15f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato */
16f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
17f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratopackage com.android.backuptest;
18f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
19f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.app.ListActivity;
204528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.BackupHelperDispatcher;
214528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.BackupDataInput;
224528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.BackupDataOutput;
234528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.BackupManager;
244528186e0d65fc68ef0dd1941aa2ac8aefcd55a3Christopher Tateimport android.app.backup.FileBackupHelper;
25f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.content.Intent;
26f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.content.SharedPreferences;
27f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.os.Bundle;
28f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.os.Handler;
29efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onoratoimport android.os.ParcelFileDescriptor;
30f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.util.Log;
31f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.view.View;
32f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.widget.ArrayAdapter;
33f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.widget.ListView;
34f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratoimport android.widget.Toast;
35f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
36b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.io.BufferedReader;
37efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onoratoimport java.io.File;
38efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onoratoimport java.io.FileOutputStream;
39efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onoratoimport java.io.FileInputStream;
40efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onoratoimport java.io.FileNotFoundException;
41b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.io.InputStreamReader;
42b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.io.IOException;
43b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.io.PrintStream;
44b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.text.DateFormat;
45b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onoratoimport java.util.Date;
46b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato
47f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onoratopublic class BackupTestActivity extends ListActivity
48f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato{
49f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    static final String TAG = "BackupTestActivity";
50f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
51f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    static final String PREF_GROUP_SETTINGS = "settings";
52f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    static final String PREF_KEY = "pref";
53b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato    static final String FILE_NAME = "file.txt";
54f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
55c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate    BackupManager sBm = new BackupManager(this);
56c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate
57f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    Test[] mTests = new Test[] {
58b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato        new Test("Show File") {
59b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato            void run() {
60b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                StringBuffer str = new StringBuffer();
61b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                str.append("Text is:");
62b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                BufferedReader reader = null;
63b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                try {
64b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    reader = new BufferedReader(new InputStreamReader(openFileInput(FILE_NAME)));
65b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    while (reader.ready()) {
66b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                        str.append("\n");
67b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                        str.append(reader.readLine());
68b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    }
69b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                } catch (IOException ex) {
70b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    str.append("ERROR: ");
71b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    str.append(ex.toString());
72b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                }
73b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                Log.d(TAG, str.toString());
74b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                Toast.makeText(BackupTestActivity.this, str, Toast.LENGTH_SHORT).show();
75b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato            }
76b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato        },
77b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato        new Test("Append to File") {
78b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato            void run() {
79b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                PrintStream output = null;
80b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                try {
81b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    output = new PrintStream(openFileOutput(FILE_NAME, MODE_APPEND));
82b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    DateFormat formatter = DateFormat.getDateTimeInstance();
83b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    output.println(formatter.format(new Date()));
84b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    output.close();
85b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                } catch (IOException ex) {
86b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    if (output != null) {
87b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                        output.close();
88b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                    }
89b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato                }
90c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sBm.dataChanged();
91b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato            }
92b1a7ffef3a0007b6991b8338460f6aac8cbb11e8Joe Onorato        },
93290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato        new Test("Clear File") {
94290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato            void run() {
95290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                PrintStream output = null;
96290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                try {
97290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                    output = new PrintStream(openFileOutput(FILE_NAME, MODE_PRIVATE));
98290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                    output.close();
99290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                } catch (IOException ex) {
100290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                    if (output != null) {
101290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                        output.close();
102290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                    }
103290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato                }
104c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sBm.dataChanged();
105290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato            }
106290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato        },
107290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato        new Test("Poke") {
108290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato            void run() {
109c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sBm.dataChanged();
110290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato            }
111290bb011c5c1a9ba1f2116810b06cf52a9c36b3eJoe Onorato        },
112f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        new Test("Show Shared Pref") {
113f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato            void run() {
114f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                SharedPreferences prefs = getSharedPreferences(PREF_GROUP_SETTINGS, MODE_PRIVATE);
115f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                int val = prefs.getInt(PREF_KEY, 0);
116f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                String str = "'" + PREF_KEY + "' is " + val;
117f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                Log.d(TAG, str);
118f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                Toast.makeText(BackupTestActivity.this, str, Toast.LENGTH_SHORT).show();
119f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato            }
120f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        },
121f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        new Test("Increment Shared Pref") {
122f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato            void run() {
123f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                SharedPreferences prefs = getSharedPreferences(PREF_GROUP_SETTINGS, MODE_PRIVATE);
124f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                int val = prefs.getInt(PREF_KEY, 0);
125f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                SharedPreferences.Editor editor = prefs.edit();
126f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                editor.putInt(PREF_KEY, val+1);
127f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato                editor.commit();
128c8daa769256b039b6bc4c5acbe6b558cd776c00aChristopher Tate                sBm.dataChanged();
129f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato            }
130efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato        },
131efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato        new Test("Backup Helpers") {
132efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            void run() {
133efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                try {
134efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    writeFile("a", "a\naa", MODE_PRIVATE);
135efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    writeFile("empty", "", MODE_PRIVATE);
136efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato
137efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    ParcelFileDescriptor state = ParcelFileDescriptor.open(
138efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                            new File(getFilesDir(), "state"),
139efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                            ParcelFileDescriptor.MODE_READ_WRITE|ParcelFileDescriptor.MODE_CREATE|
140efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                            ParcelFileDescriptor.MODE_TRUNCATE);
141efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    FileBackupHelper h = new FileBackupHelper(BackupTestActivity.this,
14206290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato                            new String[] { "a", "empty" });
143efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    FileOutputStream dataFile = openFileOutput("backup_test", MODE_WORLD_READABLE);
14483248c432ffe2e2a17abbc8e4960c26574b46bcaJoe Onorato                    BackupDataOutput data = new BackupDataOutput(dataFile.getFD());
14506290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato                    h.performBackup(null, data, state);
146efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    dataFile.close();
147efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    state.close();
148efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                } catch (IOException ex) {
149efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    throw new RuntimeException(ex);
150efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                }
151efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            }
152efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato        },
153efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato        new Test("Restore Helpers") {
154efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            void run() {
155efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                try {
15606290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato                    BackupHelperDispatcher dispatch = new BackupHelperDispatcher();
15706290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato                    dispatch.addHelper("", new FileBackupHelper(BackupTestActivity.this,
15806290a4bb9b280fa14a2bbeb2d3ceb09396a78c3Joe Onorato                            new String[] { "a", "empty" }));
159efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    FileInputStream dataFile = openFileInput("backup_test");
160efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    BackupDataInput data = new BackupDataInput(dataFile.getFD());
161d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                    ParcelFileDescriptor state = ParcelFileDescriptor.open(
162d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                            new File(getFilesDir(), "restore_state"),
163d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                            ParcelFileDescriptor.MODE_READ_WRITE|ParcelFileDescriptor.MODE_CREATE|
164d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                            ParcelFileDescriptor.MODE_TRUNCATE);
1655cbbf5652a78902ac3382dc4a3583bc5b0351027Christopher Tate                    // TODO: a more plausable synthetic stored-data version number
1665cbbf5652a78902ac3382dc4a3583bc5b0351027Christopher Tate                    dispatch.performRestore(data, 0, state);
167efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    dataFile.close();
168d2d9ceb7305d593c1b767bbb05de0082a9af4109Joe Onorato                    state.close();
169efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                } catch (IOException ex) {
170efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                    throw new RuntimeException(ex);
171efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato                }
172efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            }
173f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        }
174f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    };
175f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
176f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    abstract class Test {
177f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        String name;
178f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        Test(String n) {
179f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato            name = n;
180f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        }
181f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        abstract void run();
182f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    }
183f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
184f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    @Override
185f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    public void onCreate(Bundle icicle) {
186f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        super.onCreate(icicle);
187f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
188f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        String[] labels = new String[mTests.length];
189f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        for (int i=0; i<mTests.length; i++) {
190f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato            labels[i] = mTests[i].name;
191f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        }
192f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
193f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, labels));
194f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    }
195f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
196f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    @Override
197f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    public void onListItemClick(ListView l, View v, int position, long id)
198f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    {
199f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        Test t = mTests[position];
200f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        Log.d(TAG, "Test: " + t.name);
201f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato        t.run();
202f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato    }
203f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
204efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato    void writeFile(String name, String contents, int mode) {
205efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato        try {
206efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            PrintStream out = new PrintStream(openFileOutput(name, mode));
207efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            out.print(contents);
208efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            out.close();
209efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato        } catch (FileNotFoundException ex) {
210efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato            throw new RuntimeException(ex);
211efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato        }
212efd0fab04b96d7ab0c1d8bf3b79397c8621e31c5Joe Onorato    }
213f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato}
214f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato
215