Merge "Change Icon for Export Function" into gingerbread
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 68c3682..ead03f2 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -30,7 +30,13 @@
<!-- Needed by the Audio Quality Verifier to store the sound samples that will be mailed. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <application android:label="@string/app_name" android:icon="@drawable/icon" android:debuggable="true">
+ <application android:label="@string/app_name"
+ android:icon="@drawable/icon"
+ android:backupAgent="VerifierBackupAgent"
+ android:debuggable="true">
+
+ <meta-data android:name="com.google.android.backup.api_key"
+ android:value="AEdPqrEAAAAIbK6ldcOzoeRtQ1u1dFVJ1A7KetRhit-a1Xa82Q" />
<activity android:name=".CtsVerifierActivity" android:label="@string/app_name">
<intent-filter>
@@ -73,6 +79,13 @@
</intent-filter>
</receiver>
+ <activity android:name=".backup.BackupTestActivity" android:label="@string/backup_test">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.cts.intent.category.MANUAL_TEST" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".bluetooth.BluetoothTestActivity"
android:label="@string/bluetooth_test"
android:configChanges="keyboardHidden|orientation">
diff --git a/apps/CtsVerifier/res/layout/bu_main.xml b/apps/CtsVerifier/res/layout/bu_main.xml
new file mode 100644
index 0000000..2289fee
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/bu_main.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <ListView android:id="@+id/android:list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ />
+
+ <TextView android:id="@id/android:empty"
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/bu_loading"
+ />
+
+ <Button android:id="@+id/generate_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/bu_generate"
+ />
+
+ <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/bu_preference_row.xml b/apps/CtsVerifier/res/layout/bu_preference_row.xml
new file mode 100644
index 0000000..c37eece
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/bu_preference_row.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:padding="5dp"
+ />
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 0f0f645..628b931 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -44,6 +44,32 @@
<string name="no_storage">Cannot save report to external storage, see log for details.</string>
<string name="report_saved">Report saved to: %s</string>
+ <!-- Strings for BackupTestActivity -->
+ <string name="backup_test">Data Backup Test</string>
+ <string name="backup_info">This test checks that data backup and automatic restore works
+ properly. The test activity lists some preferences and files that are backed up and
+ restored by the CTS Verifier. If backup and restore is working properly, these values
+ should be restored after running the backup manager, uninstalling the app, and reinstalling
+ the CTS Verifier.
+ \n\nPress the \"Generate Test Data\" to populate these values
+ and then follow the on screen instructions to finish the test.
+ </string>
+ <string name="bu_preferences">Preferences</string>
+ <string name="bu_files">Files</string>
+ <string name="bu_loading">Loading...</string>
+ <string name="bu_generate">Generate Test Data</string>
+ <string name="bu_generate_error">Error occurred while generating test data...</string>
+ <string name="bu_instructions">Random values for the preferences and files have been saved.
+ \n\nFollow the instructions below to check that the data backup and restore works:
+ \n\n1. Make sure backup and automatic restore are enabled in settings. Depending on the
+ backup transport supported by the device you may need to do additional steps. For instance
+ you may need to set a Google account as the backup account for the device.
+ \n\n2. Run the backup manager: adb shell bmgr run
+ \n\n3. Uninstall the program: adb uninstall com.android.cts.verifier
+ \n\n4. Reinstall the CTS Verifier and verify that the values are still the same.
+ </string>
+ <string name="bu_settings">Settings</string>
+
<!-- Strings for Device Administration tests -->
<string name="da_policy_serialization_test">Policy Serialization Test</string>
<string name="da_policy_serialization_info">This test checks that a device policy is properly
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index f6e6f1b..38b4dbc 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -350,18 +350,7 @@
@Override
protected Void doInBackground(Void... params) {
- ContentValues values = new ContentValues(2);
- values.put(TestResultsProvider.COLUMN_TEST_RESULT, mResult);
- values.put(TestResultsProvider.COLUMN_TEST_NAME, mTestName);
-
- ContentResolver resolver = mContext.getContentResolver();
- int numUpdated = resolver.update(TestResultsProvider.RESULTS_CONTENT_URI, values,
- TestResultsProvider.COLUMN_TEST_NAME + " = ?",
- new String[] {mTestName});
-
- if (numUpdated == 0) {
- resolver.insert(TestResultsProvider.RESULTS_CONTENT_URI, values);
- }
+ TestResultsProvider.setTestResult(mContext, mTestName, mResult);
return null;
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsBackupHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsBackupHelper.java
new file mode 100644
index 0000000..0966de4
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsBackupHelper.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier;
+
+import com.android.cts.verifier.backup.BackupTestActivity;
+
+import android.app.backup.BackupDataInputStream;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BackupHelper;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/** {@link BackupHelper} for the test results database. */
+class TestResultsBackupHelper implements BackupHelper {
+
+ private static final String TAG = TestResultsBackupHelper.class.getSimpleName();
+
+ private static final String DB_BACKUP_KEY = "db";
+
+ private final Context mContext;
+
+ TestResultsBackupHelper(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
+ ContentResolver resolver = mContext.getContentResolver();
+ Cursor cursor = null;
+ try {
+ cursor = resolver.query(TestResultsProvider.RESULTS_CONTENT_URI,
+ null, null, null, null);
+ int nameIndex = cursor.getColumnIndex(TestResultsProvider.COLUMN_TEST_NAME);
+ int resultIndex = cursor.getColumnIndex(TestResultsProvider.COLUMN_TEST_RESULT);
+ int infoSeenIndex = cursor.getColumnIndex(TestResultsProvider.COLUMN_TEST_INFO_SEEN);
+
+ ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+ DataOutputStream dataOutput = new DataOutputStream(byteOutput);
+
+ dataOutput.writeInt(cursor.getCount());
+ while (cursor.moveToNext()) {
+ String name = cursor.getString(nameIndex);
+ int result = cursor.getInt(resultIndex);
+ int infoSeen = cursor.getInt(infoSeenIndex);
+
+ dataOutput.writeUTF(name);
+ dataOutput.writeInt(result);
+ dataOutput.writeInt(infoSeen);
+ }
+
+ byte[] rawBytes = byteOutput.toByteArray();
+ data.writeEntityHeader(DB_BACKUP_KEY, rawBytes.length);
+ data.writeEntityData(rawBytes, rawBytes.length);
+ } catch (IOException e) {
+ Log.e(TAG, "Couldn't backup test results...", e);
+ failBackupTest();
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+
+ @Override
+ public void restoreEntity(BackupDataInputStream data) {
+ try {
+ if (DB_BACKUP_KEY.equals(data.getKey())) {
+ byte[] rawBytes = new byte[data.size()];
+ data.read(rawBytes, 0, data.size());
+
+ ByteArrayInputStream byteInput = new ByteArrayInputStream(rawBytes);
+ DataInputStream dataInput = new DataInputStream(byteInput);
+
+ int numRows = dataInput.readInt();
+ ContentValues[] values = new ContentValues[numRows];
+ for (int i = 0; i < numRows; i++) {
+ String name = dataInput.readUTF();
+ int result = dataInput.readInt();
+ int infoSeen = dataInput.readInt();
+
+ values[i] = new ContentValues();
+ values[i].put(TestResultsProvider.COLUMN_TEST_NAME, name);
+ values[i].put(TestResultsProvider.COLUMN_TEST_RESULT, result);
+ values[i].put(TestResultsProvider.COLUMN_TEST_INFO_SEEN, infoSeen);
+ }
+
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.bulkInsert(TestResultsProvider.RESULTS_CONTENT_URI, values);
+ } else {
+ failBackupTest();
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Couldn't restore test results...", e);
+ failBackupTest();
+ }
+ }
+
+ private void failBackupTest() {
+ TestResultsProvider.setTestResult(mContext, BackupTestActivity.class.getName(),
+ TestResult.TEST_RESULT_FAILED);
+ }
+
+ @Override
+ public void writeNewStateDescription(ParcelFileDescriptor newState) {
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
index a41cb43..cc9dc73 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsProvider.java
@@ -16,7 +16,9 @@
package com.android.cts.verifier;
+import android.app.backup.BackupManager;
import android.content.ContentProvider;
+import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
@@ -40,18 +42,18 @@
return Uri.withAppendedPath(RESULTS_CONTENT_URI, testName);
}
- public static final String _ID = "_id";
+ static final String _ID = "_id";
/** String name of the test like "com.android.cts.verifier.foo.FooTestActivity" */
- public static final String COLUMN_TEST_NAME = "testname";
+ static final String COLUMN_TEST_NAME = "testname";
/** Integer test result corresponding to constants in {@link TestResult}. */
- public static final String COLUMN_TEST_RESULT = "testresult";
+ static final String COLUMN_TEST_RESULT = "testresult";
/** Boolean indicating whether the test info has been seen. */
- public static final String COLUMN_TEST_INFO_SEEN = "testinfoseen";
+ static final String COLUMN_TEST_INFO_SEEN = "testinfoseen";
- public static final String[] ALL_COLUMNS = {
+ static final String[] ALL_COLUMNS = {
_ID,
COLUMN_TEST_NAME,
COLUMN_TEST_RESULT,
@@ -72,9 +74,12 @@
private SQLiteOpenHelper mOpenHelper;
+ private BackupManager mBackupManager;
+
@Override
public boolean onCreate() {
mOpenHelper = new TestResultsOpenHelper(getContext());
+ mBackupManager = new BackupManager(getContext());
return false;
}
@@ -140,14 +145,12 @@
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long id = db.insert(TABLE_NAME, null, values);
getContext().getContentResolver().notifyChange(uri, null);
+ mBackupManager.dataChanged();
return Uri.withAppendedPath(RESULTS_CONTENT_URI, "" + id);
-
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
int match = URI_MATCHER.match(uri);
switch (match) {
case RESULTS_ALL:
@@ -176,9 +179,11 @@
throw new IllegalArgumentException("Unknown URI: " + uri);
}
+ SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int numUpdated = db.update(TABLE_NAME, values, selection, selectionArgs);
if (numUpdated > 0) {
getContext().getContentResolver().notifyChange(uri, null);
+ mBackupManager.dataChanged();
}
return numUpdated;
}
@@ -189,6 +194,7 @@
int numDeleted = db.delete(TABLE_NAME, selection, selectionArgs);
if (numDeleted > 0) {
getContext().getContentResolver().notifyChange(uri, null);
+ mBackupManager.dataChanged();
}
return numDeleted;
}
@@ -197,4 +203,20 @@
public String getType(Uri uri) {
return null;
}
+
+ static void setTestResult(Context context, String testName, int testResult) {
+ ContentValues values = new ContentValues(2);
+ values.put(TestResultsProvider.COLUMN_TEST_RESULT, testResult);
+ values.put(TestResultsProvider.COLUMN_TEST_NAME, testName);
+
+ ContentResolver resolver = context.getContentResolver();
+ int numUpdated = resolver.update(TestResultsProvider.RESULTS_CONTENT_URI, values,
+ TestResultsProvider.COLUMN_TEST_NAME + " = ?",
+ new String[] {testName});
+
+ if (numUpdated == 0) {
+ resolver.insert(TestResultsProvider.RESULTS_CONTENT_URI, values);
+ }
+ }
+
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/VerifierBackupAgent.java b/apps/CtsVerifier/src/com/android/cts/verifier/VerifierBackupAgent.java
new file mode 100644
index 0000000..3c980b9
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/VerifierBackupAgent.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier;
+
+import com.android.cts.verifier.backup.BackupTestActivity;
+
+import android.app.backup.BackupAgentHelper;
+
+public class VerifierBackupAgent extends BackupAgentHelper {
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ addHelper("test-results", new TestResultsBackupHelper(this));
+ addHelper("backup-test-prefs", BackupTestActivity.getSharedPreferencesBackupHelper(this));
+ addHelper("backup-test-files", BackupTestActivity.getFileBackupHelper(this));
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupTestActivity.java
new file mode 100644
index 0000000..cccc1c2
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupTestActivity.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.backup;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.backup.BackupManager;
+import android.app.backup.FileBackupHelper;
+import android.app.backup.SharedPreferencesBackupHelper;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Scanner;
+
+/**
+ * Test for checking whether the BackupManager is working properly. It lists the values of
+ * several preferences and contents of files that should get backed up and restored after
+ * running the backup manager and reinstalling the CTS verifier.
+ */
+public class BackupTestActivity extends PassFailButtons.ListActivity {
+
+ private static final String TAG = BackupTestActivity.class.getSimpleName();
+
+ private static final int INSTRUCTIONS_DIALOG_ID = 1;
+
+ private static final String TEST_PREFS_1 = "test-prefs-1";
+ private static final String INT_PREF = "int-pref";
+ private static final String BOOL_PREF = "bool-pref";
+
+ private static final String TEST_PREFS_2 = "test-prefs-2";
+ private static final String FLOAT_PREF = "float-pref";
+ private static final String LONG_PREF = "long-pref";
+ private static final String STRING_PREF = "string-pref";
+
+ private static final String TEST_FILE_1 = "test-file-1";
+ private static final String TEST_FILE_2 = "test-file-2";
+
+ private BackupAdapter mAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ setContentView(R.layout.bu_main);
+ setPassFailButtonClickListeners();
+ setInfoResources(R.string.backup_test, R.string.backup_info, 0);
+
+ mAdapter = new BackupAdapter(this);
+ setListAdapter(mAdapter);
+
+ new LoadBackupItemsTask().execute();
+
+ findViewById(R.id.generate_button).setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ new GenerateValuesTask().execute();
+ }
+ });
+ }
+
+ public static SharedPreferencesBackupHelper getSharedPreferencesBackupHelper(Context context) {
+ return new SharedPreferencesBackupHelper(context, TEST_PREFS_1, TEST_PREFS_2);
+ }
+
+ public static FileBackupHelper getFileBackupHelper(Context context) {
+ return new FileBackupHelper(context, TEST_FILE_1, TEST_FILE_2);
+ }
+
+ class LoadBackupItemsTask extends AsyncTask<Void, Void, List<BackupItem>> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ setProgressBarIndeterminateVisibility(true);
+ }
+
+ @Override
+ protected List<BackupItem> doInBackground(Void... params) {
+ List<BackupItem> items = new ArrayList<BackupItem>();
+
+ items.add(new CategoryBackupItem(R.string.bu_preferences));
+ loadPreferenceGroup1(items);
+ loadPreferenceGroup2(items);
+
+ items.add(new CategoryBackupItem(R.string.bu_files));
+ loadFile(TEST_FILE_1, items);
+ loadFile(TEST_FILE_2, items);
+
+ return items;
+ }
+
+ private void loadPreferenceGroup1(List<BackupItem> items) {
+ SharedPreferences prefs = getSharedPreferences(TEST_PREFS_1, MODE_PRIVATE);
+
+ int intValue = prefs.getInt(INT_PREF, 0);
+ items.add(new PreferenceBackupItem(TEST_PREFS_1, INT_PREF, "" + intValue));
+
+ boolean boolValue = prefs.getBoolean(BOOL_PREF, false);
+ items.add(new PreferenceBackupItem(TEST_PREFS_1, BOOL_PREF, "" + boolValue));
+ }
+
+ private void loadPreferenceGroup2(List<BackupItem> items) {
+ SharedPreferences prefs = getSharedPreferences(TEST_PREFS_2, MODE_PRIVATE);
+
+ float floatValue = prefs.getFloat(FLOAT_PREF, 0.0f);
+ items.add(new PreferenceBackupItem(TEST_PREFS_2, FLOAT_PREF, "" + floatValue));
+
+ long longValue = prefs.getLong(LONG_PREF, 0L);
+ items.add(new PreferenceBackupItem(TEST_PREFS_2, LONG_PREF, "" + longValue));
+
+ String stringValue = prefs.getString(STRING_PREF, null);
+ items.add(new PreferenceBackupItem(TEST_PREFS_2, STRING_PREF, stringValue));
+ }
+
+ private void loadFile(String fileName, List<BackupItem> items) {
+ StringBuilder contents = new StringBuilder();
+ Scanner scanner = null;
+ try {
+ scanner = new Scanner(new File(getFilesDir(), fileName));
+ while (scanner.hasNext()) {
+ contents.append(scanner.nextLine());
+ }
+ scanner.close();
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Couldn't find test file but this may be fine...", e);
+ } finally {
+ if (scanner != null) {
+ scanner.close();
+ }
+ }
+ items.add(new FileBackupItem(fileName, contents.toString()));
+ }
+
+ @Override
+ protected void onPostExecute(List<BackupItem> result) {
+ super.onPostExecute(result);
+ setProgressBarIndeterminateVisibility(false);
+ mAdapter.clear();
+ mAdapter.addAll(result);
+ }
+ }
+
+ class GenerateValuesTask extends AsyncTask<Void, Void, Exception> {
+
+ @Override
+ protected Exception doInBackground(Void... params) {
+ Random random = new Random();
+ generatePreferenceGroup1(random);
+ generatePreferenceGroup2(random);
+ try {
+ generateTestFile(TEST_FILE_1, random);
+ generateTestFile(TEST_FILE_2, random);
+ } catch (FileNotFoundException e) {
+ return e;
+ }
+ return null;
+ }
+
+ private void generatePreferenceGroup1(Random random) {
+ SharedPreferences prefs = getSharedPreferences(TEST_PREFS_1, MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putInt(INT_PREF, (random.nextInt(100) + 1));
+ editor.putBoolean(BOOL_PREF, random.nextBoolean());
+ editor.commit();
+ }
+
+ private void generatePreferenceGroup2(Random random) {
+ SharedPreferences prefs = getSharedPreferences(TEST_PREFS_2, MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putFloat(FLOAT_PREF, random.nextFloat());
+ editor.putLong(LONG_PREF, random.nextLong());
+ editor.putString(STRING_PREF, "Random number: " + (random.nextInt(100) + 1));
+ editor.commit();
+ }
+
+ private void generateTestFile(String fileName, Random random)
+ throws FileNotFoundException {
+ File file = new File(getFilesDir(), fileName);
+ PrintWriter writer = new PrintWriter(file);
+ writer.write("Random number: " + (random.nextInt(100) + 1));
+ writer.close();
+ }
+
+ @Override
+ protected void onPostExecute(Exception exception) {
+ super.onPostExecute(exception);
+ if (exception != null) {
+ Log.e(TAG, "Couldn't generate test data...", exception);
+ Toast.makeText(BackupTestActivity.this, R.string.bu_generate_error,
+ Toast.LENGTH_LONG).show();
+ } else {
+ showDialog(INSTRUCTIONS_DIALOG_ID);
+
+ BackupManager backupManager = new BackupManager(BackupTestActivity.this);
+ backupManager.dataChanged();
+
+ new LoadBackupItemsTask().execute();
+ }
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(int id, Bundle args) {
+ switch (id) {
+ case INSTRUCTIONS_DIALOG_ID:
+ return new AlertDialog.Builder(this)
+ .setIcon(android.R.drawable.ic_dialog_info)
+ .setTitle(R.string.backup_test)
+ .setMessage(R.string.bu_instructions)
+ .setPositiveButton(android.R.string.ok, null)
+ .setNeutralButton(R.string.bu_settings, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
+ }
+ })
+ .create();
+
+ default:
+ return super.onCreateDialog(id, args);
+ }
+ }
+
+ interface BackupItem {
+ int getViewType();
+ View getView(LayoutInflater inflater, int position, View convertView, ViewGroup parent);
+ }
+
+ static class CategoryBackupItem implements BackupItem {
+
+ private final int mTitleResId;
+
+ CategoryBackupItem(int titleResId) {
+ mTitleResId = titleResId;
+ }
+
+ @Override
+ public int getViewType() {
+ return 0;
+ }
+
+ @Override
+ public View getView(LayoutInflater inflater, int position, View convertView,
+ ViewGroup parent) {
+ TextView view = (TextView) convertView;
+ if (convertView == null) {
+ view = (TextView) inflater.inflate(R.layout.test_category_row, parent, false);
+ }
+ view.setText(mTitleResId);
+ return view;
+ }
+ }
+
+ static class PreferenceBackupItem implements BackupItem {
+
+ private final String mGroup;
+
+ private final String mName;
+
+ private final String mValue;
+
+ PreferenceBackupItem(String group, String name, String value) {
+ mGroup = group;
+ mName = name;
+ mValue = value;
+ }
+
+ @Override
+ public int getViewType() {
+ return 1;
+ }
+
+ @Override
+ public View getView(LayoutInflater inflater, int position, View convertView,
+ ViewGroup parent) {
+ TextView view = (TextView) convertView;
+ if (convertView == null) {
+ view = (TextView) inflater.inflate(R.layout.bu_preference_row, parent, false);
+ }
+ view.setText(mGroup + "/" + mName + " : " + mValue);
+ return view;
+ }
+ }
+
+ static class FileBackupItem implements BackupItem {
+
+ private final String mName;
+
+ private final String mContents;
+
+ FileBackupItem(String name, String contents) {
+ mName = name;
+ mContents = contents;
+ }
+
+ @Override
+ public int getViewType() {
+ return 2;
+ }
+
+ @Override
+ public View getView(LayoutInflater inflater, int position, View convertView,
+ ViewGroup parent) {
+ TextView view = (TextView) convertView;
+ if (convertView == null) {
+ view = (TextView) inflater.inflate(R.layout.bu_preference_row, parent, false);
+ }
+ view.setText(mName + " : " + mContents);
+ return view;
+ }
+ }
+
+ class BackupAdapter extends BaseAdapter {
+
+ private final LayoutInflater mLayoutInflater;
+
+ private final List<BackupItem> mItems = new ArrayList<BackupItem>();
+
+ public BackupAdapter(Context context) {
+ mLayoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
+ }
+
+ public void clear() {
+ mItems.clear();
+ }
+
+ public void addAll(List<BackupItem> items) {
+ mItems.addAll(items);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public BackupItem getItem(int position) {
+ return mItems.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return false;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 3;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return getItem(position).getViewType();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return getItem(position).getView(mLayoutInflater, position, convertView, parent);
+ }
+ }
+}