Show icon and label for a spam number in the new call log.
Bug: 73077158
Test: CallLogEntryTextTest, GlidePhotoManagerImplTest, PhoneLookupInfoConsolidatorTest
PiperOrigin-RevId: 185017362
Change-Id: I113472482da2213d17a847054272a22249edc578
diff --git a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
index 3f90e6a..0f00a5d 100644
--- a/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
+++ b/java/com/android/dialer/binary/aosp/AospDialerRootComponent.java
@@ -24,6 +24,7 @@
import com.android.dialer.duo.stub.StubDuoModule;
import com.android.dialer.enrichedcall.stub.StubEnrichedCallModule;
import com.android.dialer.feedback.stub.StubFeedbackModule;
+import com.android.dialer.glidephotomanager.GlidePhotoManagerModule;
import com.android.dialer.inject.ContextModule;
import com.android.dialer.phonelookup.PhoneLookupModule;
import com.android.dialer.phonenumbergeoutil.impl.PhoneNumberGeoUtilModule;
@@ -50,6 +51,7 @@
CommandLineModule.class,
ContextModule.class,
DialerExecutorModule.class,
+ GlidePhotoManagerModule.class,
PhoneLookupModule.class,
PhoneNumberGeoUtilModule.class,
PreCallModule.class,
diff --git a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
index d8efd0a..3e7db9d 100644
--- a/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
+++ b/java/com/android/dialer/binary/basecomponent/BaseDialerRootComponent.java
@@ -25,6 +25,7 @@
import com.android.dialer.duo.DuoComponent;
import com.android.dialer.enrichedcall.EnrichedCallComponent;
import com.android.dialer.feedback.FeedbackComponent;
+import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
import com.android.dialer.main.MainComponent;
import com.android.dialer.phonelookup.PhoneLookupComponent;
import com.android.dialer.phonenumbergeoutil.PhoneNumberGeoUtilComponent;
@@ -55,6 +56,7 @@
DuoComponent.HasComponent,
EnrichedCallComponent.HasComponent,
FeedbackComponent.HasComponent,
+ GlidePhotoManagerComponent.HasComponent,
MainComponent.HasComponent,
MapsComponent.HasComponent,
NewBubbleComponent.HasComponent,
diff --git a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
index 4da0f92..d4520f33 100644
--- a/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
+++ b/java/com/android/dialer/binary/google/GoogleStubDialerRootComponent.java
@@ -24,6 +24,7 @@
import com.android.dialer.duo.stub.StubDuoModule;
import com.android.dialer.enrichedcall.stub.StubEnrichedCallModule;
import com.android.dialer.feedback.stub.StubFeedbackModule;
+import com.android.dialer.glidephotomanager.GlidePhotoManagerModule;
import com.android.dialer.inject.ContextModule;
import com.android.dialer.phonelookup.PhoneLookupModule;
import com.android.dialer.phonenumbergeoutil.impl.PhoneNumberGeoUtilModule;
@@ -54,6 +55,7 @@
CommandLineModule.class,
ContextModule.class,
DialerExecutorModule.class,
+ GlidePhotoManagerModule.class,
MapsModule.class,
PhoneLookupModule.class, // TODO(zachh): Module which uses APDL?
PhoneNumberGeoUtilModule.class,
diff --git a/java/com/android/dialer/calllog/database/contract/number_attributes.proto b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
index b1a7566..594e676 100644
--- a/java/com/android/dialer/calllog/database/contract/number_attributes.proto
+++ b/java/com/android/dialer/calllog/database/contract/number_attributes.proto
@@ -22,6 +22,7 @@
package com.android.dialer;
// Information related to the phone number of the call.
+// Next ID: 12
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
@@ -59,6 +60,9 @@
// display time.
optional bool is_cp2_info_incomplete = 9;
- // The number is blocked.
+ // Whether the number is blocked.
optional bool is_blocked = 10;
+
+ // Whether the number is spam.
+ optional bool is_spam = 11;
}
\ No newline at end of file
diff --git a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
index 8fa6b67..52570c0 100644
--- a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
+++ b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java
@@ -586,6 +586,7 @@
.setIsBusiness(phoneLookupInfoConsolidator.isBusiness())
.setIsVoicemail(phoneLookupInfoConsolidator.isVoicemail())
.setIsBlocked(phoneLookupInfoConsolidator.isBlocked())
+ .setIsSpam(phoneLookupInfoConsolidator.isSpam())
.setCanReportAsInvalidNumber(phoneLookupInfoConsolidator.canReportAsInvalidNumber())
.setIsCp2InfoIncomplete(phoneLookupInfoConsolidator.isCp2LocalInfoIncomplete())
.build()
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
index 05a3399..f7ba9ef 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java
@@ -25,6 +25,8 @@
import android.view.ViewGroup;
import com.android.dialer.calllogutils.CallLogDates;
import com.android.dialer.common.Assert;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
+import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
import com.android.dialer.time.Clock;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -53,6 +55,7 @@
private final Clock clock;
private final RealtimeRowProcessor realtimeRowProcessor;
+ private final GlidePhotoManager glidePhotoManager;
private Cursor cursor;
@@ -69,6 +72,7 @@
this.cursor = cursor;
this.clock = clock;
this.realtimeRowProcessor = CallLogUiComponent.get(context).realtimeRowProcessor();
+ this.glidePhotoManager = GlidePhotoManagerComponent.get(context).glidePhotoManager();
setHeaderPositions();
}
@@ -138,7 +142,8 @@
LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.new_call_log_entry, viewGroup, false),
clock,
- realtimeRowProcessor);
+ realtimeRowProcessor,
+ glidePhotoManager);
default:
throw Assert.createUnsupportedOperationFailException("Unsupported view type: " + viewType);
}
diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
index ee114b5..cf01608 100644
--- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
+++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java
@@ -19,26 +19,22 @@
import android.content.Intent;
import android.content.res.ColorStateList;
import android.database.Cursor;
-import android.net.Uri;
import android.provider.CallLog.Calls;
import android.support.annotation.DrawableRes;
-import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
-import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.QuickContactBadge;
import android.widget.TextView;
import com.android.dialer.calllog.model.CoalescedRow;
import com.android.dialer.calllog.ui.menu.NewCallLogMenu;
-import com.android.dialer.calllogutils.CallLogContactTypes;
import com.android.dialer.calllogutils.CallLogEntryText;
import com.android.dialer.calllogutils.CallLogIntents;
+import com.android.dialer.calllogutils.NumberAttributesConverter;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.compat.AppCompatConstants;
import com.android.dialer.compat.telephony.TelephonyManagerCompat;
-import com.android.dialer.contactphoto.ContactPhotoManager;
-import com.android.dialer.contactphoto.NumberAttributeConverter;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
import com.android.dialer.oem.MotorolaUtils;
import com.android.dialer.time.Clock;
import com.google.common.util.concurrent.FutureCallback;
@@ -65,9 +61,15 @@
private final RealtimeRowProcessor realtimeRowProcessor;
private final ExecutorService uiExecutorService;
+ private final GlidePhotoManager glidePhotoManager;
+
private int currentRowId;
- NewCallLogViewHolder(View view, Clock clock, RealtimeRowProcessor realtimeRowProcessor) {
+ NewCallLogViewHolder(
+ View view,
+ Clock clock,
+ RealtimeRowProcessor realtimeRowProcessor,
+ GlidePhotoManager glidePhotoManager) {
super(view);
this.context = view.getContext();
primaryTextView = view.findViewById(R.id.primary_text);
@@ -83,6 +85,7 @@
this.clock = clock;
this.realtimeRowProcessor = realtimeRowProcessor;
+ this.glidePhotoManager = glidePhotoManager;
uiExecutorService = DialerExecutorComponent.get(context).uiExecutor();
}
@@ -147,19 +150,11 @@
}
private void setPhoto(CoalescedRow row) {
- ContactPhotoManager.getInstance(context)
- .loadDialerThumbnailOrPhoto(
- quickContactBadge,
- parseUri(row.numberAttributes().getLookupUri()),
- row.numberAttributes().getPhotoId(),
- NumberAttributeConverter.getPhotoUri(context, row.numberAttributes()),
- CallLogEntryText.buildPrimaryText(context, row).toString(),
- CallLogContactTypes.getContactType(row));
- }
-
- @Nullable
- private static Uri parseUri(@Nullable String uri) {
- return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
+ glidePhotoManager.loadQuickContactBadge(
+ quickContactBadge,
+ NumberAttributesConverter.toPhotoInfoBuilder(row.numberAttributes())
+ .setFormattedNumber(row.formattedNumber())
+ .build());
}
private void setFeatureIcons(CoalescedRow row) {
@@ -254,7 +249,8 @@
}
private void setOnClickListenerForMenuButon(CoalescedRow row) {
- menuButton.setOnClickListener(NewCallLogMenu.createOnClickListener(context, row));
+ menuButton.setOnClickListener(
+ NewCallLogMenu.createOnClickListener(context, row, glidePhotoManager));
}
private class RealtimeRowFutureCallback implements FutureCallback<CoalescedRow> {
diff --git a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
index 421c35f..5083a95 100644
--- a/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
+++ b/java/com/android/dialer/calllog/ui/RealtimeRowProcessor.java
@@ -212,6 +212,7 @@
.setIsBusiness(phoneLookupInfoConsolidator.isBusiness())
.setIsVoicemail(phoneLookupInfoConsolidator.isVoicemail())
.setIsBlocked(phoneLookupInfoConsolidator.isBlocked())
+ .setIsSpam(phoneLookupInfoConsolidator.isSpam())
.setCanReportAsInvalidNumber(phoneLookupInfoConsolidator.canReportAsInvalidNumber())
.build())
.build();
diff --git a/java/com/android/dialer/calllog/ui/menu/NewCallLogMenu.java b/java/com/android/dialer/calllog/ui/menu/NewCallLogMenu.java
index 2ae823e..81c0513 100644
--- a/java/com/android/dialer/calllog/ui/menu/NewCallLogMenu.java
+++ b/java/com/android/dialer/calllog/ui/menu/NewCallLogMenu.java
@@ -20,14 +20,19 @@
import android.view.View;
import com.android.dialer.calllog.model.CoalescedRow;
import com.android.dialer.contactactions.ContactActionBottomSheet;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
/** Handles configuration of the bottom sheet menus for call log entries. */
public final class NewCallLogMenu {
/** Creates and returns the OnClickListener which opens the menu for the provided row. */
- public static View.OnClickListener createOnClickListener(Context context, CoalescedRow row) {
+ public static View.OnClickListener createOnClickListener(
+ Context context, CoalescedRow row, GlidePhotoManager glidePhotoManager) {
return (view) ->
ContactActionBottomSheet.show(
- context, PrimaryAction.fromRow(context, row), Modules.fromRow(context, row));
+ context,
+ PrimaryAction.fromRow(context, row),
+ Modules.fromRow(context, row),
+ glidePhotoManager);
}
}
diff --git a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
index 2a43a3c..92a8453 100644
--- a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
+++ b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java
@@ -19,12 +19,10 @@
import android.content.Context;
import android.provider.CallLog.Calls;
import com.android.dialer.calllog.model.CoalescedRow;
-import com.android.dialer.calllogutils.CallLogContactTypes;
import com.android.dialer.calllogutils.CallLogEntryText;
import com.android.dialer.calllogutils.CallLogIntents;
+import com.android.dialer.calllogutils.NumberAttributesConverter;
import com.android.dialer.contactactions.ContactPrimaryActionInfo;
-import com.android.dialer.contactactions.ContactPrimaryActionInfo.PhotoInfo;
-import com.android.dialer.contactphoto.NumberAttributeConverter;
/** Configures the primary action row (top row) for the bottom sheet. */
final class PrimaryAction {
@@ -34,13 +32,9 @@
return ContactPrimaryActionInfo.builder()
.setNumber(row.number())
.setPhotoInfo(
- PhotoInfo.builder()
- .setPhotoId(row.numberAttributes().getPhotoId())
- .setPhotoUri(NumberAttributeConverter.getPhotoUri(context, row.numberAttributes()))
- .setLookupUri(row.numberAttributes().getLookupUri())
+ NumberAttributesConverter.toPhotoInfoBuilder(row.numberAttributes())
+ .setFormattedNumber(row.formattedNumber())
.setIsVideo((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO)
- .setContactType(CallLogContactTypes.getContactType(row))
- .setDisplayName(primaryText.toString())
.build())
.setPrimaryText(primaryText)
.setSecondaryText(CallLogEntryText.buildSecondaryTextForBottomSheet(context, row))
diff --git a/java/com/android/dialer/calllogutils/CallLogEntryText.java b/java/com/android/dialer/calllogutils/CallLogEntryText.java
index 49f5e42..737b1d3 100644
--- a/java/com/android/dialer/calllogutils/CallLogEntryText.java
+++ b/java/com/android/dialer/calllogutils/CallLogEntryText.java
@@ -65,7 +65,13 @@
/**
* The secondary text to show in the main call log entry list.
*
- * <p>Rules: (Blocked • )?(Duo video, )?$Label|$Location • Date
+ * <p>Rules:
+ *
+ * <ul>
+ * <li>For numbers that are not spam or blocked: (Duo video, )?$Label|$Location • Date
+ * <li>For blocked non-spam numbers: Blocked • (Duo video, )?$Label|$Location • Date
+ * <li>For spam numbers: Spam • (Duo video, )?$Label • Date
+ * </ul>
*
* <p>Examples:
*
@@ -74,6 +80,10 @@
* <li>Duo Video • 10 min ago
* <li>Mobile • 11:45 PM
* <li>Mobile • Sun
+ * <li>Blocked • Duo Video, Mobile • Now
+ * <li>Blocked • Brooklyn, NJ • 10 min ago
+ * <li>Spam • Mobile • Now
+ * <li>Spam • Now
* <li>Brooklyn, NJ • Jan 15
* </ul>
*
@@ -82,7 +92,11 @@
public static CharSequence buildSecondaryTextForEntries(
Context context, Clock clock, CoalescedRow row) {
List<CharSequence> components = new ArrayList<>();
- if (row.numberAttributes().getIsBlocked()) {
+
+ // If a number is both spam and blocked, only show "Spam".
+ if (row.numberAttributes().getIsSpam()) {
+ components.add(context.getText(R.string.new_call_log_secondary_spam));
+ } else if (row.numberAttributes().getIsBlocked()) {
components.add(context.getText(R.string.new_call_log_secondary_blocked));
}
@@ -102,7 +116,13 @@
*/
public static CharSequence buildSecondaryTextForBottomSheet(Context context, CoalescedRow row) {
/*
- * Rules: (Blocked • )(Duo video, )?$Label|$Location [• NumberIfNoName]?
+ * Rules:
+ * For numbers that are not spam or blocked:
+ * (Duo video, )?$Label|$Location [• NumberIfNoName]?
+ * For blocked non-spam numbers:
+ * Blocked • (Duo video, )?$Label|$Location [• NumberIfNoName]?
+ * For spam numbers:
+ * Spam • (Duo video, )?$Label [• NumberIfNoName]?
*
* The number is shown at the end if there is no name for the entry. (It is shown in primary
* text otherwise.)
@@ -112,11 +132,17 @@
* Duo Video • 555-1234
* Mobile • 555-1234
* Blocked • Mobile • 555-1234
+ * Blocked • Brooklyn, NJ • 555-1234
+ * Spam • Mobile • 555-1234
* Mobile • 555-1234
* Brooklyn, NJ
*/
List<CharSequence> components = new ArrayList<>();
- if (row.numberAttributes().getIsBlocked()) {
+
+ // If a number is both spam and blocked, only show "Spam".
+ if (row.numberAttributes().getIsSpam()) {
+ components.add(context.getText(R.string.new_call_log_secondary_spam));
+ } else if (row.numberAttributes().getIsBlocked()) {
components.add(context.getText(R.string.new_call_log_secondary_blocked));
}
@@ -162,7 +188,8 @@
secondaryText.append(", ");
}
secondaryText.append(numberTypeLabel);
- } else { // If there's a number type label, don't show the location.
+ } else if (!row.numberAttributes().getIsSpam()) {
+ // Don't show the location if there's a number type label or the number is spam.
String location = row.geocodedLocation();
if (!TextUtils.isEmpty(location)) {
if (secondaryText.length() > 0) {
diff --git a/java/com/android/dialer/calllogutils/NumberAttributesConverter.java b/java/com/android/dialer/calllogutils/NumberAttributesConverter.java
new file mode 100644
index 0000000..bed1edd
--- /dev/null
+++ b/java/com/android/dialer/calllogutils/NumberAttributesConverter.java
@@ -0,0 +1,37 @@
+/*
+ * 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.calllogutils;
+
+import com.android.dialer.NumberAttributes;
+import com.android.dialer.glidephotomanager.PhotoInfo;
+
+/** Converts {@link NumberAttributes} to {@link PhotoInfo} */
+public final class NumberAttributesConverter {
+
+ /** Converts to {@link PhotoInfo.Builder} */
+ public static PhotoInfo.Builder toPhotoInfoBuilder(NumberAttributes numberAttributes) {
+ return PhotoInfo.builder()
+ .setName(numberAttributes.getName())
+ .setPhotoUri(numberAttributes.getPhotoUri())
+ .setPhotoId(numberAttributes.getPhotoId())
+ .setLookupUri(numberAttributes.getLookupUri())
+ .setIsBusiness(numberAttributes.getIsBusiness())
+ .setIsSpam(numberAttributes.getIsSpam())
+ .setIsVoicemail(numberAttributes.getIsVoicemail())
+ .setIsBlocked(numberAttributes.getIsBlocked());
+ }
+}
diff --git a/java/com/android/dialer/calllogutils/res/values/strings.xml b/java/com/android/dialer/calllogutils/res/values/strings.xml
index 4622e50..f536ca6 100644
--- a/java/com/android/dialer/calllogutils/res/values/strings.xml
+++ b/java/com/android/dialer/calllogutils/res/values/strings.xml
@@ -139,4 +139,7 @@
<!-- String used to display calls from blocked numbers in the call log. [CHAR LIMIT=30] -->
<string name="new_call_log_secondary_blocked">Blocked</string>
+
+ <!-- String used to display calls from spam numbers in the call log. [CHAR LIMIT=30] -->
+ <string name="new_call_log_secondary_spam">Spam</string>
</resources>
\ No newline at end of file
diff --git a/java/com/android/dialer/contactactions/ContactActionBottomSheet.java b/java/com/android/dialer/contactactions/ContactActionBottomSheet.java
index 27e3187..98a5dd1 100644
--- a/java/com/android/dialer/contactactions/ContactActionBottomSheet.java
+++ b/java/com/android/dialer/contactactions/ContactActionBottomSheet.java
@@ -17,7 +17,6 @@
package com.android.dialer.contactactions;
import android.content.Context;
-import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.BottomSheetDialog;
import android.text.TextUtils;
@@ -29,8 +28,7 @@
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.dialer.common.Assert;
-import com.android.dialer.contactactions.ContactPrimaryActionInfo.PhotoInfo;
-import com.android.dialer.contactphoto.ContactPhotoManager;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
import java.util.List;
/**
@@ -44,23 +42,27 @@
private final List<ContactActionModule> modules;
private final ContactPrimaryActionInfo contactPrimaryActionInfo;
+ private final GlidePhotoManager glidePhotoManager;
private ContactActionBottomSheet(
Context context,
ContactPrimaryActionInfo contactPrimaryActionInfo,
- List<ContactActionModule> modules) {
+ List<ContactActionModule> modules,
+ GlidePhotoManager glidePhotoManager) {
super(context);
this.modules = modules;
this.contactPrimaryActionInfo = contactPrimaryActionInfo;
+ this.glidePhotoManager = glidePhotoManager;
setContentView(LayoutInflater.from(context).inflate(R.layout.sheet_layout, null));
}
public static ContactActionBottomSheet show(
Context context,
ContactPrimaryActionInfo contactPrimaryActionInfo,
- List<ContactActionModule> modules) {
+ List<ContactActionModule> modules,
+ GlidePhotoManager glidePhotoManager) {
ContactActionBottomSheet sheet =
- new ContactActionBottomSheet(context, contactPrimaryActionInfo, modules);
+ new ContactActionBottomSheet(context, contactPrimaryActionInfo, modules, glidePhotoManager);
sheet.show();
return sheet;
}
@@ -85,15 +87,8 @@
View contactView = inflater.inflate(R.layout.contact_layout, container, false);
// TODO(zachh): The contact image should be badged with a video icon if it is for a video call.
- PhotoInfo photoInfo = contactPrimaryActionInfo.photoInfo();
- ContactPhotoManager.getInstance(getContext())
- .loadDialerThumbnailOrPhoto(
- contactView.findViewById(R.id.quick_contact_photo),
- !TextUtils.isEmpty(photoInfo.lookupUri()) ? Uri.parse(photoInfo.lookupUri()) : null,
- photoInfo.photoId(),
- photoInfo.photoUri(),
- photoInfo.displayName(),
- photoInfo.contactType());
+ glidePhotoManager.loadQuickContactBadge(
+ contactView.findViewById(R.id.quick_contact_photo), contactPrimaryActionInfo.photoInfo());
TextView primaryTextView = contactView.findViewById(R.id.primary_text);
TextView secondaryTextView = contactView.findViewById(R.id.secondary_text);
diff --git a/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java b/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java
index f19fd28..5017d83 100644
--- a/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java
+++ b/java/com/android/dialer/contactactions/ContactPrimaryActionInfo.java
@@ -16,11 +16,10 @@
package com.android.dialer.contactactions;
import android.content.Intent;
-import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.android.dialer.DialerPhoneNumber;
-import com.android.dialer.lettertile.LetterTileDrawable;
+import com.android.dialer.glidephotomanager.PhotoInfo;
import com.google.auto.value.AutoValue;
/**
@@ -35,50 +34,6 @@
@Nullable
public abstract DialerPhoneNumber number();
- /** Information used to construct the photo for the contact. */
- @AutoValue
- public abstract static class PhotoInfo {
- public abstract long photoId();
-
- @Nullable
- public abstract Uri photoUri();
-
- @Nullable
- public abstract String lookupUri();
-
- /** Badges the photo with a video icon if true. */
- public abstract boolean isVideo();
-
- @LetterTileDrawable.ContactType
- public abstract int contactType();
-
- /** Used to generate letter tile if there is no photo. */
- @Nullable
- public abstract String displayName();
-
- /** Builder for {@link PhotoInfo}. */
- @AutoValue.Builder
- public abstract static class Builder {
- public abstract Builder setPhotoId(long photoId);
-
- public abstract Builder setPhotoUri(@Nullable Uri photoUri);
-
- public abstract Builder setLookupUri(@Nullable String lookupUri);
-
- public abstract Builder setIsVideo(boolean isVideo);
-
- public abstract Builder setContactType(@LetterTileDrawable.ContactType int contactType);
-
- public abstract Builder setDisplayName(@Nullable String displayName);
-
- public abstract PhotoInfo build();
- }
-
- public static Builder builder() {
- return new AutoValue_ContactPrimaryActionInfo_PhotoInfo.Builder();
- }
- }
-
@NonNull
public abstract PhotoInfo photoInfo();
diff --git a/java/com/android/dialer/contactphoto/NumberAttributeConverter.java b/java/com/android/dialer/contactphoto/NumberAttributeConverter.java
deleted file mode 100644
index d7bf9bd..0000000
--- a/java/com/android/dialer/contactphoto/NumberAttributeConverter.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.contactphoto;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
-import com.android.dialer.NumberAttributes;
-
-/**
- * Convert photo information in {@link NumberAttributes} to an URI suitable for {@link
- * ContactPhotoManager}.
- *
- * <p>This class is temporary. The new photo manager should take NumberAttributes directly.
- */
-public final class NumberAttributeConverter {
-
- /**
- * Computes the photo URI from NumberAttributes.
- *
- * <p>The photo URI is shown in the quick contact badge in the main call log list or in the top
- * item of the bottom sheet menu.
- */
- @Nullable
- public static Uri getPhotoUri(Context context, NumberAttributes numberAttributes) {
- if (numberAttributes.getIsBlocked()) {
- return getResourceUri(context.getResources(), R.drawable.ic_block_grey_48dp);
- } else {
- return parseUri(numberAttributes.getPhotoUri());
- }
- }
-
- @Nullable
- private static Uri parseUri(@Nullable String uri) {
- return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
- }
-
- private static Uri getResourceUri(Resources resources, @DrawableRes int drawable) {
- return Uri.parse(
- ContentResolver.SCHEME_ANDROID_RESOURCE
- + "://"
- + resources.getResourcePackageName(drawable)
- + "/"
- + resources.getResourceTypeName(drawable)
- + "/"
- + resources.getResourceEntryName(drawable));
- }
-}
diff --git a/java/com/android/dialer/glide/DialerGlideModule.java b/java/com/android/dialer/glide/DialerGlideModule.java
new file mode 100644
index 0000000..c74c7cf
--- /dev/null
+++ b/java/com/android/dialer/glide/DialerGlideModule.java
@@ -0,0 +1,27 @@
+/*
+ * 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.glide;
+
+import com.bumptech.glide.annotation.GlideModule;
+import com.bumptech.glide.module.AppGlideModule;
+
+/**
+ * Generates {@link GlideApp}. This class is required for glide annotation processor to generate
+ * generated API, which most documentations are based on.
+ */
+@GlideModule
+public class DialerGlideModule extends AppGlideModule {}
diff --git a/java/com/android/dialer/glidephotomanager/GlidePhotoManager.java b/java/com/android/dialer/glidephotomanager/GlidePhotoManager.java
new file mode 100644
index 0000000..519a394
--- /dev/null
+++ b/java/com/android/dialer/glidephotomanager/GlidePhotoManager.java
@@ -0,0 +1,33 @@
+/*
+ * 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.glidephotomanager;
+
+import android.support.annotation.MainThread;
+import android.widget.QuickContactBadge;
+
+/** Class to load photo for call/contacts */
+public interface GlidePhotoManager {
+
+ /**
+ * Load {@code photoInfo} into the {@code badge}. The loading is performed in the background and a
+ * placeholder will be used appropriately. {@code badge} must be already attached to an
+ * activity/fragment, and the load will be automatically canceled if the lifecycle of the activity
+ * ends.
+ */
+ @MainThread
+ void loadQuickContactBadge(QuickContactBadge badge, PhotoInfo photoInfo);
+}
diff --git a/java/com/android/dialer/glidephotomanager/GlidePhotoManagerComponent.java b/java/com/android/dialer/glidephotomanager/GlidePhotoManagerComponent.java
new file mode 100644
index 0000000..b4699be
--- /dev/null
+++ b/java/com/android/dialer/glidephotomanager/GlidePhotoManagerComponent.java
@@ -0,0 +1,38 @@
+/*
+ * 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.glidephotomanager;
+
+import android.content.Context;
+import com.android.dialer.inject.HasRootComponent;
+import dagger.Subcomponent;
+
+/** Entry point for {@link GlidePhotoManager} */
+@Subcomponent
+public abstract class GlidePhotoManagerComponent {
+
+ public abstract GlidePhotoManager glidePhotoManager();
+
+ public static GlidePhotoManagerComponent get(Context context) {
+ return ((HasComponent) ((HasRootComponent) context.getApplicationContext()).component())
+ .glidePhotoManagerComponent();
+ }
+
+ /** Used to refer to the root application component. */
+ public interface HasComponent {
+ GlidePhotoManagerComponent glidePhotoManagerComponent();
+ }
+}
diff --git a/java/com/android/dialer/glidephotomanager/GlidePhotoManagerModule.java b/java/com/android/dialer/glidephotomanager/GlidePhotoManagerModule.java
new file mode 100644
index 0000000..79629d6
--- /dev/null
+++ b/java/com/android/dialer/glidephotomanager/GlidePhotoManagerModule.java
@@ -0,0 +1,30 @@
+/*
+ * 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.glidephotomanager;
+
+import com.android.dialer.glidephotomanager.impl.GlidePhotoManagerImpl;
+import dagger.Binds;
+import dagger.Module;
+import javax.inject.Singleton;
+
+/** Module for {@link GlidePhotoManagerComponent} */
+@Module
+public abstract class GlidePhotoManagerModule {
+ @Binds
+ @Singleton
+ public abstract GlidePhotoManager bindGlidePhotoManager(GlidePhotoManagerImpl glidePhotoManager);
+}
diff --git a/java/com/android/dialer/glidephotomanager/PhotoInfo.java b/java/com/android/dialer/glidephotomanager/PhotoInfo.java
new file mode 100644
index 0000000..e4dd871
--- /dev/null
+++ b/java/com/android/dialer/glidephotomanager/PhotoInfo.java
@@ -0,0 +1,110 @@
+/*
+ * 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.glidephotomanager;
+
+import android.support.annotation.Nullable;
+import com.google.auto.value.AutoValue;
+
+/** The number information used to create the photo.. */
+@AutoValue
+public abstract class PhotoInfo {
+
+ /** The display name of the number */
+ @Nullable
+ public abstract String name();
+
+ /** The number displayed to the user. */
+ @Nullable
+ public abstract String formattedNumber();
+
+ /** The URI to the photo */
+ @Nullable
+ public abstract String photoUri();
+
+ /** Value of {@link android.provider.ContactsContract.CommonDataKinds.Photo#_ID} */
+ public abstract long photoId();
+
+ /** The contacts provider lookup URI for the contact associated with the number */
+ @Nullable
+ public abstract String lookupUri();
+
+ /** Should a business icon be displayed */
+ public abstract boolean isBusiness();
+
+ /** Should a voicemail icon be displayed */
+ public abstract boolean isVoicemail();
+
+ /** Should a blocked icon be displayed */
+ public abstract boolean isBlocked();
+
+ /** Should a spam icon be displayed */
+ public abstract boolean isSpam();
+
+ /**
+ * Should the photo be badged as video call.
+ *
+ * <p>Defaults to false.
+ */
+ public abstract boolean isVideo();
+
+ /**
+ * Should the result be circularized.
+ *
+ * <p>Defaults to true.
+ */
+ public abstract boolean isCircular();
+
+ /** Builder for {@link PhotoInfo} */
+ @AutoValue.Builder
+ public abstract static class Builder {
+
+ public abstract Builder setName(@Nullable String name);
+
+ public abstract Builder setFormattedNumber(@Nullable String formattedNumber);
+
+ public abstract Builder setPhotoUri(@Nullable String uri);
+
+ public abstract Builder setPhotoId(long id);
+
+ public abstract Builder setLookupUri(@Nullable String uri);
+
+ public abstract Builder setIsBusiness(boolean isBusiness);
+
+ public abstract Builder setIsVoicemail(boolean isVoicemail);
+
+ public abstract Builder setIsBlocked(boolean isBlocked);
+
+ public abstract Builder setIsSpam(boolean isSpam);
+
+ public abstract Builder setIsVideo(boolean isVideo);
+
+ public abstract Builder setIsCircular(boolean isCircular);
+
+ public abstract PhotoInfo build();
+ }
+
+ public static PhotoInfo.Builder builder() {
+ return new AutoValue_PhotoInfo.Builder()
+ .setPhotoId(0)
+ .setIsBusiness(false)
+ .setIsVoicemail(false)
+ .setIsBlocked(false)
+ .setIsSpam(false)
+ .setIsCircular(true)
+ .setIsVideo(false);
+ }
+}
diff --git a/java/com/android/dialer/glidephotomanager/impl/AndroidManifest.xml b/java/com/android/dialer/glidephotomanager/impl/AndroidManifest.xml
new file mode 100644
index 0000000..065c103
--- /dev/null
+++ b/java/com/android/dialer/glidephotomanager/impl/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<!--
+ ~ 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
+ -->
+<manifest
+ package="com.android.dialer.glidephotomanager.impl">
+</manifest>
\ No newline at end of file
diff --git a/java/com/android/dialer/glidephotomanager/impl/GlidePhotoManagerImpl.java b/java/com/android/dialer/glidephotomanager/impl/GlidePhotoManagerImpl.java
new file mode 100644
index 0000000..20d379c
--- /dev/null
+++ b/java/com/android/dialer/glidephotomanager/impl/GlidePhotoManagerImpl.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.glidephotomanager.impl;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.ContactsContract.Data;
+import android.support.annotation.MainThread;
+import android.support.annotation.Nullable;
+import android.telecom.TelecomManager;
+import android.text.TextUtils;
+import android.widget.QuickContactBadge;
+import com.android.dialer.common.Assert;
+import com.android.dialer.glide.GlideApp;
+import com.android.dialer.glide.GlideRequest;
+import com.android.dialer.glide.GlideRequests;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
+import com.android.dialer.glidephotomanager.PhotoInfo;
+import com.android.dialer.inject.ApplicationContext;
+import com.android.dialer.lettertile.LetterTileDrawable;
+import javax.inject.Inject;
+
+/** Implementation of {@link GlidePhotoManager} */
+public class GlidePhotoManagerImpl implements GlidePhotoManager {
+ private final Context appContext;
+
+ @Inject
+ public GlidePhotoManagerImpl(@ApplicationContext Context appContext) {
+ this.appContext = appContext;
+ }
+
+ @MainThread
+ @Override
+ public void loadQuickContactBadge(QuickContactBadge badge, PhotoInfo photoInfo) {
+ Assert.isMainThread();
+ badge.assignContactUri(parseUri(photoInfo.lookupUri()));
+ badge.setOverlay(null);
+ LetterTileDrawable defaultDrawable = getDefaultDrawable(photoInfo);
+ GlideRequest<Drawable> request =
+ buildRequest(GlideApp.with(badge), photoInfo)
+ .placeholder(defaultDrawable) // when the photo is still loading.
+ .fallback(defaultDrawable); // when there's nothing to load.
+
+ if (photoInfo.isCircular()) {
+ request.circleCrop();
+ }
+
+ request.into(badge);
+ }
+
+ private GlideRequest<Drawable> buildRequest(GlideRequests requestManager, PhotoInfo photoInfo) {
+ // The spam status takes precedence over whether the number is blocked.
+ if (photoInfo.isSpam()) {
+ return requestManager.load(R.drawable.ic_report_red_48dp);
+ }
+ if (photoInfo.isBlocked()) {
+ return requestManager.load(R.drawable.ic_block_grey_48dp);
+ }
+ if (!TextUtils.isEmpty(photoInfo.photoUri())) {
+ return requestManager.load(parseUri(photoInfo.photoUri()));
+ }
+ if (photoInfo.photoId() != 0) {
+ return requestManager.load(ContentUris.withAppendedId(Data.CONTENT_URI, photoInfo.photoId()));
+ }
+ // load null to indicate fallback should be used.
+ return requestManager.load((Object) null);
+ }
+
+ /**
+ * Generate the default drawable when photos are not available. Used when the photo is loading or
+ * no photo is available.
+ */
+ private LetterTileDrawable getDefaultDrawable(PhotoInfo photoInfo) {
+ LetterTileDrawable letterTileDrawable = new LetterTileDrawable(appContext.getResources());
+ String displayName;
+ String identifier;
+ if (TextUtils.isEmpty(photoInfo.lookupUri())) {
+ // Use generic avatar instead of letter for non-contacts.
+ displayName = null;
+ identifier =
+ TextUtils.isEmpty(photoInfo.name()) ? photoInfo.formattedNumber() : photoInfo.name();
+ } else {
+ displayName = photoInfo.name();
+ identifier = photoInfo.lookupUri();
+ }
+ letterTileDrawable.setCanonicalDialerLetterTileDetails(
+ displayName,
+ identifier,
+ LetterTileDrawable.SHAPE_CIRCLE,
+ LetterTileDrawable.getContactTypeFromPrimitives(
+ photoInfo.isVoicemail(),
+ false, // TODO(twyen):implement
+ photoInfo.isBusiness(),
+ TelecomManager.PRESENTATION_ALLOWED, // TODO(twyen):implement
+ false)); // TODO(twyen):implement
+ return letterTileDrawable;
+ }
+
+ @Nullable
+ private static Uri parseUri(@Nullable String uri) {
+ return TextUtils.isEmpty(uri) ? null : Uri.parse(uri);
+ }
+}
diff --git a/java/com/android/dialer/contactphoto/res/drawable-xxxhdpi/ic_block_black_48dp.png b/java/com/android/dialer/glidephotomanager/impl/res/drawable-xxxhdpi/ic_block_black_48dp.png
similarity index 100%
rename from java/com/android/dialer/contactphoto/res/drawable-xxxhdpi/ic_block_black_48dp.png
rename to java/com/android/dialer/glidephotomanager/impl/res/drawable-xxxhdpi/ic_block_black_48dp.png
Binary files differ
diff --git a/java/com/android/dialer/contactphoto/res/drawable/ic_block_grey_48dp.xml b/java/com/android/dialer/glidephotomanager/impl/res/drawable/ic_block_grey_48dp.xml
similarity index 100%
rename from java/com/android/dialer/contactphoto/res/drawable/ic_block_grey_48dp.xml
rename to java/com/android/dialer/glidephotomanager/impl/res/drawable/ic_block_grey_48dp.xml
diff --git a/java/com/android/dialer/glidephotomanager/impl/res/drawable/ic_report_red_48dp.xml b/java/com/android/dialer/glidephotomanager/impl/res/drawable/ic_report_red_48dp.xml
new file mode 100644
index 0000000..8a1ddcd
--- /dev/null
+++ b/java/com/android/dialer/glidephotomanager/impl/res/drawable/ic_report_red_48dp.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+ ~ 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
+ -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item>
+ <shape android:shape="oval">
+ <solid android:color="#A52714"/>
+ <size
+ android:height="48dp"
+ android:width="48dp"/>
+ </shape>
+ </item>
+
+ <item
+ android:drawable="@drawable/quantum_ic_report_vd_theme_24"
+ android:gravity="center"
+ android:height="36dp"
+ android:width="36dp"/>
+
+</layer-list>
\ No newline at end of file
diff --git a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
index 0373cfe..874bdbc 100644
--- a/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
+++ b/java/com/android/dialer/phonelookup/consolidator/PhoneLookupInfoConsolidator.java
@@ -228,6 +228,14 @@
}
/**
+ * The {@link PhoneLookupInfo} passed to the constructor is associated with a number. This method
+ * returns whether the number is spam.
+ */
+ public boolean isSpam() {
+ return phoneLookupInfo.getSpamInfo().getIsSpam();
+ }
+
+ /**
* Returns true if the {@link PhoneLookupInfo} passed to the constructor has incomplete CP2 local
* info.
*/
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
index 318f797..05a3bc9 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
@@ -42,6 +42,7 @@
import com.android.dialer.common.concurrent.DialerExecutor.Worker;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.concurrent.ThreadUtil;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
import com.android.dialer.time.Clock;
import com.android.dialer.voicemail.listui.NewVoicemailViewHolder.NewVoicemailViewHolderListener;
import com.android.dialer.voicemail.listui.error.VoicemailErrorMessage;
@@ -75,6 +76,7 @@
private Cursor cursor;
private Cursor voicemailStatusCursor;
private final Clock clock;
+ private final GlidePhotoManager glidePhotoManager;
/** {@link Integer#MAX_VALUE} when the "Today" header should not be displayed. */
private int todayHeaderPosition = Integer.MAX_VALUE;
@@ -117,11 +119,16 @@
new NewVoicemailMediaPlayer(new MediaPlayer());
/** @param cursor whose projection is {@link VoicemailCursorLoader#VOICEMAIL_COLUMNS} */
- NewVoicemailAdapter(Cursor cursor, Clock clock, FragmentManager fragmentManager) {
+ NewVoicemailAdapter(
+ Cursor cursor,
+ Clock clock,
+ FragmentManager fragmentManager,
+ GlidePhotoManager glidePhotoManager) {
LogUtil.enterBlock("NewVoicemailAdapter");
this.cursor = cursor;
this.clock = clock;
this.fragmentManager = fragmentManager;
+ this.glidePhotoManager = glidePhotoManager;
initializeMediaPlayerListeners();
updateHeaderPositions();
}
@@ -223,7 +230,7 @@
case NewVoicemailAdapter.RowType.VOICEMAIL_ENTRY:
view = inflater.inflate(R.layout.new_voicemail_entry, viewGroup, false);
NewVoicemailViewHolder newVoicemailViewHolder =
- new NewVoicemailViewHolder(view, clock, this);
+ new NewVoicemailViewHolder(view, clock, this, glidePhotoManager);
newVoicemailViewHolderSet.add(newVoicemailViewHolder);
return newVoicemailViewHolder;
default:
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
index 8812bcc..45a5443 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
@@ -37,6 +37,7 @@
import com.android.dialer.common.concurrent.UiListener;
import com.android.dialer.database.CallLogQueryHandler;
import com.android.dialer.database.CallLogQueryHandler.Listener;
+import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
import com.google.common.util.concurrent.ListenableFuture;
// TODO(uabdullah): Register content observer for VoicemailContract.Status.CONTENT_URI in onStart
@@ -175,7 +176,10 @@
// TODO(uabdullah): Replace getActivity().getFragmentManager() with getChildFragment()
recyclerView.setAdapter(
new NewVoicemailAdapter(
- data, System::currentTimeMillis, getActivity().getFragmentManager()));
+ data,
+ System::currentTimeMillis,
+ getActivity().getFragmentManager(),
+ GlidePhotoManagerComponent.get(getContext()).glidePhotoManager()));
} else {
// This would only be called in cases such as when voicemail has been fetched from the server
// or a changed occurred in the annotated table changed (e.g deletes). To check if the change
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
index b0c07df..5328dd3 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailViewHolder.java
@@ -27,7 +27,6 @@
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;
@@ -38,15 +37,14 @@
import android.widget.QuickContactBadge;
import android.widget.TextView;
import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog;
+import com.android.dialer.calllogutils.NumberAttributesConverter;
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.compat.android.provider.VoicemailCompat;
-import com.android.dialer.contactphoto.ContactPhotoManager;
-import com.android.dialer.contactphoto.NumberAttributeConverter;
-import com.android.dialer.lettertile.LetterTileDrawable;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
import com.android.dialer.time.Clock;
import com.android.dialer.voicemail.listui.menu.NewVoicemailMenu;
import com.android.dialer.voicemail.model.VoicemailEntry;
@@ -69,9 +67,13 @@
private VoicemailEntry voicemailEntryOfViewHolder;
@NonNull private Uri viewHolderVoicemailUri;
private final NewVoicemailViewHolderListener voicemailViewHolderListener;
+ private final GlidePhotoManager glidePhotoManager;
NewVoicemailViewHolder(
- View view, Clock clock, NewVoicemailViewHolderListener newVoicemailViewHolderListener) {
+ View view,
+ Clock clock,
+ NewVoicemailViewHolderListener newVoicemailViewHolderListener,
+ GlidePhotoManager glidePhotoManager) {
super(view);
LogUtil.enterBlock("NewVoicemailViewHolder");
this.context = view.getContext();
@@ -84,6 +86,7 @@
menuButton = view.findViewById(R.id.menu_button);
this.clock = clock;
voicemailViewHolderListener = newVoicemailViewHolderListener;
+ this.glidePhotoManager = glidePhotoManager;
viewHolderId = -1;
isViewHolderExpanded = false;
@@ -144,7 +147,8 @@
itemView.setOnClickListener(this);
menuButton.setOnClickListener(
- NewVoicemailMenu.createOnClickListener(context, voicemailEntryOfViewHolder));
+ NewVoicemailMenu.createOnClickListener(
+ context, voicemailEntryOfViewHolder, glidePhotoManager));
setPhoto(voicemailEntryOfViewHolder);
@@ -206,19 +210,11 @@
}
private void setPhoto(VoicemailEntry voicemailEntry) {
- ContactPhotoManager.getInstance(context)
- .loadDialerThumbnailOrPhoto(
- quickContactBadge,
- parseUri(voicemailEntry.numberAttributes().getLookupUri()),
- voicemailEntry.numberAttributes().getPhotoId(),
- NumberAttributeConverter.getPhotoUri(context, voicemailEntry.numberAttributes()),
- VoicemailEntryText.buildPrimaryVoicemailText(context, voicemailEntry),
- LetterTileDrawable.TYPE_DEFAULT);
- }
-
- @Nullable
- private static Uri parseUri(@Nullable String string) {
- return TextUtils.isEmpty(string) ? null : Uri.parse(string);
+ glidePhotoManager.loadQuickContactBadge(
+ quickContactBadge,
+ NumberAttributesConverter.toPhotoInfoBuilder(voicemailEntry.numberAttributes())
+ .setFormattedNumber(voicemailEntry.formattedNumber())
+ .build());
}
void collapseViewHolder() {
diff --git a/java/com/android/dialer/voicemail/listui/menu/NewVoicemailMenu.java b/java/com/android/dialer/voicemail/listui/menu/NewVoicemailMenu.java
index 9af8de6..fbd7fe8 100644
--- a/java/com/android/dialer/voicemail/listui/menu/NewVoicemailMenu.java
+++ b/java/com/android/dialer/voicemail/listui/menu/NewVoicemailMenu.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.view.View;
import com.android.dialer.contactactions.ContactActionBottomSheet;
+import com.android.dialer.glidephotomanager.GlidePhotoManager;
import com.android.dialer.voicemail.model.VoicemailEntry;
/** Handles configuration of the bottom sheet menus for voicemail entries. */
@@ -26,11 +27,12 @@
/** Creates and returns the OnClickListener which opens the menu for the provided row. */
public static View.OnClickListener createOnClickListener(
- Context context, VoicemailEntry voicemailEntry) {
+ Context context, VoicemailEntry voicemailEntry, GlidePhotoManager glidePhotoManager) {
return (view) ->
ContactActionBottomSheet.show(
context,
PrimaryAction.fromVoicemailEntry(context, voicemailEntry),
- Modules.fromVoicemailEntry(context, voicemailEntry));
+ Modules.fromVoicemailEntry(context, voicemailEntry),
+ glidePhotoManager);
}
}
diff --git a/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java b/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
index ffc53e7..91f505c 100644
--- a/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
+++ b/java/com/android/dialer/voicemail/listui/menu/PrimaryAction.java
@@ -18,10 +18,8 @@
import android.content.Context;
import android.text.TextUtils;
+import com.android.dialer.calllogutils.NumberAttributesConverter;
import com.android.dialer.contactactions.ContactPrimaryActionInfo;
-import com.android.dialer.contactactions.ContactPrimaryActionInfo.PhotoInfo;
-import com.android.dialer.contactphoto.NumberAttributeConverter;
-import com.android.dialer.lettertile.LetterTileDrawable;
import com.android.dialer.voicemail.model.VoicemailEntry;
/** Configures the primary action row (top row) for theottom sheet for the Voicemail Tab */
@@ -38,15 +36,8 @@
return ContactPrimaryActionInfo.builder()
.setNumber(voicemailEntry.number())
.setPhotoInfo(
- PhotoInfo.builder()
- .setPhotoId(voicemailEntry.numberAttributes().getPhotoId())
- .setPhotoUri(
- NumberAttributeConverter.getPhotoUri(
- context, voicemailEntry.numberAttributes()))
- .setIsVideo(false)
- .setContactType(
- LetterTileDrawable.TYPE_DEFAULT) // TODO(uabdullah): Use proper type.
- .setDisplayName(voicemailEntry.numberAttributes().getName())
+ NumberAttributesConverter.toPhotoInfoBuilder(voicemailEntry.numberAttributes())
+ .setFormattedNumber(voicemailEntry.formattedNumber())
.build())
.setPrimaryText(buildPrimaryVoicemailText(context, voicemailEntry))
.setSecondaryText(buildSecondaryVoicemailText(voicemailEntry))
diff --git a/packages.mk b/packages.mk
index 3a47e26..bc98ef5 100644
--- a/packages.mk
+++ b/packages.mk
@@ -33,6 +33,7 @@
com.android.dialer.dialpadview \
com.android.dialer.enrichedcall.simulator \
com.android.dialer.feedback \
+ com.android.dialer.glidephotomanager.impl \
com.android.dialer.interactions \
com.android.dialer.lettertile \
com.android.dialer.location \