summaryrefslogtreecommitdiff
path: root/java/com/android/dialer
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer')
-rw-r--r--java/com/android/dialer/app/calllog/CallLogAdapter.java67
-rw-r--r--java/com/android/dialer/app/calllog/CallLogGroupBuilder.java49
-rw-r--r--java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java71
-rw-r--r--java/com/android/dialer/calllogutils/CallbackActionHelper.java95
4 files changed, 232 insertions, 50 deletions
diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java
index e79c89c57..228321581 100644
--- a/java/com/android/dialer/app/calllog/CallLogAdapter.java
+++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java
@@ -64,6 +64,7 @@ import com.android.dialer.blocking.FilteredNumberAsyncQueryHandler;
import com.android.dialer.calldetails.CallDetailsEntries;
import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry;
import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction;
import com.android.dialer.calllogutils.PhoneAccountUtils;
import com.android.dialer.calllogutils.PhoneCallDetails;
import com.android.dialer.common.Assert;
@@ -479,8 +480,17 @@ public class CallLogAdapter extends GroupingListAdapter
@NonNull private final Set<Uri> mHiddenItemUris = new ArraySet<>();
private CallLogListItemViewHolder.OnClickListener mBlockReportSpamListener;
+
+ /**
+ * Map, keyed by call ID, used to track the callback action for a call. Calls associated with the
+ * same callback action will be put into the same primary call group in {@link
+ * com.android.dialer.app.calllog.CallLogGroupBuilder}. This information is used to set the
+ * callback icon and trigger the corresponding action.
+ */
+ private final Map<Long, Integer> mCallbackActions = new ArrayMap<>();
+
/**
- * Map, keyed by call Id, used to track the day group for a call. As call log entries are put into
+ * Map, keyed by call ID, used to track the day group for a call. As call log entries are put into
* the primary call groups in {@link com.android.dialer.app.calllog.CallLogGroupBuilder}, they are
* also assigned a secondary "day group". This map tracks the day group assigned to all calls in
* the call log. This information is used to trigger the display of a day group header above the
@@ -491,7 +501,7 @@ public class CallLogAdapter extends GroupingListAdapter
* previous day group without having to reverse the cursor to the start of the previous day call
* log entry.
*/
- private Map<Long, Integer> mDayGroups = new ArrayMap<>();
+ private final Map<Long, Integer> mDayGroups = new ArrayMap<>();
private boolean mLoading = true;
private ContactsPreferences mContactsPreferences;
@@ -688,7 +698,7 @@ public class CallLogAdapter extends GroupingListAdapter
@Override
protected void addGroups(Cursor cursor) {
- mCallLogGroupBuilder.addGroups(cursor);
+ mCallLogGroupBuilder.addGroups(cursor, mActivity);
}
@Override
@@ -865,10 +875,11 @@ public class CallLogAdapter extends GroupingListAdapter
protected void onPostExecute(Boolean success) {
views.isLoaded = true;
if (success) {
- int currentGroup = getDayGroupForCall(views.rowId);
- if (currentGroup != details.previousGroup) {
+ views.callbackAction = getCallbackAction(views.rowId);
+ int currentDayGroup = getDayGroup(views.rowId);
+ if (currentDayGroup != details.previousGroup) {
views.dayGroupHeaderVisibility = View.VISIBLE;
- views.dayGroupHeaderText = getGroupDescription(currentGroup);
+ views.dayGroupHeaderText = getGroupDescription(currentDayGroup);
} else {
views.dayGroupHeaderVisibility = View.GONE;
}
@@ -1226,7 +1237,7 @@ public class CallLogAdapter extends GroupingListAdapter
cursor.moveToPosition(startingPosition);
return CallLogGroupBuilder.DAY_GROUP_NONE;
}
- int result = getDayGroupForCall(cursor.getLong(CallLogQuery.ID));
+ int result = getDayGroup(cursor.getLong(CallLogQuery.ID));
cursor.moveToPosition(startingPosition);
return result;
}
@@ -1236,14 +1247,30 @@ public class CallLogAdapter extends GroupingListAdapter
}
/**
- * Given a call Id, look up the day group that the call belongs to. The day group data is
- * populated in {@link com.android.dialer.app.calllog.CallLogGroupBuilder}.
+ * Given a call ID, look up its callback action. Callback action data are populated in {@link
+ * com.android.dialer.app.calllog.CallLogGroupBuilder}.
*
- * @param callId The call to retrieve the day group for.
+ * @param callId The call ID to retrieve the callback action.
+ * @return The callback action for the call.
+ */
+ @MainThread
+ private int getCallbackAction(long callId) {
+ Integer result = mCallbackActions.get(callId);
+ if (result != null) {
+ return result;
+ }
+ return CallbackAction.NONE;
+ }
+
+ /**
+ * Given a call ID, look up the day group the call belongs to. Day group data are populated in
+ * {@link com.android.dialer.app.calllog.CallLogGroupBuilder}.
+ *
+ * @param callId The call ID to retrieve the day group.
* @return The day group for the call.
*/
@MainThread
- private int getDayGroupForCall(long callId) {
+ private int getDayGroup(long callId) {
Integer result = mDayGroups.get(callId);
if (result != null) {
return result;
@@ -1306,17 +1333,27 @@ public class CallLogAdapter extends GroupingListAdapter
}
/**
+ * Stores the callback action associated with a call in the call log.
+ *
+ * @param rowId The row ID of the current call.
+ * @param callbackAction The current call's callback action.
+ */
+ @Override
+ @MainThread
+ public void setCallbackAction(long rowId, @CallbackAction int callbackAction) {
+ mCallbackActions.put(rowId, callbackAction);
+ }
+
+ /**
* Stores the day group associated with a call in the call log.
*
- * @param rowId The row Id of the current call.
+ * @param rowId The row ID of the current call.
* @param dayGroup The day group the call belongs in.
*/
@Override
@MainThread
public void setDayGroup(long rowId, int dayGroup) {
- if (!mDayGroups.containsKey(rowId)) {
- mDayGroups.put(rowId, dayGroup);
- }
+ mDayGroups.put(rowId, dayGroup);
}
/** Clears the day group associations on re-bind of the call log. */
diff --git a/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java b/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java
index 45ff3783d..57a8be730 100644
--- a/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java
+++ b/java/com/android/dialer/app/calllog/CallLogGroupBuilder.java
@@ -16,6 +16,7 @@
package com.android.dialer.app.calllog;
+import android.content.Context;
import android.database.Cursor;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
@@ -25,6 +26,8 @@ import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.text.format.Time;
import com.android.contacts.common.util.DateUtils;
+import com.android.dialer.calllogutils.CallbackActionHelper;
+import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction;
import com.android.dialer.compat.AppCompatConstants;
import com.android.dialer.phonenumbercache.CallLogQuery;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
@@ -71,7 +74,7 @@ public class CallLogGroupBuilder {
*
* @see GroupingListAdapter#addGroups(Cursor)
*/
- public void addGroups(Cursor cursor) {
+ public void addGroups(Cursor cursor, Context context) {
final int count = cursor.getCount();
if (count == 0) {
return;
@@ -90,23 +93,32 @@ public class CallLogGroupBuilder {
int groupDayGroup = getDayGroup(firstDate, currentTime);
mGroupCreator.setDayGroup(firstRowId, groupDayGroup);
- // Instantiate the group values to those of the first call in the cursor.
+ // Determine the callback action for the first call in the cursor.
String groupNumber = cursor.getString(CallLogQuery.NUMBER);
+ String groupAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
+ int groupFeatures = cursor.getInt(CallLogQuery.FEATURES);
+ int groupCallbackAction =
+ CallbackActionHelper.getCallbackAction(
+ groupNumber, groupFeatures, groupAccountComponentName, context);
+ mGroupCreator.setCallbackAction(firstRowId, groupCallbackAction);
+
+ // Instantiate other group values to those of the first call in the cursor.
+ String groupAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
String groupPostDialDigits =
(VERSION.SDK_INT >= VERSION_CODES.N) ? cursor.getString(CallLogQuery.POST_DIAL_DIGITS) : "";
String groupViaNumbers =
(VERSION.SDK_INT >= VERSION_CODES.N) ? cursor.getString(CallLogQuery.VIA_NUMBER) : "";
int groupCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
- String groupAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
- String groupAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
int groupSize = 1;
String number;
String numberPostDialDigits;
String numberViaNumbers;
int callType;
+ int features;
String accountComponentName;
String accountId;
+ int callbackAction;
while (cursor.moveToNext()) {
// Obtain the values for the current call to group.
@@ -118,21 +130,28 @@ public class CallLogGroupBuilder {
numberViaNumbers =
(VERSION.SDK_INT >= VERSION_CODES.N) ? cursor.getString(CallLogQuery.VIA_NUMBER) : "";
callType = cursor.getInt(CallLogQuery.CALL_TYPE);
+ features = cursor.getInt(CallLogQuery.FEATURES);
accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME);
accountId = cursor.getString(CallLogQuery.ACCOUNT_ID);
+ callbackAction =
+ CallbackActionHelper.getCallbackAction(number, features, accountComponentName, context);
final boolean isSameNumber = equalNumbers(groupNumber, number);
final boolean isSamePostDialDigits = groupPostDialDigits.equals(numberPostDialDigits);
final boolean isSameViaNumbers = groupViaNumbers.equals(numberViaNumbers);
final boolean isSameAccount =
isSameAccount(groupAccountComponentName, accountComponentName, groupAccountId, accountId);
+ final boolean isSameCallbackAction = (groupCallbackAction == callbackAction);
- // Group with the same number and account. Never group voicemails. Only group blocked
- // calls with other blocked calls.
+ // Group calls with the following criteria:
+ // (1) Calls with the same number, account, and callback action should be in the same group;
+ // (2) Never group voice mails; and
+ // (3) Only group blocked calls with other blocked calls.
if (isSameNumber
&& isSameAccount
&& isSamePostDialDigits
&& isSameViaNumbers
+ && isSameCallbackAction
&& areBothNotVoicemail(callType, groupCallType)
&& (areBothNotBlocked(callType, groupCallType)
|| areBothBlocked(callType, groupCallType))) {
@@ -158,10 +177,12 @@ public class CallLogGroupBuilder {
groupCallType = callType;
groupAccountComponentName = accountComponentName;
groupAccountId = accountId;
+ groupCallbackAction = callbackAction;
}
- // Save the day group associated with the current call.
+ // Save the callback action and the day group associated with the current call.
final long currentCallId = cursor.getLong(CallLogQuery.ID);
+ mGroupCreator.setCallbackAction(currentCallId, groupCallbackAction);
mGroupCreator.setDayGroup(currentCallId, groupDayGroup);
}
@@ -259,12 +280,22 @@ public class CallLogGroupBuilder {
void addGroup(int cursorPosition, int size);
/**
+ * Defines the interface for tracking each call's callback action. Calls in a call group are
+ * associated with the same callback action as the first call in the group. The value of a
+ * callback action should be one of the categories in {@link CallbackAction}.
+ *
+ * @param rowId The row ID of the current call.
+ * @param callbackAction The current call's callback action.
+ */
+ void setCallbackAction(long rowId, @CallbackAction int callbackAction);
+
+ /**
* Defines the interface for tracking the day group each call belongs to. Calls in a call group
* are assigned the same day group as the first call in the group. The day group assigns calls
* to the buckets: Today, Yesterday, Last week, and Other
*
- * @param rowId The row Id of the current call.
- * @param dayGroup The day group the call belongs in.
+ * @param rowId The row ID of the current call.
+ * @param dayGroup The day group the call belongs to.
*/
void setDayGroup(long rowId, int dayGroup);
diff --git a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
index f0eee112b..225b6527e 100644
--- a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
+++ b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java
@@ -66,6 +66,7 @@ import com.android.dialer.callcomposer.CallComposerActivity;
import com.android.dialer.calldetails.CallDetailsActivity;
import com.android.dialer.calldetails.CallDetailsEntries;
import com.android.dialer.callintent.CallIntentBuilder;
+import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.CompatUtils;
@@ -228,6 +229,7 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
private final View.OnLongClickListener longPressListener;
private boolean mVoicemailPrimaryActionButtonClicked;
+ public int callbackAction;
public int dayGroupHeaderVisibility;
public CharSequence dayGroupHeaderText;
public boolean isAttachedToWindow;
@@ -511,36 +513,53 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
} else {
primaryActionButtonView.setVisibility(View.GONE);
}
- } else {
- // Treat as normal list item; show call button, if possible.
- if (PhoneNumberHelper.canPlaceCallsTo(number, numberPresentation)) {
- boolean isVoicemailNumber = mCallLogCache.isVoicemailNumber(accountHandle, number);
+ return;
+ }
+
+ // Treat as normal list item; show call button, if possible.
+ if (!PhoneNumberHelper.canPlaceCallsTo(number, numberPresentation)) {
+ primaryActionButtonView.setTag(null);
+ primaryActionButtonView.setVisibility(View.GONE);
+ return;
+ }
- if (!isVoicemailNumber && showLightbringerPrimaryButton()) {
+ switch (callbackAction) {
+ case CallbackAction.IMS_VIDEO:
+ primaryActionButtonView.setTag(
+ IntentProvider.getReturnVideoCallIntentProvider(number, accountHandle));
+ primaryActionButtonView.setContentDescription(
+ TextUtils.expandTemplate(
+ mContext.getString(R.string.description_video_call_action), validNameOrNumber));
+ primaryActionButtonView.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24);
+ primaryActionButtonView.setVisibility(View.VISIBLE);
+ break;
+ case CallbackAction.LIGHTBRINGER:
+ if (showLightbringerPrimaryButton()) {
CallIntentBuilder.increaseLightbringerCallButtonAppearInCollapsedCallLogItemCount();
primaryActionButtonView.setTag(IntentProvider.getLightbringerIntentProvider(number));
- primaryActionButtonView.setContentDescription(
- TextUtils.expandTemplate(
- mContext.getString(R.string.description_video_call_action), validNameOrNumber));
- primaryActionButtonView.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24);
- primaryActionButtonView.setVisibility(View.VISIBLE);
- return;
+ } else {
+ primaryActionButtonView.setTag(
+ IntentProvider.getReturnVideoCallIntentProvider(number, accountHandle));
}
-
- if (isVoicemailNumber) {
- // Call to generic voicemail number, in case there are multiple accounts.
+ primaryActionButtonView.setContentDescription(
+ TextUtils.expandTemplate(
+ mContext.getString(R.string.description_video_call_action), validNameOrNumber));
+ primaryActionButtonView.setImageResource(R.drawable.quantum_ic_videocam_vd_theme_24);
+ primaryActionButtonView.setVisibility(View.VISIBLE);
+ break;
+ case CallbackAction.VOICE:
+ if (mCallLogCache.isVoicemailNumber(accountHandle, number)) {
+ // Call to generic voicemail number, in case there are multiple accounts
primaryActionButtonView.setTag(IntentProvider.getReturnVoicemailCallIntentProvider());
+ } else if (this.info != null && this.info.lookupKey != null) {
+ primaryActionButtonView.setTag(
+ IntentProvider.getAssistedDialIntentProvider(
+ number + postDialDigits,
+ mContext,
+ mContext.getSystemService(TelephonyManager.class)));
} else {
- if (this.info != null && this.info.lookupKey != null) {
- primaryActionButtonView.setTag(
- IntentProvider.getAssistedDialIntentProvider(
- number + postDialDigits,
- mContext,
- mContext.getSystemService(TelephonyManager.class)));
- } else {
- primaryActionButtonView.setTag(
- IntentProvider.getReturnCallIntentProvider(number + postDialDigits));
- }
+ primaryActionButtonView.setTag(
+ IntentProvider.getReturnCallIntentProvider(number + postDialDigits));
}
primaryActionButtonView.setContentDescription(
@@ -548,10 +567,10 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder
mContext.getString(R.string.description_call_action), validNameOrNumber));
primaryActionButtonView.setImageResource(R.drawable.quantum_ic_call_vd_theme_24);
primaryActionButtonView.setVisibility(View.VISIBLE);
- } else {
+ break;
+ default:
primaryActionButtonView.setTag(null);
primaryActionButtonView.setVisibility(View.GONE);
- }
}
}
diff --git a/java/com/android/dialer/calllogutils/CallbackActionHelper.java b/java/com/android/dialer/calllogutils/CallbackActionHelper.java
new file mode 100644
index 000000000..297d5e649
--- /dev/null
+++ b/java/com/android/dialer/calllogutils/CallbackActionHelper.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dialer.calllogutils;
+
+import android.content.Context;
+import android.provider.CallLog.Calls;
+import android.support.annotation.IntDef;
+import android.text.TextUtils;
+import com.android.dialer.lightbringer.Lightbringer;
+import com.android.dialer.lightbringer.LightbringerComponent;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Helper class to determine the callback action associated with a call in the call log. */
+public class CallbackActionHelper {
+
+ /** Specifies the action a user can take to make a callback. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ CallbackAction.NONE,
+ CallbackAction.IMS_VIDEO,
+ CallbackAction.LIGHTBRINGER,
+ CallbackAction.VOICE
+ })
+ public @interface CallbackAction {
+ int NONE = 0;
+ int IMS_VIDEO = 1;
+ int LIGHTBRINGER = 2;
+ int VOICE = 3;
+ }
+
+ /**
+ * Returns the {@link CallbackAction} that can be associated with a call.
+ *
+ * @param number The phone number in column {@link android.provider.CallLog.Calls#NUMBER}.
+ * @param features Value of features in column {@link android.provider.CallLog.Calls#FEATURES}.
+ * @param phoneAccountComponentName Account name in column {@link
+ * android.provider.CallLog.Calls#PHONE_ACCOUNT_COMPONENT_NAME}.
+ * @param context The context in which the method is called.
+ * @return One of the values in {@link CallbackAction}
+ */
+ public static @CallbackAction int getCallbackAction(
+ String number, int features, String phoneAccountComponentName, Context context) {
+ return getCallbackAction(
+ number, features, isLightbringerCall(phoneAccountComponentName, context));
+ }
+
+ /**
+ * Returns the {@link CallbackAction} that can be associated with a call.
+ *
+ * @param number The phone number in column {@link android.provider.CallLog.Calls#NUMBER}.
+ * @param features Value of features in column {@link android.provider.CallLog.Calls#FEATURES}.
+ * @param isLightbringerCall Whether the call is a Lightbringer call.
+ * @return One of the values in {@link CallbackAction}
+ */
+ public static @CallbackAction int getCallbackAction(
+ String number, int features, boolean isLightbringerCall) {
+ if (TextUtils.isEmpty(number)) {
+ return CallbackAction.NONE;
+ }
+ if (isLightbringerCall) {
+ return CallbackAction.LIGHTBRINGER;
+ }
+
+ boolean isVideoCall = (features & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO;
+ if (isVideoCall) {
+ return CallbackAction.IMS_VIDEO;
+ }
+
+ return CallbackAction.VOICE;
+ }
+
+ private static boolean isLightbringerCall(String phoneAccountComponentName, Context context) {
+ Lightbringer lightBringer = LightbringerComponent.get(context).getLightbringer();
+ return lightBringer.getPhoneAccountComponentName() != null
+ && lightBringer
+ .getPhoneAccountComponentName()
+ .flattenToString()
+ .equals(phoneAccountComponentName);
+ }
+}