Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee5d16c7 authored by zachh's avatar zachh Committed by android-build-merger
Browse files

Merge "Enable and disable the call log framework on flag changes."

am: 6fc5a8d8

Change-Id: Ib0b87183dc6065ac7f0fdf269f667348d9c8006b
parents 433968a8 6fc5a8d8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ public abstract class DialerApplication extends Application implements HasRootCo
            new FilteredNumberAsyncQueryHandler(this),
            DialerExecutorComponent.get(this).dialerExecutorFactory())
        .asyncAutoMigrate();
    CallLogComponent.get(this).callLogFramework().onApplicationCreate(getApplicationContext());
    CallLogComponent.get(this).callLogFramework().onApplicationCreate();
    Futures.addCallback(
        CallLogComponent.get(this).getAnnotatedCallLogMigrator().migrate(),
        new DefaultFutureCallback<>(),
+13 −0
Original line number Diff line number Diff line
@@ -90,4 +90,17 @@ public final class AnnotatedCallLogMigrator {
          return true;
        });
  }

  /**
   * Clears data that indicates if migration happened or not. This is necessary if migration needs
   * to happen again, for example because the call log framework was disabled via flags due to a
   * problem.
   */
  ListenableFuture<Void> clearData() {
    return backgroundExecutor.submit(
        () -> {
          sharedPreferences.edit().remove(PREF_MIGRATED).apply();
          return null;
        });
  }
}
+71 −41
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.support.v4.os.UserManagerCompat;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.configprovider.ConfigProvider;
import com.android.dialer.constants.ScheduledJobIds;
@@ -59,18 +60,27 @@ public final class CallLogConfig {
  private static final String NEW_CALL_LOG_FRAMEWORK_ENABLED_PREF_KEY =
      "newCallLogFrameworkEnabled";

  private final CallLogFramework callLogFramework;
  private final SharedPreferences sharedPreferences;
  private final ConfigProvider configProvider;
  private final AnnotatedCallLogMigrator annotatedCallLogMigrator;
  private final ListeningExecutorService backgroundExecutor;
  private final ListeningExecutorService lightweightExecutor;

  @Inject
  public CallLogConfig(
      CallLogFramework callLogFramework,
      @Unencrypted SharedPreferences sharedPreferences,
      ConfigProvider configProvider,
      @BackgroundExecutor ListeningExecutorService backgroundExecutor) {
      AnnotatedCallLogMigrator annotatedCallLogMigrator,
      @BackgroundExecutor ListeningExecutorService backgroundExecutor,
      @LightweightExecutor ListeningExecutorService lightweightExecutor) {
    this.callLogFramework = callLogFramework;
    this.sharedPreferences = sharedPreferences;
    this.configProvider = configProvider;
    this.annotatedCallLogMigrator = annotatedCallLogMigrator;
    this.backgroundExecutor = backgroundExecutor;
    this.lightweightExecutor = lightweightExecutor;
  }

  /**
@@ -78,14 +88,11 @@ public final class CallLogConfig {
   * example by a scheduled job or broadcast receiver which rarely fires.
   */
  public ListenableFuture<Void> update() {
    return backgroundExecutor.submit(
        () -> {
    boolean newCallLogFragmentEnabledInConfigProvider =
        configProvider.getBoolean("new_call_log_fragment_enabled", false);
    boolean newVoicemailFragmentEnabledInConfigProvider =
        configProvider.getBoolean("new_voicemail_fragment_enabled", false);
          boolean newPeerEnabledInConfigProvider =
              configProvider.getBoolean("nui_peer_enabled", false);
    boolean newPeerEnabledInConfigProvider = configProvider.getBoolean("nui_peer_enabled", false);

    boolean isCallLogFrameworkEnabled = isCallLogFrameworkEnabled();
    boolean callLogFrameworkShouldBeEnabled =
@@ -94,8 +101,9 @@ public final class CallLogConfig {
            || newPeerEnabledInConfigProvider;

    if (callLogFrameworkShouldBeEnabled && !isCallLogFrameworkEnabled) {
            enableFramework();

      return Futures.transform(
          enableFramework(),
          unused -> {
            // Reflect the flag changes only after the framework is enabled.
            sharedPreferences
                .edit()
@@ -108,9 +116,14 @@ public final class CallLogConfig {
                .putBoolean(NEW_PEER_ENABLED_PREF_KEY, newPeerEnabledInConfigProvider)
                .putBoolean(NEW_CALL_LOG_FRAMEWORK_ENABLED_PREF_KEY, true)
                .apply();

            return null;
          },
          backgroundExecutor);
    } else if (!callLogFrameworkShouldBeEnabled && isCallLogFrameworkEnabled) {
      // Reflect the flag changes before disabling the framework.
      ListenableFuture<Void> writeSharedPrefsFuture =
          backgroundExecutor.submit(
              () -> {
                sharedPreferences
                    .edit()
                    .putBoolean(NEW_CALL_LOG_FRAGMENT_ENABLED_PREF_KEY, false)
@@ -118,11 +131,15 @@ public final class CallLogConfig {
                    .putBoolean(NEW_PEER_ENABLED_PREF_KEY, false)
                    .putBoolean(NEW_CALL_LOG_FRAMEWORK_ENABLED_PREF_KEY, false)
                    .apply();

            disableFramework();
                return null;
              });
      return Futures.transformAsync(
          writeSharedPrefsFuture, unused -> disableFramework(), MoreExecutors.directExecutor());
    } else {
      // We didn't need to enable/disable the framework, but we still need to update the
      // individual flags.
      return backgroundExecutor.submit(
          () -> {
            sharedPreferences
                .edit()
                .putBoolean(
@@ -133,17 +150,30 @@ public final class CallLogConfig {
                    newVoicemailFragmentEnabledInConfigProvider)
                .putBoolean(NEW_PEER_ENABLED_PREF_KEY, newPeerEnabledInConfigProvider)
                .apply();
          }
            return null;
          });
    }
  }

  private void enableFramework() {
    // TODO(zachh): Register content observers, etc.
  private ListenableFuture<Void> enableFramework() {
    ListenableFuture<Void> registerObserversFuture =
        lightweightExecutor.submit(
            () -> {
              callLogFramework.registerContentObservers();
              return null;
            });
    ListenableFuture<Void> migratorFuture = annotatedCallLogMigrator.migrate();
    return Futures.transform(
        Futures.allAsList(registerObserversFuture, migratorFuture),
        unused -> null,
        MoreExecutors.directExecutor());
  }

  private void disableFramework() {
    // TODO(zachh): Unregister content observers, delete databases, etc.
  private ListenableFuture<Void> disableFramework() {
    return Futures.transform(
        Futures.allAsList(callLogFramework.disable(), annotatedCallLogMigrator.clearData()),
        unused -> null,
        MoreExecutors.directExecutor());
  }

  public boolean isNewCallLogFragmentEnabled() {
+34 −4
Original line number Diff line number Diff line
@@ -21,6 +21,12 @@ import com.android.dialer.calllog.datasources.CallLogDataSource;
import com.android.dialer.calllog.datasources.DataSources;
import com.android.dialer.common.LogUtil;
import com.android.dialer.configprovider.ConfigProviderBindings;
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.MoreExecutors;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;

@@ -32,21 +38,23 @@ import javax.inject.Singleton;
@Singleton
public final class CallLogFramework {

  private final Context appContext;
  private final DataSources dataSources;

  @Inject
  CallLogFramework(DataSources dataSources) {
  CallLogFramework(@ApplicationContext Context appContext, DataSources dataSources) {
    this.appContext = appContext;
    this.dataSources = dataSources;
  }

  /** Performs necessary setup work when the application is created. */
  public void onApplicationCreate(Context appContext) {
    registerContentObservers(appContext);
  public void onApplicationCreate() {
    registerContentObservers();
    CallLogConfig.schedulePollingJob(appContext);
  }

  /** Registers the content observers for all data sources. */
  public void registerContentObservers(Context appContext) {
  public void registerContentObservers() {
    LogUtil.enterBlock("CallLogFramework.registerContentObservers");

    // This is the same condition used in MainImpl#isNewUiEnabled. It means that bugfood/debug
@@ -61,4 +69,26 @@ public final class CallLogFramework {
      LogUtil.i("CallLogFramework.registerContentObservers", "not registering content observers");
    }
  }

  /** Disables the framework. */
  public ListenableFuture<Void> disable() {
    LogUtil.enterBlock("CallLogFramework.disable");

    if (!ConfigProviderBindings.get(appContext).getBoolean("is_nui_shortcut_enabled", false)) {
      LogUtil.i("CallLogFramework.disable", "not disabling");
      return Futures.immediateFuture(null);
    }

    for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) {
      dataSource.unregisterContentObservers(appContext);
    }

    // Clear data only after all content observers have been disabled.
    List<ListenableFuture<Void>> allFutures = new ArrayList<>();
    for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) {
      allFutures.add(dataSource.clearData());
    }
    return Futures.transform(
        Futures.allAsList(allFutures), unused -> null, MoreExecutors.directExecutor());
  }
}