summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/phonelookup
diff options
context:
space:
mode:
authorlinyuh <linyuh@google.com>2018-04-19 16:23:10 -0700
committerCopybara-Service <copybara-piper@google.com>2018-04-19 16:48:50 -0700
commitac069a79d2f0701d1ce0371a11e3d2ed63afc4de (patch)
treeafe3be6804dbcc5150bced9fb93cec7f2661342d /java/com/android/dialer/phonelookup
parent4473e4b5e53ded7dffe86bdb344ff113ee72f9be (diff)
Support extracting info from a Call in PhoneLookup
Bug: 70988915 Test: CompositePhoneLookupTest, PhoneLookupTest PiperOrigin-RevId: 193592973 Change-Id: I27b6a63049117ce6d31e50aea9c56c14f01d0e1d
Diffstat (limited to 'java/com/android/dialer/phonelookup')
-rw-r--r--java/com/android/dialer/phonelookup/PhoneLookup.java42
-rw-r--r--java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java70
2 files changed, 96 insertions, 16 deletions
diff --git a/java/com/android/dialer/phonelookup/PhoneLookup.java b/java/com/android/dialer/phonelookup/PhoneLookup.java
index d11f023af..0b9cbf6eb 100644
--- a/java/com/android/dialer/phonelookup/PhoneLookup.java
+++ b/java/com/android/dialer/phonelookup/PhoneLookup.java
@@ -16,11 +16,20 @@
package com.android.dialer.phonelookup;
+import android.content.Context;
import android.support.annotation.MainThread;
+import android.telecom.Call;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
+import com.android.dialer.location.GeoUtil;
+import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
+import com.android.dialer.telecom.TelecomCallUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+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;
/**
* Provides operations related to retrieving information about phone numbers.
@@ -32,11 +41,44 @@ import com.google.common.util.concurrent.ListenableFuture;
public interface PhoneLookup<T> {
/**
+ * Returns a future containing a new info for the number associated with the provided call.
+ *
+ * <p>The returned message should contain populated data for the sub-message corresponding to this
+ * {@link PhoneLookup}. For example, the CP2 implementation returns a {@link
+ * PhoneLookupInfo.Cp2Info} sub-message.
+ *
+ * <p>The default implementation is for all {@link PhoneLookup} implementations that don't need
+ * info in the given call, i.e., it simply extracts the phone number from the call and delegates
+ * to {@link #lookup(DialerPhoneNumber)}.
+ *
+ * <p>However, for {@link PhoneLookup} implementations that need info in the call (such as one for
+ * CNAP), they should override this method.
+ */
+ default ListenableFuture<T> lookup(Context appContext, Call call) {
+ ListeningExecutorService backgroundExecutor =
+ DialerExecutorComponent.get(appContext).backgroundExecutor();
+
+ ListenableFuture<DialerPhoneNumber> numberFuture =
+ backgroundExecutor.submit(
+ () -> {
+ DialerPhoneNumberUtil dialerPhoneNumberUtil = new DialerPhoneNumberUtil();
+ return dialerPhoneNumberUtil.parse(
+ TelecomCallUtil.getNumber(call), GeoUtil.getCurrentCountryIso(appContext));
+ });
+
+ return Futures.transformAsync(numberFuture, this::lookup, MoreExecutors.directExecutor());
+ }
+
+ /**
* Returns a future containing a new info for the provided number.
*
* <p>The returned message should contain populated data for the sub-message corresponding to this
* {@link PhoneLookup}. For example, the CP2 implementation returns a {@link
* PhoneLookupInfo.Cp2Info} sub-message.
+ *
+ * <p>If the lookup can't be done without info in a {@link Call} (e.g., CNAP), this method is
+ * expected to return existing info saved during the most recent lookup for a call to/from the
+ * provided number ({@link #lookup(Context, Call)}).
*/
ListenableFuture<T> lookup(DialerPhoneNumber dialerPhoneNumber);
diff --git a/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java b/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java
index 7cc7a6d7f..1ac13df33 100644
--- a/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java
+++ b/java/com/android/dialer/phonelookup/composite/CompositePhoneLookup.java
@@ -16,13 +16,16 @@
package com.android.dialer.phonelookup.composite;
+import android.content.Context;
import android.support.annotation.MainThread;
import android.support.annotation.VisibleForTesting;
+import android.telecom.Call;
import com.android.dialer.DialerPhoneNumber;
import com.android.dialer.calllog.CallLogState;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
import com.android.dialer.common.concurrent.DialerFutures;
+import com.android.dialer.inject.ApplicationContext;
import com.android.dialer.metrics.FutureTimer;
import com.android.dialer.metrics.FutureTimer.LogCatMode;
import com.android.dialer.metrics.Metrics;
@@ -51,6 +54,7 @@ import javax.inject.Inject;
*/
public final class CompositePhoneLookup {
+ private final Context appContext;
private final ImmutableList<PhoneLookup> phoneLookups;
private final FutureTimer futureTimer;
private final CallLogState callLogState;
@@ -59,10 +63,12 @@ public final class CompositePhoneLookup {
@VisibleForTesting
@Inject
public CompositePhoneLookup(
+ @ApplicationContext Context appContext,
ImmutableList<PhoneLookup> phoneLookups,
FutureTimer futureTimer,
CallLogState callLogState,
@LightweightExecutor ListeningExecutorService lightweightExecutorService) {
+ this.appContext = appContext;
this.phoneLookups = phoneLookups;
this.futureTimer = futureTimer;
this.callLogState = callLogState;
@@ -70,12 +76,37 @@ public final class CompositePhoneLookup {
}
/**
- * Delegates to a set of dependent lookups to build a complete {@link PhoneLookupInfo}.
+ * Delegates to a set of dependent lookups to build a complete {@link PhoneLookupInfo} for the
+ * number associated with the provided call.
+ *
+ * <p>Note: If any of the dependent lookups fails, the returned future will also fail. If any of
+ * the dependent lookups does not complete, the returned future will also not complete.
+ */
+ public ListenableFuture<PhoneLookupInfo> lookup(Call call) {
+ // TODO(zachh): Add short-circuiting logic so that this call is not blocked on low-priority
+ // lookups finishing when a higher-priority one has already finished.
+ List<ListenableFuture<?>> futures = new ArrayList<>();
+ for (PhoneLookup<?> phoneLookup : phoneLookups) {
+ ListenableFuture<?> lookupFuture = phoneLookup.lookup(appContext, call);
+ String eventName =
+ String.format(Metrics.LOOKUP_FOR_CALL_TEMPLATE, phoneLookup.getClass().getSimpleName());
+ futureTimer.applyTiming(lookupFuture, eventName);
+ futures.add(lookupFuture);
+ }
+ ListenableFuture<PhoneLookupInfo> combinedFuture = combineSubMessageFutures(futures);
+ String eventName =
+ String.format(Metrics.LOOKUP_FOR_CALL_TEMPLATE, CompositePhoneLookup.class.getSimpleName());
+ futureTimer.applyTiming(combinedFuture, eventName);
+ return combinedFuture;
+ }
+
+ /**
+ * Delegates to a set of dependent lookups to build a complete {@link PhoneLookupInfo} for the
+ * provided number.
*
* <p>Note: If any of the dependent lookups fails, the returned future will also fail. If any of
* the dependent lookups does not complete, the returned future will also not complete.
*/
- @SuppressWarnings({"unchecked", "rawtype"})
public ListenableFuture<PhoneLookupInfo> lookup(DialerPhoneNumber dialerPhoneNumber) {
// TODO(zachh): Add short-circuiting logic so that this call is not blocked on low-priority
// lookups finishing when a higher-priority one has already finished.
@@ -83,28 +114,35 @@ public final class CompositePhoneLookup {
for (PhoneLookup<?> phoneLookup : phoneLookups) {
ListenableFuture<?> lookupFuture = phoneLookup.lookup(dialerPhoneNumber);
String eventName =
- String.format(Metrics.LOOKUP_TEMPLATE, phoneLookup.getClass().getSimpleName());
+ String.format(Metrics.LOOKUP_FOR_NUMBER_TEMPLATE, phoneLookup.getClass().getSimpleName());
futureTimer.applyTiming(lookupFuture, eventName);
futures.add(lookupFuture);
}
- ListenableFuture<PhoneLookupInfo> combinedFuture =
- Futures.transform(
- Futures.allAsList(futures),
- infos -> {
- Builder mergedInfo = PhoneLookupInfo.newBuilder();
- for (int i = 0; i < infos.size(); i++) {
- PhoneLookup phoneLookup = phoneLookups.get(i);
- phoneLookup.setSubMessage(mergedInfo, infos.get(i));
- }
- return mergedInfo.build();
- },
- lightweightExecutorService);
+ ListenableFuture<PhoneLookupInfo> combinedFuture = combineSubMessageFutures(futures);
String eventName =
- String.format(Metrics.LOOKUP_TEMPLATE, CompositePhoneLookup.class.getSimpleName());
+ String.format(
+ Metrics.LOOKUP_FOR_NUMBER_TEMPLATE, CompositePhoneLookup.class.getSimpleName());
futureTimer.applyTiming(combinedFuture, eventName);
return combinedFuture;
}
+ /** Combines a list of sub-message futures into a future for {@link PhoneLookupInfo}. */
+ @SuppressWarnings({"unchecked", "rawtype"})
+ private ListenableFuture<PhoneLookupInfo> combineSubMessageFutures(
+ List<ListenableFuture<?>> subMessageFutures) {
+ return Futures.transform(
+ Futures.allAsList(subMessageFutures),
+ subMessages -> {
+ Builder mergedInfo = PhoneLookupInfo.newBuilder();
+ for (int i = 0; i < subMessages.size(); i++) {
+ PhoneLookup phoneLookup = phoneLookups.get(i);
+ phoneLookup.setSubMessage(mergedInfo, subMessages.get(i));
+ }
+ return mergedInfo.build();
+ },
+ lightweightExecutorService);
+ }
+
/**
* Delegates to sub-lookups' {@link PhoneLookup#isDirty(ImmutableSet)} completing when the first
* sub-lookup which returns true completes.