Merge "Some cleanup of incoming call latency." am: c2590357cf
am: f69b768a05

Change-Id: I9c4b754011edd40c13a11746d4b7b50d0f88dca1
diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java
index 871243c..0ef0c98 100644
--- a/java/com/android/incallui/CallCardPresenter.java
+++ b/java/com/android/incallui/CallCardPresenter.java
@@ -319,17 +319,19 @@
       previousPrimary.removeListener(this);
     }
 
-    if (mSecondary == null) {
-      // Secondary call may have ended.  Update the ui.
-      mSecondaryContactInfo = null;
-      updateSecondaryDisplayInfo();
-    } else if (secondaryChanged) {
-      // secondary call has changed
-      mSecondaryContactInfo =
-          ContactInfoCache.buildCacheEntryFromCall(
-              mContext, mSecondary, mSecondary.getState() == DialerCall.State.INCOMING);
-      updateSecondaryDisplayInfo();
-      maybeStartSearch(mSecondary, false);
+    if (secondaryChanged) {
+      if (mSecondary == null) {
+        // Secondary call may have ended.  Update the ui.
+        mSecondaryContactInfo = null;
+        updateSecondaryDisplayInfo();
+      } else {
+        // secondary call has changed
+        mSecondaryContactInfo =
+            ContactInfoCache.buildCacheEntryFromCall(
+                mContext, mSecondary, mSecondary.getState() == DialerCall.State.INCOMING);
+        updateSecondaryDisplayInfo();
+        maybeStartSearch(mSecondary, false);
+      }
     }
 
     // Set the call state
diff --git a/java/com/android/incallui/ContactInfoCache.java b/java/com/android/incallui/ContactInfoCache.java
index 2fb18b8..272c2b7 100644
--- a/java/com/android/incallui/ContactInfoCache.java
+++ b/java/com/android/incallui/ContactInfoCache.java
@@ -85,7 +85,6 @@
   // worker thread.
   private final ConcurrentHashMap<String, ContactCacheEntry> mInfoMap = new ConcurrentHashMap<>();
   private final Map<String, Set<ContactInfoCacheCallback>> mCallBacks = new ArrayMap<>();
-  private Drawable mDefaultContactPhotoDrawable;
   private int mQueryId;
   private final DialerExecutor<CnapInformationWrapper> cachedNumberLookupExecutor =
       DialerExecutors.createNonUiTaskBuilder(new CachedNumberLookupWorker()).build();
@@ -350,12 +349,14 @@
     Assert.isMainThread();
     Objects.requireNonNull(callback);
 
+    Trace.beginSection("prepare callback");
     final String callId = call.getId();
     final ContactCacheEntry cacheEntry = mInfoMap.get(callId);
     Set<ContactInfoCacheCallback> callBacks = mCallBacks.get(callId);
 
     // We need to force a new query if phone number has changed.
     boolean forceQuery = needForceQuery(call, cacheEntry);
+    Trace.endSection();
     Log.d(TAG, "findInfo: callId = " + callId + "; forceQuery = " + forceQuery);
 
     // If we have a previously obtained intermediate result return that now except needs
@@ -390,6 +391,7 @@
       mCallBacks.put(callId, callBacks);
     }
 
+    Trace.beginSection("prepare query");
     /**
      * Performs a query for caller information. Save any immediate data we get from the query. An
      * asynchronous query may also be made for any data that we do not already have. Some queries,
@@ -404,6 +406,7 @@
             call,
             new DialerCallCookieWrapper(callId, call.getNumberPresentation(), call.getCnapName()),
             new FindInfoCallback(isIncoming, queryToken));
+    Trace.endSection();
 
     if (cacheEntry != null) {
       // We should not override the old cache item until the new query is
diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java
index 70fe88b..1ba3b5d 100644
--- a/java/com/android/incallui/InCallPresenter.java
+++ b/java/com/android/incallui/InCallPresenter.java
@@ -273,7 +273,9 @@
 
   public static synchronized InCallPresenter getInstance() {
     if (sInCallPresenter == null) {
+      Trace.beginSection("InCallPresenter.Constructor");
       sInCallPresenter = new InCallPresenter();
+      Trace.endSection();
     }
     return sInCallPresenter;
   }
@@ -1033,7 +1035,7 @@
     // We need to update the notification bar when we leave the UI because that
     // could trigger it to show again.
     if (mStatusBarNotifier != null) {
-      mStatusBarNotifier.updateNotification(mCallList);
+      mStatusBarNotifier.updateNotification();
     }
 
     if (mProximitySensor != null) {
@@ -1088,10 +1090,6 @@
   void onActivityStarted() {
     LogUtil.d("InCallPresenter.onActivityStarted", "onActivityStarted");
     notifyVideoPauseController(true);
-    if (mStatusBarNotifier != null) {
-      // TODO(maxwelb) - b/36649622: Investigate this redundant call
-      mStatusBarNotifier.updateNotification(mCallList);
-    }
     applyScreenTimeout();
   }
 
@@ -1385,7 +1383,7 @@
     } else if (startIncomingCallSequence) {
       LogUtil.i("InCallPresenter.startOrFinishUi", "Start Full Screen in call UI");
 
-      mStatusBarNotifier.updateNotification(mCallList);
+      mStatusBarNotifier.updateNotification();
     } else if (newState == InCallState.NO_CALLS) {
       // The new state is the no calls state.  Tear everything down.
       attemptFinishActivity();
diff --git a/java/com/android/incallui/ProximitySensor.java b/java/com/android/incallui/ProximitySensor.java
index 339a2e9..123ca53 100644
--- a/java/com/android/incallui/ProximitySensor.java
+++ b/java/com/android/incallui/ProximitySensor.java
@@ -60,6 +60,7 @@
       @NonNull Context context,
       @NonNull AudioModeProvider audioModeProvider,
       @NonNull AccelerometerListener accelerometerListener) {
+    Trace.beginSection("ProximitySensor.Constructor");
     mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
     if (mPowerManager.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) {
       mProximityWakeLock =
@@ -78,6 +79,7 @@
 
     mAudioModeProvider = audioModeProvider;
     mAudioModeProvider.addListener(this);
+    Trace.endSection();
   }
 
   public void tearDown() {
diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java
index e5908f1..7ff0040 100644
--- a/java/com/android/incallui/StatusBarNotifier.java
+++ b/java/com/android/incallui/StatusBarNotifier.java
@@ -52,7 +52,6 @@
 import android.telecom.Call.Details;
 import android.telecom.CallAudioState;
 import android.telecom.PhoneAccount;
-import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.text.BidiFormatter;
 import android.text.Spannable;
@@ -89,14 +88,14 @@
 import com.android.incallui.ringtone.InCallTonePlayer;
 import com.android.incallui.ringtone.ToneGeneratorFactory;
 import com.android.incallui.videotech.utils.SessionModificationState;
-import java.util.List;
 import java.util.Objects;
 
 /** This class adds Notifications to the status bar for the in-call experience. */
 public class StatusBarNotifier
     implements InCallPresenter.InCallStateListener,
         EnrichedCallManager.StateChangedListener,
-        AudioModeProvider.AudioModeListener {
+        AudioModeProvider.AudioModeListener,
+        ContactInfoCacheCallback {
 
   private static final int NOTIFICATION_ID = 1;
 
@@ -128,6 +127,7 @@
   private StatusBarCallListener mStatusBarCallListener;
 
   public StatusBarNotifier(@NonNull Context context, @NonNull ContactInfoCache contactInfoCache) {
+    Trace.beginSection("StatusBarNotifier.Constructor");
     mContext = Assert.isNotNull(context);
     mContactsPreferences = ContactsPreferencesFactory.newContactsPreferences(mContext);
     mContactInfoCache = contactInfoCache;
@@ -137,6 +137,7 @@
             CallList.getInstance());
     mCurrentNotification = NOTIFICATION_NONE;
     AudioModeProvider.getInstance().addListener(this);
+    Trace.endSection();
   }
 
   /**
@@ -175,13 +176,13 @@
   @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
   public void onStateChange(InCallState oldState, InCallState newState, CallList callList) {
     LogUtil.d("StatusBarNotifier.onStateChange", "%s->%s", oldState, newState);
-    updateNotification(callList);
+    updateNotification();
   }
 
   @Override
   public void onEnrichedCallStateChanged() {
     LogUtil.enterBlock("StatusBarNotifier.onEnrichedCallStateChanged");
-    updateNotification(CallList.getInstance());
+    updateNotification();
   }
 
   /**
@@ -199,17 +200,17 @@
    * more likely, if an incoming call *was* ringing briefly but then disconnected). In that case,
    * we'll simply update or cancel the in-call notification based on the current phone state.
    *
-   * @see #updateInCallNotification(CallList)
+   * @see #updateInCallNotification()
    */
   @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
-  public void updateNotification(CallList callList) {
-    updateInCallNotification(callList);
+  public void updateNotification() {
+    updateInCallNotification();
   }
 
   /**
    * Take down the in-call notification.
    *
-   * @see #updateInCallNotification(CallList)
+   * @see #updateInCallNotification()
    */
   private void cancelNotification() {
     if (mStatusBarCallListener != null) {
@@ -227,20 +228,20 @@
    * the phone is totally idle.
    */
   @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
-  private void updateInCallNotification(CallList callList) {
+  private void updateInCallNotification() {
     LogUtil.d("StatusBarNotifier.updateInCallNotification", "");
 
-    final DialerCall call = getCallToShow(callList);
+    final DialerCall call = getCallToShow(CallList.getInstance());
 
     if (call != null) {
-      showNotification(callList, call);
+      showNotification(call);
     } else {
       cancelNotification();
     }
   }
 
   @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
-  private void showNotification(final CallList callList, final DialerCall call) {
+  private void showNotification(final DialerCall call) {
     Trace.beginSection("StatusBarNotifier.showNotification");
     final boolean isIncoming =
         (call.getState() == DialerCall.State.INCOMING
@@ -252,29 +253,7 @@
     // This callback will always get called immediately and synchronously with whatever data
     // it has available, and may make a subsequent call later (same thread) if it had to
     // call into the contacts provider for more data.
-    mContactInfoCache.findInfo(
-        call,
-        isIncoming,
-        new ContactInfoCacheCallback() {
-          @Override
-          @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
-          public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
-            DialerCall call = callList.getCallById(callId);
-            if (call != null) {
-              call.getLogState().contactLookupResult = entry.contactLookupResult;
-              buildAndSendNotification(callList, call, entry);
-            }
-          }
-
-          @Override
-          @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
-          public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
-            DialerCall call = callList.getCallById(callId);
-            if (call != null) {
-              buildAndSendNotification(callList, call, entry);
-            }
-          }
-        });
+    mContactInfoCache.findInfo(call, isIncoming, this);
     Trace.endSection();
   }
 
@@ -296,11 +275,13 @@
     final int callState = call.getState();
     final CallAudioState callAudioState = AudioModeProvider.getInstance().getAudioState();
 
+    Trace.beginSection("read icon and strings");
     // Check if data has changed; if nothing is different, don't issue another notification.
     final int iconResId = getIconToDisplay(call);
     Bitmap largeIcon = getLargeIconToDisplay(mContext, contactInfo, call);
     final CharSequence content = getContentString(call, contactInfo.userType);
     final String contentTitle = getContentTitle(contactInfo, call);
+    Trace.endSection();
 
     final boolean isVideoUpgradeRequest =
         call.getVideoTech().getSessionModificationState()
@@ -363,18 +344,13 @@
     // Set up the main intent to send the user to the in-call screen
     builder.setContentIntent(createLaunchPendingIntent(false /* isFullScreen */));
 
-    // Set the intent as a full screen intent as well if a call is incoming
-    PhoneAccountHandle accountHandle = call.getAccountHandle();
-    if (accountHandle == null) {
-      accountHandle = getAnyPhoneAccount();
-    }
-
     LogUtil.i("StatusBarNotifier.buildAndSendNotification", "notificationType=" + notificationType);
     switch (notificationType) {
       case NOTIFICATION_INCOMING_CALL:
         if (BuildCompat.isAtLeastO()) {
           builder.setChannelId(NotificationChannelId.INCOMING_CALL);
         }
+        // Set the intent as a full screen intent as well if a call is incoming
         configureFullScreenIntent(builder, createLaunchPendingIntent(true /* isFullScreen */));
         // Set the notification category and bump the priority for incoming calls
         builder.setCategory(Notification.CATEGORY_CALL);
@@ -457,21 +433,6 @@
     Trace.endSection();
   }
 
-  @Nullable
-  @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
-  private PhoneAccountHandle getAnyPhoneAccount() {
-    PhoneAccountHandle accountHandle;
-    TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
-    accountHandle = telecomManager.getDefaultOutgoingPhoneAccount(PhoneAccount.SCHEME_TEL);
-    if (accountHandle == null) {
-      List<PhoneAccountHandle> accountHandles = telecomManager.getCallCapablePhoneAccounts();
-      if (!accountHandles.isEmpty()) {
-        accountHandle = accountHandles.get(0);
-      }
-    }
-    return accountHandle;
-  }
-
   private void createIncomingCallNotification(
       DialerCall call, int state, CallAudioState callAudioState, Notification.Builder builder) {
     setNotificationWhen(call, state, builder);
@@ -615,6 +576,7 @@
   /** Gets a large icon from the contact info object to display in the notification. */
   private static Bitmap getLargeIconToDisplay(
       Context context, ContactCacheEntry contactInfo, DialerCall call) {
+    Trace.beginSection("StatusBarNotifier.getLargeIconToDisplay");
     Resources resources = context.getResources();
     Bitmap largeIcon = null;
     if (contactInfo.photo != null && (contactInfo.photo instanceof BitmapDrawable)) {
@@ -645,6 +607,7 @@
       Drawable drawable = resources.getDrawable(R.drawable.blocked_contact, context.getTheme());
       largeIcon = DrawableConverter.drawableToBitmap(drawable);
     }
+    Trace.endSection();
     return largeIcon;
   }
 
@@ -1069,7 +1032,26 @@
       return;
     }
 
-    updateNotification(CallList.getInstance());
+    updateNotification();
+  }
+
+  @Override
+  @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+  public void onContactInfoComplete(String callId, ContactCacheEntry entry) {
+    DialerCall call = CallList.getInstance().getCallById(callId);
+    if (call != null) {
+      call.getLogState().contactLookupResult = entry.contactLookupResult;
+      buildAndSendNotification(CallList.getInstance(), call, entry);
+    }
+  }
+
+  @Override
+  @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+  public void onImageLoadComplete(String callId, ContactCacheEntry entry) {
+    DialerCall call = CallList.getInstance().getCallById(callId);
+    if (call != null) {
+      buildAndSendNotification(CallList.getInstance(), call, entry);
+    }
   }
 
   private class StatusBarCallListener implements DialerCallListener {
@@ -1125,7 +1107,7 @@
       if (mDialerCall.getVideoTech().getSessionModificationState()
           == SessionModificationState.NO_REQUEST) {
         cleanup();
-        updateNotification(CallList.getInstance());
+        updateNotification();
       }
     }
   }
diff --git a/java/com/android/incallui/call/CallList.java b/java/com/android/incallui/call/CallList.java
index 7c35e4b..fcfb0a6 100644
--- a/java/com/android/incallui/call/CallList.java
+++ b/java/com/android/incallui/call/CallList.java
@@ -175,7 +175,9 @@
                 }
               });
 
+      Trace.beginSection("updateUserMarkedSpamStatus");
       updateUserMarkedSpamStatus(call, context, number);
+      Trace.endSection();
     }
     Trace.endSection();
 
@@ -189,8 +191,7 @@
           public void onCheckComplete(Integer id) {
             if (id != null && id != FilteredNumberAsyncQueryHandler.INVALID_ID) {
               call.setBlockedStatus(true);
-              onUpdateCall(call);
-              notifyGenericListeners();
+              // No need to update UI since it's only used for logging.
             }
           }
         },