diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml index 86cbcb607..c723f4dc3 100644 --- a/MyTracks/res/values/keys.xml +++ b/MyTracks/res/values/keys.xml @@ -71,8 +71,6 @@ limitations under the License. weight settingsAdvanced - settingsBackup - settingsBackupReset settingsChart settingsGoogle settingsMap @@ -81,7 +79,6 @@ limitations under the License. settingsMapSlowDisplay settingsRecording settingsReset - settingsRestore settingsSensor settingsSensorAnt settingsSensorAntResetBikeCadenceSensor diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 976943771..3abc31118 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -1551,100 +1551,6 @@ limitations under the License. Photo size - - - Backup & reset - - - - - Backup - - - This will write a full copy of all your tracks and settings to ‘%1$s’ on the - external storage. - - - Backup now? - - - Unable to backup. - - - Writing all tracks and settings… - - - Finished backup. - - - - - Restore - - - Restoring a backup from external storage will delete all your tracks and settings, and update - them with the backup copy. Google Drive sync will be turned off. No tracks will be deleted on - Google Drive and on external storage. - - - Restore now? - - - Unable to restore from backup. - - - No backups found in %1$s. - - - Reading all tracks and settings… - - - Select a backup to restore - - - Finished restoring from backup. - - + \ No newline at end of file diff --git a/MyTracks/res/xml/backup_reset_settings.xml b/MyTracks/res/xml/backup_reset_settings.xml deleted file mode 100644 index fb61ac08b..000000000 --- a/MyTracks/res/xml/backup_reset_settings.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/MyTracks/res/xml/settings.xml b/MyTracks/res/xml/settings.xml index d820c79e9..8f830cbc2 100644 --- a/MyTracks/res/xml/settings.xml +++ b/MyTracks/res/xml/settings.xml @@ -40,10 +40,6 @@ limitations under the License. android:key="@string/settings_sensor_key" android:persistent="false" android:title="@string/settings_sensor" /> - { - - private static final String TAG = BackupAsyncTask.class.getSimpleName(); - - private BackupActivity backupActivity; - private final ExternalFileBackup externalFileBackup; - - // true if the AsyncTask result is success - private boolean success; - - // true if the AsyncTask has completed - private boolean completed; - - // message id to return to the activity - private int messageId; - - /** - * Creates an AsyncTask. - * - * @param backupActivity the activity currently associated with this - * AsyncTask - */ - public BackupAsyncTask(BackupActivity backupActivity) { - this.backupActivity = backupActivity; - this.externalFileBackup = new ExternalFileBackup(backupActivity); - success = false; - completed = false; - messageId = R.string.settings_backup_now_error; - } - - /** - * Sets the current {@link BackupActivity} associated with this AyncTask. - * - * @param activity the current {@link BackupActivity}, can be null - */ - public void setActivity(BackupActivity activity) { - this.backupActivity = activity; - if (completed && backupActivity != null) { - backupActivity.onAsyncTaskCompleted(success, messageId); - } - } - - @Override - protected void onPreExecute() { - if (backupActivity != null) { - backupActivity.showProgressDialog(); - } - } - - @Override - protected Boolean doInBackground(Void... params) { - if (!FileUtils.isExternalStorageWriteable()) { - messageId = R.string.external_storage_not_writable; - return false; - } - - if (!externalFileBackup.isBackupsDirectoryAvailable(true)) { - messageId = R.string.external_storage_not_writable; - return false; - } - - try { - externalFileBackup.writeToDefaultFile(); - messageId = R.string.settings_backup_now_success; - return true; - } catch (IOException e) { - Log.d(TAG, "IO exception", e); - return false; - } - } - - @Override - protected void onPostExecute(Boolean result) { - success = result; - completed = true; - if (backupActivity != null) { - backupActivity.onAsyncTaskCompleted(success, messageId); - } - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseDumper.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseDumper.java deleted file mode 100644 index f6ce5080e..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseDumper.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.content.ContentTypeIds; - -import android.database.Cursor; -import android.database.MergeCursor; - -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Database dumper which is able to write only part of the database - * according to some query. - * - * This dumper is symmetrical to {@link DatabaseImporter}. - * - * @author Rodrigo Damazio - */ -class DatabaseDumper { - - /** The names of the columns being dumped. */ - private final String[] columnNames; - /** The types of the columns being dumped. */ - private final byte[] columnTypes; - /** Whether to output null fields. */ - private final boolean outputNullFields; - - // Temporary state - private int[] columnIndices; - private boolean[] hasFields; - - public DatabaseDumper(String[] columnNames, byte[] columnTypes, - boolean outputNullFields) { - if (columnNames.length != columnTypes.length) { - throw new IllegalArgumentException("Names don't match types"); - } - - this.columnNames = columnNames; - this.columnTypes = columnTypes; - this.outputNullFields = outputNullFields; - } - - /** - * Writes the header plus all rows that can be read from the given cursor. - * This assumes the cursor will have the same column and column indices on - * every row (and thus may not work with a {@link MergeCursor}). - */ - public void writeAllRows(Cursor cursor, DataOutputStream writer) - throws IOException { - writeHeaders(cursor, cursor.getCount(), writer); - - if (!cursor.moveToFirst()) { - return; - } - - do { - writeOneRow(cursor, writer); - } while (cursor.moveToNext()); - } - - /** - * Writes just the headers for the data that will come from the given cursor. - * The headers include column information and the number of rows that will be - * written. - * - * @param cursor the cursor to get columns from - * @param numRows the number of rows that will be later written - * @param writer the output to write to - * @throws IOException if there are errors while writing - */ - public void writeHeaders(Cursor cursor, int numRows, DataOutputStream writer) - throws IOException { - initializeCachedValues(cursor); - writeQueryMetadata(numRows, writer); - } - - /** - * Writes the current row from the cursor. The cursor is not advanced. - * This must be called after {@link #writeHeaders}. - * - * @param cursor the cursor to write data from - * @param writer the output to write to - * @throws IOException if there are any errors while writing - */ - public void writeOneRow(Cursor cursor, DataOutputStream writer) - throws IOException { - if (columnIndices == null) { - throw new IllegalStateException( - "Cannot write rows before writing the header"); - } - - if (columnIndices.length > Long.SIZE) { - throw new IllegalArgumentException("Too many fields"); - } - - // Build a bitmap of which fields are present - long fields = 0; - for (int i = 0; i < columnIndices.length; i++) { - hasFields[i] = !cursor.isNull(columnIndices[i]); - fields |= (hasFields[i] ? 1 : 0) << i; - } - writer.writeLong(fields); - - // Actually write the present fields - for (int i = 0; i < columnIndices.length; i++) { - if (hasFields[i]) { - writeCell(columnIndices[i], columnTypes[i], cursor, writer); - } else if (outputNullFields) { - writeDummyCell(columnTypes[i], writer); - } - } - } - - /** - * Initializes the column indices and other temporary state for reading from - * the given cursor. - */ - private void initializeCachedValues(Cursor cursor) { - // These indices are constant for every row (unless we're fed a MergeCursor) - if (cursor instanceof MergeCursor) { - throw new IllegalArgumentException("Cannot use a MergeCursor"); - } - - columnIndices = new int[columnNames.length]; - for (int i = 0; i < columnNames.length; i++) { - String columnName = columnNames[i]; - columnIndices[i] = cursor.getColumnIndexOrThrow(columnName); - } - - hasFields = new boolean[columnIndices.length]; - } - - /** - * Writes metadata about the query to be dumped. - * - * @param numRows the number of rows that will be dumped - * @param writer the output to write to - * @throws IOException if there are any errors while writing - */ - private void writeQueryMetadata( - int numRows, DataOutputStream writer) throws IOException { - // Write column data - writer.writeInt(columnNames.length); - for (int i = 0; i < columnNames.length; i++) { - String columnName = columnNames[i]; - byte columnType = columnTypes[i]; - writer.writeUTF(columnName); - writer.writeByte(columnType); - } - - // Write the number of rows - writer.writeInt(numRows); - } - - /** - * Writes a single cell of the database to the output. - * - * @param columnIdx the column index to read from - * @param columnTypeId the type of the column to be read - * @param cursor the cursor to read from - * @param writer the output to write to - * @throws IOException if there are any errors while writing - */ - private void writeCell( - int columnIdx, byte columnTypeId, Cursor cursor, DataOutputStream writer) - throws IOException { - switch (columnTypeId) { - case ContentTypeIds.LONG_TYPE_ID: - writer.writeLong(cursor.getLong(columnIdx)); - return; - case ContentTypeIds.DOUBLE_TYPE_ID: - writer.writeDouble(cursor.getDouble(columnIdx)); - return; - case ContentTypeIds.FLOAT_TYPE_ID: - writer.writeFloat(cursor.getFloat(columnIdx)); - return; - case ContentTypeIds.BOOLEAN_TYPE_ID: - writer.writeBoolean(cursor.getInt(columnIdx) != 0); - return; - case ContentTypeIds.INT_TYPE_ID: - writer.writeInt(cursor.getInt(columnIdx)); - return; - case ContentTypeIds.STRING_TYPE_ID: - writer.writeUTF(cursor.getString(columnIdx)); - return; - case ContentTypeIds.BLOB_TYPE_ID: { - byte[] blob = cursor.getBlob(columnIdx); - writer.writeInt(blob.length); - writer.write(blob); - return; - } - default: - throw new IllegalArgumentException( - "Type " + columnTypeId + " not supported"); - } - } - - /** - * Writes a dummy cell value to the output. - * - * @param columnTypeId the type of the value to write - * @throws IOException if there are any errors while writing - */ - private void writeDummyCell(byte columnTypeId, DataOutputStream writer) - throws IOException { - switch (columnTypeId) { - case ContentTypeIds.LONG_TYPE_ID: - writer.writeLong(0L); - return; - case ContentTypeIds.DOUBLE_TYPE_ID: - writer.writeDouble(0.0); - return; - case ContentTypeIds.FLOAT_TYPE_ID: - writer.writeFloat(0.0f); - return; - case ContentTypeIds.BOOLEAN_TYPE_ID: - writer.writeBoolean(false); - return; - case ContentTypeIds.INT_TYPE_ID: - writer.writeInt(0); - return; - case ContentTypeIds.STRING_TYPE_ID: - writer.writeUTF(""); - return; - case ContentTypeIds.BLOB_TYPE_ID: - writer.writeInt(0); - return; - default: - throw new IllegalArgumentException( - "Type " + columnTypeId + " not supported"); - } - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseImporter.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseImporter.java deleted file mode 100644 index 949963d5f..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseImporter.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.content.ContentTypeIds; - -import android.content.ContentResolver; -import android.content.ContentValues; -import android.net.Uri; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Locale; - -/** - * Database importer which reads values written by {@link DatabaseDumper}. - * - * @author Rodrigo Damazio - */ -public class DatabaseImporter { - - /** Maximum number of entries in a bulk insertion */ - private static final int DEFAULT_BULK_SIZE = 1024; - - private final Uri destinationUri; - private final ContentResolver resolver; - private final boolean readNullFields; - private final int bulkSize; - - // Metadata read from the reader - private String[] columnNames; - private byte[] columnTypes; - - public DatabaseImporter(Uri destinationUri, ContentResolver resolver, - boolean readNullFields) { - this(destinationUri, resolver, readNullFields, DEFAULT_BULK_SIZE); - } - - protected DatabaseImporter(Uri destinationUri, ContentResolver resolver, - boolean readNullFields, int bulkSize) { - this.destinationUri = destinationUri; - this.resolver = resolver; - this.readNullFields = readNullFields; - this.bulkSize = bulkSize; - } - - /** - * Reads the header which includes metadata about the table being imported. - * - * @throws IOException if there are any problems while reading - */ - private void readHeaders(DataInputStream reader) throws IOException { - int numColumns = reader.readInt(); - columnNames = new String[numColumns]; - columnTypes = new byte[numColumns]; - for (int i = 0; i < numColumns; i++) { - columnNames[i] = reader.readUTF(); - columnTypes[i] = reader.readByte(); - } - } - - /** - * Imports all rows from the reader into the database. - * Insertion is done in bulks for efficiency. - * - * @throws IOException if there are any errors while reading - */ - public void importAllRows(DataInputStream reader) throws IOException { - readHeaders(reader); - - ContentValues[] valueBulk = new ContentValues[bulkSize]; - int numValues = 0; - - int numRows = reader.readInt(); - int numColumns = columnNames.length; - - // For each row - for (int r = 0; r < numRows; r++) { - if (valueBulk[numValues] == null) { - valueBulk[numValues] = new ContentValues(numColumns); - } else { - // Reuse values objects - valueBulk[numValues].clear(); - } - - // Read the fields bitmap - long fields = reader.readLong(); - for (int c = 0; c < numColumns; c++) { - if ((fields & 1) == 1) { - // Field is present, read into values - readOneCell(columnNames[c], columnTypes[c], valueBulk[numValues], - reader); - } else if (readNullFields) { - // Field not present but still written, read and discard - readOneCell(columnNames[c], columnTypes[c], null, reader); - } - - fields >>= 1; - } - - numValues++; - - // If we have enough values, flush them as a bulk insertion - if (numValues >= bulkSize) { - doBulkInsert(valueBulk); - numValues = 0; - } - } - - // Do a final bulk insert with the leftovers - if (numValues > 0) { - ContentValues[] leftovers = new ContentValues[numValues]; - System.arraycopy(valueBulk, 0, leftovers, 0, numValues); - doBulkInsert(leftovers); - } - } - - protected void doBulkInsert(ContentValues[] values) { - resolver.bulkInsert(destinationUri, values); - } - - /** - * Reads a single cell from the reader. - * - * @param name the name of the column to be read - * @param typeId the type ID of the column to be read - * @param values the {@link ContentValues} object to put the read cell value - * in - if null, the value is just discarded - * @throws IOException if there are any problems while reading - */ - private void readOneCell(String name, byte typeId, ContentValues values, - DataInputStream reader) throws IOException { - switch (typeId) { - case ContentTypeIds.BOOLEAN_TYPE_ID: { - boolean value = reader.readBoolean(); - if (values != null) { values.put(name, value); } - return; - } - case ContentTypeIds.LONG_TYPE_ID: { - long value = reader.readLong(); - if (values != null) { values.put(name, value); } - return; - } - case ContentTypeIds.DOUBLE_TYPE_ID: { - double value = reader.readDouble(); - if (values != null) { values.put(name, value); } - return; - } - case ContentTypeIds.FLOAT_TYPE_ID: { - Float value = reader.readFloat(); - if (values != null) { values.put(name, value); } - return; - } - case ContentTypeIds.INT_TYPE_ID: { - int value = reader.readInt(); - if (values != null) { values.put(name, value); } - return; - } - case ContentTypeIds.STRING_TYPE_ID: { - String value = reader.readUTF(); - if (values != null) { values.put(name, value); } - return; - } - case ContentTypeIds.BLOB_TYPE_ID: { - int blobLength = reader.readInt(); - if (blobLength != 0) { - byte[] blob = new byte[blobLength]; - int readBytes = reader.read(blob, 0, blobLength); - if (readBytes != blobLength) { - throw new IOException(String.format(Locale.US, - "Short read on column %s; expected %d bytes, read %d", - name, blobLength, readBytes)); - } - - if (values != null) { - values.put(name, blob); - } - } - return; - } - default: - throw new IOException("Read unknown type " + typeId); - } - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/ExternalFileBackup.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/ExternalFileBackup.java deleted file mode 100644 index 35c261bdd..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/ExternalFileBackup.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.Constants; -import com.google.android.apps.mytracks.content.TrackPointsColumns; -import com.google.android.apps.mytracks.content.TracksColumns; -import com.google.android.apps.mytracks.content.WaypointsColumns; -import com.google.android.apps.mytracks.util.FileUtils; - -import android.content.ContentResolver; -import android.content.Context; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.util.Log; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; - -/** - * Handler for writing or reading single-file backups. - * - * @author Rodrigo Damazio - */ -class ExternalFileBackup { - - private static final String TAG = ExternalFileBackup.class.getSimpleName(); - - // Filename format - in UTC - private static final SimpleDateFormat BACKUP_FILENAME_FORMAT = new SimpleDateFormat( - "'backup-'yyyy-MM-dd_HH-mm-ss'.zip'", Locale.US); - static { - BACKUP_FILENAME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); - } - - private static final int BACKUP_FORMAT_VERSION = 1; - private static final String ZIP_ENTRY_NAME = - "backup.mytracks.v" + BACKUP_FORMAT_VERSION; - private static final int COMPRESSION_LEVEL = 8; - - private final Context context; - - public ExternalFileBackup(Context context) { - this.context = context; - } - - /** - * Returns whether the backups directory is (or can be made) available. - * - * @param create whether to try creating the directory if it doesn't exist - */ - public boolean isBackupsDirectoryAvailable(boolean create) { - return getBackupsDirectory(create) != null; - } - - /** - * Returns the backup directory, or null if not available. - * - * @param create whether to try creating the directory if it doesn't exist - */ - private File getBackupsDirectory(boolean create) { - String directoryPath = FileUtils.getPath(FileUtils.BACKUPS_DIR); - final File dir = new File(directoryPath); - Log.d(TAG, "Dir: " + dir.getAbsolutePath()); - if (create) { - // Try to create - if that fails, return null - return FileUtils.ensureDirectoryExists(dir) ? dir : null; - } else { - // Return it if it already exists, otherwise return null - return FileUtils.isDirectory(dir) ? dir : null; - } - } - - /** - * Returns a list of available backups to be restored. - */ - public Date[] getAvailableBackups() { - File dir = getBackupsDirectory(false); - if (dir == null) { return null; } - String[] fileNames = dir.list(); - - List backupDates = new ArrayList(fileNames.length); - for (int i = 0; i < fileNames.length; i++) { - String fileName = fileNames[i]; - try { - backupDates.add(BACKUP_FILENAME_FORMAT.parse(fileName)); - } catch (ParseException e) { - // Not a backup file, ignore - } - } - - return backupDates.toArray(new Date[backupDates.size()]); - } - - /** - * Writes the backup to the default file. - */ - public void writeToDefaultFile() throws IOException { - writeToFile(getFileForDate(new Date())); - } - - /** - * Restores the backup from the given date. - */ - public void restoreFromDate(Date when) throws IOException { - restoreFromFile(getFileForDate(when)); - } - - /** - * Produces the proper file descriptor for the given backup date. - */ - private File getFileForDate(Date when) { - File dir = getBackupsDirectory(false); - String fileName = BACKUP_FILENAME_FORMAT.format(when); - File file = new File(dir, fileName); - return file; - } - - /** - * Synchronously writes a backup to the given file. - */ - private void writeToFile(File outputFile) throws IOException { - Log.d(TAG, "Writing backup to file " + outputFile.getAbsolutePath()); - - // Create all the auxiliary classes that will do the writing - PreferenceBackupHelper preferencesHelper = new PreferenceBackupHelper(context); - DatabaseDumper trackDumper = new DatabaseDumper( - TracksColumns.COLUMNS, - TracksColumns.COLUMN_TYPES, - false); - DatabaseDumper waypointDumper = new DatabaseDumper( - WaypointsColumns.COLUMNS, - WaypointsColumns.COLUMN_TYPES, - false); - DatabaseDumper pointDumper = new DatabaseDumper( - TrackPointsColumns.COLUMNS, - TrackPointsColumns.COLUMN_TYPES, - false); - - // Open the target for writing - FileOutputStream outputStream = new FileOutputStream(outputFile); - ZipOutputStream compressedStream = new ZipOutputStream(outputStream); - compressedStream.setLevel(COMPRESSION_LEVEL); - compressedStream.putNextEntry(new ZipEntry(ZIP_ENTRY_NAME)); - DataOutputStream outWriter = new DataOutputStream(compressedStream); - - try { - // Dump the entire contents of each table - ContentResolver contentResolver = context.getContentResolver(); - Cursor tracksCursor = null; - try { - tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, null); - if (tracksCursor != null) { - trackDumper.writeAllRows(tracksCursor, outWriter); - } - } finally { - if (tracksCursor != null) { - tracksCursor.close(); - } - } - - Cursor waypointsCursor = null; - try { - waypointsCursor = contentResolver.query( - WaypointsColumns.CONTENT_URI, null, null, null, null); - if (waypointsCursor != null) { - waypointDumper.writeAllRows(waypointsCursor, outWriter); - } - } finally { - if (waypointsCursor != null) { - waypointsCursor.close(); - } - } - - Cursor pointsCursor = null; - try { - pointsCursor = contentResolver.query( - TrackPointsColumns.CONTENT_URI, null, null, null, null); - if (pointsCursor != null) { - pointDumper.writeAllRows(pointsCursor, outWriter); - } - } finally { - if (pointsCursor != null) { - pointsCursor.close(); - } - } - - // Dump preferences - SharedPreferences preferences = context.getSharedPreferences( - Constants.SETTINGS_NAME, Context.MODE_PRIVATE); - preferencesHelper.exportPreferences(preferences, outWriter); - } catch (IOException e) { - // We tried to delete the partially created file, but do nothing - // if that also fails. - if (!outputFile.delete()) { - Log.w(TAG, "Failed to delete file " + outputFile.getAbsolutePath()); - } - - throw e; - } finally { - compressedStream.closeEntry(); - compressedStream.close(); - } - } - - /** - * Synchronously restores the backup from the given file. - */ - private void restoreFromFile(File inputFile) throws IOException { - Log.d(TAG, "Restoring from file " + inputFile.getAbsolutePath()); - - PreferenceBackupHelper preferencesHelper = new PreferenceBackupHelper(context); - ContentResolver resolver = context.getContentResolver(); - DatabaseImporter trackImporter = - new DatabaseImporter(TracksColumns.CONTENT_URI, resolver, false); - DatabaseImporter waypointImporter = - new DatabaseImporter(WaypointsColumns.CONTENT_URI, resolver, false); - DatabaseImporter pointImporter = - new DatabaseImporter(TrackPointsColumns.CONTENT_URI, resolver, false); - - ZipFile zipFile = new ZipFile(inputFile, ZipFile.OPEN_READ); - ZipEntry zipEntry = zipFile.getEntry(ZIP_ENTRY_NAME); - if (zipEntry == null) { - throw new IOException("Invalid backup ZIP file"); - } - - InputStream compressedStream = zipFile.getInputStream(zipEntry); - DataInputStream reader = new DataInputStream(compressedStream); - - try { - // Delete all previous contents of the tables and preferences. - resolver.delete(TracksColumns.CONTENT_URI, null, null); - resolver.delete(TrackPointsColumns.CONTENT_URI, null, null); - resolver.delete(WaypointsColumns.CONTENT_URI, null, null); - - // Import the new contents of each table - trackImporter.importAllRows(reader); - waypointImporter.importAllRows(reader); - pointImporter.importAllRows(reader); - - // Restore preferences - SharedPreferences preferences = context.getSharedPreferences( - Constants.SETTINGS_NAME, Context.MODE_PRIVATE); - preferencesHelper.importPreferences(reader, preferences); - } finally { - compressedStream.close(); - zipFile.close(); - } - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreActivity.java deleted file mode 100644 index 83bf7d02a..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreActivity.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.TrackListActivity; -import com.google.android.apps.mytracks.util.DialogUtils; -import com.google.android.apps.mytracks.util.IntentUtils; -import com.google.android.maps.mytracks.R; - -import android.app.Activity; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.widget.Toast; - -import java.util.Date; - -/** - * An activity to restore data from the SD card. - * - * @author Jimmy Shih - */ -public class RestoreActivity extends Activity { - - public static final String EXTRA_DATE = "date"; - - private static final String TAG = RestoreActivity.class.getSimpleName(); - private static final int DIALOG_PROGRESS_ID = 0; - - private RestoreAsyncTask restoreAsyncTask; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Object retained = getLastNonConfigurationInstance(); - if (retained instanceof RestoreAsyncTask) { - restoreAsyncTask = (RestoreAsyncTask) retained; - restoreAsyncTask.setActivity(this); - } else { - long date = getIntent().getLongExtra(EXTRA_DATE, -1L); - if (date == -1L) { - Log.d(TAG, "Invalid date"); - finish(); - return; - } - restoreAsyncTask = new RestoreAsyncTask(this, new Date(date)); - restoreAsyncTask.execute(); - } - } - - @Override - public Object onRetainNonConfigurationInstance() { - restoreAsyncTask.setActivity(null); - return restoreAsyncTask; - } - - @Override - protected Dialog onCreateDialog(int id) { - if (id != DIALOG_PROGRESS_ID) { - return null; - } - return DialogUtils.createSpinnerProgressDialog(this, - R.string.settings_backup_restore_progress_message, new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - finish(); - } - }); - } - - /** - * Invokes when the associated AsyncTask completes. - * - * @param success true if the AsyncTask is successful - * @param messageId message id to display to user - */ - public void onAsyncTaskCompleted(boolean success, int messageId) { - removeDialog(DIALOG_PROGRESS_ID); - Toast.makeText(this, messageId, success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show(); - Intent intent = IntentUtils.newIntent(this, TrackListActivity.class); - startActivity(intent); - } - - /** - * Shows the progress dialog. - */ - public void showProgressDialog() { - showDialog(DIALOG_PROGRESS_ID); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreAsyncTask.java deleted file mode 100644 index 586937e37..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreAsyncTask.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.io.sync.SyncUtils; -import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.maps.mytracks.R; - -import android.os.AsyncTask; -import android.util.Log; - -import java.io.IOException; -import java.util.Date; - -/** - * AsyncTask to restore data from the SD card. - * - * @author Jimmy Shih - */ -public class RestoreAsyncTask extends AsyncTask { - - private static final String TAG = RestoreAsyncTask.class.getSimpleName(); - - private RestoreActivity restoreActivity; - private final Date date; - private final ExternalFileBackup externalFileBackup; - - // true if the AsyncTask result is success - private boolean success; - - // true if the AsyncTask has completed - private boolean completed; - - // message id to return to the activity - private int messageId; - - /** - * Creates an AsyncTask. - * - * @param restoreActivity the activity currently associated with this - * AsyncTask - * @param date the date to retore from - */ - public RestoreAsyncTask(RestoreActivity restoreActivity, Date date) { - this.restoreActivity = restoreActivity; - this.date = date; - this.externalFileBackup = new ExternalFileBackup(restoreActivity); - success = false; - completed = false; - messageId = R.string.settings_backup_restore_error; - } - - /** - * Sets the current {@link RestoreActivity} associated with this AyncTask. - * - * @param activity the current {@link RestoreActivity}, can be null - */ - public void setActivity(RestoreActivity activity) { - this.restoreActivity = activity; - if (completed && restoreActivity != null) { - restoreActivity.onAsyncTaskCompleted(success, messageId); - } - } - - @Override - protected void onPreExecute() { - if (restoreActivity != null) { - restoreActivity.showProgressDialog(); - } - } - - @Override - protected Boolean doInBackground(Void... params) { - try { - PreferencesUtils.setBoolean( - restoreActivity, R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT); - SyncUtils.disableSync(restoreActivity); - externalFileBackup.restoreFromDate(date); - SyncUtils.clearSyncState(restoreActivity); - messageId = R.string.settings_backup_restore_success; - return true; - } catch (IOException e) { - Log.d(TAG, "IO exception", e); - return false; - } - } - - @Override - protected void onPostExecute(Boolean result) { - success = result; - completed = true; - if (restoreActivity != null) { - restoreActivity.onAsyncTaskCompleted(success, messageId); - } - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreChooserActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreChooserActivity.java deleted file mode 100644 index 65d36a441..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreChooserActivity.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.util.DialogUtils; -import com.google.android.apps.mytracks.util.FileUtils; -import com.google.android.apps.mytracks.util.IntentUtils; -import com.google.android.apps.mytracks.util.StringUtils; -import com.google.android.maps.mytracks.R; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.widget.Toast; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.Date; - -/** - * An activity to choose a date to restore from. - * - * @author Jimmy Shih - */ -public class RestoreChooserActivity extends Activity { - - private static final Comparator REVERSE_DATE_ORDER = new Comparator() { - @Override - public int compare(Date s1, Date s2) { - return s2.compareTo(s1); - } - }; - private static final int DIALOG_CHOOSER_ID = 0; - - private Date[] backupDates; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - ExternalFileBackup externalFileBackup = new ExternalFileBackup(this); - - // Get the list of existing backups - if (!FileUtils.isExternalStorageAvailable()) { - Toast.makeText(this, R.string.external_storage_not_available, Toast.LENGTH_LONG).show(); - finish(); - return; - } - - if (!externalFileBackup.isBackupsDirectoryAvailable(false)) { - showNoBackupMessage(); - finish(); - return; - } - - backupDates = externalFileBackup.getAvailableBackups(); - if (backupDates == null || backupDates.length == 0) { - showNoBackupMessage(); - finish(); - return; - } - - if (backupDates.length == 1) { - Intent intent = IntentUtils.newIntent(this, RestoreActivity.class) - .putExtra(RestoreActivity.EXTRA_DATE, backupDates[0].getTime()); - startActivity(intent); - finish(); - return; - } - - Arrays.sort(backupDates, REVERSE_DATE_ORDER); - showDialog(DIALOG_CHOOSER_ID); - } - - @Override - protected Dialog onCreateDialog(int id) { - if (id != DIALOG_CHOOSER_ID) { - return null; - } - String items[] = new String[backupDates.length]; - for (int i = 0; i < backupDates.length; i++) { - items[i] = StringUtils.formatDateTime(this, backupDates[i].getTime()); - } - final Dialog dialog = new AlertDialog.Builder(this).setCancelable(true) - .setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int which) { - Intent intent = IntentUtils.newIntent( - RestoreChooserActivity.this, RestoreActivity.class) - .putExtra(RestoreActivity.EXTRA_DATE, backupDates[which].getTime()); - startActivity(intent); - finish(); - } - }).setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialogInterface) { - finish(); - } - }).setTitle(R.string.settings_backup_restore_select_title).create(); - dialog.setOnShowListener(new DialogInterface.OnShowListener() { - - @Override - public void onShow(DialogInterface dialogInterface) { - DialogUtils.setDialogTitleDivider(RestoreChooserActivity.this, dialog); - } - }); - return dialog; - } - - /** - * Shows a no backup message. - */ - private void showNoBackupMessage() { - String message = getString(R.string.settings_backup_restore_no_backups, - FileUtils.getPathDisplayName(FileUtils.BACKUPS_DIR)); - Toast.makeText(this, message, Toast.LENGTH_LONG).show(); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java index 170345b23..0a4a265d0 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java @@ -16,17 +16,26 @@ package com.google.android.apps.mytracks.settings; +import com.google.android.apps.mytracks.Constants; +import com.google.android.apps.mytracks.io.sync.SyncUtils; import com.google.android.apps.mytracks.util.DialogUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.maps.mytracks.R; import android.app.Dialog; +import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.Preference.OnPreferenceClickListener; +import android.util.Log; +import android.widget.Toast; /** * An activity for advanced settings. @@ -35,9 +44,38 @@ import android.preference.Preference.OnPreferenceChangeListener; */ public class AdvancedSettingsActivity extends AbstractSettingsActivity { + private static final String TAG = AdvancedSettingsActivity.class.getSimpleName(); + private static final int DIALOG_CONFIRM_ALLOW_ACCESS_ID = 0; + private static final int DIALOG_CONFIRM_RESET_ID = 1; private CheckBoxPreference allowAccessCheckBoxPreference; + private Preference resetPreference; + + private SharedPreferences sharedPreferences; + private long recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT; + + /* + * Note that sharedPreferenceChangeListenr cannot be an anonymous inner class. + * Anonymous inner class will get garbage collected. + */ + private final OnSharedPreferenceChangeListener + sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { + if (key != null && key.equals(PreferencesUtils.getKey( + AdvancedSettingsActivity.this, R.string.recording_track_id_key))) { + recordingTrackId = PreferencesUtils.getLong( + AdvancedSettingsActivity.this, R.string.recording_track_id_key); + runOnUiThread(new Runnable() { + @Override + public void run() { + updateUi(); + } + }); + } + } + }; @SuppressWarnings("deprecation") @Override @@ -45,20 +83,6 @@ public class AdvancedSettingsActivity extends AbstractSettingsActivity { super.onCreate(bundle); addPreferencesFromResource(R.xml.advanced_settings); - allowAccessCheckBoxPreference = (CheckBoxPreference) findPreference( - getString(R.string.allow_access_key)); - allowAccessCheckBoxPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - if ((Boolean) newValue) { - showDialog(DIALOG_CONFIRM_ALLOW_ACCESS_ID); - return false; - } else { - return true; - } - } - }); - ListPreference preference = (ListPreference) findPreference(getString(R.string.photo_size_key)); int value = PreferencesUtils.getInt( this, R.string.photo_size_key, PreferencesUtils.PHOTO_SIZE_DEFAULT); @@ -67,22 +91,72 @@ public class AdvancedSettingsActivity extends AbstractSettingsActivity { String[] summary = new String[values.length]; setPhotoSizeSummaryAndOptions(summary, options, values); configureListPreference(preference, summary, options, values, String.valueOf(value), null); + + allowAccessCheckBoxPreference = (CheckBoxPreference) findPreference( + getString(R.string.allow_access_key)); + allowAccessCheckBoxPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference pref, Object newValue) { + if ((Boolean) newValue) { + showDialog(DIALOG_CONFIRM_ALLOW_ACCESS_ID); + return false; + } else { + return true; + } + } + }); + + sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + + resetPreference = findPreference(getString(R.string.settings_reset_key)); + resetPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference arg0) { + showDialog(DIALOG_CONFIRM_RESET_ID); + return true; + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); + recordingTrackId = PreferencesUtils.getLong(this, R.string.recording_track_id_key); + updateUi(); + } + + @Override + protected void onPause() { + super.onPause(); + sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); } @Override protected Dialog onCreateDialog(int id) { - if (id != DIALOG_CONFIRM_ALLOW_ACCESS_ID) { - return null; + switch (id) { + case DIALOG_CONFIRM_ALLOW_ACCESS_ID: + return DialogUtils.createConfirmationDialog(this, + R.string.settings_sharing_allow_access_confirm_title, + getString(R.string.settings_sharing_allow_access_confirm_message), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int button) { + allowAccessCheckBoxPreference.setChecked(true); + } + }); + case DIALOG_CONFIRM_RESET_ID: + return DialogUtils.createConfirmationDialog(this, R.string.settings_reset_confirm_title, + getString(R.string.settings_reset_confirm_message), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface d, int button) { + onResetPreferencesConfirmed(); + } + }); + default: + return null; } - return DialogUtils.createConfirmationDialog(this, - R.string.settings_sharing_allow_access_confirm_title, - getString(R.string.settings_sharing_allow_access_confirm_message), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int button) { - allowAccessCheckBoxPreference.setChecked(true); - } - }); } private void setPhotoSizeSummaryAndOptions(String[] summary, String[] options, String[] values) { @@ -101,4 +175,46 @@ public class AdvancedSettingsActivity extends AbstractSettingsActivity { } } } + + /** + * Updates the UI based on the recording state. + */ + private void updateUi() { + boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT; + resetPreference.setEnabled(!isRecording); + resetPreference.setSummary(isRecording ? getString(R.string.settings_not_while_recording) : ""); + } + + /** + * Callback when the user confirms resetting all settings. + */ + private void onResetPreferencesConfirmed() { + // Change preferences in a separate thread + new Thread() { + @Override + public void run() { + Log.i(TAG, "Resetting all settings"); + + // Actually wipe preferences and save synchronously + sharedPreferences.edit().clear().commit(); + + SyncUtils.disableSync(AdvancedSettingsActivity.this); + SyncUtils.clearSyncState(AdvancedSettingsActivity.this); + + // Give UI feedback in the UI thread + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText( + AdvancedSettingsActivity.this, R.string.settings_reset_done, Toast.LENGTH_SHORT) + .show(); + // Restart the settings activity so all changes are loaded + Intent intent = getIntent() + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } + }); + } + }.start(); + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java deleted file mode 100644 index 0046e3ff5..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * 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.google.android.apps.mytracks.settings; - -import com.google.android.apps.mytracks.Constants; -import com.google.android.apps.mytracks.io.backup.BackupActivity; -import com.google.android.apps.mytracks.io.backup.RestoreChooserActivity; -import com.google.android.apps.mytracks.io.sync.SyncUtils; -import com.google.android.apps.mytracks.util.DialogUtils; -import com.google.android.apps.mytracks.util.FileUtils; -import com.google.android.apps.mytracks.util.IntentUtils; -import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.maps.mytracks.R; - -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.os.Bundle; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; -import android.util.Log; -import android.widget.Toast; - -/** - * An activity for accessing the backup and reset settings. - * - * @author Jimmy Shih - */ -public class BackupResetSettingsActivity extends AbstractSettingsActivity { - - private static final String TAG = BackupResetSettingsActivity.class.getSimpleName(); - private static final int DIALOG_CONFIRM_BACKUP_ID = 0; - private static final int DIALOG_CONFIRM_RESTORE_ID = 1; - private static final int DIALOG_CONFIRM_RESET_ID = 2; - - private SharedPreferences sharedPreferences; - private Preference backupPreference; - private Preference restoreNowPreference; - private Preference resetPreference; - - private long recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT; - - /* - * Note that sharedPreferenceChangeListenr cannot be an anonymous inner class. - * Anonymous inner class will get garbage collected. - */ - private final OnSharedPreferenceChangeListener - sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { - if (key != null && key.equals(PreferencesUtils.getKey( - BackupResetSettingsActivity.this, R.string.recording_track_id_key))) { - recordingTrackId = PreferencesUtils.getLong( - BackupResetSettingsActivity.this, R.string.recording_track_id_key); - runOnUiThread(new Runnable() { - @Override - public void run() { - updateUi(); - } - }); - } - } - }; - - @SuppressWarnings("deprecation") - @Override - protected void onCreate(Bundle bundle) { - super.onCreate(bundle); - addPreferencesFromResource(R.xml.backup_reset_settings); - - sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); - - backupPreference = findPreference(getString(R.string.settings_backup_key)); - backupPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showDialog(DIALOG_CONFIRM_BACKUP_ID); - return true; - } - }); - restoreNowPreference = findPreference(getString(R.string.settings_restore_key)); - restoreNowPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - showDialog(DIALOG_CONFIRM_RESTORE_ID); - return true; - } - }); - - resetPreference = findPreference(getString(R.string.settings_reset_key)); - resetPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference arg0) { - showDialog(DIALOG_CONFIRM_RESET_ID); - return true; - } - }); - } - - @Override - protected Dialog onCreateDialog(int id) { - String message; - Dialog dialog; - switch (id) { - case DIALOG_CONFIRM_BACKUP_ID: - message = getString(R.string.settings_backup_confirm_message, - FileUtils.getPathDisplayName(FileUtils.BACKUPS_DIR)); - dialog = DialogUtils.createConfirmationDialog(this, R.string.settings_backup_confirm_title, - message, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface d, int which) { - Intent intent = IntentUtils.newIntent( - BackupResetSettingsActivity.this, BackupActivity.class); - startActivity(intent); - } - }); - break; - case DIALOG_CONFIRM_RESTORE_ID: - message = getString(R.string.settings_backup_restore_confirm_message); - dialog = DialogUtils.createConfirmationDialog(this, - R.string.settings_backup_restore_confirm_title, message, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface d, int which) { - Intent intent = IntentUtils.newIntent( - BackupResetSettingsActivity.this, RestoreChooserActivity.class); - startActivity(intent); - } - }); - break; - case DIALOG_CONFIRM_RESET_ID: - message = getString(R.string.settings_reset_confirm_message); - dialog = DialogUtils.createConfirmationDialog(this, R.string.settings_reset_confirm_title, - message, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface d, int button) { - onResetPreferencesConfirmed(); - } - }); - break; - default: - dialog = null; - } - return dialog; - } - - @Override - protected void onResume() { - super.onResume(); - sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); - recordingTrackId = PreferencesUtils.getLong(this, R.string.recording_track_id_key); - updateUi(); - } - - @Override - protected void onPause() { - super.onPause(); - sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); - } - - /** - * Updates the UI based on the recording state. - */ - private void updateUi() { - boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT; - String summary = isRecording ? getString(R.string.settings_not_while_recording) : ""; - backupPreference.setEnabled(!isRecording); - backupPreference.setSummary(summary); - restoreNowPreference.setEnabled(!isRecording); - restoreNowPreference.setSummary(summary); - resetPreference.setEnabled(!isRecording); - resetPreference.setSummary(summary); - } - - /** - * Callback when the user confirms resetting all settings. - */ - private void onResetPreferencesConfirmed() { - // Change preferences in a separate thread - new Thread() { - @Override - public void run() { - Log.i(TAG, "Resetting all settings"); - - // Actually wipe preferences and save synchronously - sharedPreferences.edit().clear().commit(); - - SyncUtils.disableSync(BackupResetSettingsActivity.this); - SyncUtils.clearSyncState(BackupResetSettingsActivity.this); - - // Give UI feedback in the UI thread - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText( - BackupResetSettingsActivity.this, R.string.settings_reset_done, Toast.LENGTH_SHORT) - .show(); - // Restart the settings activity so all changes are loaded - Intent intent = getIntent() - .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); - } - }); - } - }.start(); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java index c3df05ace..35280417c 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java @@ -44,7 +44,6 @@ public class SettingsActivity extends AbstractSettingsActivity { configPreference(R.string.settings_stats_key, StatsSettingsActivity.class); configPreference(R.string.settings_recording_key, RecordingSettingsActivity.class); configPreference(R.string.settings_sensor_key, SensorSettingsActivity.class); - configPreference(R.string.settings_backup_reset_key, BackupResetSettingsActivity.class); configPreference(R.string.settings_advanced_key, AdvancedSettingsActivity.class); } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseDumperTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseDumperTest.java deleted file mode 100644 index 2f74afb5c..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseDumperTest.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.content.ContentTypeIds; - -import android.database.MatrixCursor; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; - -import junit.framework.TestCase; - -/** - * Tests for {@link DatabaseDumper}. - * - * @author Rodrigo Damazio - */ -public class DatabaseDumperTest extends TestCase { - /** - * This class is the same as {@link MatrixCursor}, except this class - * implements {@link #getBlob} ({@link MatrixCursor} leaves it - * unimplemented). - */ - private class BlobAwareMatrixCursor extends MatrixCursor { - public BlobAwareMatrixCursor(String[] columnNames) { - super(columnNames); - } - - @Override public byte[] getBlob(int columnIndex) { - return getString(columnIndex).getBytes(); - } - } - - private static final String[] COLUMN_NAMES = { - "intCol", "longCol", "floatCol", "doubleCol", "stringCol", "boolCol", "blobCol" - }; - private static final byte[] COLUMN_TYPES = { - ContentTypeIds.INT_TYPE_ID, ContentTypeIds.LONG_TYPE_ID, - ContentTypeIds.FLOAT_TYPE_ID, ContentTypeIds.DOUBLE_TYPE_ID, - ContentTypeIds.STRING_TYPE_ID, ContentTypeIds.BOOLEAN_TYPE_ID, - ContentTypeIds.BLOB_TYPE_ID - }; - private static final String[][] FAKE_DATA = { - { "42", "123456789", "3.1415", "2.72", "lolcat", "1", "blob" }, - { null, "123456789", "3.1415", "2.72", "lolcat", "1", "blob" }, - { "42", null, "3.1415", "2.72", "lolcat", "1", "blob" }, - { "42", "123456789", null, "2.72", "lolcat", "1", "blob" }, - { "42", "123456789", "3.1415", null, "lolcat", "1", "blob" }, - { "42", "123456789", "3.1415", "2.72", null, "1", "blob" }, - { "42", "123456789", "3.1415", "2.72", "lolcat", null, "blob" }, - { "42", "123456789", "3.1415", "2.72", "lolcat", "1", null }, - }; - private static final long[] EXPECTED_FIELD_SETS = { - 0x7F, 0x7E, 0x7D, 0x7B, 0x77, 0x6F, 0x5F, 0x3F - }; - - private BlobAwareMatrixCursor cursor; - - @Override - protected void setUp() throws Exception { - super.setUp(); - // Add fake data to the cursor - cursor = new BlobAwareMatrixCursor(COLUMN_NAMES); - for (String[] row : FAKE_DATA) { - cursor.addRow(row); - } - } - - public void testWriteAllRows_noNulls() throws Exception { - testWriteAllRows(false); - } - - public void testWriteAllRows_withNulls() throws Exception { - testWriteAllRows(true); - } - - private void testWriteAllRows(boolean hasNullFields) throws Exception { - // Dump it - DatabaseDumper dumper = new DatabaseDumper(COLUMN_NAMES, COLUMN_TYPES, hasNullFields); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024); - DataOutputStream writer = new DataOutputStream(outStream ); - dumper.writeAllRows(cursor, writer); - - // Read the results - byte[] result = outStream.toByteArray(); - ByteArrayInputStream inputStream = new ByteArrayInputStream(result); - DataInputStream reader = new DataInputStream(inputStream); - - // Verify the header - assertHeader(reader); - - // Verify the number of rows - assertEquals(FAKE_DATA.length, reader.readInt()); - - // Row 0 -- everything populated - assertEquals(EXPECTED_FIELD_SETS[0], reader.readLong()); - assertEquals(42, reader.readInt()); - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 1 -- no int - assertEquals(EXPECTED_FIELD_SETS[1], reader.readLong()); - if (hasNullFields) reader.readInt(); - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 2 -- no long - assertEquals(EXPECTED_FIELD_SETS[2], reader.readLong()); - assertEquals(42, reader.readInt()); - if (hasNullFields) reader.readLong(); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 3 -- no float - assertEquals(EXPECTED_FIELD_SETS[3], reader.readLong()); - assertEquals(42, reader.readInt()); - assertEquals(123456789L, reader.readLong()); - if (hasNullFields) reader.readFloat(); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 4 -- no double - assertEquals(EXPECTED_FIELD_SETS[4], reader.readLong()); - assertEquals(42, reader.readInt()); - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - if (hasNullFields) reader.readDouble(); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 5 -- no string - assertEquals(EXPECTED_FIELD_SETS[5], reader.readLong()); - assertEquals(42, reader.readInt()); - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - if (hasNullFields) reader.readUTF(); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 6 -- no boolean - assertEquals(EXPECTED_FIELD_SETS[6], reader.readLong()); - assertEquals(42, reader.readInt()); - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - if (hasNullFields) reader.readBoolean(); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 7 -- no blob - assertEquals(EXPECTED_FIELD_SETS[7], reader.readLong()); - assertEquals(42, reader.readInt()); - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - if (hasNullFields) { - int length = reader.readInt(); - readBlob(reader, length); - } - } - - public void testFewerRows() throws Exception { - // Dump only the first two rows - DatabaseDumper dumper = new DatabaseDumper(COLUMN_NAMES, COLUMN_TYPES, false); - ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024); - DataOutputStream writer = new DataOutputStream(outStream); - - dumper.writeHeaders(cursor, 2, writer); - cursor.moveToFirst(); - dumper.writeOneRow(cursor, writer); - cursor.moveToNext(); - dumper.writeOneRow(cursor, writer); - - // Read the results - byte[] result = outStream.toByteArray(); - ByteArrayInputStream inputStream = new ByteArrayInputStream(result); - DataInputStream reader = new DataInputStream(inputStream); - - // Verify the header - assertHeader(reader); - - // Verify the number of rows - assertEquals(2, reader.readInt()); - - // Row 0 - assertEquals(EXPECTED_FIELD_SETS[0], reader.readLong()); - assertEquals(42, reader.readInt()); - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - - // Row 1 - assertEquals(EXPECTED_FIELD_SETS[1], reader.readLong()); - // Null field not read - assertEquals(123456789L, reader.readLong()); - assertEquals(3.1415f, reader.readFloat()); - assertEquals(2.72, reader.readDouble()); - assertEquals("lolcat", reader.readUTF()); - assertTrue(reader.readBoolean()); - assertEquals(4, reader.readInt()); - assertEquals("blob", readBlob(reader, 4)); - } - - private void assertHeader(DataInputStream reader) throws IOException { - assertEquals(COLUMN_NAMES.length, reader.readInt()); - for (int i = 0; i < COLUMN_NAMES.length; i++) { - assertEquals(COLUMN_NAMES[i], reader.readUTF()); - assertEquals(COLUMN_TYPES[i], reader.readByte()); - } - } - - private String readBlob(InputStream reader, int length) throws Exception { - if (length == 0) { - return ""; - } - - byte[] blob = new byte[length]; - assertEquals(length, reader.read(blob)); - return new String(blob); - } -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseImporterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseImporterTest.java deleted file mode 100644 index 916af61d3..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseImporterTest.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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.google.android.apps.mytracks.io.backup; - -import com.google.android.apps.mytracks.content.ContentTypeIds; - -import android.content.ContentValues; -import android.net.Uri; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; - -import junit.framework.TestCase; - -/** - * Tests for {@link DatabaseImporter}. - * - * @author Rodrigo Damazio - */ -public class DatabaseImporterTest extends TestCase { - - private static final Uri DESTINATION_URI = Uri.parse("http://www.google.com/"); - private static final int TEST_BULK_SIZE = 10; - private ArrayList insertedValues; - - private class TestableDatabaseImporter extends DatabaseImporter { - public TestableDatabaseImporter(boolean readNullFields) { - super(DESTINATION_URI, null, readNullFields, TEST_BULK_SIZE); - } - - @Override - protected void doBulkInsert(ContentValues[] values) { - insertedValues.ensureCapacity(insertedValues.size() + values.length); - - // We need to make a copy of the values since the objects are re-used - for (ContentValues contentValues : values) { - insertedValues.add(new ContentValues(contentValues)); - } - } - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - - insertedValues = new ArrayList(); - } - - public void testImportAllRows() throws Exception { - testImportAllRows(false); - } - - public void testImportAllRows_readNullFields() throws Exception { - testImportAllRows(true); - } - - private void testImportAllRows(boolean readNullFields) throws Exception { - // Create a fake data stream to be read - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024); - DataOutputStream writer = new DataOutputStream(outputStream); - - writeFullHeader(writer); - - // Add the number of rows - writer.writeInt(2); - - // Add a row with all fields present - writer.writeLong(0x7F); - writer.writeInt(42); - writer.writeBoolean(true); - writer.writeUTF("lolcat"); - writer.writeFloat(3.1415f); - writer.writeDouble(2.72); - writer.writeLong(123456789L); - writer.writeInt(4); - writer.writeBytes("blob"); - - // Add a row with some missing fields - writer.writeLong(0x15); - writer.writeInt(42); - if (readNullFields) writer.writeBoolean(false); - writer.writeUTF("lolcat"); - if (readNullFields) writer.writeFloat(0.0f); - writer.writeDouble(2.72); - if (readNullFields) writer.writeLong(0L); - if (readNullFields) writer.writeInt(0); // empty blob - - writer.flush(); - - // Do the importing - DatabaseImporter importer = new TestableDatabaseImporter(readNullFields); - byte[] dataBytes = outputStream.toByteArray(); - importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes))); - - assertEquals(2, insertedValues.size()); - - // Verify the first row - ContentValues value = insertedValues.get(0); - assertEquals(value.toString(), 7, value.size()); - - assertValue(42, "col1", value); - assertValue(true, "col2", value); - assertValue("lolcat", "col3", value); - assertValue(3.1415f, "col4", value); - assertValue(2.72, "col5", value); - assertValue(123456789L, "col6", value); - assertBlobValue("blob", "col7", value); - - // Verify the second row - value = insertedValues.get(1); - assertEquals(value.toString(), 3, value.size()); - - assertValue(42, "col1", value); - assertValue("lolcat", "col3", value); - assertValue(2.72, "col5", value); - } - - public void testImportAllRows_noRows() throws Exception { - // Create a fake data stream to be read - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024); - DataOutputStream writer = new DataOutputStream(outputStream); - - writeFullHeader(writer); - - // Add the number of rows - writer.writeInt(0); - - writer.flush(); - - // Do the importing - DatabaseImporter importer = new TestableDatabaseImporter(false); - byte[] dataBytes = outputStream.toByteArray(); - importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes))); - - assertTrue(insertedValues.isEmpty()); - } - - public void testImportAllRows_emptyRows() throws Exception { - testImportAllRowsWithEmptyRows(false); - } - - public void testImportAllRows_emptyRowsWithNulls() throws Exception { - testImportAllRowsWithEmptyRows(true); - } - - private void testImportAllRowsWithEmptyRows(boolean readNullFields) throws Exception { - // Create a fake data stream to be read - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024); - DataOutputStream writer = new DataOutputStream(outputStream); - - writeFullHeader(writer); - - // Add the number of rows - writer.writeInt(3); - - // Add 2 rows with no fields - for (int i = 0; i < 2; i++) { - writer.writeLong(0); - if (readNullFields) { - writer.writeInt(0); - writer.writeBoolean(false); - writer.writeUTF(""); - writer.writeFloat(0.0f); - writer.writeDouble(0.0); - writer.writeLong(0L); - writer.writeInt(0); // empty blob - } - } - - // Add a row with some missing fields - writer.writeLong(0x15); - writer.writeInt(42); - if (readNullFields) writer.writeBoolean(false); - writer.writeUTF("lolcat"); - if (readNullFields) writer.writeFloat(0.0f); - writer.writeDouble(2.72); - if (readNullFields) writer.writeLong(0L); - if (readNullFields) writer.writeInt(0); // empty blob - - writer.flush(); - - // Do the importing - DatabaseImporter importer = new TestableDatabaseImporter(readNullFields); - byte[] dataBytes = outputStream.toByteArray(); - importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes))); - - assertEquals(insertedValues.toString(), 3, insertedValues.size()); - - ContentValues value = insertedValues.get(0); - assertEquals(value.toString(), 0, value.size()); - - value = insertedValues.get(1); - assertEquals(value.toString(), 0, value.size()); - - // Verify the third row (only one with values) - value = insertedValues.get(2); - assertEquals(value.toString(), 3, value.size()); - - assertFalse(value.containsKey("col2")); - assertFalse(value.containsKey("col4")); - assertFalse(value.containsKey("col6")); - - assertValue(42, "col1", value); - assertValue("lolcat", "col3", value); - assertValue(2.72, "col5", value); - } - - public void testImportAllRows_bulks() throws Exception { - // Create a fake data stream to be read - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024); - DataOutputStream writer = new DataOutputStream(outputStream); - - // Add the header - writer.writeInt(2); - writer.writeUTF("col1"); - writer.writeByte(ContentTypeIds.INT_TYPE_ID); - writer.writeUTF("col2"); - writer.writeByte(ContentTypeIds.STRING_TYPE_ID); - - // Add lots of rows (so the insertions are split in multiple bulks) - int numRows = TEST_BULK_SIZE * 5 / 2; - writer.writeInt(numRows); - for (int i = 0; i < numRows; i++) { - writer.writeLong(3); - writer.writeInt(i); - writer.writeUTF(Integer.toString(i * 2)); - } - - writer.flush(); - - // Do the importing - DatabaseImporter importer = new TestableDatabaseImporter(false); - byte[] dataBytes = outputStream.toByteArray(); - importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes))); - - // Verify the rows - assertEquals(numRows, insertedValues.size()); - for (int i = 0; i < numRows; i++) { - ContentValues value = insertedValues.get(i); - assertEquals(value.toString(), 2, value.size()); - assertValue(i, "col1", value); - assertValue(Integer.toString(i * 2), "col2", value); - } - } - - private void writeFullHeader(DataOutputStream writer) throws IOException { - // Add the header - writer.writeInt(7); - writer.writeUTF("col1"); - writer.writeByte(ContentTypeIds.INT_TYPE_ID); - writer.writeUTF("col2"); - writer.writeByte(ContentTypeIds.BOOLEAN_TYPE_ID); - writer.writeUTF("col3"); - writer.writeByte(ContentTypeIds.STRING_TYPE_ID); - writer.writeUTF("col4"); - writer.writeByte(ContentTypeIds.FLOAT_TYPE_ID); - writer.writeUTF("col5"); - writer.writeByte(ContentTypeIds.DOUBLE_TYPE_ID); - writer.writeUTF("col6"); - writer.writeByte(ContentTypeIds.LONG_TYPE_ID); - writer.writeUTF("col7"); - writer.writeByte(ContentTypeIds.BLOB_TYPE_ID); - } - - private void assertValue(T expectedValue, String name, ContentValues values) { - @SuppressWarnings("unchecked") - T value = (T) values.get(name); - assertNotNull(value); - assertEquals(expectedValue, value); - } - - private void assertBlobValue(String expectedValue, String name, ContentValues values ){ - byte[] blob = values.getAsByteArray(name); - assertEquals(expectedValue, new String(blob)); - } -} diff --git a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java index 332347ee1..2248bbf01 100644 --- a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java +++ b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java @@ -271,73 +271,6 @@ public class SettingTest extends ActivityInstrumentationTestCase2