Merge changes I47f1e487,I715a97ba,Idb424831
* changes:
Added logging for popping in new call log.
Move update color code from CallCardPresenter to InCallPresenter.
Log the number of "invalid" CP2 rows.
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
index 05a3399..839ba33 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
@@ -25,6 +25,7 @@
import android.view.ViewGroup;
import com.android.dialer.calllogutils.CallLogDates;
import com.android.dialer.common.Assert;
+import com.android.dialer.logging.Logger;
import com.android.dialer.time.Clock;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -53,6 +54,7 @@
private final Clock clock;
private final RealtimeRowProcessor realtimeRowProcessor;
+ private final PopCounts popCounts = new PopCounts();
private Cursor cursor;
@@ -76,6 +78,7 @@
void updateCursor(Cursor updatedCursor) {
this.cursor = updatedCursor;
this.realtimeRowProcessor.clearCache();
+ this.popCounts.reset();
setHeaderPositions();
notifyDataSetChanged();
@@ -85,6 +88,10 @@
this.realtimeRowProcessor.clearCache();
}
+ void logMetrics(Context context) {
+ Logger.get(context).logAnnotatedCallLogMetrics(popCounts.popped, popCounts.didNotPop);
+ }
+
private void setHeaderPositions() {
// If there are no rows to display, set all header positions to null.
if (!cursor.moveToFirst()) {
@@ -138,7 +145,8 @@
LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.new_call_log_entry, viewGroup, false),
clock,
- realtimeRowProcessor);
+ realtimeRowProcessor,
+ popCounts);
default:
throw Assert.createUnsupportedOperationFailException("Unsupported view type: " + viewType);
}
@@ -207,4 +215,14 @@
}
return cursor.getCount() + numberOfHeaders;
}
+
+ static class PopCounts {
+ int popped;
+ int didNotPop;
+
+ private void reset() {
+ popped = 0;
+ didNotPop = 0;
+ }
+ }
}
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java
index bb1a730..0f1c251 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java
@@ -89,6 +89,15 @@
}
@Override
+ public void onStop() {
+ super.onStop();
+
+ if (recyclerView.getAdapter() != null) {
+ ((NewCallLogAdapter) recyclerView.getAdapter()).logMetrics(getContext());
+ }
+ }
+
+ @Override
public void onPause() {
super.onPause();
LogUtil.enterBlock("NewCallLogFragment.onPause");
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
index f322b56..1f84ebf 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
@@ -27,6 +27,7 @@
import android.widget.ImageView;
import android.widget.TextView;
import com.android.dialer.calllog.model.CoalescedRow;
+import com.android.dialer.calllog.ui.NewCallLogAdapter.PopCounts;
import com.android.dialer.calllog.ui.menu.NewCallLogMenu;
import com.android.dialer.calllogutils.CallLogEntryText;
import com.android.dialer.calllogutils.CallLogIntents;
@@ -60,10 +61,12 @@
private final Clock clock;
private final RealtimeRowProcessor realtimeRowProcessor;
private final ExecutorService uiExecutorService;
+ private final PopCounts popCounts;
private long currentRowId;
- NewCallLogViewHolder(View view, Clock clock, RealtimeRowProcessor realtimeRowProcessor) {
+ NewCallLogViewHolder(
+ View view, Clock clock, RealtimeRowProcessor realtimeRowProcessor, PopCounts popCounts) {
super(view);
this.context = view.getContext();
contactPhotoView = view.findViewById(R.id.contact_photo_view);
@@ -79,6 +82,7 @@
this.clock = clock;
this.realtimeRowProcessor = realtimeRowProcessor;
+ this.popCounts = popCounts;
uiExecutorService = DialerExecutorComponent.get(context).uiExecutor();
}
@@ -258,13 +262,17 @@
// If the user scrolled then this ViewHolder may not correspond to the completed task and
// there's nothing to do.
if (originalRow.getId() != currentRowId) {
+ popCounts.didNotPop++;
return;
}
// Only update the UI if the updated row differs from the original row (which has already
// been displayed).
if (!updatedRow.equals(originalRow)) {
displayRow(updatedRow);
+ popCounts.popped++;
+ return;
}
+ popCounts.didNotPop++;
}
@Override
diff --git a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
index b955e02..c5148d9 100644
--- a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
+++ b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
@@ -198,8 +198,14 @@
private CoalescedRow applyPhoneLookupInfoToRow(
PhoneLookupInfo phoneLookupInfo, CoalescedRow row) {
+ // Force the "cp2_info_incomplete" value to the original value so that it is not used when
+ // comparing the original row to the updated row.
+ // TODO(linyuh): Improve the comparison instead.
return row.toBuilder()
- .setNumberAttributes(NumberAttributesConverter.fromPhoneLookupInfo(phoneLookupInfo).build())
+ .setNumberAttributes(
+ NumberAttributesConverter.fromPhoneLookupInfo(phoneLookupInfo)
+ .setIsCp2InfoIncomplete(row.getNumberAttributes().getIsCp2InfoIncomplete())
+ .build())
.build();
}
}
diff --git a/java/com/android/dialer/logging/LoggingBindings.java b/java/com/android/dialer/logging/LoggingBindings.java
index a6795ed..7c580cb 100644
--- a/java/com/android/dialer/logging/LoggingBindings.java
+++ b/java/com/android/dialer/logging/LoggingBindings.java
@@ -90,4 +90,10 @@
/** Logs a call auto-blocked in call screening. */
void logAutoBlockedCall(String phoneNumber);
+
+ /** Logs annotated call log metrics. */
+ void logAnnotatedCallLogMetrics(int invalidNumbersInCallLog);
+
+ /** Logs annotated call log metrics. */
+ void logAnnotatedCallLogMetrics(int numberRowsThatDidPop, int numberRowsThatDidNotPop);
}
diff --git a/java/com/android/dialer/logging/LoggingBindingsStub.java b/java/com/android/dialer/logging/LoggingBindingsStub.java
index de08f44..65ebd1a 100644
--- a/java/com/android/dialer/logging/LoggingBindingsStub.java
+++ b/java/com/android/dialer/logging/LoggingBindingsStub.java
@@ -64,4 +64,10 @@
@Override
public void logAutoBlockedCall(String phoneNumber) {}
+
+ @Override
+ public void logAnnotatedCallLogMetrics(int invalidNumbersInCallLog) {}
+
+ @Override
+ public void logAnnotatedCallLogMetrics(int numberRowsThatDidPop, int numberRowsThatDidNotPop) {}
}
diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2DefaultDirectoryPhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2DefaultDirectoryPhoneLookup.java
index 902a2fb..c5d4e53 100644
--- a/java/com/android/dialer/phonelookup/cp2/Cp2DefaultDirectoryPhoneLookup.java
+++ b/java/com/android/dialer/phonelookup/cp2/Cp2DefaultDirectoryPhoneLookup.java
@@ -33,7 +33,9 @@
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.configprovider.ConfigProvider;
import com.android.dialer.inject.ApplicationContext;
+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;
@@ -64,15 +66,11 @@
private static final String PREF_LAST_TIMESTAMP_PROCESSED =
"cp2DefaultDirectoryPhoneLookupLastTimestampProcessed";
- // We cannot efficiently process invalid numbers because batch queries cannot be constructed which
- // accomplish the necessary loose matching. We'll attempt to process a limited number of them,
- // but if there are too many we fall back to querying CP2 at render time.
- private static final int MAX_SUPPORTED_INVALID_NUMBERS = 5;
-
private final Context appContext;
private final SharedPreferences sharedPreferences;
private final ListeningExecutorService backgroundExecutorService;
private final ListeningExecutorService lightweightExecutorService;
+ private final ConfigProvider configProvider;
@Nullable private Long currentLastTimestampProcessed;
@@ -81,11 +79,13 @@
@ApplicationContext Context appContext,
@Unencrypted SharedPreferences sharedPreferences,
@BackgroundExecutor ListeningExecutorService backgroundExecutorService,
- @LightweightExecutor ListeningExecutorService lightweightExecutorService) {
+ @LightweightExecutor ListeningExecutorService lightweightExecutorService,
+ ConfigProvider configProvider) {
this.appContext = appContext;
this.sharedPreferences = sharedPreferences;
this.backgroundExecutorService = backgroundExecutorService;
this.lightweightExecutorService = lightweightExecutorService;
+ this.configProvider = configProvider;
}
@Override
@@ -138,7 +138,7 @@
@Override
public ListenableFuture<Boolean> isDirty(ImmutableSet<DialerPhoneNumber> phoneNumbers) {
PartitionedNumbers partitionedNumbers = new PartitionedNumbers(phoneNumbers);
- if (partitionedNumbers.invalidNumbers().size() > MAX_SUPPORTED_INVALID_NUMBERS) {
+ if (partitionedNumbers.invalidNumbers().size() > getMaxSupportedInvalidNumbers()) {
// If there are N invalid numbers, we can't determine determine dirtiness without running N
// queries; since running this many queries is not feasible for the (lightweight) isDirty
// check, simply return true. The expectation is that this should rarely be the case as the
@@ -234,7 +234,8 @@
// Then run a separate query for each invalid number. Separate queries are done to accomplish
// loose matching which couldn't be accomplished with a batch query.
- Assert.checkState(partitionedNumbers.invalidNumbers().size() <= MAX_SUPPORTED_INVALID_NUMBERS);
+ Assert.checkState(
+ partitionedNumbers.invalidNumbers().size() <= getMaxSupportedInvalidNumbers());
for (String invalidNumber : partitionedNumbers.invalidNumbers()) {
queryFutures.add(queryPhoneLookupTableForContactIdsBasedOnRawNumber(invalidNumber));
}
@@ -529,7 +530,11 @@
ImmutableMap<DialerPhoneNumber, Cp2Info> existingInfoMap) {
ArraySet<DialerPhoneNumber> unprocessableNumbers = new ArraySet<>();
PartitionedNumbers partitionedNumbers = new PartitionedNumbers(existingInfoMap.keySet());
- if (partitionedNumbers.invalidNumbers().size() > MAX_SUPPORTED_INVALID_NUMBERS) {
+
+ int invalidNumberCount = partitionedNumbers.invalidNumbers().size();
+ Logger.get(appContext).logAnnotatedCallLogMetrics(invalidNumberCount);
+
+ if (invalidNumberCount > getMaxSupportedInvalidNumbers()) {
for (String invalidNumber : partitionedNumbers.invalidNumbers()) {
unprocessableNumbers.addAll(partitionedNumbers.dialerPhoneNumbersForInvalid(invalidNumber));
}
@@ -928,4 +933,13 @@
}
return where.toString();
}
+
+ /**
+ * We cannot efficiently process invalid numbers because batch queries cannot be constructed which
+ * accomplish the necessary loose matching. We'll attempt to process a limited number of them, but
+ * if there are too many we fall back to querying CP2 at render time.
+ */
+ private long getMaxSupportedInvalidNumbers() {
+ return configProvider.getLong("cp2_phone_lookup_max_invalid_numbers", 5);
+ }
}
diff --git a/java/com/android/incallui/CallCardPresenter.java b/java/com/android/incallui/CallCardPresenter.java
index 9c5e062..2f88c88 100644
--- a/java/com/android/incallui/CallCardPresenter.java
+++ b/java/com/android/incallui/CallCardPresenter.java
@@ -271,10 +271,10 @@
// getCallToDisplay doesn't go through outgoing or incoming calls. It will return the
// highest priority call to display as the secondary call.
- secondary = getCallToDisplay(callList, null, true);
+ secondary = InCallPresenter.getCallToDisplay(callList, null, true);
} else if (newState == InCallState.INCALL) {
- primary = getCallToDisplay(callList, null, false);
- secondary = getCallToDisplay(callList, primary, true);
+ primary = InCallPresenter.getCallToDisplay(callList, null, false);
+ secondary = InCallPresenter.getCallToDisplay(callList, primary, true);
}
LogUtil.v("CallCardPresenter.onStateChange", "primary call: " + primary);
@@ -302,7 +302,6 @@
this.primaryNumber = primaryNumber;
if (this.primary != null) {
- InCallPresenter.getInstance().onForegroundCallChanged(this.primary);
inCallScreen.updateInCallScreenColors();
}
@@ -636,54 +635,6 @@
}
}
- /**
- * Get the highest priority call to display. Goes through the calls and chooses which to return
- * based on priority of which type of call to display to the user. Callers can use the "ignore"
- * feature to get the second best call by passing a previously found primary call as ignore.
- *
- * @param ignore A call to ignore if found.
- */
- private DialerCall getCallToDisplay(
- CallList callList, DialerCall ignore, boolean skipDisconnected) {
- // Active calls come second. An active call always gets precedent.
- DialerCall retval = callList.getActiveCall();
- if (retval != null && retval != ignore) {
- return retval;
- }
-
- // Sometimes there is intemediate state that two calls are in active even one is about
- // to be on hold.
- retval = callList.getSecondActiveCall();
- if (retval != null && retval != ignore) {
- return retval;
- }
-
- // Disconnected calls get primary position if there are no active calls
- // to let user know quickly what call has disconnected. Disconnected
- // calls are very short lived.
- if (!skipDisconnected) {
- retval = callList.getDisconnectingCall();
- if (retval != null && retval != ignore) {
- return retval;
- }
- retval = callList.getDisconnectedCall();
- if (retval != null && retval != ignore) {
- return retval;
- }
- }
-
- // Then we go to background call (calls on hold)
- retval = callList.getBackgroundCall();
- if (retval != null && retval != ignore) {
- return retval;
- }
-
- // Lastly, we go to a second background call.
- retval = callList.getSecondBackgroundCall();
-
- return retval;
- }
-
private void updatePrimaryDisplayInfo() {
if (inCallScreen == null) {
// TODO: May also occur if search result comes back after ui is destroyed. Look into
diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java
index 2e98a96..e11b376 100644
--- a/java/com/android/incallui/InCallPresenter.java
+++ b/java/com/android/incallui/InCallPresenter.java
@@ -771,6 +771,22 @@
"Phone switching state: " + oldState + " -> " + newState);
inCallState = newState;
+ // Foreground call changed
+ DialerCall primary = null;
+ if (newState == InCallState.INCOMING) {
+ primary = callList.getIncomingCall();
+ } else if (newState == InCallState.PENDING_OUTGOING || newState == InCallState.OUTGOING) {
+ primary = callList.getOutgoingCall();
+ if (primary == null) {
+ primary = callList.getPendingOutgoingCall();
+ }
+ } else if (newState == InCallState.INCALL) {
+ primary = getCallToDisplay(callList, null, false);
+ }
+ if (primary != null) {
+ onForegroundCallChanged(primary);
+ }
+
// notify listeners of new state
for (InCallStateListener listener : listeners) {
LogUtil.d(
@@ -787,6 +803,54 @@
Trace.endSection();
}
+ /**
+ * Get the highest priority call to display. Goes through the calls and chooses which to return
+ * based on priority of which type of call to display to the user. Callers can use the "ignore"
+ * feature to get the second best call by passing a previously found primary call as ignore.
+ *
+ * @param ignore A call to ignore if found.
+ */
+ static DialerCall getCallToDisplay(
+ CallList callList, DialerCall ignore, boolean skipDisconnected) {
+ // Active calls come second. An active call always gets precedent.
+ DialerCall retval = callList.getActiveCall();
+ if (retval != null && retval != ignore) {
+ return retval;
+ }
+
+ // Sometimes there is intemediate state that two calls are in active even one is about
+ // to be on hold.
+ retval = callList.getSecondActiveCall();
+ if (retval != null && retval != ignore) {
+ return retval;
+ }
+
+ // Disconnected calls get primary position if there are no active calls
+ // to let user know quickly what call has disconnected. Disconnected
+ // calls are very short lived.
+ if (!skipDisconnected) {
+ retval = callList.getDisconnectingCall();
+ if (retval != null && retval != ignore) {
+ return retval;
+ }
+ retval = callList.getDisconnectedCall();
+ if (retval != null && retval != ignore) {
+ return retval;
+ }
+ }
+
+ // Then we go to background call (calls on hold)
+ retval = callList.getBackgroundCall();
+ if (retval != null && retval != ignore) {
+ return retval;
+ }
+
+ // Lastly, we go to a second background call.
+ retval = callList.getSecondBackgroundCall();
+
+ return retval;
+ }
+
/** Called when there is a new incoming call. */
@Override
public void onIncomingCall(DialerCall call) {