summaryrefslogtreecommitdiff
path: root/java/com
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-01-12 02:48:25 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-01-12 02:48:25 +0000
commit6bd659e6e90346f58ed08f6c127835a320bbd2e4 (patch)
treeb90e5f582dcab0d3ad6393f4ffbc7a4dd78e81dc /java/com
parent58bade2ace277dff4db3bbbfa2e07015f0f7c6ad (diff)
parent01aac5de58903555a089d16a58b9346d34d54e7b (diff)
Merge changes I2e091371,I4e0bc1c6,I24063ee4
* changes: Implement PhoneLookup for CP2 remote contacts Merge PhoneLookupDataSource results into a proto in annotated call log. Attempt to place call even call permission is missing
Diffstat (limited to 'java/com')
-rw-r--r--java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java10
-rw-r--r--java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java80
-rw-r--r--java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java36
-rw-r--r--java/com/android/dialer/calllog/model/CoalescedRow.java47
-rw-r--r--java/com/android/dialer/calllog/model/number_attributes.proto61
-rw-r--r--java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java52
-rw-r--r--java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java12
-rw-r--r--java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java20
-rw-r--r--java/com/android/dialer/calllog/ui/menu/Modules.java28
-rw-r--r--java/com/android/dialer/calllog/ui/menu/PrimaryAction.java6
-rw-r--r--java/com/android/dialer/calllogutils/CallLogEntryText.java8
-rw-r--r--java/com/android/dialer/phonelookup/PhoneLookupModule.java5
-rw-r--r--java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java104
-rw-r--r--java/com/android/dialer/phonelookup/cp2/Cp2Projections.java119
-rw-r--r--java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java248
-rw-r--r--java/com/android/dialer/phonelookup/phone_lookup_info.proto49
-rw-r--r--java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java16
-rw-r--r--java/com/android/dialer/precall/impl/PermissionCheckAction.java4
-rw-r--r--java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java14
-rw-r--r--java/com/android/dialer/voicemail/listui/VoicemailCursorLoader.java40
-rw-r--r--java/com/android/dialer/voicemail/listui/VoicemailEntryText.java4
-rw-r--r--java/com/android/dialer/voicemail/listui/menu/Modules.java4
-rw-r--r--java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java10
-rw-r--r--java/com/android/dialer/voicemail/model/VoicemailEntry.java25
24 files changed, 644 insertions, 358 deletions
diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
index f90d657b8..da93ff8a3 100644
--- a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
+++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java
@@ -38,15 +38,10 @@ class AnnotatedCallLogDatabaseHelper extends SQLiteOpenHelper {
+ " ("
+ (AnnotatedCallLog._ID + " integer primary key, ")
+ (AnnotatedCallLog.TIMESTAMP + " integer, ")
- + (AnnotatedCallLog.NAME + " text, ")
+ (AnnotatedCallLog.NUMBER + " blob, ")
+ (AnnotatedCallLog.FORMATTED_NUMBER + " text, ")
- + (AnnotatedCallLog.PHOTO_URI + " text, ")
- + (AnnotatedCallLog.PHOTO_ID + " integer, ")
- + (AnnotatedCallLog.LOOKUP_URI + " text, ")
+ (AnnotatedCallLog.DURATION + " integer, ")
+ (AnnotatedCallLog.DATA_USAGE + " integer, ")
- + (AnnotatedCallLog.NUMBER_TYPE_LABEL + " text, ")
+ (AnnotatedCallLog.IS_READ + " integer, ")
+ (AnnotatedCallLog.NEW + " integer, ")
+ (AnnotatedCallLog.GEOCODED_LOCATION + " text, ")
@@ -55,13 +50,10 @@ class AnnotatedCallLogDatabaseHelper extends SQLiteOpenHelper {
+ (AnnotatedCallLog.PHONE_ACCOUNT_LABEL + " text, ")
+ (AnnotatedCallLog.PHONE_ACCOUNT_COLOR + " integer, ")
+ (AnnotatedCallLog.FEATURES + " integer, ")
- + (AnnotatedCallLog.IS_BUSINESS + " integer, ")
- + (AnnotatedCallLog.IS_VOICEMAIL + " integer, ")
+ (AnnotatedCallLog.TRANSCRIPTION + " integer, ")
+ (AnnotatedCallLog.VOICEMAIL_URI + " text, ")
+ (AnnotatedCallLog.CALL_TYPE + " integer, ")
- + (AnnotatedCallLog.CAN_REPORT_AS_INVALID_NUMBER + " integer, ")
- + (AnnotatedCallLog.CP2_INFO_INCOMPLETE + " integer")
+ + (AnnotatedCallLog.NUMBER_ATTRIBUTES + " blob ")
+ ");";
/** Deletes all but the first maxRows rows (by timestamp) to keep the table a manageable size. */
diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
index 9161d6087..d382517cd 100644
--- a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
+++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java
@@ -42,15 +42,6 @@ public class AnnotatedCallLogContract {
String TIMESTAMP = "timestamp";
/**
- * The name (which may be a person's name or business name, but not a number) formatted exactly
- * as it should appear to the user. If the user's locale or name display preferences change,
- * this column should be rewritten.
- *
- * <p>Type: TEXT
- */
- String NAME = "name";
-
- /**
* The phone number called or number the call came from, encoded as a {@link
* com.android.dialer.DialerPhoneNumber} proto. The number may be empty if it was an incoming
* call and the number was unknown.
@@ -68,38 +59,6 @@ public class AnnotatedCallLogContract {
String FORMATTED_NUMBER = "formatted_number";
/**
- * A photo URI for the contact to display in the call log list view.
- *
- * <p>TYPE: TEXT
- */
- String PHOTO_URI = "photo_uri";
-
- /**
- * A photo ID (from the contacts provider) for the contact to display in the call log list view.
- *
- * <p>Type: INTEGER (long)
- */
- String PHOTO_ID = "photo_id";
-
- /**
- * The contacts provider lookup URI for the contact associated with the call.
- *
- * <p>TYPE: TEXT
- */
- String LOOKUP_URI = "lookup_uri";
-
- // TODO(zachh): If we need to support photos other than local contacts', add a (blob?) column.
-
- /**
- * The number type as a string to be displayed to the user, for example "Home" or "Mobile".
- *
- * <p>This column should be updated for the appropriate language when the locale changes.
- *
- * <p>TYPE: TEXT
- */
- String NUMBER_TYPE_LABEL = "number_type_label";
-
- /**
* See {@link android.provider.CallLog.Calls#IS_READ}.
*
* <p>TYPE: INTEGER (boolean)
@@ -156,20 +115,13 @@ public class AnnotatedCallLogContract {
String FEATURES = "features";
/**
- * True if a caller ID data source informed us that this is a business number. This is used to
- * determine if a generic business avatar should be shown vs. a generic person avatar.
+ * Additional attributes about the number.
*
- * <p>TYPE: INTEGER (boolean)
- */
- String IS_BUSINESS = "is_business";
-
- /**
- * True if this was a call to voicemail. This is used to determine if the voicemail avatar
- * should be displayed.
+ * <p>TYPE: BLOB
*
- * <p>TYPE: INTEGER (boolean)
+ * @see com.android.dialer.calllog.model.NumberAttributes
*/
- String IS_VOICEMAIL = "is_voicemail";
+ String NUMBER_ATTRIBUTES = "number_attributes";
/**
* Copied from {@link android.provider.CallLog.Calls#TYPE}.
@@ -178,31 +130,12 @@ public class AnnotatedCallLogContract {
*/
String CALL_TYPE = "call_type";
- /**
- * True if the number can be reported as invalid.
- *
- * <p>TYPE: INTEGER (boolean)
- */
- String CAN_REPORT_AS_INVALID_NUMBER = "can_report_as_invalid_number";
-
- /**
- * True if the CP2 information is incomplete and needs to be queried at display time.
- *
- * <p>TYPE: INTEGER (boolean)
- */
- String CP2_INFO_INCOMPLETE = "cp2_info_incomplete";
-
String[] ALL_COMMON_COLUMNS =
new String[] {
_ID,
TIMESTAMP,
- NAME,
NUMBER,
FORMATTED_NUMBER,
- PHOTO_URI,
- PHOTO_ID,
- LOOKUP_URI,
- NUMBER_TYPE_LABEL,
IS_READ,
NEW,
GEOCODED_LOCATION,
@@ -211,11 +144,8 @@ public class AnnotatedCallLogContract {
PHONE_ACCOUNT_LABEL,
PHONE_ACCOUNT_COLOR,
FEATURES,
- IS_BUSINESS,
- IS_VOICEMAIL,
+ NUMBER_ATTRIBUTES,
CALL_TYPE,
- CAN_REPORT_AS_INVALID_NUMBER,
- CP2_INFO_INCOMPLETE
};
}
diff --git a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
index 30461a4be..b73c169b9 100644
--- a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
+++ b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
@@ -28,6 +28,7 @@ import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.NumberAttributes;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
import com.android.dialer.calllog.datasources.CallLogDataSource;
import com.android.dialer.calllog.datasources.CallLogMutations;
@@ -286,13 +287,7 @@ public final class PhoneLookupDataSource
@Override
public ContentValues coalesce(List<ContentValues> individualRowsSortedByTimestampDesc) {
return new RowCombiner(individualRowsSortedByTimestampDesc)
- .useMostRecentString(AnnotatedCallLog.NAME)
- .useMostRecentString(AnnotatedCallLog.NUMBER_TYPE_LABEL)
- .useMostRecentString(AnnotatedCallLog.PHOTO_URI)
- .useMostRecentLong(AnnotatedCallLog.PHOTO_ID)
- .useMostRecentString(AnnotatedCallLog.LOOKUP_URI)
- .useMostRecentInt(AnnotatedCallLog.CAN_REPORT_AS_INVALID_NUMBER)
- .useMostRecentInt(AnnotatedCallLog.CP2_INFO_INCOMPLETE)
+ .useMostRecentBlob(AnnotatedCallLog.NUMBER_ATTRIBUTES)
.combine();
}
@@ -584,19 +579,20 @@ public final class PhoneLookupDataSource
}
private void updateContentValues(ContentValues contentValues, PhoneLookupInfo phoneLookupInfo) {
- contentValues.put(AnnotatedCallLog.NAME, phoneLookupSelector.selectName(phoneLookupInfo));
contentValues.put(
- AnnotatedCallLog.PHOTO_URI, phoneLookupSelector.selectPhotoUri(phoneLookupInfo));
- contentValues.put(
- AnnotatedCallLog.PHOTO_ID, phoneLookupSelector.selectPhotoId(phoneLookupInfo));
- contentValues.put(
- AnnotatedCallLog.LOOKUP_URI, phoneLookupSelector.selectLookupUri(phoneLookupInfo));
- contentValues.put(
- AnnotatedCallLog.NUMBER_TYPE_LABEL, phoneLookupSelector.selectNumberLabel(phoneLookupInfo));
- contentValues.put(
- AnnotatedCallLog.CAN_REPORT_AS_INVALID_NUMBER,
- PhoneLookupSelector.canReportAsInvalidNumber(phoneLookupInfo));
- contentValues.put(
- AnnotatedCallLog.CP2_INFO_INCOMPLETE, phoneLookupInfo.getCp2LocalInfo().getIsIncomplete());
+ AnnotatedCallLog.NUMBER_ATTRIBUTES,
+ NumberAttributes.newBuilder()
+ .setName(phoneLookupSelector.selectName(phoneLookupInfo))
+ .setPhotoUri(phoneLookupSelector.selectPhotoUri(phoneLookupInfo))
+ .setPhotoId(phoneLookupSelector.selectPhotoId(phoneLookupInfo))
+ .setLookupUri(phoneLookupSelector.selectLookupUri(phoneLookupInfo))
+ .setNumberTypeLabel(phoneLookupSelector.selectNumberLabel(phoneLookupInfo))
+ .setIsBusiness(phoneLookupSelector.selectIsBusiness(phoneLookupInfo))
+ .setIsVoicemail(phoneLookupSelector.selectIsVoicemail(phoneLookupInfo))
+ .setCanReportAsInvalidNumber(
+ phoneLookupSelector.canReportAsInvalidNumber(phoneLookupInfo))
+ .setIsCp2InfoIncomplete(phoneLookupSelector.selectIsCp2InfoIncomplete(phoneLookupInfo))
+ .build()
+ .toByteArray());
}
}
diff --git a/java/com/android/dialer/calllog/model/CoalescedRow.java b/java/com/android/dialer/calllog/model/CoalescedRow.java
index 2520d996a..312c29cc0 100644
--- a/java/com/android/dialer/calllog/model/CoalescedRow.java
+++ b/java/com/android/dialer/calllog/model/CoalescedRow.java
@@ -20,6 +20,7 @@ import android.support.annotation.ColorInt;
import android.support.annotation.Nullable;
import com.android.dialer.CoalescedIds;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.NumberAttributes;
import com.google.auto.value.AutoValue;
/** Data class containing the contents of a row from the CoalescedAnnotatedCallLog. */
@@ -31,16 +32,12 @@ public abstract class CoalescedRow {
.setId(0)
.setTimestamp(0)
.setNumber(DialerPhoneNumber.getDefaultInstance())
- .setPhotoId(0)
.setIsRead(false)
.setIsNew(false)
.setPhoneAccountColor(0)
.setFeatures(0)
- .setIsBusiness(false)
- .setIsVoicemail(false)
.setCallType(0)
- .setCanReportAsInvalidNumber(false)
- .setCp2InfoIncomplete(false)
+ .setNumberAttributes(NumberAttributes.getDefaultInstance())
.setCoalescedIds(CoalescedIds.getDefaultInstance());
}
@@ -53,22 +50,8 @@ public abstract class CoalescedRow {
public abstract DialerPhoneNumber number();
@Nullable
- public abstract String name();
-
- @Nullable
public abstract String formattedNumber();
- @Nullable
- public abstract String photoUri();
-
- public abstract long photoId();
-
- @Nullable
- public abstract String lookupUri();
-
- @Nullable
- public abstract String numberTypeLabel();
-
public abstract boolean isRead();
public abstract boolean isNew();
@@ -90,15 +73,9 @@ public abstract class CoalescedRow {
public abstract int features();
- public abstract boolean isBusiness();
-
- public abstract boolean isVoicemail();
-
public abstract int callType();
- public abstract boolean canReportAsInvalidNumber();
-
- public abstract boolean cp2InfoIncomplete();
+ public abstract NumberAttributes numberAttributes();
public abstract CoalescedIds coalescedIds();
@@ -112,18 +89,8 @@ public abstract class CoalescedRow {
public abstract Builder setNumber(DialerPhoneNumber number);
- public abstract Builder setName(@Nullable String name);
-
public abstract Builder setFormattedNumber(@Nullable String formattedNumber);
- public abstract Builder setPhotoUri(@Nullable String photoUri);
-
- public abstract Builder setPhotoId(long photoId);
-
- public abstract Builder setLookupUri(@Nullable String lookupUri);
-
- public abstract Builder setNumberTypeLabel(@Nullable String numberTypeLabel);
-
public abstract Builder setIsRead(boolean isRead);
public abstract Builder setIsNew(boolean isNew);
@@ -141,15 +108,9 @@ public abstract class CoalescedRow {
public abstract Builder setFeatures(int features);
- public abstract Builder setIsBusiness(boolean isBusiness);
-
- public abstract Builder setIsVoicemail(boolean isVoicemail);
-
public abstract Builder setCallType(int callType);
- public abstract Builder setCanReportAsInvalidNumber(boolean canReportAsInvalidNumber);
-
- public abstract Builder setCp2InfoIncomplete(boolean cp2InfoIncomplete);
+ public abstract Builder setNumberAttributes(NumberAttributes numberAttributes);
public abstract Builder setCoalescedIds(CoalescedIds coalescedIds);
diff --git a/java/com/android/dialer/calllog/model/number_attributes.proto b/java/com/android/dialer/calllog/model/number_attributes.proto
new file mode 100644
index 000000000..64f8f180e
--- /dev/null
+++ b/java/com/android/dialer/calllog/model/number_attributes.proto
@@ -0,0 +1,61 @@
+// Copyright (C) 2018 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
+
+syntax = "proto2";
+
+option java_package = "com.android.dialer";
+option java_multiple_files = true;
+option optimize_for = LITE_RUNTIME;
+
+
+package com.android.dialer;
+
+// Information related to the phone number of the call.
+message NumberAttributes {
+ // The name (which may be a person's name or business name, but not a number)
+ // formatted exactly as it should appear to the user. If the user's locale or
+ // name display preferences change, this field should be rewritten.
+ optional string name = 1;
+
+ // A photo URI for the contact to display in the call log list view.
+ optional string photo_uri = 2;
+
+ // A photo ID (from the contacts provider) for the contact to display in the
+ // call log list view.
+ optional int64 photo_id = 3;
+
+ // TODO(zachh): If we need to support photos other than local contacts', add a
+ // (blob?) column.
+
+ // The contacts provider lookup URI for the contact associated with the call.
+ optional string lookup_uri = 4;
+
+ // The number type as a string to be displayed to the user, for example "Home"
+ // or "Mobile". This column should be updated for the appropriate language
+ // when the locale changes.
+ optional string number_type_label = 5;
+
+ // The number is a call to a business from nearby places lookup.
+ optional bool is_business = 6;
+
+ // The number is a call to the voicemail inbox.
+ optional bool is_voicemail = 7;
+
+ // Can the number be reported as invalid through People API
+ optional bool can_report_as_invalid_number = 8;
+
+ // True if the CP2 information is incomplete and needs to be queried at
+ // display time.
+ optional bool is_cp2_info_incomplete = 9;
+} \ No newline at end of file
diff --git a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
index 5c0ce2816..d72544b56 100644
--- a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
+++ b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java
@@ -21,6 +21,7 @@ import android.database.Cursor;
import android.support.v4.content.CursorLoader;
import com.android.dialer.CoalescedIds;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.NumberAttributes;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog;
import com.android.dialer.calllog.model.CoalescedRow;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -31,27 +32,19 @@ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader {
// Indexes for CoalescedAnnotatedCallLog.ALL_COLUMNS
private static final int ID = 0;
private static final int TIMESTAMP = 1;
- private static final int NAME = 2;
- private static final int NUMBER = 3;
- private static final int FORMATTED_NUMBER = 4;
- private static final int PHOTO_URI = 5;
- private static final int PHOTO_ID = 6;
- private static final int LOOKUP_URI = 7;
- private static final int NUMBER_TYPE_LABEL = 8;
- private static final int IS_READ = 9;
- private static final int NEW = 10;
- private static final int GEOCODED_LOCATION = 11;
- private static final int PHONE_ACCOUNT_COMPONENT_NAME = 12;
- private static final int PHONE_ACCOUNT_ID = 13;
- private static final int PHONE_ACCOUNT_LABEL = 14;
- private static final int PHONE_ACCOUNT_COLOR = 15;
- private static final int FEATURES = 16;
- private static final int IS_BUSINESS = 17;
- private static final int IS_VOICEMAIL = 18;
- private static final int CALL_TYPE = 19;
- private static final int CAN_REPORT_AS_INVALID_NUMBER = 20;
- private static final int CP2_INFO_INCOMPLETE = 21;
- private static final int COALESCED_IDS = 22;
+ 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;
CoalescedAnnotatedCallLogCursorLoader(Context context) {
// CoalescedAnnotatedCallLog requires that PROJECTION be ALL_COLUMNS and the following params be
@@ -81,16 +74,18 @@ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader {
throw new IllegalStateException("Couldn't parse CoalescedIds bytes");
}
+ NumberAttributes numberAttributes;
+ try {
+ numberAttributes = NumberAttributes.parseFrom(cursor.getBlob(NUMBER_ATTRIBUTES));
+ } catch (InvalidProtocolBufferException e) {
+ throw new IllegalStateException("Couldn't parse NumberAttributes bytes");
+ }
+
return CoalescedRow.builder()
.setId(cursor.getInt(ID))
.setTimestamp(cursor.getLong(TIMESTAMP))
- .setName(cursor.getString(NAME))
.setNumber(number)
.setFormattedNumber(cursor.getString(FORMATTED_NUMBER))
- .setPhotoUri(cursor.getString(PHOTO_URI))
- .setPhotoId(cursor.getLong(PHOTO_ID))
- .setLookupUri(cursor.getString(LOOKUP_URI))
- .setNumberTypeLabel(cursor.getString(NUMBER_TYPE_LABEL))
.setIsRead(cursor.getInt(IS_READ) == 1)
.setIsNew(cursor.getInt(NEW) == 1)
.setGeocodedLocation(cursor.getString(GEOCODED_LOCATION))
@@ -99,11 +94,8 @@ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader {
.setPhoneAccountLabel(cursor.getString(PHONE_ACCOUNT_LABEL))
.setPhoneAccountColor(cursor.getInt(PHONE_ACCOUNT_COLOR))
.setFeatures(cursor.getInt(FEATURES))
- .setIsBusiness(cursor.getInt(IS_BUSINESS) == 1)
- .setIsVoicemail(cursor.getInt(IS_VOICEMAIL) == 1)
.setCallType(cursor.getInt(CALL_TYPE))
- .setCanReportAsInvalidNumber(cursor.getInt(CAN_REPORT_AS_INVALID_NUMBER) == 1)
- .setCp2InfoIncomplete(cursor.getInt(CP2_INFO_INCOMPLETE) == 1)
+ .setNumberAttributes(numberAttributes)
.setCoalescedIds(coalescedIds)
.build();
}
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
index 7482efdea..5b526b49d 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
@@ -20,6 +20,7 @@ import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog.Calls;
+import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
@@ -134,13 +135,18 @@ final class NewCallLogViewHolder extends RecyclerView.ViewHolder {
ContactPhotoManager.getInstance(context)
.loadDialerThumbnailOrPhoto(
quickContactBadge,
- TextUtils.isEmpty(row.lookupUri()) ? null : Uri.parse(row.lookupUri()),
- row.photoId(),
- TextUtils.isEmpty(row.photoUri()) ? null : Uri.parse(row.photoUri()),
+ parseUri(row.numberAttributes().getLookupUri()),
+ row.numberAttributes().getPhotoId(),
+ parseUri(row.numberAttributes().getPhotoUri()),
CallLogEntryText.buildPrimaryText(context, row).toString(),
CallLogContactTypes.getContactType(row));
}
+ @Nullable
+ private static Uri parseUri(@Nullable String uri) {
+ return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
+ }
+
private void setPrimaryCallTypes(CoalescedRow row) {
primaryCallTypeIconsView.setShowHd(
(row.features() & Calls.FEATURES_HD_CALL) == Calls.FEATURES_HD_CALL);
diff --git a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
index 74b7defb0..2cfe0b4ad 100644
--- a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
+++ b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
@@ -19,6 +19,7 @@ package com.android.dialer.calllog.ui;
import android.support.annotation.MainThread;
import android.util.ArrayMap;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.NumberAttributes;
import com.android.dialer.calllog.model.CoalescedRow;
import com.android.dialer.common.concurrent.Annotations.Ui;
import com.android.dialer.phonelookup.PhoneLookupInfo;
@@ -68,7 +69,7 @@ public final class RealtimeRowProcessor {
@MainThread
ListenableFuture<Optional<CoalescedRow>> applyRealtimeProcessing(final CoalescedRow row) {
// Cp2LocalPhoneLookup can not always efficiently process all rows.
- if (!row.cp2InfoIncomplete()) {
+ if (!row.numberAttributes().getIsCp2InfoIncomplete()) {
return Futures.immediateFuture(Optional.absent());
}
@@ -97,11 +98,18 @@ public final class RealtimeRowProcessor {
PhoneLookupInfo phoneLookupInfo = PhoneLookupInfo.newBuilder().setCp2LocalInfo(cp2Info).build();
// It is safe to overwrite any existing data because CP2 always has highest priority.
return row.toBuilder()
- .setName(phoneLookupSelector.selectName(phoneLookupInfo))
- .setPhotoUri(phoneLookupSelector.selectPhotoUri(phoneLookupInfo))
- .setPhotoId(phoneLookupSelector.selectPhotoId(phoneLookupInfo))
- .setLookupUri(phoneLookupSelector.selectLookupUri(phoneLookupInfo))
- .setNumberTypeLabel(phoneLookupSelector.selectNumberLabel(phoneLookupInfo))
+ .setNumberAttributes(
+ NumberAttributes.newBuilder()
+ .setName(phoneLookupSelector.selectName(phoneLookupInfo))
+ .setPhotoUri(phoneLookupSelector.selectPhotoUri(phoneLookupInfo))
+ .setPhotoId(phoneLookupSelector.selectPhotoId(phoneLookupInfo))
+ .setLookupUri(phoneLookupSelector.selectLookupUri(phoneLookupInfo))
+ .setNumberTypeLabel(phoneLookupSelector.selectNumberLabel(phoneLookupInfo))
+ .setIsBusiness(phoneLookupSelector.selectIsBusiness(phoneLookupInfo))
+ .setIsVoicemail(phoneLookupSelector.selectIsVoicemail(phoneLookupInfo))
+ .setCanReportAsInvalidNumber(
+ phoneLookupSelector.canReportAsInvalidNumber(phoneLookupInfo))
+ .build())
.build();
}
}
diff --git a/java/com/android/dialer/calllog/ui/menu/Modules.java b/java/com/android/dialer/calllog/ui/menu/Modules.java
index 3d667fc79..92dd41163 100644
--- a/java/com/android/dialer/calllog/ui/menu/Modules.java
+++ b/java/com/android/dialer/calllog/ui/menu/Modules.java
@@ -45,7 +45,11 @@ final class Modules {
maybeAddModuleForVideoOrAudioCall(context, modules, row);
SharedModules.maybeAddModuleForAddingToContacts(
- context, modules, row.number(), row.name(), row.lookupUri());
+ context,
+ modules,
+ row.number(),
+ row.numberAttributes().getName(),
+ row.numberAttributes().getLookupUri());
String originalNumber = row.number().getRawInput().getNumber();
SharedModules.maybeAddModuleForSendingTextMessage(context, modules, originalNumber);
@@ -98,8 +102,8 @@ final class Modules {
private static void addModuleForAccessingCallDetails(
Context context, List<ContactActionModule> modules, CoalescedRow row) {
- boolean canReportAsInvalidNumber = row.canReportAsInvalidNumber();
- boolean canSupportAssistedDialing = !TextUtils.isEmpty(row.lookupUri());
+ boolean canReportAsInvalidNumber = row.numberAttributes().getCanReportAsInvalidNumber();
+ boolean canSupportAssistedDialing = !TextUtils.isEmpty(row.numberAttributes().getLookupUri());
modules.add(
new IntentModule(
@@ -122,21 +126,21 @@ final class Modules {
DialerContact.newBuilder()
.setNumber(originalNumber)
.setContactType(LetterTileDrawable.TYPE_DEFAULT) // TODO(zachh): Use proper type.
- .setPhotoId(row.photoId());
+ .setPhotoId(row.numberAttributes().getPhotoId());
- if (!TextUtils.isEmpty(row.name())) {
- dialerContactBuilder.setNameOrNumber(row.name());
+ if (!TextUtils.isEmpty(row.numberAttributes().getName())) {
+ dialerContactBuilder.setNameOrNumber(row.numberAttributes().getName());
} else if (!TextUtils.isEmpty(originalNumber)) {
dialerContactBuilder.setNameOrNumber(originalNumber);
}
- if (row.numberTypeLabel() != null) {
- dialerContactBuilder.setNumberLabel(row.numberTypeLabel());
+ if (row.numberAttributes().hasNumberTypeLabel()) {
+ dialerContactBuilder.setNumberLabel(row.numberAttributes().getNumberTypeLabel());
}
- if (row.photoUri() != null) {
- dialerContactBuilder.setPhotoUri(row.photoUri());
+ if (row.numberAttributes().hasPhotoUri()) {
+ dialerContactBuilder.setPhotoUri(row.numberAttributes().getPhotoUri());
}
- if (row.lookupUri() != null) {
- dialerContactBuilder.setContactUri(row.lookupUri());
+ if (row.numberAttributes().hasLookupUri()) {
+ dialerContactBuilder.setContactUri(row.numberAttributes().getLookupUri());
}
if (row.formattedNumber() != null) {
dialerContactBuilder.setDisplayNumber(row.formattedNumber());
diff --git a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
index faedc8f62..c7126e9dc 100644
--- a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
+++ b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
@@ -34,9 +34,9 @@ final class PrimaryAction {
.setNumber(row.number())
.setPhotoInfo(
PhotoInfo.builder()
- .setPhotoId(row.photoId())
- .setPhotoUri(row.photoUri())
- .setLookupUri(row.lookupUri())
+ .setPhotoId(row.numberAttributes().getPhotoId())
+ .setPhotoUri(row.numberAttributes().getPhotoUri())
+ .setLookupUri(row.numberAttributes().getLookupUri())
.setIsVideo((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO)
.setContactType(CallLogContactTypes.getContactType(row))
.setDisplayName(primaryText.toString())
diff --git a/java/com/android/dialer/calllogutils/CallLogEntryText.java b/java/com/android/dialer/calllogutils/CallLogEntryText.java
index 873f9ebd0..1df44583f 100644
--- a/java/com/android/dialer/calllogutils/CallLogEntryText.java
+++ b/java/com/android/dialer/calllogutils/CallLogEntryText.java
@@ -38,8 +38,8 @@ public final class CallLogEntryText {
*/
public static CharSequence buildPrimaryText(Context context, CoalescedRow row) {
StringBuilder primaryText = new StringBuilder();
- if (!TextUtils.isEmpty(row.name())) {
- primaryText.append(row.name());
+ if (!TextUtils.isEmpty(row.numberAttributes().getName())) {
+ primaryText.append(row.numberAttributes().getName());
} else if (!TextUtils.isEmpty(row.formattedNumber())) {
primaryText.append(row.formattedNumber());
} else {
@@ -98,7 +98,7 @@ public final class CallLogEntryText {
*/
StringBuilder secondaryText = secondaryTextPrefix(context, row);
- if (TextUtils.isEmpty(row.name())) {
+ 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 secondaryText.toString();
}
@@ -128,7 +128,7 @@ public final class CallLogEntryText {
// TODO(zachh): Add "Duo" prefix?
secondaryText.append(context.getText(R.string.new_call_log_video));
}
- String numberTypeLabel = row.numberTypeLabel();
+ String numberTypeLabel = row.numberAttributes().getNumberTypeLabel();
if (!TextUtils.isEmpty(numberTypeLabel)) {
if (secondaryText.length() > 0) {
secondaryText.append(", ");
diff --git a/java/com/android/dialer/phonelookup/PhoneLookupModule.java b/java/com/android/dialer/phonelookup/PhoneLookupModule.java
index 5e215bafe..e93ca0f77 100644
--- a/java/com/android/dialer/phonelookup/PhoneLookupModule.java
+++ b/java/com/android/dialer/phonelookup/PhoneLookupModule.java
@@ -19,6 +19,7 @@ package com.android.dialer.phonelookup;
import com.android.dialer.phonelookup.blockednumber.DialerBlockedNumberPhoneLookup;
import com.android.dialer.phonelookup.composite.CompositePhoneLookup;
import com.android.dialer.phonelookup.cp2.Cp2LocalPhoneLookup;
+import com.android.dialer.phonelookup.cp2.Cp2RemotePhoneLookup;
import com.google.common.collect.ImmutableList;
import dagger.Module;
import dagger.Provides;
@@ -31,8 +32,10 @@ public abstract class PhoneLookupModule {
@SuppressWarnings({"unchecked", "rawtype"})
static ImmutableList<PhoneLookup> providePhoneLookupList(
Cp2LocalPhoneLookup cp2LocalPhoneLookup,
+ Cp2RemotePhoneLookup cp2RemotePhoneLookup,
DialerBlockedNumberPhoneLookup dialerBlockedNumberPhoneLookup) {
- return ImmutableList.of(cp2LocalPhoneLookup, dialerBlockedNumberPhoneLookup);
+ return ImmutableList.of(
+ cp2LocalPhoneLookup, cp2RemotePhoneLookup, dialerBlockedNumberPhoneLookup);
}
@Provides
diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java
index 727977f5c..8879fee06 100644
--- a/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java
+++ b/java/com/android/dialer/phonelookup/cp2/Cp2LocalPhoneLookup.java
@@ -66,45 +66,7 @@ import javax.inject.Inject;
public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
private static final String PREF_LAST_TIMESTAMP_PROCESSED =
- "cp2PhoneLookupLastTimestampProcessed";
-
- /** Projection for performing batch lookups based on E164 numbers using the PHONE table. */
- private static final String[] PHONE_PROJECTION =
- new String[] {
- Phone.DISPLAY_NAME_PRIMARY, // 0
- Phone.PHOTO_THUMBNAIL_URI, // 1
- Phone.PHOTO_ID, // 2
- Phone.TYPE, // 3
- Phone.LABEL, // 4
- Phone.NORMALIZED_NUMBER, // 5
- Phone.CONTACT_ID, // 6
- Phone.LOOKUP_KEY // 7
- };
-
- /**
- * Projection for performing individual lookups of non-E164 numbers using the PHONE_LOOKUP table.
- */
- private static final String[] PHONE_LOOKUP_PROJECTION =
- new String[] {
- ContactsContract.PhoneLookup.DISPLAY_NAME_PRIMARY, // 0
- ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI, // 1
- ContactsContract.PhoneLookup.PHOTO_ID, // 2
- ContactsContract.PhoneLookup.TYPE, // 3
- ContactsContract.PhoneLookup.LABEL, // 4
- ContactsContract.PhoneLookup.NORMALIZED_NUMBER, // 5
- ContactsContract.PhoneLookup.CONTACT_ID, // 6
- ContactsContract.PhoneLookup.LOOKUP_KEY // 7
- };
-
- // The following indexes should match both PHONE_PROJECTION and PHONE_LOOKUP_PROJECTION above.
- private static final int CP2_INFO_NAME_INDEX = 0;
- private static final int CP2_INFO_PHOTO_URI_INDEX = 1;
- private static final int CP2_INFO_PHOTO_ID_INDEX = 2;
- private static final int CP2_INFO_TYPE_INDEX = 3;
- private static final int CP2_INFO_LABEL_INDEX = 4;
- private static final int CP2_INFO_NORMALIZED_NUMBER_INDEX = 5;
- private static final int CP2_INFO_CONTACT_ID_INDEX = 6;
- private static final int CP2_INFO_LOOKUP_KEY_INDEX = 7;
+ "cp2LocalPhoneLookupLastTimestampProcessed";
// We cannot efficiently process invalid numbers because batch queries cannot be constructed which
// accomplish the necessary loose matching. We'll attempt to process a limited number of them,
@@ -146,14 +108,15 @@ public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
// ensure consistency when the batch methods are used to update data.
try (Cursor cursor =
e164.isPresent()
- ? queryPhoneTableBasedOnE164(PHONE_PROJECTION, ImmutableSet.of(e164.get()))
- : queryPhoneLookup(PHONE_LOOKUP_PROJECTION, rawNumber)) {
+ ? queryPhoneTableBasedOnE164(
+ Cp2Projections.getProjectionForPhoneTable(), ImmutableSet.of(e164.get()))
+ : queryPhoneLookup(Cp2Projections.getProjectionForPhoneLookupTable(), rawNumber)) {
if (cursor == null) {
LogUtil.w("Cp2LocalPhoneLookup.lookupInternal", "null cursor");
return Cp2Info.getDefaultInstance();
}
while (cursor.moveToNext()) {
- cp2ContactInfos.add(buildCp2ContactInfoFromPhoneCursor(appContext, cursor));
+ cp2ContactInfos.add(Cp2Projections.buildCp2ContactInfoFromCursor(appContext, cursor));
}
}
return Cp2Info.newBuilder().addAllCp2ContactInfo(cp2ContactInfos).build();
@@ -174,13 +137,14 @@ public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
return Cp2Info.getDefaultInstance();
}
Set<Cp2ContactInfo> cp2ContactInfos = new ArraySet<>();
- try (Cursor cursor = queryPhoneLookup(PHONE_LOOKUP_PROJECTION, rawNumber)) {
+ try (Cursor cursor =
+ queryPhoneLookup(Cp2Projections.getProjectionForPhoneLookupTable(), rawNumber)) {
if (cursor == null) {
LogUtil.w("Cp2LocalPhoneLookup.lookup", "null cursor");
return Cp2Info.getDefaultInstance();
}
while (cursor.moveToNext()) {
- cp2ContactInfos.add(buildCp2ContactInfoFromPhoneCursor(appContext, cursor));
+ cp2ContactInfos.add(Cp2Projections.buildCp2ContactInfoFromCursor(appContext, cursor));
}
}
return Cp2Info.newBuilder().addAllCp2ContactInfo(cp2ContactInfos).build();
@@ -767,18 +731,21 @@ public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
if (e164Numbers.isEmpty()) {
return cp2ContactInfosByNumber;
}
- try (Cursor cursor = queryPhoneTableBasedOnE164(PHONE_PROJECTION, e164Numbers)) {
+ try (Cursor cursor =
+ queryPhoneTableBasedOnE164(
+ Cp2Projections.getProjectionForPhoneTable(), e164Numbers)) {
if (cursor == null) {
LogUtil.w("Cp2LocalPhoneLookup.batchQueryForValidNumbers", "null cursor");
} else {
while (cursor.moveToNext()) {
- String e164Number = cursor.getString(CP2_INFO_NORMALIZED_NUMBER_INDEX);
+ String e164Number = Cp2Projections.getNormalizedNumberFromCursor(cursor);
Set<Cp2ContactInfo> cp2ContactInfos = cp2ContactInfosByNumber.get(e164Number);
if (cp2ContactInfos == null) {
cp2ContactInfos = new ArraySet<>();
cp2ContactInfosByNumber.put(e164Number, cp2ContactInfos);
}
- cp2ContactInfos.add(buildCp2ContactInfoFromPhoneCursor(appContext, cursor));
+ cp2ContactInfos.add(
+ Cp2Projections.buildCp2ContactInfoFromCursor(appContext, cursor));
}
}
}
@@ -794,12 +761,14 @@ public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
if (invalidNumber.isEmpty()) {
return cp2ContactInfos;
}
- try (Cursor cursor = queryPhoneLookup(PHONE_LOOKUP_PROJECTION, invalidNumber)) {
+ try (Cursor cursor =
+ queryPhoneLookup(Cp2Projections.getProjectionForPhoneLookupTable(), invalidNumber)) {
if (cursor == null) {
LogUtil.w("Cp2LocalPhoneLookup.individualQueryForInvalidNumber", "null cursor");
} else {
while (cursor.moveToNext()) {
- cp2ContactInfos.add(buildCp2ContactInfoFromPhoneCursor(appContext, cursor));
+ cp2ContactInfos.add(
+ Cp2Projections.buildCp2ContactInfoFromCursor(appContext, cursor));
}
}
}
@@ -843,43 +812,6 @@ public final class Cp2LocalPhoneLookup implements PhoneLookup<Cp2Info> {
return appContext.getContentResolver().query(uri, projection, null, null, null);
}
- /**
- * @param cursor with projection {@link #PHONE_PROJECTION}.
- * @return new {@link Cp2ContactInfo} based on current row of {@code cursor}.
- */
- private static Cp2ContactInfo buildCp2ContactInfoFromPhoneCursor(
- Context appContext, Cursor cursor) {
- String displayName = cursor.getString(CP2_INFO_NAME_INDEX);
- String photoUri = cursor.getString(CP2_INFO_PHOTO_URI_INDEX);
- int photoId = cursor.getInt(CP2_INFO_PHOTO_ID_INDEX);
- int type = cursor.getInt(CP2_INFO_TYPE_INDEX);
- String label = cursor.getString(CP2_INFO_LABEL_INDEX);
- int contactId = cursor.getInt(CP2_INFO_CONTACT_ID_INDEX);
- String lookupKey = cursor.getString(CP2_INFO_LOOKUP_KEY_INDEX);
-
- Cp2ContactInfo.Builder infoBuilder = Cp2ContactInfo.newBuilder();
- if (!TextUtils.isEmpty(displayName)) {
- infoBuilder.setName(displayName);
- }
- if (!TextUtils.isEmpty(photoUri)) {
- infoBuilder.setPhotoUri(photoUri);
- }
- if (photoId > 0) {
- infoBuilder.setPhotoId(photoId);
- }
-
- // Phone.getTypeLabel returns "Custom" if given (0, null) which is not of any use. Just
- // omit setting the label if there's no information for it.
- if (type != 0 || !TextUtils.isEmpty(label)) {
- infoBuilder.setLabel(Phone.getTypeLabel(appContext.getResources(), type, label).toString());
- }
- infoBuilder.setContactId(contactId);
- if (!TextUtils.isEmpty(lookupKey)) {
- infoBuilder.setLookupUri(Contacts.getLookupUri(contactId, lookupKey).toString());
- }
- return infoBuilder.build();
- }
-
/** Returns set of DialerPhoneNumbers that were associated with now deleted contacts. */
private ListenableFuture<Set<DialerPhoneNumber>> getDeletedPhoneNumbers(
ImmutableMap<DialerPhoneNumber, Cp2Info> existingInfoMap, long lastModified) {
diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2Projections.java b/java/com/android/dialer/phonelookup/cp2/Cp2Projections.java
new file mode 100644
index 000000000..e3929990e
--- /dev/null
+++ b/java/com/android/dialer/phonelookup/cp2/Cp2Projections.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 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.phonelookup.cp2;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.PhoneLookup;
+import android.text.TextUtils;
+import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info.Cp2ContactInfo;
+
+/**
+ * A class providing projection-related functionality for {@link
+ * com.android.dialer.phonelookup.PhoneLookup} implementations for ContactsProvider2 (CP2).
+ */
+final class Cp2Projections {
+
+ // Projection for performing lookups using the PHONE table
+ private static final String[] PHONE_PROJECTION =
+ new String[] {
+ Phone.DISPLAY_NAME_PRIMARY, // 0
+ Phone.PHOTO_THUMBNAIL_URI, // 1
+ Phone.PHOTO_ID, // 2
+ Phone.TYPE, // 3
+ Phone.LABEL, // 4
+ Phone.NORMALIZED_NUMBER, // 5
+ Phone.CONTACT_ID, // 6
+ Phone.LOOKUP_KEY // 7
+ };
+
+ // Projection for performing lookups using the PHONE_LOOKUP table
+ private static final String[] PHONE_LOOKUP_PROJECTION =
+ new String[] {
+ PhoneLookup.DISPLAY_NAME_PRIMARY, // 0
+ PhoneLookup.PHOTO_THUMBNAIL_URI, // 1
+ PhoneLookup.PHOTO_ID, // 2
+ PhoneLookup.TYPE, // 3
+ PhoneLookup.LABEL, // 4
+ PhoneLookup.NORMALIZED_NUMBER, // 5
+ PhoneLookup.CONTACT_ID, // 6
+ PhoneLookup.LOOKUP_KEY // 7
+ };
+
+ // The following indexes should match both PHONE_PROJECTION and PHONE_LOOKUP_PROJECTION above.
+ private static final int CP2_INFO_NAME_INDEX = 0;
+ private static final int CP2_INFO_PHOTO_URI_INDEX = 1;
+ private static final int CP2_INFO_PHOTO_ID_INDEX = 2;
+ private static final int CP2_INFO_TYPE_INDEX = 3;
+ private static final int CP2_INFO_LABEL_INDEX = 4;
+ private static final int CP2_INFO_NORMALIZED_NUMBER_INDEX = 5;
+ private static final int CP2_INFO_CONTACT_ID_INDEX = 6;
+ private static final int CP2_INFO_LOOKUP_KEY_INDEX = 7;
+
+ private Cp2Projections() {}
+
+ static String[] getProjectionForPhoneTable() {
+ return PHONE_PROJECTION;
+ }
+
+ static String[] getProjectionForPhoneLookupTable() {
+ return PHONE_LOOKUP_PROJECTION;
+ }
+
+ /**
+ * Builds a {@link Cp2ContactInfo} based on the current row of {@code cursor}, of which the
+ * projection is either {@link #PHONE_PROJECTION} or {@link #PHONE_LOOKUP_PROJECTION}.
+ */
+ static Cp2ContactInfo buildCp2ContactInfoFromCursor(Context appContext, Cursor cursor) {
+ String displayName = cursor.getString(CP2_INFO_NAME_INDEX);
+ String photoUri = cursor.getString(CP2_INFO_PHOTO_URI_INDEX);
+ int photoId = cursor.getInt(CP2_INFO_PHOTO_ID_INDEX);
+ int type = cursor.getInt(CP2_INFO_TYPE_INDEX);
+ String label = cursor.getString(CP2_INFO_LABEL_INDEX);
+ int contactId = cursor.getInt(CP2_INFO_CONTACT_ID_INDEX);
+ String lookupKey = cursor.getString(CP2_INFO_LOOKUP_KEY_INDEX);
+
+ Cp2ContactInfo.Builder infoBuilder = Cp2ContactInfo.newBuilder();
+ if (!TextUtils.isEmpty(displayName)) {
+ infoBuilder.setName(displayName);
+ }
+ if (!TextUtils.isEmpty(photoUri)) {
+ infoBuilder.setPhotoUri(photoUri);
+ }
+ if (photoId > 0) {
+ infoBuilder.setPhotoId(photoId);
+ }
+
+ // Phone.getTypeLabel returns "Custom" if given (0, null) which is not of any use. Just
+ // omit setting the label if there's no information for it.
+ if (type != 0 || !TextUtils.isEmpty(label)) {
+ infoBuilder.setLabel(Phone.getTypeLabel(appContext.getResources(), type, label).toString());
+ }
+ infoBuilder.setContactId(contactId);
+ if (!TextUtils.isEmpty(lookupKey)) {
+ infoBuilder.setLookupUri(Contacts.getLookupUri(contactId, lookupKey).toString());
+ }
+ return infoBuilder.build();
+ }
+
+ /** Returns the normalized number in the current row of {@code cursor}. */
+ static String getNormalizedNumberFromCursor(Cursor cursor) {
+ return cursor.getString(CP2_INFO_NORMALIZED_NUMBER_INDEX);
+ }
+}
diff --git a/java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java b/java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java
new file mode 100644
index 000000000..6a4682958
--- /dev/null
+++ b/java/com/android/dialer/phonelookup/cp2/Cp2RemotePhoneLookup.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2018 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.phonelookup.cp2;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Directory;
+import android.support.annotation.VisibleForTesting;
+import android.telecom.Call;
+import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.common.LogUtil;
+import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor;
+import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
+import com.android.dialer.inject.ApplicationContext;
+import com.android.dialer.phonelookup.PhoneLookup;
+import com.android.dialer.phonelookup.PhoneLookupInfo;
+import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info;
+import com.android.dialer.phonenumberutil.PhoneNumberHelper;
+import com.android.dialer.telecom.TelecomCallUtil;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import java.util.ArrayList;
+import java.util.List;
+import javax.inject.Inject;
+
+/** PhoneLookup implementation for remote contacts. */
+public final class Cp2RemotePhoneLookup implements PhoneLookup<Cp2Info> {
+
+ private final Context appContext;
+ private final ListeningExecutorService backgroundExecutorService;
+ private final ListeningExecutorService lightweightExecutorService;
+
+ @Inject
+ Cp2RemotePhoneLookup(
+ @ApplicationContext Context appContext,
+ @BackgroundExecutor ListeningExecutorService backgroundExecutorService,
+ @LightweightExecutor ListeningExecutorService lightweightExecutorService) {
+ this.appContext = appContext;
+ this.backgroundExecutorService = backgroundExecutorService;
+ this.lightweightExecutorService = lightweightExecutorService;
+ }
+
+ @Override
+ public ListenableFuture<Cp2Info> lookup(Call call) {
+ String number = TelecomCallUtil.getNumber(call);
+ if (number == null) {
+ return Futures.immediateFuture(Cp2Info.getDefaultInstance());
+ }
+
+ return Futures.transformAsync(
+ queryCp2ForRemoteDirectoryIds(),
+ remoteDirectoryIds -> queryCp2ForRemoteContact(number, remoteDirectoryIds),
+ lightweightExecutorService);
+ }
+
+ private ListenableFuture<List<Long>> queryCp2ForRemoteDirectoryIds() {
+ return backgroundExecutorService.submit(
+ () -> {
+ List<Long> remoteDirectoryIds = new ArrayList<>();
+ try (Cursor cursor =
+ appContext
+ .getContentResolver()
+ .query(
+ getContentUriForDirectoryIds(),
+ /* projection = */ new String[] {ContactsContract.Directory._ID},
+ /* selection = */ null,
+ /* selectionArgs = */ null,
+ /* sortOrder = */ ContactsContract.Directory._ID)) {
+ if (cursor == null) {
+ LogUtil.e("Cp2RemotePhoneLookup.queryCp2ForDirectoryIds", "null cursor");
+ return remoteDirectoryIds;
+ }
+
+ if (!cursor.moveToFirst()) {
+ LogUtil.i("Cp2RemotePhoneLookup.queryCp2ForDirectoryIds", "empty cursor");
+ return remoteDirectoryIds;
+ }
+
+ int idColumnIndex = cursor.getColumnIndexOrThrow(ContactsContract.Directory._ID);
+ do {
+ long directoryId = cursor.getLong(idColumnIndex);
+
+ // Note that IDs of non-remote directories will be included in the result, such as
+ // android.provider.ContactsContract.Directory.DEFAULT (the default directory that
+ // represents locally stored contacts).
+ if (isRemoteDirectory(directoryId)) {
+ remoteDirectoryIds.add(cursor.getLong(idColumnIndex));
+ }
+ } while (cursor.moveToNext());
+ return remoteDirectoryIds;
+ }
+ });
+ }
+
+ private ListenableFuture<Cp2Info> queryCp2ForRemoteContact(
+ String number, List<Long> remoteDirectoryIds) {
+ if (remoteDirectoryIds.isEmpty()) {
+ return Futures.immediateFuture(Cp2Info.getDefaultInstance());
+ }
+
+ List<ListenableFuture<Cp2Info>> cp2InfoFutures = new ArrayList<>();
+ for (long remoteDirectoryId : remoteDirectoryIds) {
+ cp2InfoFutures.add(queryCp2ForRemoteContact(number, remoteDirectoryId));
+ }
+
+ return Futures.transform(
+ Futures.allAsList(cp2InfoFutures),
+ cp2InfoList -> {
+ Cp2Info.Builder cp2InfoBuilder = Cp2Info.newBuilder();
+ for (Cp2Info cp2Info : cp2InfoList) {
+ cp2InfoBuilder.addAllCp2ContactInfo(cp2Info.getCp2ContactInfoList());
+ }
+ return cp2InfoBuilder.build();
+ },
+ lightweightExecutorService);
+ }
+
+ private ListenableFuture<Cp2Info> queryCp2ForRemoteContact(
+ String number, long remoteDirectoryId) {
+ return backgroundExecutorService.submit(
+ () -> {
+ Cp2Info.Builder cp2InfoBuilder = Cp2Info.newBuilder();
+ try (Cursor cursor =
+ appContext
+ .getContentResolver()
+ .query(
+ getContentUriForContacts(number, remoteDirectoryId),
+ Cp2Projections.getProjectionForPhoneLookupTable(),
+ /* selection = */ null,
+ /* selectionArgs = */ null,
+ /* sortOrder = */ null)) {
+ if (cursor == null) {
+ LogUtil.e(
+ "Cp2RemotePhoneLookup.queryCp2ForRemoteContact",
+ "null cursor returned when querying directory %d",
+ remoteDirectoryId);
+ return cp2InfoBuilder.build();
+ }
+
+ if (!cursor.moveToFirst()) {
+ LogUtil.i(
+ "Cp2RemotePhoneLookup.queryCp2ForRemoteContact",
+ "empty cursor returned when querying directory %d",
+ remoteDirectoryId);
+ return cp2InfoBuilder.build();
+ }
+
+ do {
+ cp2InfoBuilder.addCp2ContactInfo(
+ Cp2Projections.buildCp2ContactInfoFromCursor(appContext, cursor));
+ } while (cursor.moveToNext());
+ }
+
+ return cp2InfoBuilder.build();
+ });
+ }
+
+ @VisibleForTesting
+ static Uri getContentUriForDirectoryIds() {
+ return VERSION.SDK_INT >= VERSION_CODES.N
+ ? ContactsContract.Directory.ENTERPRISE_CONTENT_URI
+ : ContactsContract.Directory.CONTENT_URI;
+ }
+
+ @VisibleForTesting
+ static Uri getContentUriForContacts(String number, long directoryId) {
+ Uri baseUri =
+ VERSION.SDK_INT >= VERSION_CODES.N
+ ? ContactsContract.PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI
+ : ContactsContract.PhoneLookup.CONTENT_FILTER_URI;
+
+ Uri.Builder builder =
+ baseUri
+ .buildUpon()
+ .appendPath(number)
+ .appendQueryParameter(
+ ContactsContract.PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS,
+ String.valueOf(PhoneNumberHelper.isUriNumber(number)))
+ .appendQueryParameter(
+ ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(directoryId));
+
+ return builder.build();
+ }
+
+ private static boolean isRemoteDirectory(long directoryId) {
+ return VERSION.SDK_INT >= VERSION_CODES.N
+ ? Directory.isRemoteDirectoryId(directoryId)
+ : (directoryId != Directory.DEFAULT
+ && directoryId != Directory.LOCAL_INVISIBLE
+ // Directory.ENTERPRISE_DEFAULT is the default work profile directory for locally stored
+ // contacts
+ && directoryId != Directory.ENTERPRISE_DEFAULT
+ && directoryId != Directory.ENTERPRISE_LOCAL_INVISIBLE);
+ }
+
+ @Override
+ public ListenableFuture<Boolean> isDirty(ImmutableSet<DialerPhoneNumber> phoneNumbers) {
+ return Futures.immediateFuture(false);
+ }
+
+ @Override
+ public ListenableFuture<ImmutableMap<DialerPhoneNumber, Cp2Info>> getMostRecentInfo(
+ ImmutableMap<DialerPhoneNumber, Cp2Info> existingInfoMap) {
+ return Futures.immediateFuture(existingInfoMap);
+ }
+
+ @Override
+ public void setSubMessage(PhoneLookupInfo.Builder destination, Cp2Info subMessage) {
+ destination.setCp2RemoteInfo(subMessage);
+ }
+
+ @Override
+ public Cp2Info getSubMessage(PhoneLookupInfo phoneLookupInfo) {
+ return phoneLookupInfo.getCp2RemoteInfo();
+ }
+
+ @Override
+ public ListenableFuture<Void> onSuccessfulBulkUpdate() {
+ return Futures.immediateFuture(null);
+ }
+
+ @Override
+ public void registerContentObservers(
+ Context appContext, ContentObserverCallbacks contentObserverCallbacks) {
+ // No content observer needed for remote contacts
+ }
+}
diff --git a/java/com/android/dialer/phonelookup/phone_lookup_info.proto b/java/com/android/dialer/phonelookup/phone_lookup_info.proto
index f1497bdca..b5e73ccbe 100644
--- a/java/com/android/dialer/phonelookup/phone_lookup_info.proto
+++ b/java/com/android/dialer/phonelookup/phone_lookup_info.proto
@@ -13,29 +13,51 @@ package com.android.dialer.phonelookup;
// to an implementation of PhoneLookup. For example, field "cp2_local_info"
// corresponds to class Cp2LocalPhoneLookup, and class Cp2LocalPhoneLookup
// alone is responsible for populating it.
+// Next ID: 7
message PhoneLookupInfo {
- // Information about a PhoneNumber retrieved from CP2. Cp2LocalPhoneLookup is
- // responsible for populating the data in this message.
+ // Information about a PhoneNumber retrieved from CP2.
message Cp2Info {
- // Information about a single local contact.
+ // Information about a single contact, which can be a local contact or a
+ // remote one.
message Cp2ContactInfo {
- // android.provider.ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY
+ // For a local contact:
+ // android.provider.ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY
+ // For a remote contact:
+ // android.provider.ContactsContract.PhoneLookup.DISPLAY_NAME_PRIMARY
optional string name = 1;
- // android.provider.ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI
+ // For a local contact:
+ // android.provider.ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI
+ // For a remote contact:
+ // android.provider.ContactsContract.PhoneLookup.PHOTO_THUMBNAIL_URI
optional string photo_uri = 2;
- // android.provider.ContactsContract.CommonDataKinds.Phone.PHOTO_ID
+ // For a local contact:
+ // android.provider.ContactsContract.CommonDataKinds.Phone.PHOTO_ID
+ // For a remote contact:
+ // android.provider.ContactsContract.PhoneLookup.PHOTO_ID
optional fixed64 photo_id = 3;
- // android.provider.ContactsContract.CommonDataKinds.Phone.LABEL
- // "Home", "Mobile", ect.
+ // For a local contact:
+ // android.provider.ContactsContract.CommonDataKinds.Phone.LABEL
+ // For a remote contact:
+ // android.provider.ContactsContract.PhoneLookup.LABEL
+ //
+ // The value can be "Home", "Mobile", ect.
optional string label = 4;
- // android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ // For a local contact:
+ // android.provider.ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ // For a remote contact:
+ // android.provider.ContactsContract.PhoneLookup.CONTACT_ID
optional fixed64 contact_id = 5;
- // android.provider.ContactsContract.CONTENT_LOOKUP_URI
+ // For a local contact:
+ // constructed based on
+ // android.provider.ContactsContract.CommonDataKinds.Phone.LOOKUP_KEY
+ // For a remote contact:
+ // constructed based on
+ // android.provider.ContactsContract.PhoneLookup.LOOKUP_KEY
optional string lookup_uri = 6;
}
// Repeated because one phone number can be associated with multiple CP2
@@ -50,8 +72,15 @@ message PhoneLookupInfo {
// log needs to query for the CP2 information at render time.
optional bool is_incomplete = 2;
}
+
+ // Information about a local contact retrieved via CP2.
+ // Cp2LocalPhoneLookup is responsible for populating this field.
optional Cp2Info cp2_local_info = 1;
+ // Information about a remote contact retrieved via CP2.
+ // Cp2RemotePhoneLookup is responsible for populating this field.
+ optional Cp2Info cp2_remote_info = 6;
+
// Message for APDL, a lookup for the proprietary Google dialer.
message ApdlInfo {
optional bool is_spam = 1;
diff --git a/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java b/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java
index 6b217e951..8d082911c 100644
--- a/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java
+++ b/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java
@@ -127,6 +127,20 @@ public final class PhoneLookupSelector {
return "";
}
+ public boolean selectIsBusiness(PhoneLookupInfo phoneLookupInfo) {
+ return phoneLookupInfo.hasPeopleApiInfo()
+ && phoneLookupInfo.getPeopleApiInfo().getInfoType() == InfoType.NEARBY_BUSINESS;
+ }
+
+ public boolean selectIsVoicemail(PhoneLookupInfo unused) {
+ // TODO(twyen): implement
+ return false;
+ }
+
+ public boolean selectIsCp2InfoIncomplete(PhoneLookupInfo phoneLookupInfo) {
+ return phoneLookupInfo.getCp2LocalInfo().getIsIncomplete();
+ }
+
/**
* Returns true if the number associated with the given {@link PhoneLookupInfo} can be reported as
* invalid.
@@ -134,7 +148,7 @@ public final class PhoneLookupSelector {
* <p>As we currently report invalid numbers via the People API, only numbers from the People API
* can be reported as invalid.
*/
- public static boolean canReportAsInvalidNumber(PhoneLookupInfo phoneLookupInfo) {
+ public boolean canReportAsInvalidNumber(PhoneLookupInfo phoneLookupInfo) {
// The presence of Cp2ContactInfo means the number associated with the given PhoneLookupInfo
// matches that of a Cp2 (local) contact, and PeopleApiInfo will not be used to display
// information like name, photo, etc. We should not allow the user to report the number in this
diff --git a/java/com/android/dialer/precall/impl/PermissionCheckAction.java b/java/com/android/dialer/precall/impl/PermissionCheckAction.java
index b57b37a6f..85e9ceb9c 100644
--- a/java/com/android/dialer/precall/impl/PermissionCheckAction.java
+++ b/java/com/android/dialer/precall/impl/PermissionCheckAction.java
@@ -21,14 +21,14 @@ import android.widget.Toast;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.precall.PreCallAction;
import com.android.dialer.precall.PreCallCoordinator;
-import com.android.dialer.util.PermissionsUtil;
+import com.android.dialer.telecom.TelecomUtil;
/** Aborts call and show a toast if phone permissions are missing. */
public class PermissionCheckAction implements PreCallAction {
@Override
public boolean requiresUi(Context context, CallIntentBuilder builder) {
- return !PermissionsUtil.hasPhonePermissions(context);
+ return !TelecomUtil.hasCallPhonePermission(context);
}
@Override
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
index 90581580d..46e29956d 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
@@ -27,6 +27,7 @@ import android.graphics.Typeface;
import android.net.Uri;
import android.provider.VoicemailContract.Voicemails;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
@@ -205,13 +206,18 @@ final class NewVoicemailViewHolder extends RecyclerView.ViewHolder implements On
ContactPhotoManager.getInstance(context)
.loadDialerThumbnailOrPhoto(
quickContactBadge,
- voicemailEntry.lookupUri() == null ? null : Uri.parse(voicemailEntry.lookupUri()),
- voicemailEntry.photoId(),
- voicemailEntry.photoUri() == null ? null : Uri.parse(voicemailEntry.photoUri()),
- voicemailEntry.name(),
+ parseUri(voicemailEntry.numberAttributes().getLookupUri()),
+ voicemailEntry.numberAttributes().getPhotoId(),
+ parseUri(voicemailEntry.numberAttributes().getPhotoUri()),
+ VoicemailEntryText.buildPrimaryVoicemailText(context, voicemailEntry),
LetterTileDrawable.TYPE_DEFAULT);
}
+ @Nullable
+ private static Uri parseUri(@Nullable String string) {
+ return TextUtils.isEmpty(string) ? null : Uri.parse(string);
+ }
+
void collapseViewHolder() {
LogUtil.i(
"NewVoicemailViewHolder.collapseViewHolder",
diff --git a/java/com/android/dialer/voicemail/listui/VoicemailCursorLoader.java b/java/com/android/dialer/voicemail/listui/VoicemailCursorLoader.java
index 55d36b364..7e0381871 100644
--- a/java/com/android/dialer/voicemail/listui/VoicemailCursorLoader.java
+++ b/java/com/android/dialer/voicemail/listui/VoicemailCursorLoader.java
@@ -21,6 +21,7 @@ import android.database.Cursor;
import android.provider.CallLog.Calls;
import android.support.v4.content.CursorLoader;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.NumberAttributes;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
import com.android.dialer.voicemail.model.VoicemailEntry;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -33,35 +34,29 @@ final class VoicemailCursorLoader extends CursorLoader {
new String[] {
AnnotatedCallLog._ID,
AnnotatedCallLog.TIMESTAMP,
- AnnotatedCallLog.NAME,
AnnotatedCallLog.NUMBER,
AnnotatedCallLog.FORMATTED_NUMBER,
- AnnotatedCallLog.PHOTO_URI,
- AnnotatedCallLog.PHOTO_ID,
- AnnotatedCallLog.LOOKUP_URI,
AnnotatedCallLog.DURATION,
AnnotatedCallLog.GEOCODED_LOCATION,
AnnotatedCallLog.CALL_TYPE,
AnnotatedCallLog.TRANSCRIPTION,
AnnotatedCallLog.VOICEMAIL_URI,
- AnnotatedCallLog.IS_READ
+ AnnotatedCallLog.IS_READ,
+ AnnotatedCallLog.NUMBER_ATTRIBUTES,
};
// Indexes for VOICEMAIL_COLUMNS
private static final int ID = 0;
private static final int TIMESTAMP = 1;
- private static final int NAME = 2;
- private static final int NUMBER = 3;
- private static final int FORMATTED_NUMBER = 4;
- private static final int PHOTO_URI = 5;
- private static final int PHOTO_ID = 6;
- private static final int LOOKUP_URI = 7;
- private static final int DURATION = 8;
- private static final int GEOCODED_LOCATION = 9;
- private static final int CALL_TYPE = 10;
- private static final int TRANSCRIPTION = 11;
- private static final int VOICEMAIL_URI = 12;
- private static final int IS_READ = 13;
+ private static final int NUMBER = 2;
+ private static final int FORMATTED_NUMBER = 3;
+ private static final int DURATION = 4;
+ private static final int GEOCODED_LOCATION = 5;
+ private static final int CALL_TYPE = 6;
+ private static final int TRANSCRIPTION = 7;
+ private static final int VOICEMAIL_URI = 8;
+ private static final int IS_READ = 9;
+ private static final int NUMBER_ATTRIBUTES = 10;
// TODO(zachh): Optimize indexes
VoicemailCursorLoader(Context context) {
@@ -82,22 +77,25 @@ final class VoicemailCursorLoader extends CursorLoader {
} catch (InvalidProtocolBufferException e) {
throw new IllegalStateException("Couldn't parse DialerPhoneNumber bytes");
}
+ NumberAttributes numberAttributes;
+ try {
+ numberAttributes = NumberAttributes.parseFrom(cursor.getBlob(NUMBER_ATTRIBUTES));
+ } catch (InvalidProtocolBufferException e) {
+ throw new IllegalStateException("Couldn't parse NumberAttributes bytes");
+ }
return VoicemailEntry.builder()
.setId(cursor.getInt(ID))
.setTimestamp(cursor.getLong(TIMESTAMP))
- .setName(cursor.getString(NAME))
.setNumber(number)
.setFormattedNumber(cursor.getString(FORMATTED_NUMBER))
- .setPhotoUri(cursor.getString(PHOTO_URI))
- .setPhotoId(cursor.getLong(PHOTO_ID))
- .setLookupUri(cursor.getString(LOOKUP_URI))
.setDuration(cursor.getLong(DURATION))
.setTranscription(cursor.getString(TRANSCRIPTION))
.setVoicemailUri(cursor.getString(VOICEMAIL_URI))
.setGeocodedLocation(cursor.getString(GEOCODED_LOCATION))
.setCallType(cursor.getInt(CALL_TYPE))
.setIsRead(cursor.getInt(IS_READ))
+ .setNumberAttributes(numberAttributes)
.build();
}
diff --git a/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java b/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java
index d73d1f0de..4aaf2d1e7 100644
--- a/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java
+++ b/java/com/android/dialer/voicemail/listui/VoicemailEntryText.java
@@ -33,8 +33,8 @@ public class VoicemailEntryText {
public static String buildPrimaryVoicemailText(Context context, VoicemailEntry data) {
StringBuilder primaryText = new StringBuilder();
- if (!TextUtils.isEmpty(data.name())) {
- primaryText.append(data.name());
+ if (!TextUtils.isEmpty(data.numberAttributes().getName())) {
+ primaryText.append(data.numberAttributes().getName());
} else if (!TextUtils.isEmpty(data.formattedNumber())) {
primaryText.append(data.formattedNumber());
} else {
diff --git a/java/com/android/dialer/voicemail/listui/menu/Modules.java b/java/com/android/dialer/voicemail/listui/menu/Modules.java
index bb98d76eb..bd79932e7 100644
--- a/java/com/android/dialer/voicemail/listui/menu/Modules.java
+++ b/java/com/android/dialer/voicemail/listui/menu/Modules.java
@@ -40,8 +40,8 @@ final class Modules {
context,
modules,
voicemailEntry.number(),
- voicemailEntry.name(),
- voicemailEntry.lookupUri());
+ voicemailEntry.numberAttributes().getName(),
+ voicemailEntry.numberAttributes().getLookupUri());
String originalNumber = voicemailEntry.number().getRawInput().getNumber();
SharedModules.maybeAddModuleForSendingTextMessage(context, modules, originalNumber);
diff --git a/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java b/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
index 7f4ac8052..7b8adfe30 100644
--- a/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
+++ b/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
@@ -38,12 +38,12 @@ final class PrimaryAction {
.setNumber(voicemailEntry.number())
.setPhotoInfo(
PhotoInfo.builder()
- .setPhotoId(voicemailEntry.photoId())
- .setPhotoUri(voicemailEntry.photoUri())
+ .setPhotoId(voicemailEntry.numberAttributes().getPhotoId())
+ .setPhotoUri(voicemailEntry.numberAttributes().getPhotoUri())
.setIsVideo(false)
.setContactType(
LetterTileDrawable.TYPE_DEFAULT) // TODO(uabdullah): Use proper type.
- .setDisplayName(voicemailEntry.name())
+ .setDisplayName(voicemailEntry.numberAttributes().getName())
.build())
.setPrimaryText(buildPrimaryVoicemailText(context, voicemailEntry))
.setSecondaryText(buildSecondaryVoicemailText(voicemailEntry))
@@ -56,8 +56,8 @@ final class PrimaryAction {
public static String buildPrimaryVoicemailText(Context context, VoicemailEntry data) {
StringBuilder primaryText = new StringBuilder();
- if (!TextUtils.isEmpty(data.name())) {
- primaryText.append(data.name());
+ if (!TextUtils.isEmpty(data.numberAttributes().getName())) {
+ primaryText.append(data.numberAttributes().getName());
} else if (!TextUtils.isEmpty(data.formattedNumber())) {
primaryText.append(data.formattedNumber());
} else {
diff --git a/java/com/android/dialer/voicemail/model/VoicemailEntry.java b/java/com/android/dialer/voicemail/model/VoicemailEntry.java
index 702f52d17..f17a23e54 100644
--- a/java/com/android/dialer/voicemail/model/VoicemailEntry.java
+++ b/java/com/android/dialer/voicemail/model/VoicemailEntry.java
@@ -19,6 +19,7 @@ package com.android.dialer.voicemail.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.android.dialer.DialerPhoneNumber;
+import com.android.dialer.NumberAttributes;
import com.google.auto.value.AutoValue;
/** Data class containing the contents of a voicemail entry from the AnnotatedCallLog. */
@@ -30,7 +31,7 @@ public abstract class VoicemailEntry {
.setId(0)
.setTimestamp(0)
.setNumber(DialerPhoneNumber.getDefaultInstance())
- .setPhotoId(0)
+ .setNumberAttributes(NumberAttributes.getDefaultInstance())
.setDuration(0)
.setCallType(0)
.setIsRead(0);
@@ -43,21 +44,11 @@ public abstract class VoicemailEntry {
@NonNull
public abstract DialerPhoneNumber number();
- @Nullable
- public abstract String name();
@Nullable
public abstract String formattedNumber();
@Nullable
- public abstract String photoUri();
-
- public abstract long photoId();
-
- @Nullable
- public abstract String lookupUri();
-
- @Nullable
public abstract String geocodedLocation();
public abstract long duration();
@@ -72,6 +63,8 @@ public abstract class VoicemailEntry {
public abstract int isRead();
+ public abstract NumberAttributes numberAttributes();
+
/** Builder for {@link VoicemailEntry}. */
@AutoValue.Builder
public abstract static class Builder {
@@ -82,16 +75,8 @@ public abstract class VoicemailEntry {
public abstract Builder setNumber(@NonNull DialerPhoneNumber number);
- public abstract Builder setName(@Nullable String name);
-
public abstract Builder setFormattedNumber(@Nullable String formattedNumber);
- public abstract Builder setPhotoUri(@Nullable String photoUri);
-
- public abstract Builder setPhotoId(long photoId);
-
- public abstract Builder setLookupUri(@Nullable String lookupUri);
-
public abstract Builder setDuration(long duration);
public abstract Builder setTranscription(@Nullable String transcription);
@@ -104,6 +89,8 @@ public abstract class VoicemailEntry {
public abstract Builder setIsRead(int isRead);
+ public abstract Builder setNumberAttributes(NumberAttributes numberAttributes);
+
public abstract VoicemailEntry build();
}
}