• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.shortcuts;
18 
19 import android.content.Context;
20 import android.content.pm.ShortcutInfo;
21 import android.graphics.Bitmap;
22 import android.graphics.BitmapFactory;
23 import android.graphics.drawable.Drawable;
24 import android.graphics.drawable.Icon;
25 import android.net.Uri;
26 import android.provider.ContactsContract;
27 import android.support.annotation.NonNull;
28 import android.support.annotation.WorkerThread;
29 import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
30 import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
31 import com.android.contacts.common.lettertiles.LetterTileDrawable;
32 import com.android.dialer.common.Assert;
33 import com.android.dialer.util.DrawableConverter;
34 import java.io.InputStream;
35 
36 /** Constructs the icons for dialer shortcuts. */
37 class IconFactory {
38 
39   private final Context context;
40 
IconFactory(@onNull Context context)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
create(@onNull DialerShortcut shortcut)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
create(@onNull ShortcutInfo shortcutInfo)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
create( @onNull Uri lookupUri, @NonNull String displayName, @NonNull String lookupKey)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
createCircularDrawable(@onNull Bitmap bitmap)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 }
113