From c8cf79e8e834148ff37759f59e83e169584ee99f Mon Sep 17 00:00:00 2001 From: wangqi Date: Tue, 17 Oct 2017 09:21:00 -0700 Subject: Some cleanup of incoming call latency. 1. Only update secondary info when it's changed. 2. Removed redundant call to update notification on activity start (b/36649622) 3. Use same call back for notification update from contact info query to avoid duplicated call backs. The actual latency reduction is insignificant (<10%). Bug: 36649622,64542087 Test: manual PiperOrigin-RevId: 172475223 Change-Id: I1c91cb5715287991de774a1d9b95e4c8b722d28f --- java/com/android/incallui/CallCardPresenter.java | 24 +++--- java/com/android/incallui/ContactInfoCache.java | 5 +- java/com/android/incallui/InCallPresenter.java | 10 +-- java/com/android/incallui/ProximitySensor.java | 2 + java/com/android/incallui/StatusBarNotifier.java | 100 ++++++++++------------- java/com/android/incallui/call/CallList.java | 5 +- 6 files changed, 67 insertions(+), 79 deletions(-) (limited to 'java') diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java index 871243c7d..0ef0c9827 100644 --- a/java/com/android/incallui/CallCardPresenter.java +++ b/java/com/android/incallui/CallCardPresenter.java @@ -319,17 +319,19 @@ public class CallCardPresenter 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 2fb18b8d7..272c2b776 100644 --- a/java/com/android/incallui/ContactInfoCache.java +++ b/java/com/android/incallui/ContactInfoCache.java @@ -85,7 +85,6 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { // worker thread. private final ConcurrentHashMap mInfoMap = new ConcurrentHashMap<>(); private final Map> mCallBacks = new ArrayMap<>(); - private Drawable mDefaultContactPhotoDrawable; private int mQueryId; private final DialerExecutor cachedNumberLookupExecutor = DialerExecutors.createNonUiTaskBuilder(new CachedNumberLookupWorker()).build(); @@ -350,12 +349,14 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { Assert.isMainThread(); Objects.requireNonNull(callback); + Trace.beginSection("prepare callback"); final String callId = call.getId(); final ContactCacheEntry cacheEntry = mInfoMap.get(callId); Set 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 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { 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 @@ public class ContactInfoCache implements OnImageLoadCompleteListener { 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 70fe88be8..1ba3b5d3a 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -273,7 +273,9 @@ public class InCallPresenter implements CallList.Listener { public static synchronized InCallPresenter getInstance() { if (sInCallPresenter == null) { + Trace.beginSection("InCallPresenter.Constructor"); sInCallPresenter = new InCallPresenter(); + Trace.endSection(); } return sInCallPresenter; } @@ -1033,7 +1035,7 @@ public class InCallPresenter implements CallList.Listener { // 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 @@ public class InCallPresenter implements CallList.Listener { 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 @@ public class InCallPresenter implements CallList.Listener { } 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 339a2e941..123ca539f 100644 --- a/java/com/android/incallui/ProximitySensor.java +++ b/java/com/android/incallui/ProximitySensor.java @@ -60,6 +60,7 @@ public class ProximitySensor @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 @@ public class ProximitySensor 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 e5908f12e..7ff0040e2 100644 --- a/java/com/android/incallui/StatusBarNotifier.java +++ b/java/com/android/incallui/StatusBarNotifier.java @@ -52,7 +52,6 @@ import android.support.v4.os.BuildCompat; 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.DialerRingtoneManager; 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 @@ public class StatusBarNotifier 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 @@ public class StatusBarNotifier CallList.getInstance()); mCurrentNotification = NOTIFICATION_NONE; AudioModeProvider.getInstance().addListener(this); + Trace.endSection(); } /** @@ -175,13 +176,13 @@ public class StatusBarNotifier @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 @@ public class StatusBarNotifier * 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 @@ public class StatusBarNotifier * 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 @@ public class StatusBarNotifier // 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 @@ public class StatusBarNotifier 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 @@ public class StatusBarNotifier // 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 @@ public class StatusBarNotifier 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 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 @@ public class StatusBarNotifier /** 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 @@ public class StatusBarNotifier Drawable drawable = resources.getDrawable(R.drawable.blocked_contact, context.getTheme()); largeIcon = DrawableConverter.drawableToBitmap(drawable); } + Trace.endSection(); return largeIcon; } @@ -1069,7 +1032,26 @@ public class StatusBarNotifier 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 @@ public class StatusBarNotifier 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 7c35e4b92..fcfb0a663 100644 --- a/java/com/android/incallui/call/CallList.java +++ b/java/com/android/incallui/call/CallList.java @@ -175,7 +175,9 @@ public class CallList implements DialerCallDelegate { } }); + Trace.beginSection("updateUserMarkedSpamStatus"); updateUserMarkedSpamStatus(call, context, number); + Trace.endSection(); } Trace.endSection(); @@ -189,8 +191,7 @@ public class CallList implements DialerCallDelegate { 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. } } }, -- cgit v1.2.3