From 450a605729a2d45710e988e5ff4855eb36137e8f Mon Sep 17 00:00:00 2001 From: Sarmad Hashmi Date: Tue, 9 Feb 2016 18:54:26 -0800 Subject: Add voicemail_archive_table to dialer database. Stores the voicemail content and call log information for all the voicemails that have been archived. BUG=22797391 Change-Id: I1b5d98ab17d3d6f32d6797c2c51b50bcd29cd5fa (cherry picked from commit ca67dbe4b04a6eaaa106d40c199bc86d64d94e40) --- AndroidManifest.xml | 7 + .../dialer/database/DialerDatabaseHelper.java | 49 +++- .../dialer/database/VoicemailArchiveContract.java | 201 ++++++++++++++++ .../dialer/database/VoicemailArchiveProvider.java | 211 ++++++++++++++++ .../database/VoicemailArchiveProviderTest.java | 266 +++++++++++++++++++++ 5 files changed, 733 insertions(+), 1 deletion(-) create mode 100644 src/com/android/dialer/database/VoicemailArchiveContract.java create mode 100644 src/com/android/dialer/database/VoicemailArchiveProvider.java create mode 100644 tests/src/com/android/dialer/database/VoicemailArchiveProviderTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 89fdc1ff2..ac5d042ac 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -343,5 +343,12 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> + + diff --git a/src/com/android/dialer/database/DialerDatabaseHelper.java b/src/com/android/dialer/database/DialerDatabaseHelper.java index 1f926c140..5edfb270d 100644 --- a/src/com/android/dialer/database/DialerDatabaseHelper.java +++ b/src/com/android/dialer/database/DialerDatabaseHelper.java @@ -39,6 +39,7 @@ import android.util.Log; import com.android.contacts.common.util.PermissionsUtil; import com.android.contacts.common.util.StopWatch; import com.android.dialer.database.FilteredNumberContract.FilteredNumberColumns; +import com.android.dialer.database.VoicemailArchiveContract.VoicemailArchive; import com.android.dialer.R; import com.android.dialer.dialpad.SmartDialNameMatcher; import com.android.dialer.dialpad.SmartDialPrefix; @@ -75,7 +76,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { * 0-98 KitKat * */ - public static final int DATABASE_VERSION = 8; + public static final int DATABASE_VERSION = 9; public static final String DATABASE_NAME = "dialer.db"; /** @@ -94,6 +95,8 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { static final String SMARTDIAL_TABLE = "smartdial_table"; /** Saves all possible prefixes to refer to a contacts.*/ static final String PREFIX_TABLE = "prefix_table"; + /** Saves all archived voicemail information. */ + static final String VOICEMAIL_ARCHIVE_TABLE = "voicemail_archive_table"; /** Database properties for internal use */ static final String PROPERTIES = "properties"; } @@ -434,6 +437,8 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { + FilteredNumberColumns.TYPE + " INTEGER," + FilteredNumberColumns.SOURCE + " INTEGER" + ");"); + + createVoicemailArchiveTable(db); setProperty(db, DATABASE_VERSION_PROPERTY, String.valueOf(DATABASE_VERSION)); if (!mIsTestInstance) { resetSmartDialLastUpdatedTime(); @@ -445,6 +450,7 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { db.execSQL("DROP TABLE IF EXISTS " + Tables.SMARTDIAL_TABLE); db.execSQL("DROP TABLE IF EXISTS " + Tables.PROPERTIES); db.execSQL("DROP TABLE IF EXISTS " + Tables.FILTERED_NUMBER_TABLE); + db.execSQL("DROP TABLE IF EXISTS " + Tables.VOICEMAIL_ARCHIVE_TABLE); } @Override @@ -486,6 +492,12 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { oldVersion = 8; } + if (oldVersion < 9) { + db.execSQL("DROP TABLE IF EXISTS " + Tables.VOICEMAIL_ARCHIVE_TABLE); + createVoicemailArchiveTable(db); + oldVersion = 9; + } + if (oldVersion != DATABASE_VERSION) { throw new IllegalStateException( "error upgrading the database to version " + DATABASE_VERSION); @@ -652,6 +664,41 @@ public class DialerDatabaseHelper extends SQLiteOpenHelper { SmartDialDbColumns.LAST_SMARTDIAL_UPDATE_TIME + " > " + last_update_time, null); } + /** + * All columns excluding MIME_TYPE, _DATA, ARCHIVED, SERVER_ID, are the same as + * the columns in the {@link android.provider.CallLog.Calls} table. + * + * @param db Database pointer to the dialer database. + */ + private void createVoicemailArchiveTable(SQLiteDatabase db) { + db.execSQL("CREATE TABLE " + Tables.VOICEMAIL_ARCHIVE_TABLE + " (" + + VoicemailArchive._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + VoicemailArchive.NUMBER + " TEXT," + + VoicemailArchive.DATE + " LONG," + + VoicemailArchive.DURATION + " LONG," + + VoicemailArchive.MIME_TYPE + " TEXT," + + VoicemailArchive.COUNTRY_ISO + " TEXT," + + VoicemailArchive._DATA + " TEXT," + + VoicemailArchive.GEOCODED_LOCATION + " TEXT," + + VoicemailArchive.CACHED_NAME + " TEXT," + + VoicemailArchive.CACHED_NUMBER_TYPE + " INTEGER," + + VoicemailArchive.CACHED_NUMBER_LABEL + " TEXT," + + VoicemailArchive.CACHED_LOOKUP_URI + " TEXT," + + VoicemailArchive.CACHED_MATCHED_NUMBER + " TEXT," + + VoicemailArchive.CACHED_NORMALIZED_NUMBER + " TEXT," + + VoicemailArchive.CACHED_PHOTO_ID + " LONG," + + VoicemailArchive.CACHED_FORMATTED_NUMBER + " TEXT," + + VoicemailArchive.ARCHIVED + " INTEGER," + + VoicemailArchive.NUMBER_PRESENTATION + " INTEGER," + + VoicemailArchive.ACCOUNT_COMPONENT_NAME + " TEXT," + + VoicemailArchive.ACCOUNT_ID + " TEXT," + + VoicemailArchive.FEATURES + " INTEGER," + + VoicemailArchive.SERVER_ID + " INTEGER," + + VoicemailArchive.TRANSCRIPTION + " TEXT," + + VoicemailArchive.CACHED_PHOTO_URI + " TEXT" + + ");"); + } + /** * Removes all entries in the smartdial contact database. */ diff --git a/src/com/android/dialer/database/VoicemailArchiveContract.java b/src/com/android/dialer/database/VoicemailArchiveContract.java new file mode 100644 index 000000000..92d9c17ef --- /dev/null +++ b/src/com/android/dialer/database/VoicemailArchiveContract.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2016 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.dialer.database; + +import android.net.Uri; +import android.provider.BaseColumns; +import android.provider.CallLog; +import android.provider.OpenableColumns; + +/** + * Contains definitions for the supported URIs and columns for the voicemail archive table. + * All the fields excluding MIME_TYPE, _DATA, ARCHIVED, SERVER_ID, mirror the fields in the + * contract provided in {@link CallLog.Calls}. + */ +public final class VoicemailArchiveContract { + + /** The authority used by the voicemail archive provider. */ + public static final String AUTHORITY = "com.android.dialer.database.voicemailarchiveprovider"; + + /** A content:// style uri for the voicemail archive provider */ + public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY); + + public static final class VoicemailArchive implements BaseColumns, OpenableColumns { + + public static final String VOICEMAIL_ARCHIVE_TABLE = "voicemail_archive_table"; + + public static final Uri CONTENT_URI = Uri.withAppendedPath( + AUTHORITY_URI, + VOICEMAIL_ARCHIVE_TABLE); + + /** + * @see android.provider.CallLog.Calls#NUMBER + * TYPE: TEXT + */ + public static final String NUMBER = CallLog.Calls.NUMBER; + + /** + * @see android.provider.CallLog.Calls#DATE + * TYPE: LONG + */ + public static final String DATE = CallLog.Calls.DATE; + + /** + * @see android.provider.CallLog.Calls#DURATION + * TYPE: LONG + */ + public static final String DURATION = CallLog.Calls.DURATION; + + /** + * The mime type of the archived voicemail file. + * TYPE: TEXT + */ + public static final String MIME_TYPE = "mime_type"; + + /** + * @see android.provider.CallLog.Calls#COUNTRY_ISO + * TYPE: LONG + */ + public static final String COUNTRY_ISO = CallLog.Calls.COUNTRY_ISO; + + /** + * The path of the archived voicemail file. + * TYPE: TEXT + */ + public static final String _DATA = "_data"; + + /** + * @see android.provider.CallLog.Calls#GEOCODED_LOCATION + * TYPE: TEXT + */ + public static final String GEOCODED_LOCATION = CallLog.Calls.GEOCODED_LOCATION; + + /** + * @see android.provider.CallLog.Calls#CACHED_NAME + * TYPE: TEXT + */ + public static final String CACHED_NAME = CallLog.Calls.CACHED_NAME; + + /** + * @see android.provider.CallLog.Calls#CACHED_NUMBER_TYPE + * TYPE: INTEGER + */ + public static final String CACHED_NUMBER_TYPE = CallLog.Calls.CACHED_NUMBER_TYPE; + + /** + * @see android.provider.CallLog.Calls#CACHED_NUMBER_LABEL + * TYPE: TEXT + */ + public static final String CACHED_NUMBER_LABEL = CallLog.Calls.CACHED_NUMBER_LABEL; + + /** + * @see android.provider.CallLog.Calls#CACHED_LOOKUP_URI + * TYPE: TEXT + */ + public static final String CACHED_LOOKUP_URI = CallLog.Calls.CACHED_LOOKUP_URI; + + /** + * @see android.provider.CallLog.Calls#CACHED_MATCHED_NUMBER + * TYPE: TEXT + */ + public static final String CACHED_MATCHED_NUMBER = CallLog.Calls.CACHED_MATCHED_NUMBER; + + /** + * @see android.provider.CallLog.Calls#CACHED_NORMALIZED_NUMBER + * TYPE: TEXT + */ + public static final String CACHED_NORMALIZED_NUMBER = + CallLog.Calls.CACHED_NORMALIZED_NUMBER; + + /** + * @see android.provider.CallLog.Calls#CACHED_PHOTO_ID + * TYPE: LONG + */ + public static final String CACHED_PHOTO_ID = CallLog.Calls.CACHED_PHOTO_ID; + + /** + * @see android.provider.CallLog.Calls#CACHED_FORMATTED_NUMBER + * TYPE: TEXT + */ + public static final String CACHED_FORMATTED_NUMBER = CallLog.Calls.CACHED_FORMATTED_NUMBER; + + /** + * If the voicemail was archived by the user by pressing the archive button, this is set to + * 1 (true). If the voicemail was archived for the purpose of forwarding to other + * applications, this is set to 0 (false). + * TYPE: INTEGER + */ + public static final String ARCHIVED = "archived_by_user"; + + /** + * @see android.provider.CallLog.Calls#NUMBER_PRESENTATION + * TYPE: INTEGER + */ + public static final String NUMBER_PRESENTATION = CallLog.Calls.NUMBER_PRESENTATION; + + /** + * @see android.provider.CallLog.Calls#PHONE_ACCOUNT_COMPONENT_NAME + * TYPE: TEXT + */ + public static final String ACCOUNT_COMPONENT_NAME = + CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME; + + /** + * @see android.provider.CallLog.Calls#PHONE_ACCOUNT_ID + * TYPE: TEXT + */ + public static final String ACCOUNT_ID = CallLog.Calls.PHONE_ACCOUNT_ID; + + /** + * @see android.provider.CallLog.Calls#FEATURES + * TYPE: INTEGER + */ + public static final String FEATURES = CallLog.Calls.FEATURES; + + /** + * The id of the voicemail on the server. + * TYPE: INTEGER + */ + public static final String SERVER_ID = "server_id"; + + /** + * @see android.provider.CallLog.Calls#TRANSCRIPTION + * TYPE: TEXT + */ + public static final String TRANSCRIPTION = CallLog.Calls.TRANSCRIPTION; + + /** + * @see android.provider.CallLog.Calls#CACHED_PHOTO_URI + * TYPE: TEXT + */ + public static final String CACHED_PHOTO_URI = CallLog.Calls.CACHED_PHOTO_URI; + + /** + * The MIME type of a {@link #CONTENT_URI} single voicemail. + */ + public static final String CONTENT_ITEM_TYPE = + "vnd.android.cursor.item/voicmail_archive_table"; + + public static final Uri buildWithId(int id) { + return Uri.withAppendedPath(CONTENT_URI, Integer.toString(id)); + } + + /** Not instantiable. */ + private VoicemailArchive() { + } + } +} diff --git a/src/com/android/dialer/database/VoicemailArchiveProvider.java b/src/com/android/dialer/database/VoicemailArchiveProvider.java new file mode 100644 index 000000000..ae73670b8 --- /dev/null +++ b/src/com/android/dialer/database/VoicemailArchiveProvider.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2016 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.dialer.database; + +import android.content.ContentProvider; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteQueryBuilder; +import android.net.Uri; +import android.os.ParcelFileDescriptor; +import android.support.annotation.Nullable; +import android.text.TextUtils; + +import com.android.dialerbind.DatabaseHelperManager; +import com.google.common.annotations.VisibleForTesting; + +import java.io.File; +import java.io.FileNotFoundException; + +/** + * An implementation of the Voicemail Archive content provider. This class performs + * all database level operations on the voicemail_archive_table. + */ +public class VoicemailArchiveProvider extends ContentProvider { + private static final String TAG = "VMArchiveProvider"; + private static final int VOICEMAIL_ARCHIVE_TABLE = 1; + private static final int VOICEMAIL_ARCHIVE_TABLE_ID = 2; + private static final String VOICEMAIL_FOLDER = "voicemails"; + + private DialerDatabaseHelper mDialerDatabaseHelper; + private final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + + @Override + public boolean onCreate() { + mDialerDatabaseHelper = getDatabaseHelper(getContext()); + if (mDialerDatabaseHelper == null) { + return false; + } + mUriMatcher.addURI(VoicemailArchiveContract.AUTHORITY, + VoicemailArchiveContract.VoicemailArchive.VOICEMAIL_ARCHIVE_TABLE, + VOICEMAIL_ARCHIVE_TABLE); + mUriMatcher.addURI(VoicemailArchiveContract.AUTHORITY, + VoicemailArchiveContract.VoicemailArchive.VOICEMAIL_ARCHIVE_TABLE + "/#", + VOICEMAIL_ARCHIVE_TABLE_ID); + return true; + } + + @VisibleForTesting + protected DialerDatabaseHelper getDatabaseHelper(Context context) { + return DatabaseHelperManager.getDatabaseHelper(context); + } + + /** + * Used by the test class because it extends {@link android.test.ProviderTestCase2} in which the + * {@link android.test.IsolatedContext} returns /dev/null when getFilesDir() is called. + * + * @see android.test.IsolatedContext#getFilesDir + */ + @VisibleForTesting + protected File getFilesDir() { + return getContext().getFilesDir(); + } + + @Nullable + @Override + public Cursor query(Uri uri, + @Nullable String[] projection, + @Nullable String selection, + @Nullable String[] selectionArgs, + @Nullable String sortOrder) { + SQLiteDatabase db = mDialerDatabaseHelper.getReadableDatabase(); + SQLiteQueryBuilder queryBuilder = getQueryBuilder(uri); + Cursor cursor = queryBuilder + .query(db, projection, selection, selectionArgs, null, null, sortOrder); + if (cursor != null) { + cursor.setNotificationUri(getContext().getContentResolver(), + VoicemailArchiveContract.VoicemailArchive.CONTENT_URI); + } + return cursor; + } + + @Override + public String getType(Uri uri) { + return VoicemailArchiveContract.VoicemailArchive.CONTENT_ITEM_TYPE; + } + + @Nullable + @Override + public Uri insert(Uri uri, ContentValues values) { + SQLiteDatabase db = mDialerDatabaseHelper.getWritableDatabase(); + long id = db.insert(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE, + null, values); + if (id < 0) { + return null; + } + notifyChange(uri); + // Create the directory for archived voicemails if it doesn't already exist + File directory = new File(getFilesDir(), VOICEMAIL_FOLDER); + directory.mkdirs(); + + // Update the row's _data column with a file path in the voicemails folder + Uri newUri = ContentUris.withAppendedId(uri, id); + File voicemailFile = new File(directory, Long.toString(id)); + values.put(VoicemailArchiveContract.VoicemailArchive._DATA, voicemailFile.getPath()); + update(newUri, values, null, null); + return newUri; + } + + + @Override + public int delete(Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { + SQLiteDatabase db = mDialerDatabaseHelper.getWritableDatabase(); + SQLiteQueryBuilder queryBuilder = getQueryBuilder(uri); + Cursor cursor = queryBuilder.query(db, null, selection, selectionArgs, null, null, null); + + // Delete all the voicemail files related to the selected rows + while (cursor.moveToNext()) { + deleteFile(cursor.getString(cursor.getColumnIndex( + VoicemailArchiveContract.VoicemailArchive._DATA))); + } + + int rows = db.delete(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE, + getSelectionWithId(selection, uri), + selectionArgs); + if (rows > 0) { + notifyChange(uri); + } + return rows; + } + + @Override + public int update(Uri uri, + ContentValues values, + @Nullable String selection, + @Nullable String[] selectionArgs) { + SQLiteDatabase db = mDialerDatabaseHelper.getWritableDatabase(); + selection = getSelectionWithId(selection, uri); + int rows = db.update(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE, + values, + selection, + selectionArgs); + if (rows > 0) { + notifyChange(uri); + } + return rows; + } + + @Override + public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { + if (mUriMatcher.match(uri) != VOICEMAIL_ARCHIVE_TABLE_ID) { + throw new IllegalArgumentException("URI Invalid."); + } + return openFileHelper(uri, mode); + } + + private void deleteFile(@Nullable String path) { + if (TextUtils.isEmpty(path)) { + return; + } + File file = new File(path); + if (file.exists()) { + file.delete(); + } + } + + private SQLiteQueryBuilder getQueryBuilder(Uri uri) { + SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); + queryBuilder.setTables(DialerDatabaseHelper.Tables.VOICEMAIL_ARCHIVE_TABLE); + String selectionWithId = getSelectionWithId(null, uri); + if (!TextUtils.isEmpty(selectionWithId)) { + queryBuilder.appendWhere(selectionWithId); + } + return queryBuilder; + } + + private String getSelectionWithId(String selection, Uri uri) { + int match = mUriMatcher.match(uri); + switch (match) { + case VOICEMAIL_ARCHIVE_TABLE: + return selection; + case VOICEMAIL_ARCHIVE_TABLE_ID: + String idStr = VoicemailArchiveContract.VoicemailArchive._ID + "=" + + ContentUris.parseId(uri); + return TextUtils.isEmpty(selection) ? idStr : selection + " AND " + idStr; + default: + throw new IllegalArgumentException("Unknown uri: " + uri); + } + } + + private void notifyChange(Uri uri) { + getContext().getContentResolver().notifyChange(uri, null); + } +} diff --git a/tests/src/com/android/dialer/database/VoicemailArchiveProviderTest.java b/tests/src/com/android/dialer/database/VoicemailArchiveProviderTest.java new file mode 100644 index 000000000..cec7e050d --- /dev/null +++ b/tests/src/com/android/dialer/database/VoicemailArchiveProviderTest.java @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2016 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.dialer.database; + +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.test.ProviderTestCase2; +import android.test.mock.MockContentResolver; +import com.android.dialer.database.VoicemailArchiveContract.VoicemailArchive; + +import java.io.File; +import java.io.OutputStream; + +/** + * Tests for {@link VoicemailArchiveProvider}. + */ +public class VoicemailArchiveProviderTest extends + ProviderTestCase2 { + private static final String TEST_MIME_TYPE = "audio/mp3"; + private static final String TEST_NUMBER = "+1412555555"; + private static final int TEST_ARCHIVED = 1; + private static final String TEST_STRING = "TEST"; + + private MockContentResolver mResolver; + private Cursor mCursor; + private Uri mVoicemailUri; + + public VoicemailArchiveProviderTest() { + super(TestVoicemailArchiveProvider.class, VoicemailArchiveContract.AUTHORITY); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mResolver = getMockContentResolver(); + } + + @Override + protected void tearDown() throws Exception { + if (mCursor != null) { + mCursor.close(); + } + // Need to delete test.cache folder created by {@link android.test.ProviderTestCase2} + deleteRecursive(getContext().getCacheDir()); + getProvider().closeDb(); + super.tearDown(); + } + + public void testInsert() { + insertVoicemail(); + assertNotNull(mVoicemailUri); + assertTrue(doesRowExist()); + long id = ContentUris.parseId(mVoicemailUri); + assertTrue(id > 0); + } + + public void testQuery_createFile() throws Exception { + insertVoicemail(); + assertTrue(doesRowExist()); + assertFalse(doesFileExist()); + createFile(); + assertTrue(doesFileExist()); + } + + public void testQuery() { + insertVoicemail(); + updateCursor(); + assertCursorCount(1); + assertContentValues(); + } + + public void testQuery_correctValuesSelection() { + insertVoicemail(); + updateCursorWithIdQuery(); + assertCursorCount(1); + assertContentValues(); + } + + public void testQuery_illegalUri() { + try { + mResolver.query(Uri.withAppendedPath(VoicemailArchive.CONTENT_URI, TEST_STRING), + null, null, null, null); + fail("Expecting exception but none was thrown."); + } catch (IllegalArgumentException e) {} + } + + public void testUpdate() throws Exception { + insertVoicemail(); + assertTrue(doesRowExist()); + ContentValues values = new ContentValues(); + values.put(VoicemailArchive.MIME_TYPE, TEST_STRING); + values.put(VoicemailArchive.NUMBER, TEST_STRING); + values.put(VoicemailArchive.ARCHIVED, false); + mResolver.update(mVoicemailUri, values, null, null); + updateCursor(); + assertEquals(TEST_STRING, mCursor.getString(mCursor.getColumnIndex(VoicemailArchive.MIME_TYPE))); + assertEquals(TEST_STRING, mCursor.getString(mCursor.getColumnIndex(VoicemailArchive.NUMBER))); + assertEquals(false, mCursor.getInt( + mCursor.getColumnIndex(VoicemailArchive.ARCHIVED)) == 1); + } + + public void testUpdate_selection() throws Exception { + insertVoicemail(); + assertTrue(doesRowExist()); + ContentValues values = new ContentValues(); + values.put(VoicemailArchive.MIME_TYPE, TEST_STRING); + values.put(VoicemailArchive.NUMBER, TEST_STRING); + values.put(VoicemailArchive.ARCHIVED, false); + mResolver.update(VoicemailArchive.CONTENT_URI, values, getIdQuery(), null); + updateCursor(); + assertEquals(TEST_STRING, mCursor.getString(mCursor.getColumnIndex(VoicemailArchive.MIME_TYPE))); + assertEquals(TEST_STRING, mCursor.getString(mCursor.getColumnIndex(VoicemailArchive.NUMBER))); + assertEquals(false, mCursor.getInt( + mCursor.getColumnIndex(VoicemailArchive.ARCHIVED)) == 1); + } + + public void testUpdate_illegalUri() { + try { + mResolver.update(Uri.withAppendedPath(VoicemailArchive.CONTENT_URI, TEST_STRING), + null, null, null); + fail("Expecting exception but none was thrown."); + } catch (IllegalArgumentException e) {} + } + + public void testDelete() throws Exception { + insertVoicemail(); + createFile(); + assertTrue(doesRowExist()); + assertTrue(doesFileExist()); + mResolver.delete(mVoicemailUri, null, null); + assertFalse(doesRowExist()); + assertFalse(doesFileExist()); + } + + public void testDelete_selection() throws Exception{ + insertVoicemail(); + createFile(); + assertTrue(doesRowExist()); + assertTrue(doesFileExist()); + mResolver.delete(VoicemailArchive.CONTENT_URI, getIdQuery(), null); + assertFalse(doesRowExist()); + assertFalse(doesFileExist()); + } + + public void testDelete_illegalUri() { + try { + mResolver.delete(Uri.withAppendedPath(VoicemailArchive.CONTENT_URI, TEST_STRING), + null, null); + fail("Expecting exception but none was thrown."); + } catch (IllegalArgumentException e) {} + } + + private boolean doesRowExist() { + Cursor tempCursor = mResolver.query(mVoicemailUri, null, null, null, null); + boolean rowExists = tempCursor != null && tempCursor.getCount() > 0; + tempCursor.close(); + return rowExists; + } + + private boolean doesFileExist() { + File voicemailFile = new File(getFilePath()); + return voicemailFile.exists(); + } + + private void assertCursorCount(int count) { + assertEquals(count, mCursor.getCount()); + } + + private void assertContentValues() { + assertEquals(TEST_MIME_TYPE, mCursor + .getString(mCursor.getColumnIndex(VoicemailArchive.MIME_TYPE))); + assertEquals(TEST_NUMBER, mCursor + .getString(mCursor.getColumnIndex(VoicemailArchive.NUMBER))); + assertEquals(TEST_ARCHIVED, mCursor + .getInt(mCursor.getColumnIndex(VoicemailArchive.ARCHIVED))); + } + + private void insertVoicemail() { + mVoicemailUri = mResolver.insert(VoicemailArchive.CONTENT_URI, getTestValues()); + } + + private void updateCursor() { + mCursor = mResolver.query(mVoicemailUri, null, null, null, null); + assertEquals(true, mCursor.getCount() > 0); + mCursor.moveToFirst(); + } + + private void updateCursorWithIdQuery() { + mCursor = mResolver.query(mVoicemailUri, null, getIdQuery(), null, null); + assertEquals(true, mCursor.getCount() > 0); + mCursor.moveToFirst(); + } + + private void createFile() throws Exception { + assertFalse(doesFileExist()); + // Opening output stream and closing it should create the file + OutputStream outputStream = mResolver.openOutputStream(mVoicemailUri); + outputStream.close(); + } + + private String getIdQuery() { + return VoicemailArchive._ID + "=" + ContentUris.parseId(mVoicemailUri); + } + + private String getFilePath() { + if (mCursor == null) { + updateCursor(); + } + return mCursor.getString(mCursor.getColumnIndex(VoicemailArchive._DATA)); + } + + private ContentValues getTestValues() { + ContentValues values = new ContentValues(); + values.put(VoicemailArchive.NUMBER, TEST_NUMBER); + values.put(VoicemailArchive.MIME_TYPE, TEST_MIME_TYPE); + values.put(VoicemailArchive.ARCHIVED, TEST_ARCHIVED); + return values; + } + + private void deleteRecursive(File fileOrDirectory) { + if (fileOrDirectory.isDirectory()) { + for (File child : fileOrDirectory.listFiles()) { + deleteRecursive(child); + } + } + fileOrDirectory.delete(); + } + + public static class TestVoicemailArchiveProvider extends VoicemailArchiveProvider { + private DialerDatabaseHelper mDialerDatabaseHelper; + + @Override + protected File getFilesDir() { + return getContext().getCacheDir(); + } + + @Override + protected DialerDatabaseHelper getDatabaseHelper(Context context) { + if (mDialerDatabaseHelper == null) { + mDialerDatabaseHelper = DialerDatabaseHelper.getNewInstanceForTest(context); + } + return mDialerDatabaseHelper; + } + + protected void closeDb() { + mDialerDatabaseHelper.close(); + } + } +} -- cgit v1.2.3