summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/shortcuts/IconFactory.java
blob: a8c4ada4e8540967a20b9e0324a5f0aafb4c931b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dialer.shortcuts;

import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.annotation.WorkerThread;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import com.android.contacts.common.lettertiles.LetterTileDrawable;
import com.android.dialer.common.Assert;
import com.android.dialer.util.DrawableConverter;
import java.io.InputStream;

/** Constructs the icons for dialer shortcuts. */
class IconFactory {

  private final Context context;

  IconFactory(@NonNull Context context) {
    this.context = context;
  }

  /**
   * Creates an icon for the provided {@link DialerShortcut}.
   *
   * <p>The icon is a circle which contains a photo of the contact associated with the shortcut, if
   * available. If a photo is not available, a circular colored icon with a single letter is instead
   * created, where the letter is the first letter of the contact's name. If the contact has no
   * name, a default colored "anonymous" avatar is used.
   *
   * <p>These icons should match exactly the favorites tiles in the starred tab of the dialer
   * application, except that they are circular instead of rectangular.
   */
  @WorkerThread
  @NonNull
  public Icon create(@NonNull DialerShortcut shortcut) {
    Assert.isWorkerThread();

    return create(shortcut.getLookupUri(), shortcut.getDisplayName(), shortcut.getLookupKey());
  }

  /** Same as {@link #create(DialerShortcut)}, but accepts a {@link ShortcutInfo}. */
  @WorkerThread
  @NonNull
  public Icon create(@NonNull ShortcutInfo shortcutInfo) {
    Assert.isWorkerThread();
    return create(
        DialerShortcut.getLookupUriFromShortcutInfo(shortcutInfo),
        DialerShortcut.getDisplayNameFromShortcutInfo(shortcutInfo),
        DialerShortcut.getLookupKeyFromShortcutInfo(shortcutInfo));
  }

  @WorkerThread
  @NonNull
  private Icon create(
      @NonNull Uri lookupUri, @NonNull String displayName, @NonNull String lookupKey) {
    Assert.isWorkerThread();

    // In testing, there was no difference between high-res and thumbnail.
    InputStream inputStream =
        ContactsContract.Contacts.openContactPhotoInputStream(
            context.getContentResolver(), lookupUri, false /* preferHighres */);

    Drawable drawable;
    if (inputStream == null) {
      // No photo for contact; use a letter tile.
      LetterTileDrawable letterTileDrawable = new LetterTileDrawable(context.getResources());
      letterTileDrawable.setCanonicalDialerLetterTileDetails(
          displayName, lookupKey, LetterTileDrawable.SHAPE_CIRCLE, LetterTileDrawable.TYPE_DEFAULT);
      drawable = letterTileDrawable;
    } else {
      // There's a photo, create a circular drawable from it.
      Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
      drawable = createCircularDrawable(bitmap);
    }
    int iconSize =
        context.getResources().getDimensionPixelSize(R.dimen.launcher_shortcut_icon_size);
    return Icon.createWithBitmap(
        DrawableConverter.drawableToBitmap(drawable, iconSize /* width */, iconSize /* height */));
  }

  @NonNull
  private Drawable createCircularDrawable(@NonNull Bitmap bitmap) {
    RoundedBitmapDrawable roundedBitmapDrawable =
        RoundedBitmapDrawableFactory.create(context.getResources(), bitmap);
    roundedBitmapDrawable.setCircular(true);
    roundedBitmapDrawable.setAntiAlias(true);
    return roundedBitmapDrawable;
  }
}