1bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen/*
2bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * Copyright (C) 2016 The Android Open Source Project
3bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen *
4bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * Licensed under the Apache License, Version 2.0 (the "License");
5bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * you may not use this file except in compliance with the License.
6bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * You may obtain a copy of the License at
7bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen *
8bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen *      http://www.apache.org/licenses/LICENSE-2.0
9bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen *
10bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * Unless required by applicable law or agreed to in writing, software
11bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * distributed under the License is distributed on an "AS IS" BASIS,
12bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * See the License for the specific language governing permissions and
14bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * limitations under the License.
15bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen */
16bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
17bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenpackage com.android.dialer.contactinfo;
18bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
19bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.content.Context;
20bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.graphics.Bitmap;
21bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.graphics.Canvas;
22bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.graphics.drawable.Drawable;
23bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.provider.MediaStore;
24bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.support.annotation.Nullable;
25bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.support.v4.graphics.drawable.RoundedBitmapDrawable;
26bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
27bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport android.util.Log;
28bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
29bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.android.contacts.common.GeoUtil;
30bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.android.contacts.common.lettertiles.LetterTileDrawable;
31bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.android.dialer.R;
32bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.android.dialer.calllog.ContactInfo;
33bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.android.dialer.calllog.ContactInfoHelper;
34bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.android.dialer.util.Assert;
35bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.google.common.annotations.VisibleForTesting;
36bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport com.google.common.base.Preconditions;
37bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
38bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenimport java.io.IOException;
39bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen/**
40bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * Class to create the appropriate contact icon from a ContactInfo.
41bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * This class is for synchronous, blocking calls to generate bitmaps, while
42bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen * ContactCommons.ContactPhotoManager is to cache, manage and update a ImageView asynchronously.
43bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen */
44bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yenpublic class ContactPhotoLoader {
45bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
46bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    private static final String TAG = "ContactPhotoLoader";
47bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
48bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    private final Context mContext;
49bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    private final ContactInfo mContactInfo;
50bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
51bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    public ContactPhotoLoader(Context context, ContactInfo contactInfo) {
52bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        mContext = Preconditions.checkNotNull(context);
53bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        mContactInfo = Preconditions.checkNotNull(contactInfo);
54bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    }
55bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
56bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    /**
57bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen     * Create a contact photo icon bitmap appropriate for the ContactInfo.
58bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen     */
59bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    public Bitmap loadPhotoIcon() {
60bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        Assert.assertNotUiThread("ContactPhotoLoader#loadPhotoIcon called on UI thread");
61bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        int photoSize = mContext.getResources().getDimensionPixelSize(R.dimen.contact_photo_size);
62bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        return drawableToBitmap(getIcon(), photoSize, photoSize);
63bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    }
64bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
65bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    @VisibleForTesting
66bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    Drawable getIcon() {
67bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        Drawable drawable = createPhotoIconDrawable();
68bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        if (drawable == null) {
69bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            drawable = createLetterTileDrawable();
70bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        }
71bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        return drawable;
72bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    }
73bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
74bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    /**
75bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen     * @return a {@link Drawable} of  circular photo icon if the photo can be loaded, {@code null}
76bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen     * otherwise.
77bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen     */
78bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    @Nullable
79bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    private Drawable createPhotoIconDrawable() {
80bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        if (mContactInfo.photoUri == null) {
81bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            return null;
82bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        }
83bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        try {
84bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(),
85bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen                    mContactInfo.photoUri);
86bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            final RoundedBitmapDrawable drawable =
87bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen                    RoundedBitmapDrawableFactory.create(mContext.getResources(), bitmap);
88bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            drawable.setAntiAlias(true);
89bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            drawable.setCornerRadius(bitmap.getHeight() / 2);
90bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            return drawable;
91bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        } catch (IOException e) {
92bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            Log.e(TAG, e.toString());
93bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            return null;
94bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        }
95bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    }
96bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
97bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    /**
98bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen     * @return a {@link LetterTileDrawable} based on the ContactInfo.
99bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen     */
100bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    private Drawable createLetterTileDrawable() {
101bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        LetterTileDrawable drawable = new LetterTileDrawable(mContext.getResources());
102bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        drawable.setIsCircular(true);
103bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        ContactInfoHelper helper =
104bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen                new ContactInfoHelper(mContext, GeoUtil.getCurrentCountryIso(mContext));
105bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        if (helper.isBusiness(mContactInfo.sourceType)) {
106bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen            drawable.setContactType(LetterTileDrawable.TYPE_BUSINESS);
107bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        }
108bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        drawable.setLetterAndColorFromContactDetails(mContactInfo.name, mContactInfo.lookupKey);
109bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        return drawable;
110bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    }
111bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
112bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    private static Bitmap drawableToBitmap(Drawable drawable, int width, int height) {
113bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
114bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        Canvas canvas = new Canvas(bitmap);
115bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
116bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        drawable.draw(canvas);
117bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen        return bitmap;
118bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen    }
119bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen
120bcb15f99dff4e01343bb7470135f5392a65a01f4Ta-wei Yen}
121