From 68ea8cf4e1d5a19bf8ef44e9686305ded95852de Mon Sep 17 00:00:00 2001 From: zachh Date: Tue, 27 Mar 2018 18:13:49 -0700 Subject: Support new call log fragment in old peer. This makes the old peer read the CallLogConfig#isNewCallLogFragmentEnabled and show the old or new fragment accordingly. If the user is viewing the NewCallLog and the CallLogConfig needs to disable the framework, the new fragment is immediately replaced with the old one. This is necessary because if the user were to scroll the fragment, the AnnotatedCallLog and PhoneLookupHistory databases would be read, which would trigger creation. I don't expect this to be a common case because 1) we hopefully never have to disable the framework and 2) Framework is only updated on Phenotype broadcasts and JobScheduler jobs, which hopefully don't typically happen when user is viewing the call log. However, I still want to make sure that if it happens we don't irreversibly break users when we turn the framework back on. I tested this by flipping flags and observing underlying data being removed: > dialer-cmd configprovider set new_voicemail_fragment_enabled false > adb shell ls /data/data/com.google.android.dialer/databases/ && echo && adb shell cat /data/user_de/0/com.google.android.dialer/shared_prefs/com.google.android.dialer_preferences.xml I test flipping flags back and forth on the call log tab, speed dial tab, and while the activity was paused (pressing Home after viewing call log). Note that this CL doesn't address showing missed calls and badge counts correctly with the new fragment; that will come in a later CL. Bug: 74821995 Test: unit and manual PiperOrigin-RevId: 190706481 Change-Id: I618d9c1649169abd65733502cfebc662a835e787 --- .../android/dialer/calllog/CallLogFramework.java | 34 ++++++++++++++++++++-- java/com/android/dialer/calllog/CallLogState.java | 9 ++++++ .../systemcalllog/SystemCallLogDataSource.java | 4 --- 3 files changed, 41 insertions(+), 6 deletions(-) (limited to 'java/com/android/dialer/calllog') diff --git a/java/com/android/dialer/calllog/CallLogFramework.java b/java/com/android/dialer/calllog/CallLogFramework.java index 53ff43057..b86bfbc10 100644 --- a/java/com/android/dialer/calllog/CallLogFramework.java +++ b/java/com/android/dialer/calllog/CallLogFramework.java @@ -16,11 +16,17 @@ package com.android.dialer.calllog; +import android.content.Context; +import android.content.Intent; +import android.support.v4.content.LocalBroadcastManager; import com.android.dialer.calllog.datasources.CallLogDataSource; import com.android.dialer.calllog.datasources.DataSources; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.Annotations.Ui; +import com.android.dialer.inject.ApplicationContext; 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; @@ -35,13 +41,24 @@ import javax.inject.Singleton; @Singleton public final class CallLogFramework { + private final Context appContext; private final DataSources dataSources; private final AnnotatedCallLogMigrator annotatedCallLogMigrator; + private final ListeningExecutorService uiExecutor; + private final CallLogState callLogState; @Inject - CallLogFramework(DataSources dataSources, AnnotatedCallLogMigrator annotatedCallLogMigrator) { + CallLogFramework( + @ApplicationContext Context appContext, + DataSources dataSources, + AnnotatedCallLogMigrator annotatedCallLogMigrator, + @Ui ListeningExecutorService uiExecutor, + CallLogState callLogState) { + this.appContext = appContext; this.dataSources = dataSources; this.annotatedCallLogMigrator = annotatedCallLogMigrator; + this.uiExecutor = uiExecutor; + this.callLogState = callLogState; } /** Registers the content observers for all data sources. */ @@ -73,12 +90,25 @@ public final class CallLogFramework { dataSource.unregisterContentObservers(); } + callLogState.clearData(); + // Clear data only after all content observers have been disabled. List> allFutures = new ArrayList<>(); for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { allFutures.add(dataSource.clearData()); } + return Futures.transform( - Futures.allAsList(allFutures), unused -> null, MoreExecutors.directExecutor()); + Futures.allAsList(allFutures), + unused -> { + // Send a broadcast to the OldMainActivityPeer to remove the NewCallLogFragment if it is + // currently attached. If this is not done, user interaction with the fragment could cause + // call log framework state to be unexpectedly written. For example scrolling could cause + // the AnnotatedCallLog to be read (which would trigger database creation). + LocalBroadcastManager.getInstance(appContext) + .sendBroadcastSync(new Intent("disableNewCallLogFragment")); + return null; + }, + uiExecutor); } } diff --git a/java/com/android/dialer/calllog/CallLogState.java b/java/com/android/dialer/calllog/CallLogState.java index bdb30a769..6d2ec1e5e 100644 --- a/java/com/android/dialer/calllog/CallLogState.java +++ b/java/com/android/dialer/calllog/CallLogState.java @@ -53,6 +53,15 @@ public final class CallLogState { sharedPreferences.edit().putBoolean(ANNOTATED_CALL_LOG_BUILT_PREF, true).apply(); } + /** + * Clear the call log state. This is useful for example if the annotated call log needs to be + * disabled because there was a problem. + */ + @AnyThread + public void clearData() { + sharedPreferences.edit().remove(ANNOTATED_CALL_LOG_BUILT_PREF).apply(); + } + /** * Returns true if the annotated call log has been built at least once. * diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index 9332acdb1..8362a81ac 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -30,7 +30,6 @@ import android.provider.CallLog.Calls; import android.provider.VoicemailContract; import android.provider.VoicemailContract.Voicemails; import android.support.annotation.ColorInt; -import android.support.annotation.MainThread; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; import android.support.annotation.VisibleForTesting; @@ -102,11 +101,8 @@ public class SystemCallLogDataSource implements CallLogDataSource { this.annotatedCallLogDatabaseHelper = annotatedCallLogDatabaseHelper; } - @MainThread @Override public void registerContentObservers() { - Assert.isMainThread(); - LogUtil.enterBlock("SystemCallLogDataSource.registerContentObservers"); if (!PermissionsUtil.hasCallLogReadPermissions(appContext)) { -- cgit v1.2.3