summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java')
-rw-r--r--java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java168
1 files changed, 168 insertions, 0 deletions
diff --git a/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java b/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java
new file mode 100644
index 000000000..a960d4e96
--- /dev/null
+++ b/java/com/android/dialer/phonelookup/selector/PhoneLookupSelector.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.dialer.phonelookup.selector;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
+import com.android.dialer.inject.ApplicationContext;
+import com.android.dialer.phonelookup.PhoneLookup;
+import com.android.dialer.phonelookup.PhoneLookupInfo;
+import com.android.dialer.phonelookup.PhoneLookupInfo.BlockedState;
+import com.android.dialer.phonelookup.PhoneLookupInfo.Cp2Info.Cp2ContactInfo;
+import com.android.dialer.phonelookup.PhoneLookupInfo.PeopleApiInfo;
+import com.android.dialer.phonelookup.PhoneLookupInfo.PeopleApiInfo.InfoType;
+import javax.inject.Inject;
+
+/**
+ * Prioritizes information from a {@link PhoneLookupInfo}.
+ *
+ * <p>For example, a single {@link PhoneLookupInfo} may contain different name information from many
+ * different {@link PhoneLookup} sources. This class defines the rules for deciding which name
+ * should be selected for display to the user, by prioritizing the data from some {@link PhoneLookup
+ * PhoneLookups} over others.
+ *
+ * <p>Note that the logic in this class may be highly coupled with the logic in {@code
+ * CompositePhoneLookup}, because {@code CompositePhoneLookup} may also include prioritization logic
+ * for short-circuiting low-priority {@link PhoneLookup PhoneLookups}.
+ */
+public final class PhoneLookupSelector {
+
+ private final Context appContext;
+
+ @Inject
+ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+ public PhoneLookupSelector(@ApplicationContext Context appContext) {
+ this.appContext = appContext;
+ }
+
+ /**
+ * Select the name associated with this number. Examples of this are a local contact's name or a
+ * business name received from caller ID.
+ */
+ @NonNull
+ public String selectName(PhoneLookupInfo phoneLookupInfo) {
+ Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo);
+ if (firstLocalContact != null) {
+ String name = firstLocalContact.getName();
+ if (!name.isEmpty()) {
+ return firstLocalContact.getName();
+ }
+ }
+ if (phoneLookupInfo.hasPeopleApiInfo()) {
+ return phoneLookupInfo.getPeopleApiInfo().getDisplayName();
+ }
+ return "";
+ }
+
+ /** Select the photo URI associated with this number. */
+ @NonNull
+ public String selectPhotoUri(PhoneLookupInfo phoneLookupInfo) {
+ Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo);
+ if (firstLocalContact != null) {
+ String photoUri = firstLocalContact.getPhotoUri();
+ if (!photoUri.isEmpty()) {
+ return photoUri;
+ }
+ }
+ return "";
+ }
+
+ /** Select the photo ID associated with this number, or 0 if there is none. */
+ public long selectPhotoId(PhoneLookupInfo phoneLookupInfo) {
+ Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo);
+ if (firstLocalContact != null) {
+ long photoId = firstLocalContact.getPhotoId();
+ if (photoId > 0) {
+ return photoId;
+ }
+ }
+ return 0;
+ }
+
+ /** Select the lookup URI associated with this number. */
+ @NonNull
+ public String selectLookupUri(PhoneLookupInfo phoneLookupInfo) {
+ Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo);
+ if (firstLocalContact != null) {
+ String lookupUri = firstLocalContact.getLookupUri();
+ if (!lookupUri.isEmpty()) {
+ return lookupUri;
+ }
+ }
+ return "";
+ }
+
+ /**
+ * A localized string representing the number type such as "Home" or "Mobile", or a custom value
+ * set by the user.
+ */
+ @NonNull
+ public String selectNumberLabel(PhoneLookupInfo phoneLookupInfo) {
+ if (isBlocked(phoneLookupInfo)) {
+ return appContext.getString(R.string.blocked_number_new_call_log_label);
+ }
+
+ Cp2ContactInfo firstLocalContact = firstLocalContact(phoneLookupInfo);
+ if (firstLocalContact != null) {
+ String label = firstLocalContact.getLabel();
+ if (!label.isEmpty()) {
+ return label;
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Returns true if the number associated with the given {@link PhoneLookupInfo} can be reported as
+ * invalid.
+ *
+ * <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) {
+ // 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
+ // case as the info displayed is not from the People API.
+ if (phoneLookupInfo.getCp2Info().getCp2ContactInfoCount() > 0) {
+ return false;
+ }
+
+ PeopleApiInfo peopleApiInfo = phoneLookupInfo.getPeopleApiInfo();
+ return peopleApiInfo.getInfoType() != InfoType.UNKNOWN
+ && !peopleApiInfo.getPersonId().isEmpty();
+ }
+
+ /**
+ * Arbitrarily select the first contact. In the future, it may make sense to display contact
+ * information from all contacts with the same number (for example show the name as "Mom, Dad" or
+ * show a synthesized photo containing photos of both "Mom" and "Dad").
+ */
+ @Nullable
+ private Cp2ContactInfo firstLocalContact(PhoneLookupInfo phoneLookupInfo) {
+ if (phoneLookupInfo.getCp2Info().getCp2ContactInfoCount() > 0) {
+ return phoneLookupInfo.getCp2Info().getCp2ContactInfo(0);
+ }
+ return null;
+ }
+
+ private static boolean isBlocked(PhoneLookupInfo info) {
+ return info.hasDialerBlockedNumberInfo()
+ && info.getDialerBlockedNumberInfo().getBlockedState().equals(BlockedState.BLOCKED);
+ }
+}