diff options
Diffstat (limited to 'java/com/android/dialer/calllog')
10 files changed, 214 insertions, 32 deletions
diff --git a/java/com/android/dialer/calllog/CallLogFramework.java b/java/com/android/dialer/calllog/CallLogFramework.java index 55ef15b47..d3a2c638e 100644 --- a/java/com/android/dialer/calllog/CallLogFramework.java +++ b/java/com/android/dialer/calllog/CallLogFramework.java @@ -24,8 +24,8 @@ import android.support.annotation.Nullable; import com.android.dialer.calllog.datasources.CallLogDataSource; import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.common.Assert; -import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; import javax.inject.Inject; import javax.inject.Singleton; diff --git a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java index d25ec5e65..273246649 100644 --- a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java +++ b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java @@ -31,6 +31,7 @@ import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DialerExecutor.Worker; +import com.android.dialer.inject.ApplicationContext; import javax.inject.Inject; /** @@ -44,7 +45,7 @@ public class RefreshAnnotatedCallLogWorker implements Worker<Boolean, Void> { private final DataSources dataSources; @Inject - RefreshAnnotatedCallLogWorker(Context appContext, DataSources dataSources) { + RefreshAnnotatedCallLogWorker(@ApplicationContext Context appContext, DataSources dataSources) { this.appContext = appContext; this.dataSources = dataSources; } @@ -159,11 +160,20 @@ public class RefreshAnnotatedCallLogWorker implements Worker<Boolean, Void> { "applyToDatabase took: %dms", System.currentTimeMillis() - startTime); + for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { + dataSourceName = getName(dataSource); + LogUtil.i("RefreshAnnotatedCallLogWorker.rebuild", "onSuccessfulFill'ing %s", dataSourceName); + startTime = System.currentTimeMillis(); + dataSource.onSuccessfulFill(appContext); + LogUtil.i( + "CallLogFramework.rebuild", + "%s.onSuccessfulFill took: %dms", + dataSourceName, + System.currentTimeMillis() - startTime); + } + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext); - sharedPreferences - .edit() - .putBoolean(CallLogFramework.PREF_FORCE_REBUILD, false) - .commit(); + sharedPreferences.edit().putBoolean(CallLogFramework.PREF_FORCE_REBUILD, false).apply(); } private static String getName(CallLogDataSource dataSource) { diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java index a9c0d36b0..30aa2bff5 100644 --- a/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java +++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogContentProvider.java @@ -41,6 +41,13 @@ import java.util.ArrayList; /** {@link ContentProvider} for the annotated call log. */ public class AnnotatedCallLogContentProvider extends ContentProvider { + /** + * We sometimes run queries where we potentially pass every ID into a where clause using the + * (?,?,?,...) syntax. The maximum number of host parameters is 999, so that's the maximum size + * this table can be. See https://www.sqlite.org/limits.html for more details. + */ + private static final int MAX_ROWS = 999; + private static final int ANNOTATED_CALL_LOG_TABLE_CODE = 1; private static final int ANNOTATED_CALL_LOG_TABLE_ID_CODE = 2; private static final int COALESCED_ANNOTATED_CALL_LOG_TABLE_CODE = 3; @@ -72,7 +79,7 @@ public class AnnotatedCallLogContentProvider extends ContentProvider { @Override public boolean onCreate() { - databaseHelper = new AnnotatedCallLogDatabaseHelper(getContext()); + databaseHelper = new AnnotatedCallLogDatabaseHelper(getContext(), MAX_ROWS); coalescer = CallLogDatabaseComponent.get(getContext()).coalescer(); return true; } @@ -283,7 +290,21 @@ public class AnnotatedCallLogContentProvider extends ContentProvider { throw new OperationApplicationException("error inserting row"); } } else if (result.count == 0) { - throw new OperationApplicationException("error updating or deleting rows"); + /* + * The batches built by MutationApplier happen to contain operations in order of: + * + * 1. Inserts + * 2. Updates + * 3. Deletes + * + * Let's say the last row in the table is row Z, and MutationApplier wishes to update it, + * as well as insert row A. When row A gets inserted, row Z will be deleted via the + * trigger if the table is full. Then later, when we try to process the update for row Z, + * it won't exist. + */ + LogUtil.w( + "AnnotatedCallLogContentProvider.applyBatch", + "update or delete failed, possibly because row got cleaned up"); } results[i] = result; } diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java index 3cca639ff..887dfcbb6 100644 --- a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java +++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java @@ -21,28 +21,53 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.common.LogUtil; +import java.util.Locale; /** {@link SQLiteOpenHelper} for the AnnotatedCallLog database. */ class AnnotatedCallLogDatabaseHelper extends SQLiteOpenHelper { + private final int maxRows; - AnnotatedCallLogDatabaseHelper(Context appContext) { + AnnotatedCallLogDatabaseHelper(Context appContext, int maxRows) { super(appContext, "annotated_call_log.db", null, 1); + this.maxRows = maxRows; } - private static final String CREATE_SQL = + private static final String CREATE_TABLE_SQL = new StringBuilder() .append("create table if not exists " + AnnotatedCallLog.TABLE + " (") .append(AnnotatedCallLog._ID + " integer primary key, ") .append(AnnotatedCallLog.TIMESTAMP + " integer, ") - .append(AnnotatedCallLog.CONTACT_NAME + " string") + .append(AnnotatedCallLog.CONTACT_NAME + " string, ") + .append(AnnotatedCallLog.NUMBER + " blob") .append(");") .toString(); + /** Deletes all but the first maxRows rows (by timestamp) to keep the table a manageable size. */ + private static final String CREATE_TRIGGER_SQL = + "create trigger delete_old_rows after insert on " + + AnnotatedCallLog.TABLE + + " when (select count(*) from " + + AnnotatedCallLog.TABLE + + ") > %d" + + " begin delete from " + + AnnotatedCallLog.TABLE + + " where " + + AnnotatedCallLog._ID + + " in (select " + + AnnotatedCallLog._ID + + " from " + + AnnotatedCallLog.TABLE + + " order by timestamp limit (select count(*)-%d" + + " from " + + AnnotatedCallLog.TABLE + + " )); end;"; + @Override public void onCreate(SQLiteDatabase db) { LogUtil.enterBlock("AnnotatedCallLogDatabaseHelper.onCreate"); long startTime = System.currentTimeMillis(); - db.execSQL(CREATE_SQL); + db.execSQL(CREATE_TABLE_SQL); + db.execSQL(String.format(Locale.US, CREATE_TRIGGER_SQL, maxRows, maxRows)); // TODO: Consider logging impression. LogUtil.i( "AnnotatedCallLogDatabaseHelper.onCreate", diff --git a/java/com/android/dialer/calllog/database/Coalescer.java b/java/com/android/dialer/calllog/database/Coalescer.java index e3dfb7ece..5683687fd 100644 --- a/java/com/android/dialer/calllog/database/Coalescer.java +++ b/java/com/android/dialer/calllog/database/Coalescer.java @@ -17,15 +17,18 @@ package com.android.dialer.calllog.database; import android.content.ContentValues; import android.database.Cursor; -import android.database.DatabaseUtils; import android.database.MatrixCursor; import android.support.annotation.NonNull; import android.support.annotation.WorkerThread; +import com.android.dialer.DialerPhoneNumber; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; import com.android.dialer.calllog.datasources.CallLogDataSource; import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.common.Assert; +import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.protobuf.InvalidProtocolBufferException; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -64,6 +67,9 @@ public class Coalescer { // Note: This method relies on rowsShouldBeCombined to determine which rows should be combined, // but delegates to data sources to actually aggregate column values. + DialerPhoneNumberUtil dialerPhoneNumberUtil = + new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance()); + MatrixCursor allCoalescedRowsMatrixCursor = new MatrixCursor( CoalescedAnnotatedCallLog.ALL_COLUMNS, @@ -75,9 +81,8 @@ public class Coalescer { List<ContentValues> currentRowGroup = new ArrayList<>(); do { - ContentValues currentRow = new ContentValues(); - DatabaseUtils.cursorRowToContentValues( - allAnnotatedCallLogRowsSortedByTimestampDesc, currentRow); + ContentValues currentRow = + cursorRowToContentValues(allAnnotatedCallLogRowsSortedByTimestampDesc); if (currentRowGroup.isEmpty()) { currentRowGroup.add(currentRow); @@ -86,7 +91,7 @@ public class Coalescer { ContentValues previousRow = currentRowGroup.get(currentRowGroup.size() - 1); - if (!rowsShouldBeCombined(previousRow, currentRow)) { + if (!rowsShouldBeCombined(dialerPhoneNumberUtil, previousRow, currentRow)) { ContentValues coalescedRow = coalesceRowsForAllDataSources(currentRowGroup); coalescedRow.put(CoalescedAnnotatedCallLog.NUMBER_CALLS, currentRowGroup.size()); addContentValuesToMatrixCursor( @@ -104,13 +109,46 @@ public class Coalescer { return allCoalescedRowsMatrixCursor; } + private static ContentValues cursorRowToContentValues(Cursor cursor) { + ContentValues values = new ContentValues(); + String[] columns = cursor.getColumnNames(); + int length = columns.length; + for (int i = 0; i < length; i++) { + if (cursor.getType(i) == Cursor.FIELD_TYPE_BLOB) { + values.put(columns[i], cursor.getBlob(i)); + } else { + values.put(columns[i], cursor.getString(i)); + } + } + return values; + } + /** * @param row1 a row from {@link AnnotatedCallLog} * @param row2 a row from {@link AnnotatedCallLog} */ - private static boolean rowsShouldBeCombined(ContentValues row1, ContentValues row2) { + private static boolean rowsShouldBeCombined( + DialerPhoneNumberUtil dialerPhoneNumberUtil, ContentValues row1, ContentValues row2) { // TODO: Real implementation. - return row1.get(AnnotatedCallLog.TIMESTAMP).equals(row2.get(AnnotatedCallLog.TIMESTAMP)); + DialerPhoneNumber number1; + DialerPhoneNumber number2; + try { + number1 = DialerPhoneNumber.parseFrom(row1.getAsByteArray(AnnotatedCallLog.NUMBER)); + number2 = DialerPhoneNumber.parseFrom(row2.getAsByteArray(AnnotatedCallLog.NUMBER)); + } catch (InvalidProtocolBufferException e) { + throw Assert.createAssertionFailException("error parsing DialerPhoneNumber proto", e); + } + + if (!number1.hasDialerInternalPhoneNumber() && !number2.hasDialerInternalPhoneNumber()) { + // Empty numbers should not be combined. + return false; + } + + if (!number1.hasDialerInternalPhoneNumber() || !number2.hasDialerInternalPhoneNumber()) { + // An empty number should not be combined with a non-empty number. + return false; + } + return dialerPhoneNumberUtil.isExactMatch(number1, number2); } /** diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java index 8b3b0a852..7f314e37c 100644 --- a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java +++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java @@ -66,6 +66,18 @@ public class AnnotatedCallLogContract { /** The MIME type of a {@link android.content.ContentProvider#getType(Uri)} single entry. */ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/annotated_call_log"; + + /** + * The phone number called or number the call came from, encoded as a {@link + * com.android.dialer.DialerPhoneNumber} proto. The number may be empty if it was an incoming + * call and the number was unknown. + * + * <p>This column is only present in the annotated call log, and not the coalesced annotated + * call log. The coalesced version uses a formatted number string rather than proto bytes. + * + * <p>Type: BLOB + */ + public static final String NUMBER = "number"; } /** @@ -96,10 +108,19 @@ public class AnnotatedCallLogContract { public static final String NUMBER_CALLS = "number_calls"; /** + * The phone number formatted in a way suitable for display to the user. This value is generated + * on the fly when the {@link CoalescedAnnotatedCallLog} is generated. + * + * <p>Type: TEXT + */ + public static final String FORMATTED_NUMBER = "formatted_number"; + + /** * Columns that are only in the {@link CoalescedAnnotatedCallLog} but not the {@link * AnnotatedCallLog}. */ - private static final String[] COLUMNS_ONLY_IN_COALESCED_CALL_LOG = new String[] {NUMBER_CALLS}; + private static final String[] COLUMNS_ONLY_IN_COALESCED_CALL_LOG = + new String[] {NUMBER_CALLS, FORMATTED_NUMBER}; /** All columns in the {@link CoalescedAnnotatedCallLog}. */ public static final String[] ALL_COLUMNS = diff --git a/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java b/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java index e9538daab..82a85235b 100644 --- a/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java +++ b/java/com/android/dialer/calllog/datasources/contacts/ContactsDataSource.java @@ -50,6 +50,9 @@ public final class ContactsDataSource implements CallLogDataSource { CallLogMutations mutations) { Assert.isWorkerThread(); // TODO: Implementation. + for (ContentValues contentValues : mutations.getInserts().values()) { + contentValues.put(AnnotatedCallLog.CONTACT_NAME, "Placeholder name"); + } } @Override diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index be2df6043..f2063283f 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -34,14 +34,19 @@ import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import android.text.TextUtils; import android.util.ArraySet; +import com.android.dialer.DialerPhoneNumber; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; +import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; import com.android.dialer.calllog.datasources.CallLogDataSource; import com.android.dialer.calllog.datasources.CallLogMutations; import com.android.dialer.calllog.datasources.util.RowCombiner; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.ThreadUtil; +import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; import com.android.dialer.util.PermissionsUtil; +import com.google.i18n.phonenumbers.PhoneNumberUtil; +import com.google.protobuf.InvalidProtocolBufferException; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -132,16 +137,39 @@ public class SystemCallLogDataSource implements CallLogDataSource { PreferenceManager.getDefaultSharedPreferences(appContext) .edit() .putLong(PREF_LAST_TIMESTAMP_PROCESSED, lastTimestampProcessed) - .commit(); + .apply(); } } @Override public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) { // TODO: Complete implementation. - return new RowCombiner(individualRowsSortedByTimestampDesc) - .useMostRecentLong(AnnotatedCallLog.TIMESTAMP) - .combine(); + ContentValues coalescedValues = + new RowCombiner(individualRowsSortedByTimestampDesc) + .useMostRecentLong(AnnotatedCallLog.TIMESTAMP) + .combine(); + + // All phone numbers in the provided group should be equivalent (but could be formatted + // differently). Arbitrarily show the raw phone number of the most recent call. + DialerPhoneNumber mostRecentPhoneNumber = + getMostRecentPhoneNumber(individualRowsSortedByTimestampDesc); + coalescedValues.put( + CoalescedAnnotatedCallLog.FORMATTED_NUMBER, + mostRecentPhoneNumber.getRawInput().getNumber()); + return coalescedValues; + } + + private static DialerPhoneNumber getMostRecentPhoneNumber( + List<ContentValues> individualRowsSortedByTimestampDesc) { + DialerPhoneNumber dialerPhoneNumber; + byte[] protoBytes = + individualRowsSortedByTimestampDesc.get(0).getAsByteArray(AnnotatedCallLog.NUMBER); + try { + dialerPhoneNumber = DialerPhoneNumber.parseFrom(protoBytes); + } catch (InvalidProtocolBufferException e) { + throw Assert.createAssertionFailException("couldn't parse DialerPhoneNumber", e); + } + return dialerPhoneNumber; } @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources @@ -151,12 +179,18 @@ public class SystemCallLogDataSource implements CallLogDataSource { PreferenceManager.getDefaultSharedPreferences(appContext) .getLong(PREF_LAST_TIMESTAMP_PROCESSED, 0L); + DialerPhoneNumberUtil dialerPhoneNumberUtil = + new DialerPhoneNumberUtil(PhoneNumberUtil.getInstance()); + + // TODO: Really should be getting last 1000 by timestamp, not by last modified. try (Cursor cursor = appContext .getContentResolver() .query( Calls.CONTENT_URI, // Excludes voicemail - new String[] {Calls._ID, Calls.DATE, Calls.LAST_MODIFIED}, + new String[] { + Calls._ID, Calls.DATE, Calls.LAST_MODIFIED, Calls.NUMBER, Calls.COUNTRY_ISO + }, Calls.LAST_MODIFIED + " > ?", new String[] {String.valueOf(previousTimestampProcessed)}, Calls.LAST_MODIFIED + " DESC LIMIT 1000")) { @@ -175,6 +209,8 @@ public class SystemCallLogDataSource implements CallLogDataSource { int idColumn = cursor.getColumnIndexOrThrow(Calls._ID); int dateColumn = cursor.getColumnIndexOrThrow(Calls.DATE); int lastModifiedColumn = cursor.getColumnIndexOrThrow(Calls.LAST_MODIFIED); + int numberColumn = cursor.getColumnIndexOrThrow(Calls.NUMBER); + int countryIsoColumn = cursor.getColumnIndexOrThrow(Calls.COUNTRY_ISO); // The cursor orders by LAST_MODIFIED DESC, so the first result is the most recent timestamp // processed. @@ -182,9 +218,15 @@ public class SystemCallLogDataSource implements CallLogDataSource { do { long id = cursor.getLong(idColumn); long date = cursor.getLong(dateColumn); + String numberAsStr = cursor.getString(numberColumn); + String countryIso = cursor.getString(countryIsoColumn); + + byte[] numberAsProtoBytes = + dialerPhoneNumberUtil.parse(numberAsStr, countryIso).toByteArray(); ContentValues contentValues = new ContentValues(); contentValues.put(AnnotatedCallLog.TIMESTAMP, date); + contentValues.put(AnnotatedCallLog.NUMBER, numberAsProtoBytes); if (existingAnnotatedCallLogIds.contains(id)) { mutations.update(id, contentValues); @@ -202,7 +244,7 @@ public class SystemCallLogDataSource implements CallLogDataSource { getIdsFromSystemCallLogThatMatch(appContext, existingAnnotatedCallLogIds); LogUtil.i( "SystemCallLogDataSource.handleDeletes", - "found %d entries in system call log", + "found %d matching entries in system call log", systemCallLogIds.size()); Set<Long> idsInAnnotatedCallLogNoLongerInSystemCallLog = new ArraySet<>(); idsInAnnotatedCallLogNoLongerInSystemCallLog.addAll(existingAnnotatedCallLogIds); diff --git a/java/com/android/dialer/calllog/testing/FakeCallLogApplication.java b/java/com/android/dialer/calllog/testing/FakeCallLogApplication.java index cb2240539..8aee7dd56 100644 --- a/java/com/android/dialer/calllog/testing/FakeCallLogApplication.java +++ b/java/com/android/dialer/calllog/testing/FakeCallLogApplication.java @@ -16,8 +16,12 @@ package com.android.dialer.calllog.testing; import android.app.Application; +import com.android.dialer.calllog.CallLogComponent; import com.android.dialer.calllog.CallLogModule; import com.android.dialer.calllog.database.CallLogDatabaseComponent; +import com.android.dialer.common.concurrent.DialerExecutorComponent; +import com.android.dialer.common.concurrent.testing.TestDialerExecutorModule; +import com.android.dialer.inject.ContextModule; import com.android.dialer.inject.HasRootComponent; import dagger.Component; import javax.inject.Singleton; @@ -27,13 +31,23 @@ import javax.inject.Singleton; * tests to depend on and use all of DialerApplication. */ public final class FakeCallLogApplication extends Application implements HasRootComponent { + private Object rootComponent; @Override - public Object component() { - return DaggerFakeCallLogApplication_FakeComponent.create(); + public final synchronized Object component() { + if (rootComponent == null) { + rootComponent = + DaggerFakeCallLogApplication_FakeComponent.builder() + .contextModule(new ContextModule(this)) + .build(); + } + return rootComponent; } @Singleton - @Component(modules = CallLogModule.class) - interface FakeComponent extends CallLogDatabaseComponent.HasComponent {} + @Component(modules = {CallLogModule.class, ContextModule.class, TestDialerExecutorModule.class}) + interface FakeComponent + extends CallLogDatabaseComponent.HasComponent, + CallLogComponent.HasComponent, + DialerExecutorComponent.HasComponent {} } diff --git a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java index 89ed52fd7..712f7cf25 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java @@ -39,6 +39,14 @@ import com.android.dialer.common.concurrent.DialerExecutorFactory; public final class NewCallLogFragment extends Fragment implements CallLogUi, LoaderCallbacks<Cursor> { + /* + * This is a reasonable time that it might take between related call log writes, that also + * shouldn't slow down single-writes too much. For example, when populating the database using + * the simulator, using this value results in ~6 refresh cycles (on a release build) to write 120 + * call log entries. + */ + private static final long WAIT_MILLIS = 100L; + private DialerExecutor<Boolean> refreshAnnotatedCallLogTask; private RecyclerView recyclerView; @@ -113,13 +121,13 @@ public final class NewCallLogFragment extends Fragment private void checkAnnotatedCallLogDirtyAndRefreshIfNecessary() { LogUtil.enterBlock("NewCallLogFragment.checkAnnotatedCallLogDirtyAndRefreshIfNecessary"); - refreshAnnotatedCallLogTask.executeSerial(false /* skipDirtyCheck */); + refreshAnnotatedCallLogTask.executeSerialWithWait(false /* skipDirtyCheck */, WAIT_MILLIS); } @Override public void invalidateUi() { LogUtil.enterBlock("NewCallLogFragment.invalidateUi"); - refreshAnnotatedCallLogTask.executeSerial(true /* skipDirtyCheck */); + refreshAnnotatedCallLogTask.executeSerialWithWait(true /* skipDirtyCheck */, WAIT_MILLIS); } @Override |