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

Commit 11272af4 authored by linyuh's avatar linyuh Committed by Copybara-Service
Browse files

Log existing call log impressions in the new call log.

Bug: 73741308
Test: DeleteCallLogItemModuleTest, HistoryItemActionModulesBuilderTest
PiperOrigin-RevId: 202232055
Change-Id: Idcf29c939272a335ccea469ac331c670127c583a
parent d637af51
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -29,18 +29,20 @@ import com.android.dialer.common.concurrent.DialerExecutor.Worker;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.database.Selection;
import com.android.dialer.historyitemactions.HistoryItemActionModule;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

/** {@link HistoryItemActionModule} for deleting a call log item in the new call log. */
public final class DeleteCallLogItemModule implements HistoryItemActionModule {
final class DeleteCallLogItemModule implements HistoryItemActionModule {
  private static final String TAG = DeleteCallLogItemModule.class.getName();

  private final Context context;
  private final CoalescedIds coalescedIds;

  public DeleteCallLogItemModule(Context context, CoalescedIds coalescedIds) {
  DeleteCallLogItemModule(Context context, CoalescedIds coalescedIds) {
    this.context = context;
    this.coalescedIds = coalescedIds;
  }
@@ -62,6 +64,8 @@ public final class DeleteCallLogItemModule implements HistoryItemActionModule {
        .createNonUiTaskBuilder(new CallLogItemDeletionWorker(context))
        .build()
        .executeSerial(coalescedIds);

    Logger.get(context).logImpression(DialerImpression.Type.USER_DELETED_CALL_LOG_ITEM);
    return true;
  }

+22 −4
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ package com.android.dialer.historyitemactions;
import android.content.Context;
import com.android.dialer.blockreportspam.BlockReportSpamDialogInfo;
import com.android.dialer.blockreportspam.ShowBlockReportSpamDialogNotifier;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import java.util.Optional;

/** Modules for blocking/unblocking a number and/or reporting it as spam/not spam. */
final class BlockReportSpamModules {
@@ -26,7 +29,9 @@ final class BlockReportSpamModules {
  private BlockReportSpamModules() {}

  static HistoryItemActionModule moduleForMarkingNumberAsNotSpam(
      Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) {
      Context context,
      BlockReportSpamDialogInfo blockReportSpamDialogInfo,
      Optional<DialerImpression.Type> impression) {

    return new HistoryItemActionModule() {
      @Override
@@ -43,13 +48,17 @@ final class BlockReportSpamModules {
      public boolean onClick() {
        ShowBlockReportSpamDialogNotifier.notifyShowDialogToReportNotSpam(
            context, blockReportSpamDialogInfo);

        impression.ifPresent(Logger.get(context)::logImpression);
        return true; // Close the bottom sheet.
      }
    };
  }

  static HistoryItemActionModule moduleForBlockingNumber(
      Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) {
      Context context,
      BlockReportSpamDialogInfo blockReportSpamDialogInfo,
      Optional<DialerImpression.Type> impression) {

    return new HistoryItemActionModule() {
      @Override
@@ -66,13 +75,17 @@ final class BlockReportSpamModules {
      public boolean onClick() {
        ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumber(
            context, blockReportSpamDialogInfo);

        impression.ifPresent(Logger.get(context)::logImpression);
        return true; // Close the bottom sheet.
      }
    };
  }

  static HistoryItemActionModule moduleForUnblockingNumber(
      Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) {
      Context context,
      BlockReportSpamDialogInfo blockReportSpamDialogInfo,
      Optional<DialerImpression.Type> impression) {

    return new HistoryItemActionModule() {
      @Override
@@ -90,13 +103,16 @@ final class BlockReportSpamModules {
        ShowBlockReportSpamDialogNotifier.notifyShowDialogToUnblockNumber(
            context, blockReportSpamDialogInfo);

        impression.ifPresent(Logger.get(context)::logImpression);
        return true; // Close the bottom sheet.
      }
    };
  }

  static HistoryItemActionModule moduleForBlockingNumberAndOptionallyReportingSpam(
      Context context, BlockReportSpamDialogInfo blockReportSpamDialogInfo) {
      Context context,
      BlockReportSpamDialogInfo blockReportSpamDialogInfo,
      Optional<DialerImpression.Type> impression) {

    return new HistoryItemActionModule() {
      @Override
@@ -113,6 +129,8 @@ final class BlockReportSpamModules {
      public boolean onClick() {
        ShowBlockReportSpamDialogNotifier.notifyShowDialogToBlockNumberAndOptionallyReportSpam(
            context, blockReportSpamDialogInfo);

        impression.ifPresent(Logger.get(context)::logImpression);
        return true; // Close the bottom sheet.
      }
    };
+122 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Intent;
import android.net.Uri;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract;
import android.support.annotation.IntDef;
import android.text.TextUtils;
import com.android.dialer.blockreportspam.BlockReportSpamDialogInfo;
import com.android.dialer.callintent.CallInitiationType;
@@ -29,13 +30,19 @@ import com.android.dialer.clipboard.ClipboardUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.duo.Duo;
import com.android.dialer.duo.DuoComponent;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.ReportingLocation;
import com.android.dialer.spam.Spam;
import com.android.dialer.util.CallUtil;
import com.android.dialer.util.PermissionsUtil;
import com.android.dialer.util.UriUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * Builds a list of {@link HistoryItemActionModule HistoryItemActionModules}.
@@ -76,6 +83,54 @@ import java.util.List;
 */
public final class HistoryItemActionModulesBuilder {

  /** Represents events when a module is tapped by the user. */
  @Retention(RetentionPolicy.SOURCE)
  @IntDef({
    Event.ADD_TO_CONTACT,
    Event.BLOCK_NUMBER,
    Event.BLOCK_NUMBER_AND_REPORT_SPAM,
    Event.REPORT_NOT_SPAM,
    Event.REQUEST_CARRIER_VIDEO_CALL,
    Event.REQUEST_DUO_VIDEO_CALL,
    Event.REQUEST_DUO_VIDEO_CALL_FOR_NON_CONTACT,
    Event.SEND_TEXT_MESSAGE,
    Event.UNBLOCK_NUMBER
  })
  @interface Event {
    int ADD_TO_CONTACT = 1;
    int BLOCK_NUMBER = 2;
    int BLOCK_NUMBER_AND_REPORT_SPAM = 3;
    int REPORT_NOT_SPAM = 4;
    int REQUEST_CARRIER_VIDEO_CALL = 5;
    int REQUEST_DUO_VIDEO_CALL = 6;
    int REQUEST_DUO_VIDEO_CALL_FOR_NON_CONTACT = 7;
    int SEND_TEXT_MESSAGE = 8;
    int UNBLOCK_NUMBER = 9;
  }

  /**
   * Maps each {@link Event} to a {@link DialerImpression.Type} to be logged when the modules are
   * hosted by the call log.
   */
  private static final ImmutableMap<Integer, DialerImpression.Type> CALL_LOG_IMPRESSIONS =
      new ImmutableMap.Builder<Integer, DialerImpression.Type>()
          .put(Event.ADD_TO_CONTACT, DialerImpression.Type.ADD_TO_A_CONTACT_FROM_CALL_LOG)
          .put(Event.BLOCK_NUMBER, DialerImpression.Type.CALL_LOG_BLOCK_NUMBER)
          .put(Event.BLOCK_NUMBER_AND_REPORT_SPAM, DialerImpression.Type.CALL_LOG_BLOCK_REPORT_SPAM)
          .put(Event.REPORT_NOT_SPAM, DialerImpression.Type.CALL_LOG_REPORT_AS_NOT_SPAM)
          .put(
              Event.REQUEST_CARRIER_VIDEO_CALL,
              DialerImpression.Type.IMS_VIDEO_REQUESTED_FROM_CALL_LOG)
          .put(
              Event.REQUEST_DUO_VIDEO_CALL,
              DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FROM_CALL_LOG)
          .put(
              Event.REQUEST_DUO_VIDEO_CALL_FOR_NON_CONTACT,
              DialerImpression.Type.LIGHTBRINGER_NON_CONTACT_VIDEO_REQUESTED_FROM_CALL_LOG)
          .put(Event.SEND_TEXT_MESSAGE, DialerImpression.Type.CALL_LOG_SEND_MESSAGE)
          .put(Event.UNBLOCK_NUMBER, DialerImpression.Type.CALL_LOG_UNBLOCK_NUMBER)
          .build();

  private final Context context;
  private final HistoryItemActionModuleInfo moduleInfo;
  private final List<HistoryItemActionModule> modules;
@@ -158,7 +213,14 @@ public final class HistoryItemActionModulesBuilder {

    // If the module info is for a video call, add an appropriate video call module.
    if ((moduleInfo.getFeatures() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO) {
      modules.add(IntentModule.newCallModule(context, callIntentBuilder.setIsDuoCall(isDuoCall())));
      boolean isDuoCall = isDuoCall();
      modules.add(
          IntentModule.newCallModule(
              context,
              callIntentBuilder.setIsDuoCall(isDuoCall),
              isDuoCall
                  ? getImpressionsForDuoVideoCall()
                  : getImpressions(Event.REQUEST_CARRIER_VIDEO_CALL)));
      return this;
    }

@@ -167,13 +229,28 @@ public final class HistoryItemActionModulesBuilder {
    //
    // The carrier video call module takes precedence over the Duo module.
    if (canPlaceCarrierVideoCall()) {
      modules.add(IntentModule.newCallModule(context, callIntentBuilder));
      modules.add(
          IntentModule.newCallModule(
              context, callIntentBuilder, getImpressions(Event.REQUEST_CARRIER_VIDEO_CALL)));
    } else if (canPlaceDuoCall()) {
      modules.add(IntentModule.newCallModule(context, callIntentBuilder.setIsDuoCall(true)));
      modules.add(
          IntentModule.newCallModule(
              context, callIntentBuilder.setIsDuoCall(true), getImpressionsForDuoVideoCall()));
    }
    return this;
  }

  /**
   * Returns a list of impressions to be logged when the user taps the module that attempts to
   * initiate a Duo video call.
   */
  private ImmutableList<DialerImpression.Type> getImpressionsForDuoVideoCall() {
    return isExistingContact()
        ? getImpressions(Event.REQUEST_DUO_VIDEO_CALL)
        : getImpressions(
            Event.REQUEST_DUO_VIDEO_CALL, Event.REQUEST_DUO_VIDEO_CALL_FOR_NON_CONTACT);
  }

  /**
   * Adds a module for sending text messages.
   *
@@ -199,7 +276,8 @@ public final class HistoryItemActionModulesBuilder {
    }

    modules.add(
        IntentModule.newModuleForSendingTextMessage(context, moduleInfo.getNormalizedNumber()));
        IntentModule.newModuleForSendingTextMessage(
            context, moduleInfo.getNormalizedNumber(), getImpressions(Event.SEND_TEXT_MESSAGE)));
    return this;
  }

@@ -256,7 +334,8 @@ public final class HistoryItemActionModulesBuilder {
            context,
            intent,
            R.string.add_to_contacts,
            R.drawable.quantum_ic_person_add_vd_theme_24));
            R.drawable.quantum_ic_person_add_vd_theme_24,
            getImpressions(Event.ADD_TO_CONTACT)));
    return this;
  }

@@ -302,11 +381,13 @@ public final class HistoryItemActionModulesBuilder {
    if (Spam.shouldShowAsSpam(moduleInfo.getIsSpam(), moduleInfo.getCallType())) {
      modules.add(
          BlockReportSpamModules.moduleForMarkingNumberAsNotSpam(
              context, blockReportSpamDialogInfo));
              context, blockReportSpamDialogInfo, getImpression(Event.REPORT_NOT_SPAM)));
      modules.add(
          moduleInfo.getIsBlocked()
              ? BlockReportSpamModules.moduleForUnblockingNumber(context, blockReportSpamDialogInfo)
              : BlockReportSpamModules.moduleForBlockingNumber(context, blockReportSpamDialogInfo));
              ? BlockReportSpamModules.moduleForUnblockingNumber(
                  context, blockReportSpamDialogInfo, getImpression(Event.UNBLOCK_NUMBER))
              : BlockReportSpamModules.moduleForBlockingNumber(
                  context, blockReportSpamDialogInfo, getImpression(Event.BLOCK_NUMBER)));
      return this;
    }

@@ -314,7 +395,8 @@ public final class HistoryItemActionModulesBuilder {
    // "Unblock" module.
    if (moduleInfo.getIsBlocked()) {
      modules.add(
          BlockReportSpamModules.moduleForUnblockingNumber(context, blockReportSpamDialogInfo));
          BlockReportSpamModules.moduleForUnblockingNumber(
              context, blockReportSpamDialogInfo, getImpression(Event.UNBLOCK_NUMBER)));
      return this;
    }

@@ -322,7 +404,7 @@ public final class HistoryItemActionModulesBuilder {
    // spam, add the "Block/Report spam" module.
    modules.add(
        BlockReportSpamModules.moduleForBlockingNumberAndOptionallyReportingSpam(
            context, blockReportSpamDialogInfo));
            context, blockReportSpamDialogInfo, getImpression(Event.BLOCK_NUMBER_AND_REPORT_SPAM)));
    return this;
  }

@@ -437,4 +519,34 @@ public final class HistoryItemActionModulesBuilder {
            String.format("Unsupported host: %s", moduleInfo.getHost()));
    }
  }

  /** Returns a list of impressions to be logged for the given {@link Event events}. */
  private ImmutableList<DialerImpression.Type> getImpressions(@Event int... events) {
    Assert.isNotNull(events);

    ImmutableList.Builder<DialerImpression.Type> impressionListBuilder =
        new ImmutableList.Builder<>();
    for (@Event int event : events) {
      getImpression(event).ifPresent(impressionListBuilder::add);
    }

    return impressionListBuilder.build();
  }

  /**
   * Returns an impression to be logged for the given {@link Event}, or {@link Optional#empty()} if
   * no impression is available for the event.
   */
  private Optional<DialerImpression.Type> getImpression(@Event int event) {
    switch (moduleInfo.getHost()) {
      case CALL_LOG:
        return Optional.of(CALL_LOG_IMPRESSIONS.get(event));
      case VOICEMAIL:
        // TODO(a bug): Return proper impressions for voicemail.
        return Optional.empty();
      default:
        throw Assert.createUnsupportedOperationFailException(
            String.format("Unsupported host: %s", moduleInfo.getHost()));
    }
  }
}
+45 −3
Original line number Diff line number Diff line
@@ -21,9 +21,12 @@ import android.content.Intent;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.logging.DialerImpression;
import com.android.dialer.logging.Logger;
import com.android.dialer.precall.PreCall;
import com.android.dialer.util.DialerUtils;
import com.android.dialer.util.IntentUtil;
import com.google.common.collect.ImmutableList;

/**
 * {@link HistoryItemActionModule} useful for making easy to build modules based on starting an
@@ -35,12 +38,28 @@ public class IntentModule implements HistoryItemActionModule {
  private final Intent intent;
  private final @StringRes int text;
  private final @DrawableRes int image;
  private final ImmutableList<DialerImpression.Type> impressions;

  /**
   * @deprecated use {@link IntentModule#IntentModule(Context, Intent, int, int, ImmutableList)}
   *     instead.
   */
  @Deprecated
  public IntentModule(Context context, Intent intent, @StringRes int text, @DrawableRes int image) {
    this(context, intent, text, image, /* impressions = */ ImmutableList.of());
  }

  IntentModule(
      Context context,
      Intent intent,
      @StringRes int text,
      @DrawableRes int image,
      ImmutableList<DialerImpression.Type> impressions) {
    this.context = context;
    this.intent = intent;
    this.text = text;
    this.image = image;
    this.impressions = impressions;
  }

  @Override
@@ -56,11 +75,21 @@ public class IntentModule implements HistoryItemActionModule {
  @Override
  public boolean onClick() {
    DialerUtils.startActivityWithErrorToast(context, intent);
    impressions.forEach(Logger.get(context)::logImpression);
    return true;
  }

  /** Creates a module for starting an outgoing call with a {@link CallIntentBuilder}. */
  /** @deprecated Use {@link #newCallModule(Context, CallIntentBuilder, ImmutableList)} instead. */
  @Deprecated
  public static IntentModule newCallModule(Context context, CallIntentBuilder callIntentBuilder) {
    return newCallModule(context, callIntentBuilder, /* impressions = */ ImmutableList.of());
  }

  /** Creates a module for starting an outgoing call with a {@link CallIntentBuilder}. */
  static IntentModule newCallModule(
      Context context,
      CallIntentBuilder callIntentBuilder,
      ImmutableList<DialerImpression.Type> impressions) {
    @StringRes int text;
    @DrawableRes int image;

@@ -72,14 +101,27 @@ public class IntentModule implements HistoryItemActionModule {
      image = R.drawable.quantum_ic_call_white_24;
    }

    return new IntentModule(context, PreCall.getIntent(context, callIntentBuilder), text, image);
    return new IntentModule(
        context, PreCall.getIntent(context, callIntentBuilder), text, image, impressions);
  }

  /**
   * @deprecated Use {@link #newModuleForSendingTextMessage(Context, String, ImmutableList)}
   *     instead.
   */
  @Deprecated
  public static IntentModule newModuleForSendingTextMessage(Context context, String number) {
    return newModuleForSendingTextMessage(context, number, /* impressions = */ ImmutableList.of());
  }

  /** Creates a module for sending a text message to the given number. */
  static IntentModule newModuleForSendingTextMessage(
      Context context, String number, ImmutableList<DialerImpression.Type> impressions) {
    return new IntentModule(
        context,
        IntentUtil.getSendSmsIntent(number),
        R.string.send_a_message,
        R.drawable.quantum_ic_message_vd_theme_24);
        R.drawable.quantum_ic_message_vd_theme_24,
        impressions);
  }
}