blob: a8c4ada4e8540967a20b9e0324a5f0aafb4c931b [file] [log] [blame]
Eric Erfanianccca3152017-02-22 16:32:36 -08001/*
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
17package com.android.dialer.shortcuts;
18
19import android.content.Context;
20import android.content.pm.ShortcutInfo;
21import android.graphics.Bitmap;
22import android.graphics.BitmapFactory;
23import android.graphics.drawable.Drawable;
24import android.graphics.drawable.Icon;
25import android.net.Uri;
26import android.provider.ContactsContract;
27import android.support.annotation.NonNull;
28import android.support.annotation.WorkerThread;
29import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
30import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
31import com.android.contacts.common.lettertiles.LetterTileDrawable;
32import com.android.dialer.common.Assert;
33import com.android.dialer.util.DrawableConverter;
34import java.io.InputStream;
35
36/** Constructs the icons for dialer shortcuts. */
37class IconFactory {
38
39 private final Context context;
40
41 IconFactory(@NonNull Context context) {
42 this.context = context;
43 }
44
45 /**
46 * Creates an icon for the provided {@link DialerShortcut}.
47 *
48 * <p>The icon is a circle which contains a photo of the contact associated with the shortcut, if
49 * available. If a photo is not available, a circular colored icon with a single letter is instead
50 * created, where the letter is the first letter of the contact's name. If the contact has no
51 * name, a default colored "anonymous" avatar is used.
52 *
53 * <p>These icons should match exactly the favorites tiles in the starred tab of the dialer
54 * application, except that they are circular instead of rectangular.
55 */
56 @WorkerThread
57 @NonNull
58 public Icon create(@NonNull DialerShortcut shortcut) {
59 Assert.isWorkerThread();
60
61 return create(shortcut.getLookupUri(), shortcut.getDisplayName(), shortcut.getLookupKey());
62 }
63
64 /** Same as {@link #create(DialerShortcut)}, but accepts a {@link ShortcutInfo}. */
65 @WorkerThread
66 @NonNull
67 public Icon create(@NonNull ShortcutInfo shortcutInfo) {
68 Assert.isWorkerThread();
69 return create(
70 DialerShortcut.getLookupUriFromShortcutInfo(shortcutInfo),
71 DialerShortcut.getDisplayNameFromShortcutInfo(shortcutInfo),
72 DialerShortcut.getLookupKeyFromShortcutInfo(shortcutInfo));
73 }
74
75 @WorkerThread
76 @NonNull
77 private Icon create(
78 @NonNull Uri lookupUri, @NonNull String displayName, @NonNull String lookupKey) {
79 Assert.isWorkerThread();
80
81 // In testing, there was no difference between high-res and thumbnail.
82 InputStream inputStream =
83 ContactsContract.Contacts.openContactPhotoInputStream(
84 context.getContentResolver(), lookupUri, false /* preferHighres */);
85
86 Drawable drawable;
87 if (inputStream == null) {
88 // No photo for contact; use a letter tile.
89 LetterTileDrawable letterTileDrawable = new LetterTileDrawable(context.getResources());
90 letterTileDrawable.setCanonicalDialerLetterTileDetails(
91 displayName, lookupKey, LetterTileDrawable.SHAPE_CIRCLE, LetterTileDrawable.TYPE_DEFAULT);
92 drawable = letterTileDrawable;
93 } else {
94 // There's a photo, create a circular drawable from it.
95 Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
96 drawable = createCircularDrawable(bitmap);
97 }
98 int iconSize =
99 context.getResources().getDimensionPixelSize(R.dimen.launcher_shortcut_icon_size);
100 return Icon.createWithBitmap(
101 DrawableConverter.drawableToBitmap(drawable, iconSize /* width */, iconSize /* height */));
102 }
103
104 @NonNull
105 private Drawable createCircularDrawable(@NonNull Bitmap bitmap) {
106 RoundedBitmapDrawable roundedBitmapDrawable =
107 RoundedBitmapDrawableFactory.create(context.getResources(), bitmap);
108 roundedBitmapDrawable.setCircular(true);
109 roundedBitmapDrawable.setAntiAlias(true);
110 return roundedBitmapDrawable;
111 }
112}