Loading java/com/android/dialer/calllog/AnnotatedCallLogMigrator.java +5 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.dialer.calllog; import android.content.Context; import android.content.SharedPreferences; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.inject.ApplicationContext; Loading @@ -39,7 +40,7 @@ public final class AnnotatedCallLogMigrator { private final Context appContext; private final SharedPreferences sharedPreferences; private final RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker; private final ListeningExecutorService backgorundExecutor; private final ListeningExecutorService backgroundExecutor; @Inject AnnotatedCallLogMigrator( Loading @@ -49,7 +50,7 @@ public final class AnnotatedCallLogMigrator { RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker) { this.appContext = appContext; this.sharedPreferences = sharedPreferences; this.backgorundExecutor = backgroundExecutor; this.backgroundExecutor = backgroundExecutor; this.refreshAnnotatedCallLogWorker = refreshAnnotatedCallLogWorker; } Loading @@ -58,13 +59,13 @@ public final class AnnotatedCallLogMigrator { * the latency the first time call log is shown. */ public ListenableFuture<Void> migrate() { return Futures.transformAsync( shouldMigrate(), (shouldMigrate) -> { if (!shouldMigrate) { return Futures.immediateFuture(null); } LogUtil.i("AnnotatedCallLogMigrator.migrate", "migrating annotated call log"); return Futures.transform( refreshAnnotatedCallLogWorker.refreshWithoutDirtyCheck(), (unused) -> { Loading @@ -77,7 +78,7 @@ public final class AnnotatedCallLogMigrator { } private ListenableFuture<Boolean> shouldMigrate() { return backgorundExecutor.submit( return backgroundExecutor.submit( () -> { if (!(ConfigProviderBindings.get(appContext) .getBoolean("is_nui_shortcut_enabled", false))) { Loading java/com/android/dialer/calllog/CallLogState.java 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.calllog; import android.content.SharedPreferences; import android.support.annotation.AnyThread; import android.support.annotation.VisibleForTesting; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.storage.Unencrypted; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; /** Provides information about the state of the annotated call log. */ @ThreadSafe public final class CallLogState { private static final String ANNOTATED_CALL_LOG_BUILT_PREF = "annotated_call_log_built"; private final SharedPreferences sharedPreferences; private final ListeningExecutorService backgroundExecutor; @VisibleForTesting @Inject public CallLogState( @Unencrypted SharedPreferences sharedPreferences, @BackgroundExecutor ListeningExecutorService backgroundExecutor) { this.sharedPreferences = sharedPreferences; this.backgroundExecutor = backgroundExecutor; } /** * Mark the call log as having been built. This is written to disk the first time the annotated * call log has been built and shouldn't ever be reset unless the user clears data. */ @AnyThread public void markBuilt() { sharedPreferences.edit().putBoolean(ANNOTATED_CALL_LOG_BUILT_PREF, true).apply(); } /** * Returns true if the annotated call log has been built at least once. * * <p>It may not yet have been built if the user was just upgraded to the new call log, or they * just cleared data. */ @AnyThread public ListenableFuture<Boolean> isBuilt() { return backgroundExecutor.submit( () -> sharedPreferences.getBoolean(ANNOTATED_CALL_LOG_BUILT_PREF, false)); } } java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java +51 −14 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.google.common.base.Preconditions; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; Loading @@ -51,6 +52,7 @@ public class RefreshAnnotatedCallLogWorker { private final SharedPreferences sharedPreferences; private final MutationApplier mutationApplier; private final FutureTimer futureTimer; private final CallLogState callLogState; private final ListeningExecutorService backgroundExecutorService; private final ListeningExecutorService lightweightExecutorService; // Used to ensure that only one refresh flow runs at a time. (Note that Loading @@ -64,6 +66,7 @@ public class RefreshAnnotatedCallLogWorker { @Unencrypted SharedPreferences sharedPreferences, MutationApplier mutationApplier, FutureTimer futureTimer, CallLogState callLogState, @BackgroundExecutor ListeningExecutorService backgroundExecutorService, @LightweightExecutor ListeningExecutorService lightweightExecutorService) { this.appContext = appContext; Loading @@ -71,17 +74,18 @@ public class RefreshAnnotatedCallLogWorker { this.sharedPreferences = sharedPreferences; this.mutationApplier = mutationApplier; this.futureTimer = futureTimer; this.callLogState = callLogState; this.backgroundExecutorService = backgroundExecutorService; this.lightweightExecutorService = lightweightExecutorService; } /** Checks if the annotated call log is dirty and refreshes it if necessary. */ public ListenableFuture<Void> refreshWithDirtyCheck() { ListenableFuture<Void> refreshWithDirtyCheck() { return refresh(true); } /** Refreshes the annotated call log, bypassing dirty checks. */ public ListenableFuture<Void> refreshWithoutDirtyCheck() { ListenableFuture<Void> refreshWithoutDirtyCheck() { return refresh(false); } Loading Loading @@ -131,7 +135,11 @@ public class RefreshAnnotatedCallLogWorker { "RefreshAnnotatedCallLogWorker.checkDirtyAndRebuildIfNecessary", "isDirty: %b", Preconditions.checkNotNull(isDirty)); return isDirty ? rebuild() : Futures.immediateFuture(null); if (isDirty) { return Futures.transformAsync( callLogState.isBuilt(), this::rebuild, MoreExecutors.directExecutor()); } return Futures.immediateFuture(null); }, lightweightExecutorService); } Loading @@ -152,14 +160,13 @@ public class RefreshAnnotatedCallLogWorker { return isDirtyFuture; } private ListenableFuture<Void> rebuild() { private ListenableFuture<Void> rebuild(boolean isBuilt) { CallLogMutations mutations = new CallLogMutations(); // Start by filling the data sources--the system call log data source must go first! CallLogDataSource systemCallLogDataSource = dataSources.getSystemCallLogDataSource(); ListenableFuture<Void> fillFuture = systemCallLogDataSource.fill(appContext, mutations); String systemEventName = String.format(Metrics.FILL_TEMPLATE, systemCallLogDataSource.getClass().getSimpleName()); String systemEventName = eventNameForFill(systemCallLogDataSource, isBuilt); futureTimer.applyTiming(fillFuture, systemEventName); // After the system call log data source is filled, call fill sequentially on each remaining Loading @@ -171,14 +178,14 @@ public class RefreshAnnotatedCallLogWorker { fillFuture, unused -> { ListenableFuture<Void> dataSourceFuture = dataSource.fill(appContext, mutations); String eventName = String.format(Metrics.FILL_TEMPLATE, dataSource.getClass().getSimpleName()); String eventName = eventNameForFill(dataSource, isBuilt); futureTimer.applyTiming(dataSourceFuture, eventName); return dataSourceFuture; }, lightweightExecutorService); } futureTimer.applyTiming(fillFuture, Metrics.FILL_EVENT_NAME); futureTimer.applyTiming(fillFuture, eventNameForOverallFill(isBuilt)); // After all data sources are filled, apply mutations (at this point "fillFuture" is the result // of filling the last data source). Loading @@ -188,7 +195,7 @@ public class RefreshAnnotatedCallLogWorker { unused -> { ListenableFuture<Void> mutationApplierFuture = mutationApplier.applyToDatabase(mutations, appContext); futureTimer.applyTiming(mutationApplierFuture, Metrics.APPLY_MUTATIONS_EVENT_NAME); futureTimer.applyTiming(mutationApplierFuture, eventNameForApplyMutations(isBuilt)); return mutationApplierFuture; }, lightweightExecutorService); Loading @@ -203,13 +210,11 @@ public class RefreshAnnotatedCallLogWorker { dataSources.getDataSourcesIncludingSystemCallLog()) { ListenableFuture<Void> dataSourceFuture = dataSource.onSuccessfulFill(appContext); onSuccessfulFillFutures.add(dataSourceFuture); String eventName = String.format( Metrics.ON_SUCCESSFUL_FILL_TEMPLATE, dataSource.getClass().getSimpleName()); String eventName = eventNameForOnSuccessfulFill(dataSource, isBuilt); futureTimer.applyTiming(dataSourceFuture, eventName); } ListenableFuture<List<Void>> allFutures = Futures.allAsList(onSuccessfulFillFutures); futureTimer.applyTiming(allFutures, Metrics.ON_SUCCESSFUL_FILL_EVENT_NAME); futureTimer.applyTiming(allFutures, eventNameForOverallOnSuccessfulFill(isBuilt)); return allFutures; }, lightweightExecutorService); Loading @@ -219,8 +224,40 @@ public class RefreshAnnotatedCallLogWorker { onSuccessfulFillFuture, unused -> { sharedPreferences.edit().putBoolean(SharedPrefKeys.FORCE_REBUILD, false).apply(); callLogState.markBuilt(); return null; }, backgroundExecutorService); } private static String eventNameForFill(CallLogDataSource dataSource, boolean isBuilt) { return String.format( !isBuilt ? Metrics.INITIAL_FILL_TEMPLATE : Metrics.FILL_TEMPLATE, dataSource.getClass().getSimpleName()); } private static String eventNameForOverallFill(boolean isBuilt) { return !isBuilt ? Metrics.INITIAL_FILL_EVENT_NAME : Metrics.FILL_EVENT_NAME; } private static String eventNameForOnSuccessfulFill( CallLogDataSource dataSource, boolean isBuilt) { return String.format( !isBuilt ? Metrics.INITIAL_ON_SUCCESSFUL_FILL_TEMPLATE : Metrics.ON_SUCCESSFUL_FILL_TEMPLATE, dataSource.getClass().getSimpleName()); } private static String eventNameForOverallOnSuccessfulFill(boolean isBuilt) { return !isBuilt ? Metrics.INITIAL_ON_SUCCESSFUL_FILL_EVENT_NAME : Metrics.ON_SUCCESSFUL_FILL_EVENT_NAME; } private static String eventNameForApplyMutations(boolean isBuilt) { return !isBuilt ? Metrics.INITIAL_APPLY_MUTATIONS_EVENT_NAME : Metrics.APPLY_MUTATIONS_EVENT_NAME; } } java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java +13 −8 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.common.concurrent.Annotations.LightweightExecutor; import com.android.dialer.phonelookup.PhoneLookup; import com.android.dialer.phonelookup.PhoneLookupInfo; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory; import com.google.common.collect.ImmutableMap; Loading @@ -63,7 +64,7 @@ import javax.inject.Inject; */ public final class PhoneLookupDataSource implements CallLogDataSource { private final PhoneLookup<PhoneLookupInfo> phoneLookup; private final CompositePhoneLookup compositePhoneLookup; private final ListeningExecutorService backgroundExecutorService; private final ListeningExecutorService lightweightExecutorService; Loading @@ -86,10 +87,10 @@ public final class PhoneLookupDataSource implements CallLogDataSource { @Inject PhoneLookupDataSource( PhoneLookup<PhoneLookupInfo> phoneLookup, CompositePhoneLookup compositePhoneLookup, @BackgroundExecutor ListeningExecutorService backgroundExecutorService, @LightweightExecutor ListeningExecutorService lightweightExecutorService) { this.phoneLookup = phoneLookup; this.compositePhoneLookup = compositePhoneLookup; this.backgroundExecutorService = backgroundExecutorService; this.lightweightExecutorService = lightweightExecutorService; } Loading @@ -99,7 +100,8 @@ public final class PhoneLookupDataSource implements CallLogDataSource { ListenableFuture<ImmutableSet<DialerPhoneNumber>> phoneNumbers = backgroundExecutorService.submit( () -> queryDistinctDialerPhoneNumbersFromAnnotatedCallLog(appContext)); return Futures.transformAsync(phoneNumbers, phoneLookup::isDirty, lightweightExecutorService); return Futures.transformAsync( phoneNumbers, compositePhoneLookup::isDirty, lightweightExecutorService); } /** Loading Loading @@ -157,10 +159,13 @@ public final class PhoneLookupDataSource implements CallLogDataSource { queryPhoneLookupHistoryForNumbers(appContext, annotatedCallLogIdsByNumber.keySet()), backgroundExecutorService); // Use the original info map to generate the updated info map by delegating to phoneLookup. // Use the original info map to generate the updated info map by delegating to // compositePhoneLookup. ListenableFuture<ImmutableMap<DialerPhoneNumber, PhoneLookupInfo>> updatedInfoMapFuture = Futures.transformAsync( originalInfoMapFuture, phoneLookup::getMostRecentInfo, lightweightExecutorService); originalInfoMapFuture, compositePhoneLookup::getMostRecentInfo, lightweightExecutorService); // This is the computation that will use the result of all of the above. Callable<ImmutableMap<Long, PhoneLookupInfo>> computeRowsToUpdate = Loading Loading @@ -241,7 +246,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { // the AnnotatedCallLog and PhoneLookupHistory have been successfully updated. return Futures.transformAsync( writePhoneLookupHistory, unused -> phoneLookup.onSuccessfulBulkUpdate(), unused -> compositePhoneLookup.onSuccessfulBulkUpdate(), lightweightExecutorService); } Loading Loading @@ -286,7 +291,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { @MainThread @Override public void registerContentObservers(Context appContext) { phoneLookup.registerContentObservers(appContext); compositePhoneLookup.registerContentObservers(appContext); } private static ImmutableSet<DialerPhoneNumber> Loading java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java +6 −5 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.common.concurrent.Annotations.Ui; import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.inject.ApplicationContext; import com.android.dialer.phonelookup.PhoneLookup; import com.android.dialer.phonelookup.PhoneLookupInfo; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory; import com.google.common.collect.ImmutableMap; Loading Loading @@ -68,7 +68,7 @@ public final class RealtimeRowProcessor { @VisibleForTesting static final long BATCH_WAIT_MILLIS = TimeUnit.SECONDS.toMillis(3); private final Context appContext; private final PhoneLookup<PhoneLookupInfo> phoneLookup; private final CompositePhoneLookup compositePhoneLookup; private final ListeningExecutorService uiExecutor; private final ListeningExecutorService backgroundExecutor; Loading @@ -83,11 +83,11 @@ public final class RealtimeRowProcessor { @ApplicationContext Context appContext, @Ui ListeningExecutorService uiExecutor, @BackgroundExecutor ListeningExecutorService backgroundExecutor, PhoneLookup<PhoneLookupInfo> phoneLookup) { CompositePhoneLookup compositePhoneLookup) { this.appContext = appContext; this.uiExecutor = uiExecutor; this.backgroundExecutor = backgroundExecutor; this.phoneLookup = phoneLookup; this.compositePhoneLookup = compositePhoneLookup; } /** Loading @@ -106,7 +106,8 @@ public final class RealtimeRowProcessor { return Futures.immediateFuture(applyPhoneLookupInfoToRow(cachedPhoneLookupInfo, row)); } ListenableFuture<PhoneLookupInfo> phoneLookupInfoFuture = phoneLookup.lookup(row.number()); ListenableFuture<PhoneLookupInfo> phoneLookupInfoFuture = compositePhoneLookup.lookup(row.number()); return Futures.transform( phoneLookupInfoFuture, phoneLookupInfo -> { Loading Loading
java/com/android/dialer/calllog/AnnotatedCallLogMigrator.java +5 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.dialer.calllog; import android.content.Context; import android.content.SharedPreferences; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.inject.ApplicationContext; Loading @@ -39,7 +40,7 @@ public final class AnnotatedCallLogMigrator { private final Context appContext; private final SharedPreferences sharedPreferences; private final RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker; private final ListeningExecutorService backgorundExecutor; private final ListeningExecutorService backgroundExecutor; @Inject AnnotatedCallLogMigrator( Loading @@ -49,7 +50,7 @@ public final class AnnotatedCallLogMigrator { RefreshAnnotatedCallLogWorker refreshAnnotatedCallLogWorker) { this.appContext = appContext; this.sharedPreferences = sharedPreferences; this.backgorundExecutor = backgroundExecutor; this.backgroundExecutor = backgroundExecutor; this.refreshAnnotatedCallLogWorker = refreshAnnotatedCallLogWorker; } Loading @@ -58,13 +59,13 @@ public final class AnnotatedCallLogMigrator { * the latency the first time call log is shown. */ public ListenableFuture<Void> migrate() { return Futures.transformAsync( shouldMigrate(), (shouldMigrate) -> { if (!shouldMigrate) { return Futures.immediateFuture(null); } LogUtil.i("AnnotatedCallLogMigrator.migrate", "migrating annotated call log"); return Futures.transform( refreshAnnotatedCallLogWorker.refreshWithoutDirtyCheck(), (unused) -> { Loading @@ -77,7 +78,7 @@ public final class AnnotatedCallLogMigrator { } private ListenableFuture<Boolean> shouldMigrate() { return backgorundExecutor.submit( return backgroundExecutor.submit( () -> { if (!(ConfigProviderBindings.get(appContext) .getBoolean("is_nui_shortcut_enabled", false))) { Loading
java/com/android/dialer/calllog/CallLogState.java 0 → 100644 +67 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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.calllog; import android.content.SharedPreferences; import android.support.annotation.AnyThread; import android.support.annotation.VisibleForTesting; import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.storage.Unencrypted; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; /** Provides information about the state of the annotated call log. */ @ThreadSafe public final class CallLogState { private static final String ANNOTATED_CALL_LOG_BUILT_PREF = "annotated_call_log_built"; private final SharedPreferences sharedPreferences; private final ListeningExecutorService backgroundExecutor; @VisibleForTesting @Inject public CallLogState( @Unencrypted SharedPreferences sharedPreferences, @BackgroundExecutor ListeningExecutorService backgroundExecutor) { this.sharedPreferences = sharedPreferences; this.backgroundExecutor = backgroundExecutor; } /** * Mark the call log as having been built. This is written to disk the first time the annotated * call log has been built and shouldn't ever be reset unless the user clears data. */ @AnyThread public void markBuilt() { sharedPreferences.edit().putBoolean(ANNOTATED_CALL_LOG_BUILT_PREF, true).apply(); } /** * Returns true if the annotated call log has been built at least once. * * <p>It may not yet have been built if the user was just upgraded to the new call log, or they * just cleared data. */ @AnyThread public ListenableFuture<Boolean> isBuilt() { return backgroundExecutor.submit( () -> sharedPreferences.getBoolean(ANNOTATED_CALL_LOG_BUILT_PREF, false)); } }
java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java +51 −14 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import com.google.common.base.Preconditions; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import java.util.ArrayList; import java.util.List; import javax.inject.Inject; Loading @@ -51,6 +52,7 @@ public class RefreshAnnotatedCallLogWorker { private final SharedPreferences sharedPreferences; private final MutationApplier mutationApplier; private final FutureTimer futureTimer; private final CallLogState callLogState; private final ListeningExecutorService backgroundExecutorService; private final ListeningExecutorService lightweightExecutorService; // Used to ensure that only one refresh flow runs at a time. (Note that Loading @@ -64,6 +66,7 @@ public class RefreshAnnotatedCallLogWorker { @Unencrypted SharedPreferences sharedPreferences, MutationApplier mutationApplier, FutureTimer futureTimer, CallLogState callLogState, @BackgroundExecutor ListeningExecutorService backgroundExecutorService, @LightweightExecutor ListeningExecutorService lightweightExecutorService) { this.appContext = appContext; Loading @@ -71,17 +74,18 @@ public class RefreshAnnotatedCallLogWorker { this.sharedPreferences = sharedPreferences; this.mutationApplier = mutationApplier; this.futureTimer = futureTimer; this.callLogState = callLogState; this.backgroundExecutorService = backgroundExecutorService; this.lightweightExecutorService = lightweightExecutorService; } /** Checks if the annotated call log is dirty and refreshes it if necessary. */ public ListenableFuture<Void> refreshWithDirtyCheck() { ListenableFuture<Void> refreshWithDirtyCheck() { return refresh(true); } /** Refreshes the annotated call log, bypassing dirty checks. */ public ListenableFuture<Void> refreshWithoutDirtyCheck() { ListenableFuture<Void> refreshWithoutDirtyCheck() { return refresh(false); } Loading Loading @@ -131,7 +135,11 @@ public class RefreshAnnotatedCallLogWorker { "RefreshAnnotatedCallLogWorker.checkDirtyAndRebuildIfNecessary", "isDirty: %b", Preconditions.checkNotNull(isDirty)); return isDirty ? rebuild() : Futures.immediateFuture(null); if (isDirty) { return Futures.transformAsync( callLogState.isBuilt(), this::rebuild, MoreExecutors.directExecutor()); } return Futures.immediateFuture(null); }, lightweightExecutorService); } Loading @@ -152,14 +160,13 @@ public class RefreshAnnotatedCallLogWorker { return isDirtyFuture; } private ListenableFuture<Void> rebuild() { private ListenableFuture<Void> rebuild(boolean isBuilt) { CallLogMutations mutations = new CallLogMutations(); // Start by filling the data sources--the system call log data source must go first! CallLogDataSource systemCallLogDataSource = dataSources.getSystemCallLogDataSource(); ListenableFuture<Void> fillFuture = systemCallLogDataSource.fill(appContext, mutations); String systemEventName = String.format(Metrics.FILL_TEMPLATE, systemCallLogDataSource.getClass().getSimpleName()); String systemEventName = eventNameForFill(systemCallLogDataSource, isBuilt); futureTimer.applyTiming(fillFuture, systemEventName); // After the system call log data source is filled, call fill sequentially on each remaining Loading @@ -171,14 +178,14 @@ public class RefreshAnnotatedCallLogWorker { fillFuture, unused -> { ListenableFuture<Void> dataSourceFuture = dataSource.fill(appContext, mutations); String eventName = String.format(Metrics.FILL_TEMPLATE, dataSource.getClass().getSimpleName()); String eventName = eventNameForFill(dataSource, isBuilt); futureTimer.applyTiming(dataSourceFuture, eventName); return dataSourceFuture; }, lightweightExecutorService); } futureTimer.applyTiming(fillFuture, Metrics.FILL_EVENT_NAME); futureTimer.applyTiming(fillFuture, eventNameForOverallFill(isBuilt)); // After all data sources are filled, apply mutations (at this point "fillFuture" is the result // of filling the last data source). Loading @@ -188,7 +195,7 @@ public class RefreshAnnotatedCallLogWorker { unused -> { ListenableFuture<Void> mutationApplierFuture = mutationApplier.applyToDatabase(mutations, appContext); futureTimer.applyTiming(mutationApplierFuture, Metrics.APPLY_MUTATIONS_EVENT_NAME); futureTimer.applyTiming(mutationApplierFuture, eventNameForApplyMutations(isBuilt)); return mutationApplierFuture; }, lightweightExecutorService); Loading @@ -203,13 +210,11 @@ public class RefreshAnnotatedCallLogWorker { dataSources.getDataSourcesIncludingSystemCallLog()) { ListenableFuture<Void> dataSourceFuture = dataSource.onSuccessfulFill(appContext); onSuccessfulFillFutures.add(dataSourceFuture); String eventName = String.format( Metrics.ON_SUCCESSFUL_FILL_TEMPLATE, dataSource.getClass().getSimpleName()); String eventName = eventNameForOnSuccessfulFill(dataSource, isBuilt); futureTimer.applyTiming(dataSourceFuture, eventName); } ListenableFuture<List<Void>> allFutures = Futures.allAsList(onSuccessfulFillFutures); futureTimer.applyTiming(allFutures, Metrics.ON_SUCCESSFUL_FILL_EVENT_NAME); futureTimer.applyTiming(allFutures, eventNameForOverallOnSuccessfulFill(isBuilt)); return allFutures; }, lightweightExecutorService); Loading @@ -219,8 +224,40 @@ public class RefreshAnnotatedCallLogWorker { onSuccessfulFillFuture, unused -> { sharedPreferences.edit().putBoolean(SharedPrefKeys.FORCE_REBUILD, false).apply(); callLogState.markBuilt(); return null; }, backgroundExecutorService); } private static String eventNameForFill(CallLogDataSource dataSource, boolean isBuilt) { return String.format( !isBuilt ? Metrics.INITIAL_FILL_TEMPLATE : Metrics.FILL_TEMPLATE, dataSource.getClass().getSimpleName()); } private static String eventNameForOverallFill(boolean isBuilt) { return !isBuilt ? Metrics.INITIAL_FILL_EVENT_NAME : Metrics.FILL_EVENT_NAME; } private static String eventNameForOnSuccessfulFill( CallLogDataSource dataSource, boolean isBuilt) { return String.format( !isBuilt ? Metrics.INITIAL_ON_SUCCESSFUL_FILL_TEMPLATE : Metrics.ON_SUCCESSFUL_FILL_TEMPLATE, dataSource.getClass().getSimpleName()); } private static String eventNameForOverallOnSuccessfulFill(boolean isBuilt) { return !isBuilt ? Metrics.INITIAL_ON_SUCCESSFUL_FILL_EVENT_NAME : Metrics.ON_SUCCESSFUL_FILL_EVENT_NAME; } private static String eventNameForApplyMutations(boolean isBuilt) { return !isBuilt ? Metrics.INITIAL_APPLY_MUTATIONS_EVENT_NAME : Metrics.APPLY_MUTATIONS_EVENT_NAME; } }
java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java +13 −8 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.common.concurrent.Annotations.LightweightExecutor; import com.android.dialer.phonelookup.PhoneLookup; import com.android.dialer.phonelookup.PhoneLookupInfo; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory; import com.google.common.collect.ImmutableMap; Loading @@ -63,7 +64,7 @@ import javax.inject.Inject; */ public final class PhoneLookupDataSource implements CallLogDataSource { private final PhoneLookup<PhoneLookupInfo> phoneLookup; private final CompositePhoneLookup compositePhoneLookup; private final ListeningExecutorService backgroundExecutorService; private final ListeningExecutorService lightweightExecutorService; Loading @@ -86,10 +87,10 @@ public final class PhoneLookupDataSource implements CallLogDataSource { @Inject PhoneLookupDataSource( PhoneLookup<PhoneLookupInfo> phoneLookup, CompositePhoneLookup compositePhoneLookup, @BackgroundExecutor ListeningExecutorService backgroundExecutorService, @LightweightExecutor ListeningExecutorService lightweightExecutorService) { this.phoneLookup = phoneLookup; this.compositePhoneLookup = compositePhoneLookup; this.backgroundExecutorService = backgroundExecutorService; this.lightweightExecutorService = lightweightExecutorService; } Loading @@ -99,7 +100,8 @@ public final class PhoneLookupDataSource implements CallLogDataSource { ListenableFuture<ImmutableSet<DialerPhoneNumber>> phoneNumbers = backgroundExecutorService.submit( () -> queryDistinctDialerPhoneNumbersFromAnnotatedCallLog(appContext)); return Futures.transformAsync(phoneNumbers, phoneLookup::isDirty, lightweightExecutorService); return Futures.transformAsync( phoneNumbers, compositePhoneLookup::isDirty, lightweightExecutorService); } /** Loading Loading @@ -157,10 +159,13 @@ public final class PhoneLookupDataSource implements CallLogDataSource { queryPhoneLookupHistoryForNumbers(appContext, annotatedCallLogIdsByNumber.keySet()), backgroundExecutorService); // Use the original info map to generate the updated info map by delegating to phoneLookup. // Use the original info map to generate the updated info map by delegating to // compositePhoneLookup. ListenableFuture<ImmutableMap<DialerPhoneNumber, PhoneLookupInfo>> updatedInfoMapFuture = Futures.transformAsync( originalInfoMapFuture, phoneLookup::getMostRecentInfo, lightweightExecutorService); originalInfoMapFuture, compositePhoneLookup::getMostRecentInfo, lightweightExecutorService); // This is the computation that will use the result of all of the above. Callable<ImmutableMap<Long, PhoneLookupInfo>> computeRowsToUpdate = Loading Loading @@ -241,7 +246,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { // the AnnotatedCallLog and PhoneLookupHistory have been successfully updated. return Futures.transformAsync( writePhoneLookupHistory, unused -> phoneLookup.onSuccessfulBulkUpdate(), unused -> compositePhoneLookup.onSuccessfulBulkUpdate(), lightweightExecutorService); } Loading Loading @@ -286,7 +291,7 @@ public final class PhoneLookupDataSource implements CallLogDataSource { @MainThread @Override public void registerContentObservers(Context appContext) { phoneLookup.registerContentObservers(appContext); compositePhoneLookup.registerContentObservers(appContext); } private static ImmutableSet<DialerPhoneNumber> Loading
java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java +6 −5 Original line number Diff line number Diff line Loading @@ -31,8 +31,8 @@ import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.common.concurrent.Annotations.Ui; import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.inject.ApplicationContext; import com.android.dialer.phonelookup.PhoneLookup; import com.android.dialer.phonelookup.PhoneLookupInfo; import com.android.dialer.phonelookup.composite.CompositePhoneLookup; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract; import com.android.dialer.phonelookup.database.contract.PhoneLookupHistoryContract.PhoneLookupHistory; import com.google.common.collect.ImmutableMap; Loading Loading @@ -68,7 +68,7 @@ public final class RealtimeRowProcessor { @VisibleForTesting static final long BATCH_WAIT_MILLIS = TimeUnit.SECONDS.toMillis(3); private final Context appContext; private final PhoneLookup<PhoneLookupInfo> phoneLookup; private final CompositePhoneLookup compositePhoneLookup; private final ListeningExecutorService uiExecutor; private final ListeningExecutorService backgroundExecutor; Loading @@ -83,11 +83,11 @@ public final class RealtimeRowProcessor { @ApplicationContext Context appContext, @Ui ListeningExecutorService uiExecutor, @BackgroundExecutor ListeningExecutorService backgroundExecutor, PhoneLookup<PhoneLookupInfo> phoneLookup) { CompositePhoneLookup compositePhoneLookup) { this.appContext = appContext; this.uiExecutor = uiExecutor; this.backgroundExecutor = backgroundExecutor; this.phoneLookup = phoneLookup; this.compositePhoneLookup = compositePhoneLookup; } /** Loading @@ -106,7 +106,8 @@ public final class RealtimeRowProcessor { return Futures.immediateFuture(applyPhoneLookupInfoToRow(cachedPhoneLookupInfo, row)); } ListenableFuture<PhoneLookupInfo> phoneLookupInfoFuture = phoneLookup.lookup(row.number()); ListenableFuture<PhoneLookupInfo> phoneLookupInfoFuture = compositePhoneLookup.lookup(row.number()); return Futures.transform( phoneLookupInfoFuture, phoneLookupInfo -> { Loading