diff options
6 files changed, 57 insertions, 29 deletions
diff --git a/src/com/android/providers/contacts/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java index fd2adc10..a3bed8c3 100644 --- a/src/com/android/providers/contacts/CallLogProvider.java +++ b/src/com/android/providers/contacts/CallLogProvider.java @@ -20,8 +20,6 @@ import static com.android.providers.contacts.util.DbQueryUtils.checkForSupported import static com.android.providers.contacts.util.DbQueryUtils.getEqualityClause; import static com.android.providers.contacts.util.DbQueryUtils.getInequalityClause; -import com.google.common.annotations.VisibleForTesting; - import android.app.AppOpsManager; import android.content.ContentProvider; import android.content.ContentResolver; @@ -48,12 +46,11 @@ import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.text.TextUtils; import android.util.Log; - import com.android.providers.contacts.CallLogDatabaseHelper.DbProperties; import com.android.providers.contacts.CallLogDatabaseHelper.Tables; import com.android.providers.contacts.util.SelectionBuilder; import com.android.providers.contacts.util.UserUtils; - +import com.google.common.annotations.VisibleForTesting; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -385,7 +382,7 @@ public class CallLogProvider extends ContentProvider { throw new UnsupportedOperationException("Cannot update URL: " + uri); } - return getDatabaseModifier(db).update(Tables.CALLS, values, selectionBuilder.build(), + return getDatabaseModifier(db).update(uri, Tables.CALLS, values, selectionBuilder.build(), selectionArgs); } diff --git a/src/com/android/providers/contacts/DatabaseModifier.java b/src/com/android/providers/contacts/DatabaseModifier.java index 3f5a4022..b11605b4 100644 --- a/src/com/android/providers/contacts/DatabaseModifier.java +++ b/src/com/android/providers/contacts/DatabaseModifier.java @@ -20,6 +20,7 @@ package com.android.providers.contacts; import android.content.ContentValues; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; +import android.net.Uri; /** * An interface which wraps key database modify operations (insert, update, delete) to perform @@ -41,7 +42,7 @@ public interface DatabaseModifier { * Use this method to update a table which you would otherwise do using the * {@link SQLiteDatabase#update(String, ContentValues, String, String[])} method. */ - public abstract int update(String table, ContentValues values, + public abstract int update(Uri uri, String table, ContentValues values, String whereClause, String[] whereArgs); /** * Use this method to delete entries from a table which you would otherwise do using the diff --git a/src/com/android/providers/contacts/DbModifierWithNotification.java b/src/com/android/providers/contacts/DbModifierWithNotification.java index 83530869..ef1b847b 100644 --- a/src/com/android/providers/contacts/DbModifierWithNotification.java +++ b/src/com/android/providers/contacts/DbModifierWithNotification.java @@ -20,9 +20,6 @@ package com.android.providers.contacts; import static android.Manifest.permission.ADD_VOICEMAIL; import static android.Manifest.permission.READ_VOICEMAIL; -import com.google.android.collect.Lists; -import com.google.common.collect.Iterables; - import android.content.ComponentName; import android.content.ContentUris; import android.content.ContentValues; @@ -35,17 +32,16 @@ import android.database.DatabaseUtils.InsertHelper; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.os.Binder; -import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.VoicemailContract; import android.provider.VoicemailContract.Status; import android.provider.VoicemailContract.Voicemails; import android.util.Log; - import com.android.common.io.MoreCloseables; import com.android.providers.contacts.CallLogDatabaseHelper.Tables; import com.android.providers.contacts.util.DbQueryUtils; - +import com.google.android.collect.Lists; +import com.google.common.collect.Iterables; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -155,12 +151,14 @@ public class DbModifierWithNotification implements DatabaseModifier { } @Override - public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { + public int update(Uri uri, String table, ContentValues values, String whereClause, + String[] whereArgs) { Set<String> packagesModified = getModifiedPackages(whereClause, whereArgs); packagesModified.addAll(getModifiedPackages(values)); boolean isVoicemail = packagesModified.size() != 0; + boolean hasMarkedRead = false; if (mIsCallsTable) { values.put(Calls.LAST_MODIFIED, System.currentTimeMillis()); @@ -171,6 +169,15 @@ public class DbModifierWithNotification implements DatabaseModifier { // so that the corresponding sync adapter knows they need to be synced. final int isDirty = isSelfModifyingOrInternal(packagesModified) ? 0 : 1; values.put(VoicemailContract.Voicemails.DIRTY, isDirty); + + if (isDirty == 0 && values.containsKey(Calls.IS_READ) && getAsBoolean(values, + Calls.IS_READ)) { + // If the server has set the IS_READ, it should also unset the new flag + if (!values.containsKey(Calls.NEW)) { + values.put(Calls.NEW, 0); + hasMarkedRead = true; + } + } } } @@ -181,6 +188,14 @@ public class DbModifierWithNotification implements DatabaseModifier { if (count > 0 && mIsCallsTable) { notifyCallLogChange(); } + if (hasMarkedRead) { + // A "New" voicemail has been marked as read by the server. This voicemail is no longer + // new but the content consumer might still think it is. ACTION_NEW_VOICEMAIL should + // trigger a rescan of new voicemails. + mContext.sendBroadcast( + new Intent(VoicemailContract.ACTION_NEW_VOICEMAIL, uri), + READ_VOICEMAIL); + } return count; } @@ -329,4 +344,23 @@ public class DbModifierWithNotification implements DatabaseModifier { } return Lists.newArrayList(mContext.getPackageManager().getPackagesForUid(caller)); } + + /** + * A variant of {@link ContentValues#getAsBoolean(String)} that also treat the string "0" as + * false and other integer string as true. 0, 1, false, true, "0", "1", "false", "true" might + * all be inserted into the ContentValues as a boolean, but "0" and "1" are not handled by + * {@link ContentValues#getAsBoolean(String)} + */ + private static Boolean getAsBoolean(ContentValues values, String key) { + Object value = values.get(key); + if (value instanceof CharSequence) { + try { + int intValue = Integer.parseInt(value.toString()); + return intValue != 0; + } catch (NumberFormatException nfe) { + // Do nothing. + } + } + return values.getAsBoolean(key); + } } diff --git a/src/com/android/providers/contacts/VoicemailContentProvider.java b/src/com/android/providers/contacts/VoicemailContentProvider.java index 1d7f3252..099e924d 100644 --- a/src/com/android/providers/contacts/VoicemailContentProvider.java +++ b/src/com/android/providers/contacts/VoicemailContentProvider.java @@ -32,13 +32,11 @@ import android.provider.BaseColumns; import android.provider.VoicemailContract; import android.provider.VoicemailContract.Voicemails; import android.util.Log; - import com.android.providers.contacts.CallLogDatabaseHelper.Tables; import com.android.providers.contacts.util.ContactsPermissions; import com.android.providers.contacts.util.SelectionBuilder; import com.android.providers.contacts.util.TypedUriMatcherImpl; import com.google.common.annotations.VisibleForTesting; - import java.io.FileNotFoundException; import java.util.List; @@ -56,8 +54,8 @@ public class VoicemailContentProvider extends ContentProvider @Override public boolean onCreate() { - if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { - Log.d(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate start"); + if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.INFO)) { + Log.i(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate start"); } Context context = context(); @@ -70,8 +68,8 @@ public class VoicemailContentProvider extends ContentProvider getDatabaseHelper(context), this, createCallLogInsertionHelper(context)); mVoicemailStatusTable = new VoicemailStatusTable(Tables.VOICEMAIL_STATUS, context, getDatabaseHelper(context), this); - if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.DEBUG)) { - Log.d(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate finish"); + if (Log.isLoggable(Constants.PERFORMANCE_TAG, Log.INFO)) { + Log.i(Constants.PERFORMANCE_TAG, "VoicemailContentProvider.onCreate finish"); } return true; } diff --git a/src/com/android/providers/contacts/VoicemailContentTable.java b/src/com/android/providers/contacts/VoicemailContentTable.java index 572b7ddd..24a02bc7 100644 --- a/src/com/android/providers/contacts/VoicemailContentTable.java +++ b/src/com/android/providers/contacts/VoicemailContentTable.java @@ -19,15 +19,12 @@ import static com.android.providers.contacts.util.DbQueryUtils.checkForSupported import static com.android.providers.contacts.util.DbQueryUtils.concatenateClauses; import static com.android.providers.contacts.util.DbQueryUtils.getEqualityClause; -import com.google.common.collect.ImmutableSet; - import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.os.ParcelFileDescriptor; @@ -35,11 +32,10 @@ import android.provider.CallLog.Calls; import android.provider.OpenableColumns; import android.provider.VoicemailContract.Voicemails; import android.util.Log; - import com.android.common.content.ProjectionMap; import com.android.providers.contacts.VoicemailContentProvider.UriData; import com.android.providers.contacts.util.CloseUtils; - +import com.google.common.collect.ImmutableSet; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -48,7 +44,8 @@ import java.io.IOException; * Implementation of {@link VoicemailTable.Delegate} for the voicemail content table. */ public class VoicemailContentTable implements VoicemailTable.Delegate { - private static final String TAG = "VoicemailContentProvider"; + + private static final String TAG = "VmContentProvider"; private final ProjectionMap mVoicemailProjectionMap; /** The private directory in which to store the data associated with the voicemail. */ @@ -251,7 +248,7 @@ public class VoicemailContentTable implements VoicemailTable.Delegate { // URI that include message Id. I think we do want to support bulk update. String combinedClause = concatenateClauses(selection, uriData.getWhereClause(), getCallTypeClause()); - return getDatabaseModifier(db).update(mTableName, values, combinedClause, + return getDatabaseModifier(db).update(uriData.getUri(), mTableName, values, combinedClause, selectionArgs); } @@ -285,4 +282,5 @@ public class VoicemailContentTable implements VoicemailTable.Delegate { private DatabaseModifier getDatabaseModifier(SQLiteDatabase db) { return new DbModifierWithNotification(mTableName, db, mContext); } + } diff --git a/src/com/android/providers/contacts/VoicemailStatusTable.java b/src/com/android/providers/contacts/VoicemailStatusTable.java index 01e5c24e..52da2927 100644 --- a/src/com/android/providers/contacts/VoicemailStatusTable.java +++ b/src/com/android/providers/contacts/VoicemailStatusTable.java @@ -75,7 +75,7 @@ public class VoicemailStatusTable implements VoicemailTable.Delegate { // Try to update before insert. String combinedClause = uriData.getWhereClause(); int rowsChanged = getDatabaseModifier(db) - .update(mTableName, values, combinedClause, null); + .update(uriData.getUri(), mTableName, values, combinedClause, null); if (rowsChanged != 0) { final String[] selection = new String[] {Status._ID}; Cursor c = db.query(mTableName, selection, combinedClause, null, null, null, null); @@ -131,8 +131,8 @@ public class VoicemailStatusTable implements VoicemailTable.Delegate { synchronized (DATABASE_LOCK) { SQLiteDatabase db = mDbHelper.getWritableDatabase(); String combinedClause = concatenateClauses(selection, uriData.getWhereClause()); - return getDatabaseModifier(db).update(mTableName, values, combinedClause, - selectionArgs); + return getDatabaseModifier(db) + .update(uriData.getUri(), mTableName, values, combinedClause, selectionArgs); } } |