1 /* 2 * Copyright (C) 2016 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.contactinfo; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.graphics.Canvas; 22 import android.graphics.drawable.Drawable; 23 import android.provider.MediaStore; 24 import android.support.annotation.Nullable; 25 import android.support.v4.graphics.drawable.RoundedBitmapDrawable; 26 import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory; 27 import android.util.Log; 28 29 import com.android.contacts.common.GeoUtil; 30 import com.android.contacts.common.lettertiles.LetterTileDrawable; 31 import com.android.dialer.R; 32 import com.android.dialer.calllog.ContactInfo; 33 import com.android.dialer.calllog.ContactInfoHelper; 34 import com.android.dialer.util.Assert; 35 import com.google.common.annotations.VisibleForTesting; 36 import com.google.common.base.Preconditions; 37 38 import java.io.IOException; 39 /** 40 * Class to create the appropriate contact icon from a ContactInfo. 41 * This class is for synchronous, blocking calls to generate bitmaps, while 42 * ContactCommons.ContactPhotoManager is to cache, manage and update a ImageView asynchronously. 43 */ 44 public class ContactPhotoLoader { 45 46 private static final String TAG = "ContactPhotoLoader"; 47 48 private final Context mContext; 49 private final ContactInfo mContactInfo; 50 51 public ContactPhotoLoader(Context context, ContactInfo contactInfo) { 52 mContext = Preconditions.checkNotNull(context); 53 mContactInfo = Preconditions.checkNotNull(contactInfo); 54 } 55 56 /** 57 * Create a contact photo icon bitmap appropriate for the ContactInfo. 58 */ 59 public Bitmap loadPhotoIcon() { 60 Assert.assertNotUiThread("ContactPhotoLoader#loadPhotoIcon called on UI thread"); 61 int photoSize = mContext.getResources().getDimensionPixelSize(R.dimen.contact_photo_size); 62 return drawableToBitmap(getIcon(), photoSize, photoSize); 63 } 64 65 @VisibleForTesting 66 Drawable getIcon() { 67 Drawable drawable = createPhotoIconDrawable(); 68 if (drawable == null) { 69 drawable = createLetterTileDrawable(); 70 } 71 return drawable; 72 } 73 74 /** 75 * @return a {@link Drawable} of circular photo icon if the photo can be loaded, {@code null} 76 * otherwise. 77 */ 78 @Nullable 79 private Drawable createPhotoIconDrawable() { 80 if (mContactInfo.photoUri == null) { 81 return null; 82 } 83 try { 84 Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), 85 mContactInfo.photoUri); 86 final RoundedBitmapDrawable drawable = 87 RoundedBitmapDrawableFactory.create(mContext.getResources(), bitmap); 88 drawable.setAntiAlias(true); 89 drawable.setCornerRadius(bitmap.getHeight() / 2); 90 return drawable; 91 } catch (IOException e) { 92 Log.e(TAG, e.toString()); 93 return null; 94 } 95 } 96 97 /** 98 * @return a {@link LetterTileDrawable} based on the ContactInfo. 99 */ 100 private Drawable createLetterTileDrawable() { 101 LetterTileDrawable drawable = new LetterTileDrawable(mContext.getResources()); 102 drawable.setIsCircular(true); 103 ContactInfoHelper helper = 104 new ContactInfoHelper(mContext, GeoUtil.getCurrentCountryIso(mContext)); 105 if (helper.isBusiness(mContactInfo.sourceType)) { 106 drawable.setContactType(LetterTileDrawable.TYPE_BUSINESS); 107 } 108 drawable.setLetterAndColorFromContactDetails(mContactInfo.name, mContactInfo.lookupKey); 109 return drawable; 110 } 111 112 private static Bitmap drawableToBitmap(Drawable drawable, int width, int height) { 113 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 114 Canvas canvas = new Canvas(bitmap); 115 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 116 drawable.draw(canvas); 117 return bitmap; 118 } 119 120 } 121