Fixed an issue in VoicemailCallFilter process timeouts.

Fixed an issue in VoicemailCallFilter process always timeouts
when a call incoming from anonymous number.
Test: Added two unit tests and did manual testing
Bug: 31353454
Bug: 29415740

Change-Id: I159745c25371996bb22108568b3b42ec37d358c9
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 8d98179..98310bd 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -1831,7 +1831,10 @@
      */
     private void setCallerInfo(Uri handle, CallerInfo callerInfo) {
         Trace.beginSection("setCallerInfo");
-        Preconditions.checkNotNull(callerInfo);
+        if (callerInfo == null) {
+            Log.i(this, "CallerInfo lookup returned null, skipping update");
+            return;
+        }
 
         if (!handle.equals(mHandle)) {
             Log.i(this, "setCallerInfo received stale caller info for an old handle. Ignoring.");
diff --git a/src/com/android/server/telecom/CallerInfoLookupHelper.java b/src/com/android/server/telecom/CallerInfoLookupHelper.java
index e557c8a..6276052 100644
--- a/src/com/android/server/telecom/CallerInfoLookupHelper.java
+++ b/src/com/android/server/telecom/CallerInfoLookupHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.server.telecom;
 
+import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
@@ -41,7 +42,7 @@
          * @param info
          * @return true if the value should be cached, false otherwise.
          */
-        void onCallerInfoQueryComplete(Uri handle, CallerInfo info);
+        void onCallerInfoQueryComplete(Uri handle, @Nullable CallerInfo info);
         void onContactPhotoQueryComplete(Uri handle, CallerInfo info);
     }
 
@@ -54,6 +55,7 @@
             listeners = new LinkedList<>();
         }
     }
+
     private final Map<Uri, CallerInfoQueryInfo> mQueryEntries = new HashMap<>();
 
     private final CallerInfoAsyncQueryFactory mCallerInfoAsyncQueryFactory;
@@ -74,11 +76,13 @@
 
     public void startLookup(final Uri handle, OnQueryCompleteListener listener) {
         if (handle == null) {
+            listener.onCallerInfoQueryComplete(handle, null);
             return;
         }
 
         final String number = handle.getSchemeSpecificPart();
         if (TextUtils.isEmpty(number)) {
+            listener.onCallerInfoQueryComplete(handle, null);
             return;
         }
 
diff --git a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
index 1363d62..1aaae46 100644
--- a/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
+++ b/src/com/android/server/telecom/callfiltering/DirectToVoicemailCallFilter.java
@@ -23,6 +23,8 @@
 import com.android.server.telecom.CallerInfoLookupHelper;
 import com.android.server.telecom.Log;
 
+import java.util.Objects;
+
 public class DirectToVoicemailCallFilter implements IncomingCallFilter.CallFilter {
     private final CallerInfoLookupHelper mCallerInfoLookupHelper;
 
@@ -34,13 +36,14 @@
     public void startFilterLookup(final Call call, CallFilterResultCallback callback) {
         Log.event(call, Log.Events.DIRECT_TO_VM_INITIATED);
         final Uri callHandle = call.getHandle();
+
         mCallerInfoLookupHelper.startLookup(callHandle,
                 new CallerInfoLookupHelper.OnQueryCompleteListener() {
                     @Override
                     public void onCallerInfoQueryComplete(Uri handle, CallerInfo info) {
                         CallFilteringResult result;
-                        if (callHandle.equals(handle)) {
-                            if (info.shouldSendToVoicemail) {
+                        if (Objects.equals(callHandle, handle)) {
+                            if (info != null && info.shouldSendToVoicemail) {
                                 result = new CallFilteringResult(
                                         false, // shouldAllowCall
                                         true, // shouldReject
diff --git a/tests/src/com/android/server/telecom/tests/CallerInfoLookupHelperTest.java b/tests/src/com/android/server/telecom/tests/CallerInfoLookupHelperTest.java
index 8ece571..f261d3e 100644
--- a/tests/src/com/android/server/telecom/tests/CallerInfoLookupHelperTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallerInfoLookupHelperTest.java
@@ -21,6 +21,7 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telephony.CallerInfo;
 import com.android.internal.telephony.CallerInfoAsyncQuery;
@@ -43,6 +44,7 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
 import static org.mockito.Mockito.atMost;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
@@ -93,6 +95,16 @@
         }
     }
 
+    @SmallTest
+    public void testLookupWithEmptyHandle() {
+        CallerInfoLookupHelper.OnQueryCompleteListener listener = mock(
+                CallerInfoLookupHelper.OnQueryCompleteListener.class);
+        mCallerInfoLookupHelper.startLookup(Uri.EMPTY, listener);
+
+        verify(listener).onCallerInfoQueryComplete(eq(Uri.EMPTY), isNull(CallerInfo.class));
+        verifyProperCleanup();
+    }
+
     public void testSimpleLookup() {
         CallerInfoLookupHelper.OnQueryCompleteListener listener = mock(
                 CallerInfoLookupHelper.OnQueryCompleteListener.class);
diff --git a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
index ac74604..2ebb6fc 100644
--- a/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
+++ b/tests/src/com/android/server/telecom/tests/DirectToVoicemailCallFilterTest.java
@@ -42,7 +42,6 @@
 
     public void setUp() throws Exception {
         super.setUp();
-        when(mCall.getHandle()).thenReturn(TEST_HANDLE);
     }
 
     @SmallTest
@@ -79,13 +78,32 @@
                 ));
     }
 
+    @SmallTest
+    public void testNullResponseFromLookupHelper() {
+        CallerInfoLookupHelper.OnQueryCompleteListener queryListener = verifyLookupStart(null);
+
+        queryListener.onCallerInfoQueryComplete(null, null);
+        verify(mCallback).onCallFilteringComplete(mCall,
+                new CallFilteringResult(
+                        true, // shouldAllowCall
+                        false, // shouldReject
+                        true, // shouldAddToCallLog
+                        true // shouldShowNotification
+                ));
+    }
+
     private CallerInfoLookupHelper.OnQueryCompleteListener verifyLookupStart() {
+        return verifyLookupStart(TEST_HANDLE);
+    }
+
+    private CallerInfoLookupHelper.OnQueryCompleteListener verifyLookupStart(Uri handle) {
+        when(mCall.getHandle()).thenReturn(handle);
         DirectToVoicemailCallFilter filter =
                 new DirectToVoicemailCallFilter(mCallerInfoLookupHelper);
         filter.startFilterLookup(mCall, mCallback);
         ArgumentCaptor<CallerInfoLookupHelper.OnQueryCompleteListener> captor =
                 ArgumentCaptor.forClass(CallerInfoLookupHelper.OnQueryCompleteListener.class);
-        verify(mCallerInfoLookupHelper).startLookup(eq(TEST_HANDLE), captor.capture());
+        verify(mCallerInfoLookupHelper).startLookup(eq(handle), captor.capture());
         return captor.getValue();
     }
 }