Merge "Add glide annotation processor"
diff --git a/java/com/android/dialer/app/calllog/CallLogAdapter.java b/java/com/android/dialer/app/calllog/CallLogAdapter.java
index 963967f..9e1d4a7 100644
--- a/java/com/android/dialer/app/calllog/CallLogAdapter.java
+++ b/java/com/android/dialer/app/calllog/CallLogAdapter.java
@@ -66,7 +66,6 @@
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;
import com.android.dialer.common.LogUtil;
@@ -91,6 +90,7 @@
import com.android.dialer.phonenumbercache.ContactInfoHelper;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
import com.android.dialer.spam.SpamComponent;
+import com.android.dialer.telecom.TelecomUtil;
import com.android.dialer.util.PermissionsUtil;
import java.util.ArrayList;
import java.util.Map;
@@ -1020,7 +1020,7 @@
}
final PhoneAccountHandle accountHandle =
- PhoneAccountUtils.getAccount(details.accountComponentName, details.accountId);
+ TelecomUtil.composePhoneAccountHandle(details.accountComponentName, details.accountId);
final boolean isVoicemailNumber = callLogCache.isVoicemailNumber(accountHandle, details.number);
diff --git a/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java b/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java
index a0bbfa0..0ddfb9f 100644
--- a/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java
+++ b/java/com/android/dialer/app/calllog/LegacyVoicemailNotifier.java
@@ -31,11 +31,11 @@
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.dialer.app.R;
-import com.android.dialer.calllogutils.PhoneAccountUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.notification.DialerNotificationManager;
import com.android.dialer.notification.NotificationChannelManager;
+import com.android.dialer.telecom.TelecomUtil;
/** Shows a notification in the status bar for legacy vociemail. */
@TargetApi(VERSION_CODES.O)
@@ -137,7 +137,7 @@
@NonNull
private static String getNotificationText(
@NonNull Context context, PhoneAccountHandle handle, String voicemailNumber) {
- if (PhoneAccountUtils.getSubscriptionPhoneAccounts(context).size() > 1) {
+ if (TelecomUtil.getCallCapablePhoneAccounts(context).size() > 1) {
TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
PhoneAccount phoneAccount = telecomManager.getPhoneAccount(handle);
return phoneAccount.getShortDescription().toString();
diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
index eed77eb..fea3e91 100644
--- a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
+++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
@@ -41,6 +41,7 @@
+ (AnnotatedCallLog.TIMESTAMP + " integer, ")
+ (AnnotatedCallLog.NUMBER + " blob, ")
+ (AnnotatedCallLog.FORMATTED_NUMBER + " text, ")
+ + (AnnotatedCallLog.NUMBER_PRESENTATION + " integer, ")
+ (AnnotatedCallLog.DURATION + " integer, ")
+ (AnnotatedCallLog.DATA_USAGE + " integer, ")
+ (AnnotatedCallLog.IS_READ + " integer, ")
@@ -54,7 +55,7 @@
+ (AnnotatedCallLog.TRANSCRIPTION + " integer, ")
+ (AnnotatedCallLog.VOICEMAIL_URI + " text, ")
+ (AnnotatedCallLog.CALL_TYPE + " integer not null, ")
- + (AnnotatedCallLog.NUMBER_ATTRIBUTES + " blob ")
+ + (AnnotatedCallLog.NUMBER_ATTRIBUTES + " blob")
+ ");";
/**
diff --git a/java/com/android/dialer/calllog/database/Coalescer.java b/java/com/android/dialer/calllog/database/Coalescer.java
index b10dea2..ed09eea 100644
--- a/java/com/android/dialer/calllog/database/Coalescer.java
+++ b/java/com/android/dialer/calllog/database/Coalescer.java
@@ -27,10 +27,10 @@
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog;
import com.android.dialer.calllog.datasources.CallLogDataSource;
import com.android.dialer.calllog.datasources.DataSources;
-import com.android.dialer.calllogutils.PhoneAccountUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.compat.telephony.TelephonyManagerCompat;
import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
+import com.android.dialer.telecom.TelecomUtil;
import com.google.common.base.Preconditions;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -144,11 +144,11 @@
DialerPhoneNumberUtil dialerPhoneNumberUtil, ContentValues row1, ContentValues row2) {
// Don't combine rows which don't use the same phone account.
PhoneAccountHandle phoneAccount1 =
- PhoneAccountUtils.getAccount(
+ TelecomUtil.composePhoneAccountHandle(
row1.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME),
row1.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_ID));
PhoneAccountHandle phoneAccount2 =
- PhoneAccountUtils.getAccount(
+ TelecomUtil.composePhoneAccountHandle(
row2.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME),
row2.getAsString(AnnotatedCallLog.PHONE_ACCOUNT_ID));
@@ -156,6 +156,11 @@
return false;
}
+ if (!row1.getAsInteger(AnnotatedCallLog.NUMBER_PRESENTATION)
+ .equals(row2.getAsInteger(AnnotatedCallLog.NUMBER_PRESENTATION))) {
+ return false;
+ }
+
if (!meetsAssistedDialingCriteria(row1, row2)) {
return false;
}
diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
index 96a6409..4fee4e5 100644
--- a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
+++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
@@ -59,6 +59,13 @@
String FORMATTED_NUMBER = "formatted_number";
/**
+ * See {@link android.provider.CallLog.Calls#NUMBER_PRESENTATION}.
+ *
+ * <p>Type: INTEGER (int)
+ */
+ String NUMBER_PRESENTATION = "presentation";
+
+ /**
* See {@link android.provider.CallLog.Calls#IS_READ}.
*
* <p>TYPE: INTEGER (boolean)
@@ -136,6 +143,7 @@
TIMESTAMP,
NUMBER,
FORMATTED_NUMBER,
+ NUMBER_PRESENTATION,
IS_READ,
NEW,
GEOCODED_LOCATION,
@@ -145,7 +153,7 @@
PHONE_ACCOUNT_COLOR,
FEATURES,
NUMBER_ATTRIBUTES,
- CALL_TYPE,
+ CALL_TYPE
};
}
diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java
index 14cde46..24410ee 100644
--- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java
+++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java
@@ -51,6 +51,7 @@
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil;
import com.android.dialer.storage.StorageComponent;
+import com.android.dialer.telecom.TelecomUtil;
import com.android.dialer.theme.R;
import com.android.dialer.util.PermissionsUtil;
import com.google.common.collect.Iterables;
@@ -195,6 +196,7 @@
// recent one.
.useMostRecentBlob(AnnotatedCallLog.NUMBER)
.useMostRecentString(AnnotatedCallLog.FORMATTED_NUMBER)
+ .useSingleValueInt(AnnotatedCallLog.NUMBER_PRESENTATION)
.useMostRecentString(AnnotatedCallLog.GEOCODED_LOCATION)
.useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME)
.useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_ID)
@@ -238,6 +240,7 @@
Calls.DATE,
Calls.LAST_MODIFIED, // TODO(a bug): Not available in M
Calls.NUMBER,
+ Calls.NUMBER_PRESENTATION,
Calls.TYPE,
Calls.COUNTRY_ISO,
Calls.DURATION,
@@ -250,7 +253,7 @@
Calls.PHONE_ACCOUNT_COMPONENT_NAME,
Calls.PHONE_ACCOUNT_ID,
Calls.FEATURES,
- Calls.POST_DIAL_DIGITS, // TODO(a bug): Not available in M
+ Calls.POST_DIAL_DIGITS // TODO(a bug): Not available in M
},
// TODO(a bug): LAST_MODIFIED not available on M
Calls.LAST_MODIFIED + " > ? AND " + Voicemails.DELETED + " = 0",
@@ -272,6 +275,7 @@
int dateColumn = cursor.getColumnIndexOrThrow(Calls.DATE);
int lastModifiedColumn = cursor.getColumnIndexOrThrow(Calls.LAST_MODIFIED);
int numberColumn = cursor.getColumnIndexOrThrow(Calls.NUMBER);
+ int presentationColumn = cursor.getColumnIndexOrThrow(Calls.NUMBER_PRESENTATION);
int typeColumn = cursor.getColumnIndexOrThrow(Calls.TYPE);
int countryIsoColumn = cursor.getColumnIndexOrThrow(Calls.COUNTRY_ISO);
int durationsColumn = cursor.getColumnIndexOrThrow(Calls.DURATION);
@@ -294,11 +298,18 @@
long id = cursor.getLong(idColumn);
long date = cursor.getLong(dateColumn);
String numberAsStr = cursor.getString(numberColumn);
- long type;
+ int type;
if (cursor.isNull(typeColumn) || (type = cursor.getInt(typeColumn)) == 0) {
// CallLog.Calls#TYPE lists the allowed values, which are non-null and non-zero.
throw new IllegalStateException("call type is missing");
}
+ int presentation;
+ if (cursor.isNull(presentationColumn)
+ || (presentation = cursor.getInt(presentationColumn)) == 0) {
+ // CallLog.Calls#NUMBER_PRESENTATION lists the allowed values, which are non-null and
+ // non-zero.
+ throw new IllegalStateException("presentation is missing");
+ }
String countryIso = cursor.getString(countryIsoColumn);
int duration = cursor.getInt(durationsColumn);
int dataUsage = cursor.getInt(dataUsageColumn);
@@ -332,6 +343,7 @@
contentValues.put(
AnnotatedCallLog.NUMBER, DialerPhoneNumber.getDefaultInstance().toByteArray());
}
+ contentValues.put(AnnotatedCallLog.NUMBER_PRESENTATION, presentation);
contentValues.put(AnnotatedCallLog.CALL_TYPE, type);
contentValues.put(AnnotatedCallLog.IS_READ, isRead);
contentValues.put(AnnotatedCallLog.NEW, isNew);
@@ -363,7 +375,7 @@
String phoneAccountComponentName,
String phoneAccountId) {
PhoneAccountHandle phoneAccountHandle =
- PhoneAccountUtils.getAccount(phoneAccountComponentName, phoneAccountId);
+ TelecomUtil.composePhoneAccountHandle(phoneAccountComponentName, phoneAccountId);
if (phoneAccountHandle == null) {
return;
}
diff --git a/java/com/android/dialer/calllog/datasources/util/RowCombiner.java b/java/com/android/dialer/calllog/datasources/util/RowCombiner.java
index 6e33db5..2bb65cc 100644
--- a/java/com/android/dialer/calllog/datasources/util/RowCombiner.java
+++ b/java/com/android/dialer/calllog/datasources/util/RowCombiner.java
@@ -80,6 +80,18 @@
return this;
}
+ /** Asserts that all column values for the given column name are the same, and uses it. */
+ public RowCombiner useSingleValueInt(String columnName) {
+ Iterator<ContentValues> iterator = individualRowsSortedByTimestampDesc.iterator();
+ Integer singleValue = iterator.next().getAsInteger(columnName);
+ while (iterator.hasNext()) {
+ Integer current = iterator.next().getAsInteger(columnName);
+ Assert.checkState(Objects.equals(singleValue, current), "Values different for " + columnName);
+ }
+ combinedRow.put(columnName, singleValue);
+ return this;
+ }
+
/** Performs a bitwise OR on the specified column and yields the result. */
public RowCombiner bitwiseOr(String columnName) {
int combinedValue = 0;
diff --git a/java/com/android/dialer/calllog/model/CoalescedRow.java b/java/com/android/dialer/calllog/model/CoalescedRow.java
index 312c29c..2b6db97 100644
--- a/java/com/android/dialer/calllog/model/CoalescedRow.java
+++ b/java/com/android/dialer/calllog/model/CoalescedRow.java
@@ -32,6 +32,7 @@
.setId(0)
.setTimestamp(0)
.setNumber(DialerPhoneNumber.getDefaultInstance())
+ .setNumberPresentation(0)
.setIsRead(false)
.setIsNew(false)
.setPhoneAccountColor(0)
@@ -52,6 +53,8 @@
@Nullable
public abstract String formattedNumber();
+ public abstract int numberPresentation();
+
public abstract boolean isRead();
public abstract boolean isNew();
@@ -91,6 +94,8 @@
public abstract Builder setFormattedNumber(@Nullable String formattedNumber);
+ public abstract Builder setNumberPresentation(int presentation);
+
public abstract Builder setIsRead(boolean isRead);
public abstract Builder setIsNew(boolean isNew);
diff --git a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
index d72544b..0b1c6c9 100644
--- a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
+++ b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
@@ -34,17 +34,18 @@
private static final int TIMESTAMP = 1;
private static final int NUMBER = 2;
private static final int FORMATTED_NUMBER = 3;
- private static final int IS_READ = 4;
- private static final int NEW = 5;
- private static final int GEOCODED_LOCATION = 6;
- private static final int PHONE_ACCOUNT_COMPONENT_NAME = 7;
- private static final int PHONE_ACCOUNT_ID = 8;
- private static final int PHONE_ACCOUNT_LABEL = 9;
- private static final int PHONE_ACCOUNT_COLOR = 10;
- private static final int FEATURES = 11;
- private static final int NUMBER_ATTRIBUTES = 12;
- private static final int CALL_TYPE = 13;
- private static final int COALESCED_IDS = 14;
+ private static final int NUMBER_PRESENTATION = 4;
+ private static final int IS_READ = 5;
+ private static final int NEW = 6;
+ private static final int GEOCODED_LOCATION = 7;
+ private static final int PHONE_ACCOUNT_COMPONENT_NAME = 8;
+ private static final int PHONE_ACCOUNT_ID = 9;
+ private static final int PHONE_ACCOUNT_LABEL = 10;
+ private static final int PHONE_ACCOUNT_COLOR = 11;
+ private static final int FEATURES = 12;
+ private static final int NUMBER_ATTRIBUTES = 13;
+ private static final int CALL_TYPE = 14;
+ private static final int COALESCED_IDS = 15;
CoalescedAnnotatedCallLogCursorLoader(Context context) {
// CoalescedAnnotatedCallLog requires that PROJECTION be ALL_COLUMNS and the following params be
@@ -86,6 +87,7 @@
.setTimestamp(cursor.getLong(TIMESTAMP))
.setNumber(number)
.setFormattedNumber(cursor.getString(FORMATTED_NUMBER))
+ .setNumberPresentation(cursor.getInt(NUMBER_PRESENTATION))
.setIsRead(cursor.getInt(IS_READ) == 1)
.setIsNew(cursor.getInt(NEW) == 1)
.setGeocodedLocation(cursor.getString(GEOCODED_LOCATION))
diff --git a/java/com/android/dialer/calllog/ui/menu/Modules.java b/java/com/android/dialer/calllog/ui/menu/Modules.java
index 67e5168..96e5951 100644
--- a/java/com/android/dialer/calllog/ui/menu/Modules.java
+++ b/java/com/android/dialer/calllog/ui/menu/Modules.java
@@ -24,12 +24,15 @@
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.calllog.model.CoalescedRow;
import com.android.dialer.calllogutils.CallLogContactTypes;
-import com.android.dialer.calllogutils.PhoneAccountUtils;
+import com.android.dialer.calllogutils.PhoneNumberDisplayUtil;
import com.android.dialer.contactactions.ContactActionModule;
import com.android.dialer.contactactions.DividerModule;
import com.android.dialer.contactactions.IntentModule;
import com.android.dialer.contactactions.SharedModules;
import com.android.dialer.dialercontact.DialerContact;
+import com.android.dialer.phonenumberutil.PhoneNumberHelper;
+import com.android.dialer.telecom.TelecomUtil;
+import com.google.common.base.Optional;
import java.util.ArrayList;
import java.util.List;
@@ -43,16 +46,23 @@
// Conditionally add each module, which are items in the bottom sheet's menu.
List<ContactActionModule> modules = new ArrayList<>();
- maybeAddModuleForVideoOrAudioCall(context, modules, row);
- SharedModules.maybeAddModuleForAddingToContacts(
- context,
- modules,
- row.number(),
- row.numberAttributes().getName(),
- row.numberAttributes().getLookupUri());
+ // TODO(zach): Don't use raw input.
+ String normalizedNumber = row.number().getRawInput().getNumber();
+ boolean canPlaceCalls =
+ PhoneNumberHelper.canPlaceCallsTo(normalizedNumber, row.numberPresentation());
- String originalNumber = row.number().getRawInput().getNumber();
- SharedModules.maybeAddModuleForSendingTextMessage(context, modules, originalNumber);
+ if (canPlaceCalls) {
+ addModuleForVideoOrAudioCall(context, modules, row, normalizedNumber);
+
+ SharedModules.maybeAddModuleForAddingToContacts(
+ context,
+ modules,
+ row.number(),
+ row.numberAttributes().getName(),
+ row.numberAttributes().getLookupUri());
+
+ SharedModules.maybeAddModuleForSendingTextMessage(context, modules, normalizedNumber);
+ }
if (!modules.isEmpty()) {
modules.add(new DividerModule());
@@ -62,7 +72,9 @@
// TODO(zachh): Module for blocking/unblocking spam.
// TODO(zachh): Module for CallComposer.
- SharedModules.maybeAddModuleForCopyingNumber(context, modules, originalNumber);
+ if (canPlaceCalls) {
+ SharedModules.maybeAddModuleForCopyingNumber(context, modules, normalizedNumber);
+ }
// TODO(zachh): Revisit if DialerContact is the best thing to pass to CallDetails; could
// it use a ContactPrimaryActionInfo instead?
@@ -73,30 +85,28 @@
return modules;
}
- private static void maybeAddModuleForVideoOrAudioCall(
- Context context, List<ContactActionModule> modules, CoalescedRow row) {
- String originalNumber = row.number().getRawInput().getNumber();
- if (TextUtils.isEmpty(originalNumber)) {
- // Skip adding the menu item if the phone number is unknown.
- return;
- }
-
+ private static void addModuleForVideoOrAudioCall(
+ Context context,
+ List<ContactActionModule> modules,
+ CoalescedRow row,
+ String normalizedNumber) {
PhoneAccountHandle phoneAccountHandle =
- PhoneAccountUtils.getAccount(row.phoneAccountComponentName(), row.phoneAccountId());
+ TelecomUtil.composePhoneAccountHandle(
+ row.phoneAccountComponentName(), row.phoneAccountId());
if ((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO) {
// Add an audio call item for video calls. Clicking the top entry on the bottom sheet will
// trigger a video call.
modules.add(
IntentModule.newCallModule(
- context, originalNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG));
+ context, normalizedNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG));
} else {
// Add a video call item for audio calls. Click the top entry on the bottom sheet will
// trigger an audio call.
// TODO(zachh): Only show video option if video capabilities present?
modules.add(
IntentModule.newVideoCallModule(
- context, originalNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG));
+ context, normalizedNumber, phoneAccountHandle, CallInitiationType.Type.CALL_LOG));
}
}
@@ -111,20 +121,28 @@
CallDetailsActivity.newInstance(
context,
row.coalescedIds(),
- createDialerContactFromRow(row),
+ createDialerContactFromRow(context, row),
canReportAsInvalidNumber,
canSupportAssistedDialing),
R.string.call_details_menu_label,
R.drawable.quantum_ic_info_outline_vd_theme_24));
}
- private static DialerContact createDialerContactFromRow(CoalescedRow row) {
- // TODO(zachh): Do something with parsed values to make more dialable?
- String originalNumber = row.number().getRawInput().getNumber();
+ private static DialerContact createDialerContactFromRow(Context context, CoalescedRow row) {
+ Optional<String> presentationName =
+ PhoneNumberDisplayUtil.getNameForPresentation(context, row.numberPresentation());
+ if (presentationName.isPresent()) {
+ return DialerContact.newBuilder()
+ .setNameOrNumber(presentationName.get())
+ .setContactType(CallLogContactTypes.getContactType(row))
+ .build();
+ }
+ // TODO(zachh): Don't use raw input.
+ String normalizedNumber = row.number().getRawInput().getNumber();
DialerContact.Builder dialerContactBuilder =
DialerContact.newBuilder()
- .setNumber(originalNumber)
+ .setNumber(normalizedNumber)
.setContactType(CallLogContactTypes.getContactType(row))
.setPhotoId(row.numberAttributes().getPhotoId());
diff --git a/java/com/android/dialer/calllogutils/CallLogContactTypes.java b/java/com/android/dialer/calllogutils/CallLogContactTypes.java
index 01ae653..5865156 100644
--- a/java/com/android/dialer/calllogutils/CallLogContactTypes.java
+++ b/java/com/android/dialer/calllogutils/CallLogContactTypes.java
@@ -29,7 +29,7 @@
boolean isVoicemail = false;
boolean isSpam = false;
boolean isBusiness = false;
- int numberPresentation = 0;
+ int numberPresentation = row.numberPresentation();
boolean isConference = false;
return LetterTileDrawable.getContactTypeFromPrimitives(
diff --git a/java/com/android/dialer/calllogutils/CallLogEntryText.java b/java/com/android/dialer/calllogutils/CallLogEntryText.java
index aa45a69..49f5e42 100644
--- a/java/com/android/dialer/calllogutils/CallLogEntryText.java
+++ b/java/com/android/dialer/calllogutils/CallLogEntryText.java
@@ -21,6 +21,7 @@
import android.text.TextUtils;
import com.android.dialer.calllog.model.CoalescedRow;
import com.android.dialer.time.Clock;
+import com.google.common.base.Optional;
import com.google.common.collect.Collections2;
import java.util.ArrayList;
import java.util.List;
@@ -40,16 +41,25 @@
* following the primary text.)
*/
public static CharSequence buildPrimaryText(Context context, CoalescedRow row) {
- StringBuilder primaryText = new StringBuilder();
- if (!TextUtils.isEmpty(row.numberAttributes().getName())) {
- primaryText.append(row.numberAttributes().getName());
- } else if (!TextUtils.isEmpty(row.formattedNumber())) {
- primaryText.append(row.formattedNumber());
- } else {
- // TODO(zachh): Handle CallLog.Calls.PRESENTATION_*, including Verizon restricted numbers.
- primaryText.append(context.getText(R.string.new_call_log_unknown));
+ // Always prefer the presentation name, like "Restricted".
+ Optional<String> presentationName =
+ PhoneNumberDisplayUtil.getNameForPresentation(context, row.numberPresentation());
+ if (presentationName.isPresent()) {
+ return presentationName.get();
}
- return primaryText.toString();
+
+ // Otherwise prefer the name.
+ if (!TextUtils.isEmpty(row.numberAttributes().getName())) {
+ return row.numberAttributes().getName();
+ }
+
+ // Otherwise prefer the formatted number.
+ if (!TextUtils.isEmpty(row.formattedNumber())) {
+ return row.formattedNumber();
+ }
+
+ // If there's no formatted number, just return "Unknown".
+ return context.getText(R.string.new_call_log_unknown);
}
/**
@@ -112,6 +122,14 @@
components.add(getNumberTypeLabel(context, row));
+ // If there's a presentation name, we showed it in the primary text and shouldn't show any name
+ // or number here.
+ Optional<String> presentationName =
+ PhoneNumberDisplayUtil.getNameForPresentation(context, row.numberPresentation());
+ if (presentationName.isPresent()) {
+ return joinSecondaryTextComponents(components);
+ }
+
if (TextUtils.isEmpty(row.numberAttributes().getName())) {
// If the name is empty the number is shown as the primary text and there's nothing to add.
return joinSecondaryTextComponents(components);
diff --git a/java/com/android/dialer/calllogutils/CallLogIntents.java b/java/com/android/dialer/calllogutils/CallLogIntents.java
index b06fe6e..227b15e 100644
--- a/java/com/android/dialer/calllogutils/CallLogIntents.java
+++ b/java/com/android/dialer/calllogutils/CallLogIntents.java
@@ -19,11 +19,12 @@
import android.content.Intent;
import android.provider.CallLog.Calls;
import android.support.annotation.Nullable;
-import android.text.TextUtils;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.calllog.model.CoalescedRow;
+import com.android.dialer.phonenumberutil.PhoneNumberHelper;
import com.android.dialer.precall.PreCall;
+import com.android.dialer.telecom.TelecomUtil;
/** Provides intents related to call log entries. */
public final class CallLogIntents {
@@ -38,20 +39,19 @@
*/
@Nullable
public static Intent getCallBackIntent(Context context, CoalescedRow row) {
- // TODO(zachh): Do something with parsed values to make more dialable?
- String originalNumber = row.number().getRawInput().getNumber();
- // TODO(zachh): Make this more sophisticated, e.g. return null for non-dialable numbers?
- if (TextUtils.isEmpty(originalNumber)) {
+ // TODO(zachh): Don't use raw input.
+ String normalizedNumber = row.number().getRawInput().getNumber();
+ if (!PhoneNumberHelper.canPlaceCallsTo(normalizedNumber, row.numberPresentation())) {
return null;
}
// TODO(zachh): More granular logging?
- // TODO(zachh): Support assisted dialing.
return PreCall.getIntent(
context,
- new CallIntentBuilder(originalNumber, CallInitiationType.Type.CALL_LOG)
+ new CallIntentBuilder(normalizedNumber, CallInitiationType.Type.CALL_LOG)
.setPhoneAccountHandle(
- PhoneAccountUtils.getAccount(row.phoneAccountComponentName(), row.phoneAccountId()))
+ TelecomUtil.composePhoneAccountHandle(
+ row.phoneAccountComponentName(), row.phoneAccountId()))
.setIsVideoCall((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO));
}
}
diff --git a/java/com/android/dialer/calllogutils/PhoneAccountUtils.java b/java/com/android/dialer/calllogutils/PhoneAccountUtils.java
index 153f291..2ee50a1 100644
--- a/java/com/android/dialer/calllogutils/PhoneAccountUtils.java
+++ b/java/com/android/dialer/calllogutils/PhoneAccountUtils.java
@@ -16,47 +16,15 @@
package com.android.dialer.calllogutils;
-import android.content.ComponentName;
import android.content.Context;
import android.support.annotation.Nullable;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
-import android.text.TextUtils;
import com.android.dialer.telecom.TelecomUtil;
-import java.util.ArrayList;
-import java.util.List;
/** Methods to help extract {@code PhoneAccount} information from database and Telecomm sources. */
public class PhoneAccountUtils {
- /** Return a list of phone accounts that are subscription/SIM accounts. */
- public static List<PhoneAccountHandle> getSubscriptionPhoneAccounts(Context context) {
- List<PhoneAccountHandle> subscriptionAccountHandles = new ArrayList<>();
- final List<PhoneAccountHandle> accountHandles =
- TelecomUtil.getCallCapablePhoneAccounts(context);
- for (PhoneAccountHandle accountHandle : accountHandles) {
- PhoneAccount account = TelecomUtil.getPhoneAccount(context, accountHandle);
- if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
- subscriptionAccountHandles.add(accountHandle);
- }
- }
- return subscriptionAccountHandles;
- }
-
- /** Compose PhoneAccount object from component name and account id. */
- @Nullable
- public static PhoneAccountHandle getAccount(
- @Nullable String componentString, @Nullable String accountId) {
- if (TextUtils.isEmpty(componentString) || TextUtils.isEmpty(accountId)) {
- return null;
- }
- final ComponentName componentName = ComponentName.unflattenFromString(componentString);
- if (componentName == null) {
- return null;
- }
- return new PhoneAccountHandle(componentName, accountId);
- }
-
/** Extract account label from PhoneAccount object. */
@Nullable
public static String getAccountLabel(
diff --git a/java/com/android/dialer/calllogutils/PhoneNumberDisplayUtil.java b/java/com/android/dialer/calllogutils/PhoneNumberDisplayUtil.java
index 9bebfac..f0f6963 100644
--- a/java/com/android/dialer/calllogutils/PhoneNumberDisplayUtil.java
+++ b/java/com/android/dialer/calllogutils/PhoneNumberDisplayUtil.java
@@ -23,6 +23,7 @@
import android.text.TextUtils;
import com.android.contacts.common.compat.PhoneNumberUtilsCompat;
import com.android.dialer.phonenumberutil.PhoneNumberHelper;
+import com.google.common.base.Optional;
/** Helper for formatting and managing the display of phone numbers. */
public class PhoneNumberDisplayUtil {
@@ -30,14 +31,9 @@
/** Returns the string to display for the given phone number if there is no matching contact. */
public static CharSequence getDisplayName(
Context context, CharSequence number, int presentation, boolean isVoicemail) {
- if (presentation == Calls.PRESENTATION_UNKNOWN) {
- return context.getResources().getString(R.string.unknown);
- }
- if (presentation == Calls.PRESENTATION_RESTRICTED) {
- return PhoneNumberHelper.getDisplayNameForRestrictedNumber(context);
- }
- if (presentation == Calls.PRESENTATION_PAYPHONE) {
- return context.getResources().getString(R.string.payphone);
+ Optional<String> presentationString = getNameForPresentation(context, presentation);
+ if (presentationString.isPresent()) {
+ return presentationString.get();
}
if (isVoicemail) {
return context.getResources().getString(R.string.voicemail_string);
@@ -48,13 +44,27 @@
return "";
}
+ /** Returns the string associated with the given presentation. */
+ public static Optional<String> getNameForPresentation(Context appContext, int presentation) {
+ if (presentation == Calls.PRESENTATION_UNKNOWN) {
+ return Optional.of(appContext.getResources().getString(R.string.unknown));
+ }
+ if (presentation == Calls.PRESENTATION_RESTRICTED) {
+ return Optional.of(PhoneNumberHelper.getDisplayNameForRestrictedNumber(appContext));
+ }
+ if (presentation == Calls.PRESENTATION_PAYPHONE) {
+ return Optional.of(appContext.getResources().getString(R.string.payphone));
+ }
+ return Optional.absent();
+ }
+
/**
* Returns the string to display for the given phone number.
*
* @param number the number to display
* @param formattedNumber the formatted number if available, may be null
*/
- public static CharSequence getDisplayNumber(
+ static CharSequence getDisplayNumber(
Context context,
CharSequence number,
int presentation,
diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java
index 9cee7bc..6b8401e 100644
--- a/java/com/android/dialer/dialpadview/DialpadFragment.java
+++ b/java/com/android/dialer/dialpadview/DialpadFragment.java
@@ -77,7 +77,6 @@
import com.android.dialer.animation.AnimUtils;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
-import com.android.dialer.calllogutils.PhoneAccountUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.common.FragmentUtils;
import com.android.dialer.common.LogUtil;
@@ -967,7 +966,7 @@
removePreviousDigitIfPossible('1');
List<PhoneAccountHandle> subscriptionAccountHandles =
- PhoneAccountUtils.getSubscriptionPhoneAccounts(getActivity());
+ TelecomUtil.getSubscriptionPhoneAccounts(getActivity());
boolean hasUserSelectedDefault =
subscriptionAccountHandles.contains(
TelecomUtil.getDefaultOutgoingPhoneAccount(
diff --git a/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
index 7689255..2e4caa9 100644
--- a/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
+++ b/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
@@ -44,7 +44,6 @@
import com.android.contacts.common.util.ContactDisplayUtils;
import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment;
import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener;
-import com.android.dialer.calllogutils.PhoneAccountUtils;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.compat.telephony.TelephonyManagerCompat;
@@ -215,7 +214,7 @@
sc.progressDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
List<PhoneAccountHandle> subscriptionAccountHandles =
- PhoneAccountUtils.getSubscriptionPhoneAccounts(context);
+ TelecomUtil.getSubscriptionPhoneAccounts(context);
Context applicationContext = context.getApplicationContext();
boolean hasUserSelectedDefault =
subscriptionAccountHandles.contains(
@@ -272,7 +271,7 @@
static boolean handlePinEntry(final Context context, final String input) {
if ((input.startsWith("**04") || input.startsWith("**05")) && input.endsWith("#")) {
List<PhoneAccountHandle> subscriptionAccountHandles =
- PhoneAccountUtils.getSubscriptionPhoneAccounts(context);
+ TelecomUtil.getSubscriptionPhoneAccounts(context);
boolean hasUserSelectedDefault =
subscriptionAccountHandles.contains(
TelecomUtil.getDefaultOutgoingPhoneAccount(context, PhoneAccount.SCHEME_TEL));
diff --git a/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java
index 4e7d300..841524b 100644
--- a/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java
+++ b/java/com/android/dialer/phonenumberproto/DialerPhoneNumberUtil.java
@@ -181,6 +181,7 @@
@WorkerThread
public String normalizeNumber(DialerPhoneNumber number) {
Assert.isWorkerThread();
+ // TODO(zachh): This loses country info when number is not valid.
return formatToValidE164(number)
.or(PhoneNumberUtils.normalizeNumber(number.getRawInput().getNumber()));
}
diff --git a/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java b/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java
index 12e1469..b58739d 100644
--- a/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java
+++ b/java/com/android/dialer/phonenumberutil/PhoneNumberHelper.java
@@ -341,7 +341,7 @@
* PRESENTATION_RESTRICTED. For Verizon we want this to be displayed as "Restricted". For all
* other carriers we want this to be be displayed as "Private number".
*/
- public static CharSequence getDisplayNameForRestrictedNumber(Context context) {
+ public static String getDisplayNameForRestrictedNumber(Context context) {
if (isVerizon(context)) {
return context.getString(R.string.private_num_verizon);
} else {
diff --git a/java/com/android/dialer/precall/impl/AssistedDialAction.java b/java/com/android/dialer/precall/impl/AssistedDialAction.java
index 8d2b176..15a889e 100644
--- a/java/com/android/dialer/precall/impl/AssistedDialAction.java
+++ b/java/com/android/dialer/precall/impl/AssistedDialAction.java
@@ -79,6 +79,7 @@
.putBundle(TelephonyManagerCompat.ASSISTED_DIALING_EXTRAS, assistedDialingExtras);
builder.setUri(
CallUtil.getCallUri(Assert.isNotNull(transformedNumber.get().transformedNumber())));
+ LogUtil.i("AssistedDialAction.runWithoutUi", "assisted dialing was used.");
}
}
diff --git a/java/com/android/dialer/precall/impl/CallingAccountSelector.java b/java/com/android/dialer/precall/impl/CallingAccountSelector.java
index 9397d18..d5ee0f2 100644
--- a/java/com/android/dialer/precall/impl/CallingAccountSelector.java
+++ b/java/com/android/dialer/precall/impl/CallingAccountSelector.java
@@ -56,6 +56,7 @@
import com.android.dialer.precall.PreCallAction;
import com.android.dialer.precall.PreCallCoordinator;
import com.android.dialer.precall.PreCallCoordinator.PendingAction;
+import com.android.dialer.preferredsim.PreferredAccountUtil;
import com.android.dialer.preferredsim.PreferredSimFallbackContract;
import com.android.dialer.preferredsim.PreferredSimFallbackContract.PreferredSim;
import com.android.dialer.preferredsim.suggestion.SimSuggestionComponent;
@@ -483,7 +484,8 @@
if (number != null) {
DialerExecutorComponent.get(coordinator.getActivity())
.dialerExecutorFactory()
- .createNonUiTaskBuilder(new UserSelectionReporter(selectedAccountHandle, number))
+ .createNonUiTaskBuilder(
+ new UserSelectionReporter(selectedAccountHandle, number, setDefault))
.build()
.executeParallel(coordinator.getActivity());
}
@@ -505,11 +507,13 @@
private final String number;
private final PhoneAccountHandle phoneAccountHandle;
+ private final boolean remember;
public UserSelectionReporter(
- @NonNull PhoneAccountHandle phoneAccountHandle, @Nullable String number) {
+ @NonNull PhoneAccountHandle phoneAccountHandle, @Nullable String number, boolean remember) {
this.phoneAccountHandle = Assert.isNotNull(phoneAccountHandle);
this.number = Assert.isNotNull(number);
+ this.remember = remember;
}
@Nullable
@@ -517,7 +521,7 @@
public Void doInBackground(@NonNull Context context) throws Throwable {
SimSuggestionComponent.get(context)
.getSuggestionProvider()
- .reportUserSelection(context, number, phoneAccountHandle);
+ .reportUserSelection(context, number, phoneAccountHandle, remember);
return null;
}
}
diff --git a/java/com/android/dialer/precall/impl/PreferredAccountUtil.java b/java/com/android/dialer/preferredsim/PreferredAccountUtil.java
similarity index 97%
rename from java/com/android/dialer/precall/impl/PreferredAccountUtil.java
rename to java/com/android/dialer/preferredsim/PreferredAccountUtil.java
index 6505888..1cfdbb1 100644
--- a/java/com/android/dialer/precall/impl/PreferredAccountUtil.java
+++ b/java/com/android/dialer/preferredsim/PreferredAccountUtil.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.dialer.precall.impl;
+package com.android.dialer.preferredsim;
import android.content.ComponentName;
import android.content.Context;
@@ -64,7 +64,7 @@
return Optional.absent();
}
- private static boolean isPhoneAccountValid(
+ public static boolean isPhoneAccountValid(
Context context, PhoneAccountHandle phoneAccountHandle) {
if (VERSION.SDK_INT >= VERSION_CODES.O) {
return context
diff --git a/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java b/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java
index c1114b3..bb50889 100644
--- a/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java
+++ b/java/com/android/dialer/preferredsim/suggestion/SuggestionProvider.java
@@ -62,8 +62,10 @@
void reportUserSelection(
@NonNull Context context,
@NonNull String number,
- @NonNull PhoneAccountHandle phoneAccountHandle);
+ @NonNull PhoneAccountHandle phoneAccountHandle,
+ boolean rememberSelection);
@WorkerThread
- void reportIncorrectSuggestion(@NonNull Context context, @NonNull String number);
+ void reportIncorrectSuggestion(
+ @NonNull Context context, @NonNull String number, @NonNull PhoneAccountHandle newAccount);
}
diff --git a/java/com/android/dialer/preferredsim/suggestion/stub/StubSuggestionProvider.java b/java/com/android/dialer/preferredsim/suggestion/stub/StubSuggestionProvider.java
index 6fb73ac..bd54ddb 100644
--- a/java/com/android/dialer/preferredsim/suggestion/stub/StubSuggestionProvider.java
+++ b/java/com/android/dialer/preferredsim/suggestion/stub/StubSuggestionProvider.java
@@ -40,8 +40,10 @@
public void reportUserSelection(
@NonNull Context context,
@NonNull String number,
- @NonNull PhoneAccountHandle phoneAccountHandle) {}
+ @NonNull PhoneAccountHandle phoneAccountHandle,
+ boolean rememberSelection) {}
@Override
- public void reportIncorrectSuggestion(@NonNull Context context, @NonNull String number) {}
+ public void reportIncorrectSuggestion(
+ @NonNull Context context, @NonNull String number, PhoneAccountHandle newAccount) {}
}
diff --git a/java/com/android/dialer/simulator/Simulator.java b/java/com/android/dialer/simulator/Simulator.java
index 3931ae4..3c2526b 100644
--- a/java/com/android/dialer/simulator/Simulator.java
+++ b/java/com/android/dialer/simulator/Simulator.java
@@ -63,11 +63,24 @@
@StringDef({
IS_VOLTE,
PRESENTATION_CHOICE,
+ IS_ENRICHED_CALL,
})
@interface BundleKey {}
public final String IS_VOLTE = "ISVOLTE";
public final String PRESENTATION_CHOICE = "PRESENTATIONCHOICE";
+ public final String IS_ENRICHED_CALL = "ISENRICHEDCALL";
+
+ /** Phone numbers for outgoing and incoming enriched call scenario. */
+ public static final String ENRICHED_CALL_OUTGOING_NUMBER = "+55-31-2128-6800";
+
+ public static final String ENRICHED_CALL_INCOMING_NUMBER = "+44 (0) 20 7031 3000";
+
+ boolean isSimulatorMode();
+
+ void enableSimulatorMode();
+
+ void disableSimulatorMode();
/** Information about a connection event. */
public static class Event {
diff --git a/java/com/android/dialer/simulator/SimulatorEnrichedCall.java b/java/com/android/dialer/simulator/SimulatorEnrichedCall.java
index f6c8a6c..ae9447b 100644
--- a/java/com/android/dialer/simulator/SimulatorEnrichedCall.java
+++ b/java/com/android/dialer/simulator/SimulatorEnrichedCall.java
@@ -16,13 +16,14 @@
package com.android.dialer.simulator;
-import com.android.dialer.enrichedcall.EnrichedCallManager.StateChangedListener;
+import com.android.dialer.enrichedcall.EnrichedCallManager;
+import com.google.common.util.concurrent.ListenableFuture;
/** Setup enriched calling environment for {@link Simulator}. */
-public interface SimulatorEnrichedCall extends StateChangedListener {
+public interface SimulatorEnrichedCall extends EnrichedCallManager.StateChangedListener {
/** Setup a session for an incoming enriched call. */
- long setupIncomingEnrichedCall(String number);
+ ListenableFuture<Void> setupIncomingEnrichedCall(String number);
/** Setup a session for outgoing enriched call. */
- long setupOutgoingEnrichedCall(String number);
+ ListenableFuture<Void> setupOutgoingEnrichedCall(String number);
}
diff --git a/java/com/android/dialer/simulator/impl/SimulatorImpl.java b/java/com/android/dialer/simulator/impl/SimulatorImpl.java
index be86763..24f3410 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorImpl.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorImpl.java
@@ -25,7 +25,9 @@
/** The entry point for the simulator feature. */
final class SimulatorImpl implements Simulator {
-
+
+ private boolean simulatorMode = false;
+
@Inject
public SimulatorImpl() {}
@@ -38,4 +40,19 @@
public ActionProvider getActionProvider(AppCompatActivity activity) {
return SimulatorMainMenu.getActionProvider(activity);
}
+
+ @Override
+ public boolean isSimulatorMode() {
+ return simulatorMode;
+ }
+
+ @Override
+ public void enableSimulatorMode() {
+ simulatorMode = true;
+ }
+
+ @Override
+ public void disableSimulatorMode() {
+ simulatorMode = false;
+ }
}
diff --git a/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java b/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java
index 174aab5..69da2f4 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorMainMenu.java
@@ -32,6 +32,7 @@
import com.android.dialer.enrichedcall.simulator.EnrichedCallSimulatorActivity;
import com.android.dialer.persistentlog.PersistentLogger;
import com.android.dialer.preferredsim.PreferredSimFallbackContract;
+import com.android.dialer.simulator.SimulatorComponent;
import com.android.incallui.rtt.impl.RttChatActivity;
import com.android.incallui.speakeasy.SpeakEasy;
import com.android.incallui.speakeasy.SpeakEasyActivity;
@@ -65,7 +66,19 @@
"Enriched call simulator",
() ->
activity.startActivity(
- EnrichedCallSimulatorActivity.newIntent(activity.getApplicationContext())));
+ EnrichedCallSimulatorActivity.newIntent(activity.getApplicationContext())))
+ .addItem(
+ "Enable simulator mode",
+ () ->
+ SimulatorComponent.get(activity.getApplicationContext())
+ .getSimulator()
+ .enableSimulatorMode())
+ .addItem(
+ "Disable simulator mode",
+ () ->
+ SimulatorComponent.get(activity.getApplicationContext())
+ .getSimulator()
+ .disableSimulatorMode());
SpeakEasy speakEasy = SpeakEasyComponent.get(activity.getApplicationContext()).speakEasy();
if (speakEasy.isEnabled()) {
simulatorSubMenu.addItem(
diff --git a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
index ff00dd8..67a2db8 100644
--- a/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
+++ b/java/com/android/dialer/simulator/impl/SimulatorVoiceCall.java
@@ -26,15 +26,21 @@
import android.view.ActionProvider;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.enrichedcall.EnrichedCallComponent;
+import com.android.dialer.enrichedcall.EnrichedCallManager;
import com.android.dialer.simulator.Simulator;
import com.android.dialer.simulator.Simulator.Event;
+import com.android.dialer.simulator.SimulatorComponent;
+import com.android.dialer.simulator.SimulatorEnrichedCall;
/** Entry point in the simulator to create voice calls. */
final class SimulatorVoiceCall
implements SimulatorConnectionService.Listener, SimulatorConnection.Listener {
@NonNull private final Context context;
@Nullable private String connectionTag;
+ private final SimulatorEnrichedCall simulatorEnrichedCall;
static ActionProvider getActionProvider(@NonNull AppCompatActivity activity) {
return new SimulatorSubMenu(activity.getApplicationContext())
@@ -55,6 +61,12 @@
new SimulatorVoiceCall(activity.getApplicationContext())
.addNewOutgoingCall(activity))
.addItem(
+ "Incoming enriched call",
+ () -> new SimulatorVoiceCall(activity.getApplicationContext()).incomingEnrichedCall())
+ .addItem(
+ "Outgoing enriched call",
+ () -> new SimulatorVoiceCall(activity.getApplicationContext()).outgoingEnrichedCall())
+ .addItem(
"Spam incoming call",
() -> new SimulatorVoiceCall(activity.getApplicationContext()).addSpamIncomingCall())
.addItem(
@@ -77,23 +89,47 @@
private SimulatorVoiceCall(@NonNull Context context) {
this.context = Assert.isNotNull(context);
+ simulatorEnrichedCall = SimulatorComponent.get(context).getSimulatorEnrichedCall();
SimulatorConnectionService.addListener(this);
SimulatorConnectionService.addListener(
new SimulatorConferenceCreator(context, Simulator.CONFERENCE_TYPE_GSM));
}
+ private void incomingEnrichedCall() {
+ simulatorEnrichedCall
+ .setupIncomingEnrichedCall(Simulator.ENRICHED_CALL_INCOMING_NUMBER)
+ .addListener(
+ () -> {
+ Bundle extras = new Bundle();
+ extras.putBoolean(Simulator.IS_ENRICHED_CALL, true);
+ connectionTag =
+ SimulatorSimCallManager.addNewIncomingCall(
+ context, Simulator.ENRICHED_CALL_INCOMING_NUMBER, false, extras);
+ },
+ DialerExecutorComponent.get(context).uiExecutor());
+ }
+
+ private void outgoingEnrichedCall() {
+ getEnrichedCallManager().registerStateChangedListener(simulatorEnrichedCall);
+ simulatorEnrichedCall
+ .setupOutgoingEnrichedCall(Simulator.ENRICHED_CALL_OUTGOING_NUMBER)
+ .addListener(
+ () -> {
+ Bundle extras = new Bundle();
+ extras.putBoolean(Simulator.IS_ENRICHED_CALL, true);
+ connectionTag =
+ SimulatorSimCallManager.addNewOutgoingCall(
+ context, Simulator.ENRICHED_CALL_OUTGOING_NUMBER, false, extras);
+ },
+ DialerExecutorComponent.get(context).uiExecutor());
+ }
+
private void addNewIncomingCall() {
String callerId = "+44 (0) 20 7031 3000" /* Google London office */;
connectionTag =
SimulatorSimCallManager.addNewIncomingCall(context, callerId, false /* isVideo */);
}
- private void addNewOutgoingCall() {
- String callerId = "+55-31-2128-6800"; // Brazil office.
- connectionTag =
- SimulatorSimCallManager.addNewOutgoingCall(context, callerId, false /* isVideo */);
- }
-
private void addNewIncomingCall(AppCompatActivity activity) {
SimulatorDialogFragment.newInstance(
(callerId, callerIdPresentation) -> {
@@ -106,6 +142,12 @@
.show(activity.getSupportFragmentManager(), "SimulatorDialog");
}
+ private void addNewOutgoingCall() {
+ String callerId = "+55-31-2128-6800"; // Brazil office.
+ connectionTag =
+ SimulatorSimCallManager.addNewOutgoingCall(context, callerId, false /* isVideo */);
+ }
+
private void addNewOutgoingCall(AppCompatActivity activity) {
SimulatorDialogFragment.newInstance(
(callerId, callerIdPresentation) -> {
@@ -184,6 +226,9 @@
break;
case Event.DISCONNECT:
connection.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
+ if (connection.getExtras().getBoolean(Simulator.IS_ENRICHED_CALL)) {
+ getEnrichedCallManager().unregisterStateChangedListener(simulatorEnrichedCall);
+ }
break;
case Event.SESSION_MODIFY_REQUEST:
ThreadUtil.postDelayedOnUiThread(() -> connection.handleSessionModifyRequest(event), 2000);
@@ -194,7 +239,8 @@
}
}
- private interface DialogCallback {
- void callback(String callerId, int callerIdPresentation);
+ @NonNull
+ private EnrichedCallManager getEnrichedCallManager() {
+ return EnrichedCallComponent.get(context).getEnrichedCallManager();
}
}
diff --git a/java/com/android/dialer/simulator/stub/SimulatorEnrichedCallStub.java b/java/com/android/dialer/simulator/stub/SimulatorEnrichedCallStub.java
index 056722f..5b07271 100644
--- a/java/com/android/dialer/simulator/stub/SimulatorEnrichedCallStub.java
+++ b/java/com/android/dialer/simulator/stub/SimulatorEnrichedCallStub.java
@@ -17,6 +17,8 @@
package com.android.dialer.simulator.stub;
import com.android.dialer.simulator.SimulatorEnrichedCall;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
import javax.inject.Inject;
/** Stub implementation of {@link SimulatorEnrichedCall}. */
@@ -26,13 +28,13 @@
public SimulatorEnrichedCallStub() {}
@Override
- public long setupIncomingEnrichedCall(String number) {
- return -1;
+ public ListenableFuture<Void> setupIncomingEnrichedCall(String number) {
+ return Futures.immediateFuture(null);
}
@Override
- public long setupOutgoingEnrichedCall(String number) {
- return -1;
+ public ListenableFuture<Void> setupOutgoingEnrichedCall(String number) {
+ return Futures.immediateFuture(null);
}
@Override
diff --git a/java/com/android/dialer/telecom/TelecomUtil.java b/java/com/android/dialer/telecom/TelecomUtil.java
index f79ca86..56349b6 100644
--- a/java/com/android/dialer/telecom/TelecomUtil.java
+++ b/java/com/android/dialer/telecom/TelecomUtil.java
@@ -18,6 +18,7 @@
import android.Manifest;
import android.Manifest.permission;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -49,6 +50,7 @@
* perform the required check and return the fallback default if the permission is missing,
* otherwise return the value from TelecomManager.
*/
+@SuppressWarnings("MissingPermission")
public abstract class TelecomUtil {
private static final String TAG = "TelecomUtil";
@@ -148,6 +150,34 @@
return new ArrayList<>();
}
+ /** Return a list of phone accounts that are subscription/SIM accounts. */
+ public static List<PhoneAccountHandle> getSubscriptionPhoneAccounts(Context context) {
+ List<PhoneAccountHandle> subscriptionAccountHandles = new ArrayList<>();
+ final List<PhoneAccountHandle> accountHandles =
+ TelecomUtil.getCallCapablePhoneAccounts(context);
+ for (PhoneAccountHandle accountHandle : accountHandles) {
+ PhoneAccount account = TelecomUtil.getPhoneAccount(context, accountHandle);
+ if (account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)) {
+ subscriptionAccountHandles.add(accountHandle);
+ }
+ }
+ return subscriptionAccountHandles;
+ }
+
+ /** Compose {@link PhoneAccountHandle} object from component name and account id. */
+ @Nullable
+ public static PhoneAccountHandle composePhoneAccountHandle(
+ @Nullable String componentString, @Nullable String accountId) {
+ if (TextUtils.isEmpty(componentString) || TextUtils.isEmpty(accountId)) {
+ return null;
+ }
+ final ComponentName componentName = ComponentName.unflattenFromString(componentString);
+ if (componentName == null) {
+ return null;
+ }
+ return new PhoneAccountHandle(componentName, accountId);
+ }
+
/**
* @return the {@link SubscriptionInfo} of the SIM if {@code phoneAccountHandle} corresponds to a
* valid SIM. Absent otherwise.
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
index 5519aa4..318f797 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
@@ -25,6 +25,7 @@
import android.net.Uri;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
@@ -43,9 +44,15 @@
import com.android.dialer.common.concurrent.ThreadUtil;
import com.android.dialer.time.Clock;
import com.android.dialer.voicemail.listui.NewVoicemailViewHolder.NewVoicemailViewHolderListener;
+import com.android.dialer.voicemail.listui.error.VoicemailErrorMessage;
+import com.android.dialer.voicemail.listui.error.VoicemailErrorMessageCreator;
+import com.android.dialer.voicemail.listui.error.VoicemailStatus;
import com.android.dialer.voicemail.model.VoicemailEntry;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
import java.util.Objects;
import java.util.Set;
@@ -66,6 +73,7 @@
}
private Cursor cursor;
+ private Cursor voicemailStatusCursor;
private final Clock clock;
/** {@link Integer#MAX_VALUE} when the "Today" header should not be displayed. */
@@ -81,6 +89,8 @@
/** A valid id for {@link VoicemailEntry} is greater than 0 */
private int currentlyExpandedViewHolderId = -1;
+ private VoicemailErrorMessage voicemailErrorMessage;
+
/**
* It takes time to delete voicemails from the server, so we "remove" them and remember the
* positions we removed until a new cursor is ready.
@@ -248,34 +258,14 @@
if (viewHolder instanceof NewVoicemailHeaderViewHolder) {
LogUtil.i(
"NewVoicemailAdapter.onBindViewHolder", "view holder at pos:%d is a header", position);
- NewVoicemailHeaderViewHolder headerViewHolder = (NewVoicemailHeaderViewHolder) viewHolder;
- @RowType int viewType = getItemViewType(position);
- if (position == todayHeaderPosition) {
- headerViewHolder.setHeader(R.string.new_voicemail_header_today);
- } else if (position == yesterdayHeaderPosition) {
- headerViewHolder.setHeader(R.string.new_voicemail_header_yesterday);
- } else if (position == olderHeaderPosition) {
- headerViewHolder.setHeader(R.string.new_voicemail_header_older);
- } else {
- throw Assert.createIllegalStateFailException(
- "Unexpected view type " + viewType + " at position: " + position);
- }
+ onBindHeaderViewHolder(viewHolder, position);
return;
}
if (viewHolder instanceof NewVoicemailAlertViewHolder) {
LogUtil.i(
"NewVoicemailAdapter.onBindViewHolder", "view holder at pos:%d is a alert", position);
- NewVoicemailAlertViewHolder alertViewHolder = (NewVoicemailAlertViewHolder) viewHolder;
- @RowType int viewType = getItemViewType(position);
- Assert.checkArgument(position == 0);
- if (position == voicemailAlertPosition) {
- // TODO(a bug): Update this with the alert messages
- alertViewHolder.setHeader("Temporary placeholder, update this with the alert messages");
- } else {
- throw Assert.createIllegalStateFailException(
- "Unexpected view type " + viewType + " at position: " + position);
- }
+ onBindAlertViewHolder(viewHolder, position);
return;
}
@@ -285,26 +275,13 @@
position);
NewVoicemailViewHolder newVoicemailViewHolder = (NewVoicemailViewHolder) viewHolder;
-
- int previousHeaders = 0;
- if (voicemailAlertPosition != Integer.MAX_VALUE && position > voicemailAlertPosition) {
- previousHeaders++;
- }
- if (todayHeaderPosition != Integer.MAX_VALUE && position > todayHeaderPosition) {
- previousHeaders++;
- }
- if (yesterdayHeaderPosition != Integer.MAX_VALUE && position > yesterdayHeaderPosition) {
- previousHeaders++;
- }
- if (olderHeaderPosition != Integer.MAX_VALUE && position > olderHeaderPosition) {
- previousHeaders++;
- }
+ int nonVoicemailEntryHeaders = getHeaderCountAtPosition(position);
LogUtil.i(
"NewVoicemailAdapter.onBindViewHolder",
- "view holder at pos:%d, prevHeaderCount:%d",
+ "view holder at pos:%d, nonVoicemailEntryHeaders:%d",
position,
- previousHeaders);
+ nonVoicemailEntryHeaders);
// Remove if the viewholder is being recycled.
if (newVoicemailViewHolderArrayMap.containsKey(newVoicemailViewHolder.getViewHolderId())) {
@@ -322,7 +299,7 @@
}
newVoicemailViewHolder.reset();
- cursor.moveToPosition(position - previousHeaders);
+ cursor.moveToPosition(position - nonVoicemailEntryHeaders);
newVoicemailViewHolder.bindViewHolderValuesFromAdapter(
cursor, fragmentManager, mediaPlayer, position, currentlyExpandedViewHolderId);
@@ -378,6 +355,72 @@
printArrayMap();
}
+ private int getHeaderCountAtPosition(int position) {
+ int previousHeaders = 0;
+ if (voicemailAlertPosition != Integer.MAX_VALUE && position > voicemailAlertPosition) {
+ previousHeaders++;
+ }
+ if (todayHeaderPosition != Integer.MAX_VALUE && position > todayHeaderPosition) {
+ previousHeaders++;
+ }
+ if (yesterdayHeaderPosition != Integer.MAX_VALUE && position > yesterdayHeaderPosition) {
+ previousHeaders++;
+ }
+ if (olderHeaderPosition != Integer.MAX_VALUE && position > olderHeaderPosition) {
+ previousHeaders++;
+ }
+ return previousHeaders;
+ }
+
+ private void onBindAlertViewHolder(ViewHolder viewHolder, int position) {
+ LogUtil.i(
+ "NewVoicemailAdapter.onBindAlertViewHolder",
+ "pos:%d, voicemailAlertPosition:%d",
+ position,
+ voicemailAlertPosition);
+
+ NewVoicemailAlertViewHolder alertViewHolder = (NewVoicemailAlertViewHolder) viewHolder;
+ @RowType int viewType = getItemViewType(position);
+
+ Assert.checkArgument(position == 0, "position is not 0");
+ Assert.checkArgument(
+ position == voicemailAlertPosition,
+ String.format(
+ Locale.US,
+ "position:%d and voicemailAlertPosition:%d are different",
+ position,
+ voicemailAlertPosition));
+ Assert.checkArgument(viewType == RowType.VOICEMAIL_ALERT, "Invalid row type: " + viewType);
+ Assert.checkArgument(
+ voicemailErrorMessage.getActions().size() <= 2,
+ "Too many actions: " + voicemailErrorMessage.getActions().size());
+
+ alertViewHolder.setTitle(voicemailErrorMessage.getTitle());
+ alertViewHolder.setDescription(voicemailErrorMessage.getDescription());
+
+ if (!voicemailErrorMessage.getActions().isEmpty()) {
+ alertViewHolder.setPrimaryButton(voicemailErrorMessage.getActions().get(0));
+ }
+ if (voicemailErrorMessage.getActions().size() > 1) {
+ alertViewHolder.setSecondaryButton(voicemailErrorMessage.getActions().get(1));
+ }
+ }
+
+ private void onBindHeaderViewHolder(ViewHolder viewHolder, int position) {
+ NewVoicemailHeaderViewHolder headerViewHolder = (NewVoicemailHeaderViewHolder) viewHolder;
+ @RowType int viewType = getItemViewType(position);
+ if (position == todayHeaderPosition) {
+ headerViewHolder.setHeader(R.string.new_voicemail_header_today);
+ } else if (position == yesterdayHeaderPosition) {
+ headerViewHolder.setHeader(R.string.new_voicemail_header_yesterday);
+ } else if (position == olderHeaderPosition) {
+ headerViewHolder.setHeader(R.string.new_voicemail_header_older);
+ } else {
+ throw Assert.createIllegalStateFailException(
+ "Unexpected view type " + viewType + " at position: " + position);
+ }
+ }
+
private void printArrayMap() {
LogUtil.i(
"NewVoicemailAdapter.printArrayMap",
@@ -958,4 +1001,47 @@
LogUtil.i("NewVoicemailAdapter.checkAndPlayVoicemail", "not playing downloaded voicemail");
}
}
+
+ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ public void setVoicemailStatusCursor(Cursor voicemailStatusCursor) {
+ this.voicemailStatusCursor = voicemailStatusCursor;
+ }
+
+ // TODO(uabdullah): Handle ToS properly
+ public void updateAlert(Context context) {
+ if (voicemailStatusCursor == null) {
+ LogUtil.i("NewVoicemailAdapter.updateAlert", "status cursor was null");
+ return;
+ }
+
+ LogUtil.i(
+ "NewVoicemailAdapter.updateAlert",
+ "status cursor size was " + voicemailStatusCursor.getCount());
+
+ List<VoicemailStatus> statuses = new ArrayList<>();
+
+ while (voicemailStatusCursor.moveToNext()) {
+ VoicemailStatus status = new VoicemailStatus(context, voicemailStatusCursor);
+ if (status.isActive()) {
+ statuses.add(status);
+ // TODO(uabdullah): addServiceStateListener
+ }
+ }
+
+ voicemailErrorMessage = null;
+ VoicemailErrorMessageCreator messageCreator = new VoicemailErrorMessageCreator();
+
+ for (VoicemailStatus status : statuses) {
+ voicemailErrorMessage = messageCreator.create(context, status, null);
+ if (voicemailErrorMessage != null) {
+ break;
+ }
+ }
+
+ if (voicemailErrorMessage != null) {
+ voicemailAlertPosition = 0;
+ updateHeaderPositions();
+ notifyItemChanged(0);
+ }
+ }
}
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java
index ec603b5..ac989a8 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java
@@ -18,19 +18,43 @@
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.View;
+import android.widget.Button;
import android.widget.TextView;
+import com.android.dialer.voicemail.listui.error.VoicemailErrorMessage.Action;
/** ViewHolder for {@link NewVoicemailAdapter} to display voicemail error states. */
final class NewVoicemailAlertViewHolder extends ViewHolder {
- private final TextView errorTextView;
+ private final TextView voicemailErrorTitleTextView;
+ private final TextView voicemailErrorDetailsTextView;
+ private final Button primaryButton;
+ private final Button secondaryButton;
NewVoicemailAlertViewHolder(View view) {
super(view);
- errorTextView = view.findViewById(R.id.new_voicemail_alert_text);
+ voicemailErrorTitleTextView = view.findViewById(R.id.voicemail_alert_header);
+ voicemailErrorDetailsTextView = view.findViewById(R.id.voicemail_alert_details);
+ primaryButton = view.findViewById(R.id.voicemail_alert_primary_button);
+ secondaryButton = view.findViewById(R.id.voicemail_alert_primary_button);
}
- void setHeader(String error) {
- errorTextView.setText(error);
+ void setTitle(CharSequence error) {
+ voicemailErrorTitleTextView.setText(error);
+ }
+
+ void setDescription(CharSequence error) {
+ voicemailErrorDetailsTextView.setText(error);
+ }
+
+ void setPrimaryButton(Action action) {
+ primaryButton.setVisibility(View.VISIBLE);
+ primaryButton.setText(action.getText());
+ primaryButton.setOnClickListener(action.getListener());
+ }
+
+ void setSecondaryButton(Action action) {
+ secondaryButton.setVisibility(View.VISIBLE);
+ secondaryButton.setText(action.getText());
+ secondaryButton.setOnClickListener(action.getListener());
}
}
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
index b4be424..0d91f01 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
@@ -28,11 +28,15 @@
import android.view.View;
import android.view.ViewGroup;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.database.CallLogQueryHandler;
+import com.android.dialer.database.CallLogQueryHandler.Listener;
+// TODO(uabdullah): Register content observer for VoicemailContract.Status.CONTENT_URI in onStart
/** Fragment for Dialer Voicemail Tab. */
public final class NewVoicemailFragment extends Fragment implements LoaderCallbacks<Cursor> {
private RecyclerView recyclerView;
+ private CallLogQueryHandler callLogQueryHandler;
@Nullable
@Override
@@ -72,6 +76,31 @@
((NewVoicemailAdapter) recyclerView.getAdapter()).updateCursor(data);
((NewVoicemailAdapter) recyclerView.getAdapter()).checkAndPlayVoicemail();
}
+ callLogQueryHandler =
+ new CallLogQueryHandler(
+ getContext(), getContext().getContentResolver(), new NewVoicemailFragmentListener());
+ callLogQueryHandler.fetchVoicemailStatus();
+ }
+
+ private final class NewVoicemailFragmentListener implements Listener {
+
+ @Override
+ public void onVoicemailStatusFetched(Cursor statusCursor) {
+ LogUtil.enterBlock("NewVoicemailFragmentListener.onVoicemailStatusFetched");
+ ((NewVoicemailAdapter) recyclerView.getAdapter()).setVoicemailStatusCursor(statusCursor);
+ ((NewVoicemailAdapter) recyclerView.getAdapter()).updateAlert(getContext());
+ }
+
+ @Override
+ public void onVoicemailUnreadCountFetched(Cursor cursor) {}
+
+ @Override
+ public void onMissedCallsUnreadCountFetched(Cursor cursor) {}
+
+ @Override
+ public boolean onCallsFetched(Cursor combinedCursor) {
+ return false;
+ }
}
@Override
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayer.java b/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayer.java
index 48062a8..519a0df 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayer.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayer.java
@@ -26,6 +26,7 @@
import android.support.annotation.Nullable;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
+import com.android.dialer.strictmode.StrictModeUtils;
import java.io.IOException;
/** A wrapper around {@link MediaPlayer} */
@@ -45,6 +46,7 @@
mediaPlayer = Assert.isNotNull(player);
}
+ // TODO(uabdullah): Consider removing the StrictModeUtils.bypass (a bug)
public void prepareMediaPlayerAndPlayVoicemailWhenReady(Context context, Uri uri)
throws IOException {
Assert.checkArgument(uri != null, "Media player cannot play a null uri");
@@ -57,9 +59,23 @@
voicemailUriLastPreparedOrPreparingToPlay = uri;
verifyListenersNotNull();
LogUtil.i("NewVoicemailMediaPlayer", "setData source");
- mediaPlayer.setDataSource(context, uri);
+ StrictModeUtils.bypass(
+ () -> {
+ try {
+ mediaPlayer.setDataSource(context, uri);
+ } catch (IOException e) {
+ LogUtil.i(
+ "NewVoicemailMediaPlayer",
+ "threw an Exception when setting datasource "
+ + e
+ + " for uri: "
+ + uri
+ + "for context : "
+ + context);
+ }
+ });
LogUtil.i("NewVoicemailMediaPlayer", "prepare async");
- mediaPlayer.prepareAsync();
+ StrictModeUtils.bypass(() -> mediaPlayer.prepareAsync());
} catch (IllegalStateException e) {
LogUtil.i(
"NewVoicemailMediaPlayer", "caught an IllegalStateException state exception : \n" + e);
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java b/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java
index 66a6fea..3becd27 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailMediaPlayerView.java
@@ -17,16 +17,17 @@
package com.android.dialer.voicemail.listui;
import android.app.FragmentManager;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
+import android.media.AudioManager;
import android.net.Uri;
import android.provider.VoicemailContract;
import android.provider.VoicemailContract.Voicemails;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pair;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -35,12 +36,15 @@
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
+import com.android.dialer.callintent.CallInitiationType.Type;
+import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener;
import com.android.dialer.common.concurrent.DialerExecutor.Worker;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
+import com.android.dialer.precall.PreCall;
import com.android.dialer.voicemail.listui.NewVoicemailViewHolder.NewVoicemailViewHolderListener;
import com.android.dialer.voicemail.model.VoicemailEntry;
import java.util.Locale;
@@ -60,6 +64,7 @@
private TextView totalDurationView;
private TextView voicemailLoadingStatusView;
private Uri voicemailUri;
+ private String numberVoicemailFrom;
private FragmentManager fragmentManager;
private NewVoicemailViewHolder newVoicemailViewHolder;
private NewVoicemailMediaPlayer mediaPlayer;
@@ -103,9 +108,12 @@
}
public void reset() {
- LogUtil.i("NewVoicemailMediaPlayer.reset", "the uri for this is " + voicemailUri);
+ LogUtil.i(
+ "NewVoicemailMediaPlayer.reset",
+ "the uri for this is " + voicemailUri + " and number is " + numberVoicemailFrom);
voicemailUri = null;
voicemailLoadingStatusView.setVisibility(GONE);
+ numberVoicemailFrom = null;
}
/**
@@ -134,6 +142,7 @@
Assert.isNotNull(voicemailEntryFromAdapter);
Uri uri = Uri.parse(voicemailEntryFromAdapter.voicemailUri());
+ numberVoicemailFrom = voicemailEntryFromAdapter.number().getRawInput().getNumber();
Assert.isNotNull(viewHolder);
Assert.isNotNull(uri);
Assert.isNotNull(listener);
@@ -452,31 +461,40 @@
"NewVoicemailMediaPlayer.speakerButtonListener",
"speaker request for voicemailUri: %s",
voicemailUri.toString());
+ AudioManager audioManager =
+ (AudioManager) getContext().getSystemService(AudioManager.class);
+ audioManager.setMode(AudioManager.STREAM_MUSIC);
+ if (audioManager.isSpeakerphoneOn()) {
+ LogUtil.i(
+ "NewVoicemailMediaPlayer.phoneButtonListener", "speaker was on, turning it off");
+ audioManager.setSpeakerphoneOn(false);
+ } else {
+ LogUtil.i(
+ "NewVoicemailMediaPlayer.phoneButtonListener", "speaker was off, turning it on");
+ audioManager.setSpeakerphoneOn(true);
+ }
+ // TODO(uabdullah): Handle colors of speaker icon when speaker is on and off.
}
};
+ // TODO(uabdullah): Add phone account handle (a bug)
+ // TODO(uabdullah): If the call cannot be made then the phone icon should be greyed out
+ // (a bug)
private final View.OnClickListener phoneButtonListener =
new View.OnClickListener() {
@Override
public void onClick(View view) {
LogUtil.i(
"NewVoicemailMediaPlayer.phoneButtonListener",
- "speaker request for voicemailUri: %s",
- voicemailUri.toString());
- ContentValues contentValues = new ContentValues();
- contentValues.put("has_content", 0);
- // TODO(uabdullah): It only sets the has_content to 0, to allow the annotated call log to
- // change, and refresh the fragment. This is used to demo and test the downloading of
- // voicemails from the server. This will be removed once we implement this listener.
- try {
- getContext().getContentResolver().update(voicemailUri, contentValues, "type = 4", null);
- } catch (Exception e) {
- LogUtil.i(
- "NewVoicemailMediaPlayer.deleteButtonListener",
- "update has content of voicemailUri %s caused an error: %s",
- voicemailUri.toString(),
- e.toString());
- }
+ "phone request for voicemailUri: %s with number:%s",
+ voicemailUri.toString(),
+ numberVoicemailFrom);
+
+ Assert.checkArgument(
+ !TextUtils.isEmpty(numberVoicemailFrom),
+ "number cannot be empty:" + numberVoicemailFrom);
+ PreCall.start(
+ getContext(), new CallIntentBuilder(numberVoicemailFrom, Type.VOICEMAIL_LOG));
}
};
diff --git a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml
index e8dcd02..28d6391 100644
--- a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml
+++ b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml
@@ -14,17 +14,96 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<RelativeLayout
+
+<!-- TODO(uabdullah): Use a relative layout instead of nested linear layouts.-->
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="48dp"
+ android:id="@+id/voicemail_alert_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <!-- TODO(uabdullah): Confirm with UX on mocks -->
- <TextView
- android:id="@+id/new_voicemail_alert_text"
- style="@style/SecondaryText"
- android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/voicemail_header_margin_start"
- android:layout_centerVertical="true"/>
-</RelativeLayout>
+ android:paddingTop="@dimen/alert_main_padding"
+ android:paddingBottom="@dimen/alert_main_padding"
+ android:paddingStart="@dimen/alert_main_padding"
+ android:paddingEnd="@dimen/alert_main_padding"
+ android:gravity="top"
+ android:orientation="horizontal">
+
+ <ImageView
+ android:id="@+id/voicemail_alert_icon"
+ android:layout_width="@dimen/voicemail_promo_card_icon_size"
+ android:layout_height="@dimen/voicemail_promo_card_icon_size"
+ android:layout_gravity="top"
+ android:src="@drawable/ic_voicemail_error_24px"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/voicemail_promo_card_main_padding"
+ android:gravity="center_vertical"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/voicemail_alert_header"
+ android:textStyle="bold"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/voicemail_promo_card_title_padding"
+ android:layout_gravity="center_vertical"
+ android:singleLine="false"
+ android:text="Voicemail Alert"
+ android:textSize="@dimen/voicemail_promo_card_title_text_size"/>
+
+ <TextView
+ android:id="@+id/voicemail_alert_details"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:lineSpacingExtra="@dimen/voicemail_promo_card_line_spacing"
+ android:singleLine="false"
+ android:text="This is a voicemail alert message."
+ android:textSize="@dimen/voicemail_promo_card_message_size"/>
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/voicemail_alert_button"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="end"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp"
+ android:gravity="end"
+ android:minHeight="56dp"
+ android:orientation="horizontal">
+ <Button
+ android:id="@+id/voicemail_alert_secondary_button"
+ style="@style/TosButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/dialer_theme_color"/>
+
+ <Button
+ android:id="@+id/voicemail_alert_primary_button"
+ style="@style/TosButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/dialer_theme_color"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:layout_gravity="center"
+ android:divider="?android:dividerHorizontal"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:showDividers="middle">
+ </LinearLayout>
+</LinearLayout>
diff --git a/java/com/android/dialer/voicemail/listui/res/values/dimens.xml b/java/com/android/dialer/voicemail/listui/res/values/dimens.xml
index 59da7f2..960d327 100644
--- a/java/com/android/dialer/voicemail/listui/res/values/dimens.xml
+++ b/java/com/android/dialer/voicemail/listui/res/values/dimens.xml
@@ -41,4 +41,13 @@
<dimen name="voicemail_tos_image_size">280dp</dimen>
+ <!-- Dimensions for voicemail alert -->
+ <dimen name="alert_main_padding">24dp</dimen>
+ <dimen name="voicemail_promo_card_icon_size">24dp</dimen>
+ <dimen name="voicemail_promo_card_main_padding">24dp</dimen>
+ <dimen name="voicemail_promo_card_title_padding">12dp</dimen>
+ <dimen name="voicemail_promo_card_title_text_size">16sp</dimen>
+ <dimen name="voicemail_promo_card_line_spacing">4dp</dimen>
+ <dimen name="voicemail_promo_card_message_size">14sp</dimen>
+
</resources>
diff --git a/java/com/android/incallui/ContactInfoCache.java b/java/com/android/incallui/ContactInfoCache.java
index fbee743..fc41df4 100644
--- a/java/com/android/incallui/ContactInfoCache.java
+++ b/java/com/android/incallui/ContactInfoCache.java
@@ -291,7 +291,7 @@
return name;
} else {
if (presentation == TelecomManager.PRESENTATION_RESTRICTED) {
- name = PhoneNumberHelper.getDisplayNameForRestrictedNumber(context).toString();
+ name = PhoneNumberHelper.getDisplayNameForRestrictedNumber(context);
} else if (presentation == TelecomManager.PRESENTATION_PAYPHONE) {
name = context.getString(R.string.payphone);
}
diff --git a/java/com/android/incallui/multisim/SwapSimWorker.java b/java/com/android/incallui/multisim/SwapSimWorker.java
index 28cf293..1014d82 100644
--- a/java/com/android/incallui/multisim/SwapSimWorker.java
+++ b/java/com/android/incallui/multisim/SwapSimWorker.java
@@ -102,7 +102,7 @@
try {
SimSuggestionComponent.get(context)
.getSuggestionProvider()
- .reportIncorrectSuggestion(context, number);
+ .reportIncorrectSuggestion(context, number, otherAccount);
if (!PermissionsUtil.hasPhonePermissions(context)) {
LogUtil.e("SwapSimWorker.doInBackground", "missing phone permission");
diff --git a/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java b/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java
index 60ba166..c0ab678 100644
--- a/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java
+++ b/java/com/android/voicemail/impl/sync/VvmNetworkRequestCallback.java
@@ -56,6 +56,7 @@
private final VoicemailStatus.Editor status;
private boolean requestSent = false;
private boolean resultReceived = false;
+ private boolean released = false;
public VvmNetworkRequestCallback(
Context context, PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) {
@@ -112,7 +113,7 @@
@Override
@CallSuper
public void onLost(Network network) {
- VvmLog.d(TAG, "onLost");
+ VvmLog.i(TAG, "onLost");
resultReceived = true;
onFailed(NETWORK_REQUEST_FAILED_LOST);
}
@@ -126,7 +127,7 @@
@CallSuper
public void onUnavailable() {
- // TODO(twyen): a bug this is hidden, do we really need this?
+ VvmLog.i(TAG, "onUnavailable");
resultReceived = true;
onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
}
@@ -156,8 +157,13 @@
}
public void releaseNetwork() {
- VvmLog.d(TAG, "releaseNetwork");
- getConnectivityManager().unregisterNetworkCallback(this);
+ VvmLog.i(TAG, "releaseNetwork");
+ if (!released) {
+ getConnectivityManager().unregisterNetworkCallback(this);
+ released = true;
+ } else {
+ VvmLog.w(TAG, "already released");
+ }
}
public ConnectivityManager getConnectivityManager() {
@@ -170,7 +176,7 @@
@CallSuper
public void onFailed(String reason) {
- VvmLog.d(TAG, "onFailed: " + reason);
+ VvmLog.i(TAG, "onFailed: " + reason);
if (carrierConfigHelper.isCellularDataRequired()) {
carrierConfigHelper.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
} else {