1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dialer.glidephotomanager.impl; 18 19 import android.content.ContentUris; 20 import android.content.Context; 21 import android.graphics.drawable.Drawable; 22 import android.net.Uri; 23 import android.provider.ContactsContract.Data; 24 import android.support.annotation.MainThread; 25 import android.support.annotation.Nullable; 26 import android.telecom.TelecomManager; 27 import android.text.TextUtils; 28 import android.widget.QuickContactBadge; 29 import com.android.dialer.common.Assert; 30 import com.android.dialer.glide.GlideApp; 31 import com.android.dialer.glide.GlideRequest; 32 import com.android.dialer.glide.GlideRequests; 33 import com.android.dialer.glidephotomanager.GlidePhotoManager; 34 import com.android.dialer.glidephotomanager.PhotoInfo; 35 import com.android.dialer.inject.ApplicationContext; 36 import com.android.dialer.lettertile.LetterTileDrawable; 37 import javax.inject.Inject; 38 39 /** Implementation of {@link GlidePhotoManager} */ 40 public class GlidePhotoManagerImpl implements GlidePhotoManager { 41 private final Context appContext; 42 43 @Inject GlidePhotoManagerImpl(@pplicationContext Context appContext)44 public GlidePhotoManagerImpl(@ApplicationContext Context appContext) { 45 this.appContext = appContext; 46 } 47 48 @MainThread 49 @Override loadQuickContactBadge(QuickContactBadge badge, PhotoInfo photoInfo)50 public void loadQuickContactBadge(QuickContactBadge badge, PhotoInfo photoInfo) { 51 Assert.isMainThread(); 52 badge.assignContactUri(parseUri(photoInfo.lookupUri())); 53 badge.setOverlay(null); 54 GlideRequest<Drawable> request = buildRequest(GlideApp.with(badge), photoInfo); 55 request.into(badge); 56 } 57 buildRequest(GlideRequests requestManager, PhotoInfo photoInfo)58 private GlideRequest<Drawable> buildRequest(GlideRequests requestManager, PhotoInfo photoInfo) { 59 // Warning: Glide ignores extra attributes on BitmapDrawable such as tint and draw the bitmap 60 // directly so be sure not to set tint in the XML of any drawable referenced below. 61 62 GlideRequest<Drawable> request; 63 boolean circleCrop = true; // Photos are cropped to a circle by default. 64 65 if (photoInfo.isBlocked()) { 66 // Whether the number is blocked takes precedence over the spam status. 67 request = requestManager.load(R.drawable.ic_block_grey_48dp); 68 69 } else if (photoInfo.isSpam()) { 70 request = requestManager.load(R.drawable.quantum_ic_report_vd_red_24); 71 circleCrop = false; // The spam icon is an octagon so we don't crop it. 72 73 } else if (!TextUtils.isEmpty(photoInfo.photoUri())) { 74 request = requestManager.load(parseUri(photoInfo.photoUri())); 75 76 } else if (photoInfo.photoId() != 0) { 77 request = 78 requestManager.load(ContentUris.withAppendedId(Data.CONTENT_URI, photoInfo.photoId())); 79 80 } else { 81 // load null to indicate fallback should be used. 82 request = requestManager.load((Object) null); 83 } 84 85 LetterTileDrawable defaultDrawable = getDefaultDrawable(photoInfo); 86 request 87 .placeholder(defaultDrawable) // when the photo is still loading. 88 .fallback(defaultDrawable); // when there's nothing to load. 89 90 if (circleCrop) { 91 request.circleCrop(); 92 } 93 94 return request; 95 } 96 97 /** 98 * Generate the default drawable when photos are not available. Used when the photo is loading or 99 * no photo is available. 100 */ getDefaultDrawable(PhotoInfo photoInfo)101 private LetterTileDrawable getDefaultDrawable(PhotoInfo photoInfo) { 102 LetterTileDrawable letterTileDrawable = new LetterTileDrawable(appContext.getResources()); 103 String displayName; 104 String identifier; 105 if (TextUtils.isEmpty(photoInfo.lookupUri())) { 106 // Use generic avatar instead of letter for non-contacts. 107 displayName = null; 108 identifier = 109 TextUtils.isEmpty(photoInfo.name()) ? photoInfo.formattedNumber() : photoInfo.name(); 110 } else { 111 displayName = photoInfo.name(); 112 identifier = photoInfo.lookupUri(); 113 } 114 letterTileDrawable.setCanonicalDialerLetterTileDetails( 115 displayName, 116 identifier, 117 LetterTileDrawable.SHAPE_CIRCLE, 118 LetterTileDrawable.getContactTypeFromPrimitives( 119 photoInfo.isVoicemail(), 120 photoInfo.isSpam(), 121 photoInfo.isBusiness(), 122 TelecomManager.PRESENTATION_ALLOWED, // TODO(twyen):implement 123 false)); // TODO(twyen):implement 124 return letterTileDrawable; 125 } 126 127 @Nullable parseUri(@ullable String uri)128 private static Uri parseUri(@Nullable String uri) { 129 return TextUtils.isEmpty(uri) ? null : Uri.parse(uri); 130 } 131 } 132