From 3a319297f71f9c87b8dcd3e137ae111872161fb4 Mon Sep 17 00:00:00 2001 From: linyuh Date: Tue, 5 Jun 2018 15:09:37 -0700 Subject: Handling timeout in PeopleApiPhoneLookup & Cp2ExtendedDirectoryPhoneLookup Bug: 70989631 Test: PeopleApiPhoneLookupTest, Cp2ExtendedDirectoryPhoneLookupTest PiperOrigin-RevId: 199365461 Change-Id: I017cca8bdb469236ac60382e5fbe7f55976a12b9 --- .../cp2/Cp2ExtendedDirectoryPhoneLookup.java | 49 ++++++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'java/com/android/dialer/phonelookup') diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java index 528959342..bbbd18664 100644 --- a/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java +++ b/java/com/android/dialer/phonelookup/cp2/Cp2ExtendedDirectoryPhoneLookup.java @@ -26,7 +26,11 @@ import com.android.dialer.DialerPhoneNumber; 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.Annotations.NonUiSerial; +import com.android.dialer.configprovider.ConfigProvider; import com.android.dialer.inject.ApplicationContext; +import com.android.dialer.logging.DialerImpression; +import com.android.dialer.logging.Logger; import com.android.dialer.phonelookup.PhoneLookup; import com.android.dialer.phonelookup.PhoneLookupInfo; import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info; @@ -39,6 +43,9 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.function.Predicate; import javax.inject.Inject; @@ -51,20 +58,31 @@ import javax.inject.Inject; @SuppressWarnings("AndroidApiChecker") // Use of Java 8 APIs. public final class Cp2ExtendedDirectoryPhoneLookup implements PhoneLookup { + /** Config flag for timeout (in ms). */ + @VisibleForTesting + static final String CP2_EXTENDED_DIRECTORY_PHONE_LOOKUP_TIMEOUT_MILLIS = + "cp2_extended_directory_phone_lookup_timout_millis"; + private final Context appContext; + private final ConfigProvider configProvider; private final ListeningExecutorService backgroundExecutorService; private final ListeningExecutorService lightweightExecutorService; private final MissingPermissionsOperations missingPermissionsOperations; + private final ScheduledExecutorService scheduledExecutorService; @Inject Cp2ExtendedDirectoryPhoneLookup( @ApplicationContext Context appContext, @BackgroundExecutor ListeningExecutorService backgroundExecutorService, @LightweightExecutor ListeningExecutorService lightweightExecutorService, + @NonUiSerial ScheduledExecutorService scheduledExecutorService, + ConfigProvider configProvider, MissingPermissionsOperations missingPermissionsOperations) { this.appContext = appContext; this.backgroundExecutorService = backgroundExecutorService; this.lightweightExecutorService = lightweightExecutorService; + this.scheduledExecutorService = scheduledExecutorService; + this.configProvider = configProvider; this.missingPermissionsOperations = missingPermissionsOperations; } @@ -73,10 +91,33 @@ public final class Cp2ExtendedDirectoryPhoneLookup implements PhoneLookup queryCp2ForDirectoryContact(dialerPhoneNumber, directoryIds), - lightweightExecutorService); + + ListenableFuture cp2InfoFuture = + Futures.transformAsync( + queryCp2ForExtendedDirectoryIds(), + directoryIds -> queryCp2ForDirectoryContact(dialerPhoneNumber, directoryIds), + lightweightExecutorService); + + long timeoutMillis = + configProvider.getLong(CP2_EXTENDED_DIRECTORY_PHONE_LOOKUP_TIMEOUT_MILLIS, Long.MAX_VALUE); + + // Do not pass Long.MAX_VALUE to Futures.withTimeout as it will cause the internal + // ScheduledExecutorService for timing to keep waiting even after "cp2InfoFuture" is done. + // Do not pass 0 or a negative value to Futures.withTimeout either as it will cause the timeout + // event to be triggered immediately. + return timeoutMillis == Long.MAX_VALUE + ? cp2InfoFuture + : Futures.catching( + Futures.withTimeout( + cp2InfoFuture, timeoutMillis, TimeUnit.MILLISECONDS, scheduledExecutorService), + TimeoutException.class, + unused -> { + LogUtil.w("Cp2ExtendedDirectoryPhoneLookup.lookup", "Time out!"); + Logger.get(appContext) + .logImpression(DialerImpression.Type.CP2_EXTENDED_DIRECTORY_PHONE_LOOKUP_TIMEOUT); + return Cp2Info.getDefaultInstance(); + }, + lightweightExecutorService); } private ListenableFuture> queryCp2ForExtendedDirectoryIds() { -- cgit v1.2.3