1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2013 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License.
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.contacts.common.lettertiles;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.res.Resources;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.content.res.TypedArray;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Bitmap;
22d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanianimport android.graphics.Bitmap.Config;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Canvas;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.ColorFilter;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Outline;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Paint;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Paint.Align;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Rect;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Typeface;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.drawable.Drawable;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.IntDef;
322f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.annotation.NonNull;
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.support.annotation.Nullable;
342f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.telecom.TelecomManager;
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.text.TextUtils;
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.contacts.common.R;
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.Assert;
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.lang.annotation.Retention;
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.lang.annotation.RetentionPolicy;
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/**
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * A drawable that encapsulates all the functionality needed to display a letter tile to represent a
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * contact image.
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class LetterTileDrawable extends Drawable {
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * ContactType indicates the avatar type of the contact. For a person or for the default when no
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * name is provided, it is {@link #TYPE_DEFAULT}, otherwise, for a business it is {@link
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * #TYPE_BUSINESS}, and voicemail contacts should use {@link #TYPE_VOICEMAIL}.
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Retention(RetentionPolicy.SOURCE)
538369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  @IntDef({TYPE_PERSON, TYPE_BUSINESS, TYPE_VOICEMAIL, TYPE_GENERIC_AVATAR, TYPE_SPAM})
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public @interface ContactType {}
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Contact type constants */
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static final int TYPE_PERSON = 1;
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static final int TYPE_BUSINESS = 2;
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static final int TYPE_VOICEMAIL = 3;
60d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  /**
61d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * A generic avatar that features the default icon, default color, and no letter. Useful for
62d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   * situations where a contact is anonymous.
63d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian   */
64d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public static final int TYPE_GENERIC_AVATAR = 4;
658369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  public static final int TYPE_SPAM = 5;
6683b20211c3be04a850de3674977deee8e448d17fEric Erfanian  public static final int TYPE_CONFERENCE = 6;
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @ContactType public static final int TYPE_DEFAULT = TYPE_PERSON;
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Shape indicates the letter tile shape. It can be either a {@link #SHAPE_CIRCLE}, otherwise, it
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * is a {@link #SHAPE_RECTANGLE}.
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Retention(RetentionPolicy.SOURCE)
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @IntDef({SHAPE_CIRCLE, SHAPE_RECTANGLE})
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public @interface Shape {}
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Shape constants */
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static final int SHAPE_CIRCLE = 1;
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public static final int SHAPE_RECTANGLE = 2;
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** 54% opacity */
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int ALPHA = 138;
848369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  /** 100% opacity */
858369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  private static final int SPAM_ALPHA = 255;
868369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  /** Default icon scale for vector drawable. */
878369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  private static final float VECTOR_ICON_SCALE = 0.7f;
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Reusable components to avoid new allocations */
909ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private final Paint mPaint = new Paint();
919ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb
929ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private final Rect mRect = new Rect();
939ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private final char[] mFirstChar = new char[1];
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Letter tile */
969ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  @NonNull private final TypedArray mColors;
979ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb
989ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private final int mSpamColor;
999ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private final int mDefaultColor;
1009ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private final int mTileFontColor;
1019ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private final float mLetterToTileRatio;
1029ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  @NonNull private final Drawable mDefaultPersonAvatar;
1039ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  @NonNull private final Drawable mDefaultBusinessAvatar;
1049ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  @NonNull private final Drawable mDefaultVoicemailAvatar;
1059ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  @NonNull private final Drawable mDefaultSpamAvatar;
1069ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  @NonNull private final Drawable mDefaultConferenceAvatar;
1079ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb
1088369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  @ContactType private int mContactType = TYPE_DEFAULT;
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private float mScale = 1.0f;
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private float mOffset = 0.0f;
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mIsCircle = false;
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int mColor;
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Character mLetter = null;
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String mDisplayName;
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public LetterTileDrawable(final Resources res) {
1199ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mColors = res.obtainTypedArray(R.array.letter_tile_colors);
1209ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mSpamColor = res.getColor(R.color.spam_contact_background);
1219ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mDefaultColor = res.getColor(R.color.letter_tile_default_color);
1229ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mTileFontColor = res.getColor(R.color.letter_tile_font_color);
1239ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mLetterToTileRatio = res.getFraction(R.dimen.letter_to_tile_ratio, 1, 1);
1249ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mDefaultPersonAvatar =
1259ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb        res.getDrawable(R.drawable.product_logo_avatar_anonymous_white_color_120, null);
1269ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mDefaultBusinessAvatar = res.getDrawable(R.drawable.quantum_ic_business_vd_theme_24, null);
1279ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mDefaultVoicemailAvatar = res.getDrawable(R.drawable.quantum_ic_voicemail_vd_theme_24, null);
1289ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mDefaultSpamAvatar = res.getDrawable(R.drawable.quantum_ic_report_vd_theme_24, null);
1299ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mDefaultConferenceAvatar = res.getDrawable(R.drawable.quantum_ic_group_vd_theme_24, null);
1309ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb
1319ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mPaint.setTypeface(
1329ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb        Typeface.create(res.getString(R.string.letter_tile_letter_font_family), Typeface.NORMAL));
1339ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mPaint.setTextAlign(Align.CENTER);
1349ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mPaint.setAntiAlias(true);
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPaint.setFilterBitmap(true);
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPaint.setDither(true);
1379ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mColor = mDefaultColor;
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
1408369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  private Rect getScaledBounds(float scale, float offset) {
1418369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    // The drawable should be drawn in the middle of the canvas without changing its width to
1428369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    // height ratio.
1438369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    final Rect destRect = copyBounds();
1448369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    // Crop the destination bounds into a square, scaled and offset as appropriate
1458369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    final int halfLength = (int) (scale * Math.min(destRect.width(), destRect.height()) / 2);
1468369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian
1478369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    destRect.set(
1488369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian        destRect.centerX() - halfLength,
1498369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian        (int) (destRect.centerY() - halfLength + offset * destRect.height()),
1508369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian        destRect.centerX() + halfLength,
1518369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian        (int) (destRect.centerY() + halfLength + offset * destRect.height()));
1528369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    return destRect;
1538369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  }
1548369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian
1558369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian  private Drawable getDrawableForContactType(int contactType) {
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    switch (contactType) {
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      case TYPE_BUSINESS:
1588369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian        mScale = VECTOR_ICON_SCALE;
1599ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb        return mDefaultBusinessAvatar;
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      case TYPE_VOICEMAIL:
1618369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian        mScale = VECTOR_ICON_SCALE;
1629ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb        return mDefaultVoicemailAvatar;
1638369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      case TYPE_SPAM:
1648369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian        mScale = VECTOR_ICON_SCALE;
1659ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb        return mDefaultSpamAvatar;
16683b20211c3be04a850de3674977deee8e448d17fEric Erfanian      case TYPE_CONFERENCE:
16783b20211c3be04a850de3674977deee8e448d17fEric Erfanian        mScale = VECTOR_ICON_SCALE;
1689ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb        return mDefaultConferenceAvatar;
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      case TYPE_PERSON:
170d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      case TYPE_GENERIC_AVATAR:
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      default:
1729ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb        return mDefaultPersonAvatar;
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static boolean isEnglishLetter(final char c) {
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
1812f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public void draw(@NonNull final Canvas canvas) {
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final Rect bounds = getBounds();
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!isVisible() || bounds.isEmpty()) {
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Draw letter tile.
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    drawLetterTile(canvas);
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
190d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public Bitmap getBitmap(int width, int height) {
191d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
192d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    this.setBounds(0, 0, width, height);
193d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    Canvas canvas = new Canvas(bitmap);
194d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    this.draw(canvas);
195d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return bitmap;
196d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
197d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void drawLetterTile(final Canvas canvas) {
199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Draw background color.
2009ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    mPaint.setColor(mColor);
2018369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian
202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final Rect bounds = getBounds();
203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final int minDimension = Math.min(bounds.width(), bounds.height());
204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
205ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mIsCircle) {
2069ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      canvas.drawCircle(bounds.centerX(), bounds.centerY(), minDimension / 2, mPaint);
207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
2089ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      canvas.drawRect(bounds, mPaint);
209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Draw letter/digit only if the first character is an english letter or there's a override
212ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mLetter != null) {
213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Draw letter or digit.
2149ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      mFirstChar[0] = mLetter;
215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Scale text by canvas bounds and user selected scaling factor
2179ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      mPaint.setTextSize(mScale * mLetterToTileRatio * minDimension);
2189ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      mPaint.getTextBounds(mFirstChar, 0, 1, mRect);
2199ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      mPaint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
2209ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      mPaint.setColor(mTileFontColor);
2219ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      mPaint.setAlpha(ALPHA);
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Draw the letter in the canvas, vertically shifted up or down by the user-defined
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // offset
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      canvas.drawText(
2269ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb          mFirstChar,
227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          0,
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          1,
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          bounds.centerX(),
2309ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb          bounds.centerY() + mOffset * bounds.height() - mRect.exactCenterY(),
2319ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb          mPaint);
232ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
233ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Draw the default image if there is no letter/digit to be drawn
2348369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      Drawable drawable = getDrawableForContactType(mContactType);
2352f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      if (drawable == null) {
2362f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        throw Assert.createIllegalStateFailException(
2372f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            "Unable to find drawable for contact type " + mContactType);
2382f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      }
2392f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
2408369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      drawable.setBounds(getScaledBounds(mScale, mOffset));
2419ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      drawable.setAlpha(drawable == mDefaultSpamAvatar ? SPAM_ALPHA : ALPHA);
2428369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian      drawable.draw(canvas);
243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public int getColor() {
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mColor;
248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public LetterTileDrawable setColor(int color) {
251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mColor = color;
252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Returns a deterministic color based on the provided contact identifier string. */
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int pickColor(final String identifier) {
2578369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    if (mContactType == TYPE_SPAM) {
2589ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      return mSpamColor;
2598369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    }
2608369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian
261d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (mContactType == TYPE_VOICEMAIL
262d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        || mContactType == TYPE_BUSINESS
263d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        || TextUtils.isEmpty(identifier)) {
2649ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb      return mDefaultColor;
265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
2668369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian
267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // String.hashCode() implementation is not supposed to change across java versions, so
268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // this should guarantee the same email address always maps to the same color.
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // The email should already have been normalized by the ContactRequest.
2709ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    final int color = Math.abs(identifier.hashCode()) % mColors.length();
2719ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb    return mColors.getColor(color, mDefaultColor);
272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setAlpha(final int alpha) {
276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPaint.setAlpha(alpha);
277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
279ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
280ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setColorFilter(final ColorFilter cf) {
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPaint.setColorFilter(cf);
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public int getOpacity() {
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return android.graphics.PixelFormat.OPAQUE;
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @Override
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void getOutline(Outline outline) {
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mIsCircle) {
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      outline.setOval(getBounds());
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      outline.setRect(getBounds());
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    outline.setAlpha(1);
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Scale the drawn letter tile to a ratio of its default size
302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param scale The ratio the letter tile should be scaled to as a percentage of its default size,
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     from a scale of 0 to 2.0f. The default is 1.0f.
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public LetterTileDrawable setScale(float scale) {
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mScale = scale;
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Assigns the vertical offset of the position of the letter tile to the ContactDrawable
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param offset The provided offset must be within the range of -0.5f to 0.5f. If set to -0.5f,
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     the letter will be shifted upwards by 0.5 times the height of the canvas it is being drawn
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     on, which means it will be drawn with the center of the letter starting at the top edge of
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     the canvas. If set to 0.5f, the letter will be shifted downwards by 0.5 times the height of
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     the canvas it is being drawn on, which means it will be drawn with the center of the letter
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     starting at the bottom edge of the canvas. The default is 0.0f.
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public LetterTileDrawable setOffset(float offset) {
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Assert.checkArgument(offset >= -0.5f && offset <= 0.5f);
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mOffset = offset;
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public LetterTileDrawable setLetter(Character letter) {
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mLetter = letter;
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public Character getLetter() {
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this.mLetter;
334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private LetterTileDrawable setLetterAndColorFromContactDetails(
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final String displayName, final String identifier) {
3388369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    if (!TextUtils.isEmpty(displayName) && isEnglishLetter(displayName.charAt(0))) {
339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mLetter = Character.toUpperCase(displayName.charAt(0));
340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mLetter = null;
342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mColor = pickColor(identifier);
344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
3479ef68bd518def395a5b9cbc8b8d4646c9d27e8d6maxwelb  private LetterTileDrawable setContactType(@ContactType int contactType) {
348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mContactType = contactType;
349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  @ContactType
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public int getContactType() {
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this.mContactType;
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public LetterTileDrawable setIsCircular(boolean isCircle) {
358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mIsCircle = isCircle;
359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return this;
360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
362d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  public boolean tileIsCircular() {
363d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return this.mIsCircle;
364d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian  }
365d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /**
367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * Creates a canonical letter tile for use across dialer fragments.
368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *
369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param displayName The display name to produce the letter in the tile. Null values or numbers
370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   *     yield no letter.
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param identifierForTileColor The string used to produce the tile color.
372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param shape The shape of the tile.
373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @param contactType The type of contact, e.g. TYPE_VOICEMAIL.
374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   * @return this
375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian   */
376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public LetterTileDrawable setCanonicalDialerLetterTileDetails(
377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @Nullable final String displayName,
378ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @Nullable final String identifierForTileColor,
379ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      @Shape final int shape,
380ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      final int contactType) {
381d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
382d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    this.setIsCircular(shape == SHAPE_CIRCLE);
383d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    /**
385d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian     * We return quickly under the following conditions: 1. We are asked to draw a default tile, and
386d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian     * no coloring information is provided, meaning no further initialization is necessary OR 2.
387d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian     * We've already invoked this method before, set mDisplayName, and found that it has not
388d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian     * changed. This is useful during events like hangup, when we lose the call state for special
389d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian     * types of contacts, like voicemail. We keep track of the special case until we encounter a new
390d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian     * display name.
391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian     */
392d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    if (contactType == TYPE_DEFAULT
393d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian        && ((displayName == null && identifierForTileColor == null)
394d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian            || (displayName != null && displayName.equals(mDisplayName)))) {
395d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      return this;
396ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
397d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian
398ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    this.mDisplayName = displayName;
3998369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    setContactType(contactType);
400ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
401d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    // Special contact types receive default color and no letter tile, but special iconography.
4028369df095a73a77b3715f8ae7ba06089cebca4ceEric Erfanian    if (contactType != TYPE_PERSON) {
403d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian      this.setLetterAndColorFromContactDetails(null, null);
404ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
405ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (identifierForTileColor != null) {
406ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        this.setLetterAndColorFromContactDetails(displayName, identifierForTileColor);
407ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
408ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        this.setLetterAndColorFromContactDetails(displayName, displayName);
409ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
410ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
411d5e47f6da5b08b13ecdfa7f1edc7e12aeb83fab9Eric Erfanian    return this;
412ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
4132f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
4142f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  /**
4152f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian   * Returns the appropriate LetterTileDrawable.TYPE_ based on the given primitive conditions.
4162f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian   *
4172f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian   * <p>If no special state is detected, yields TYPE_DEFAULT
4182f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian   */
4192f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public static @ContactType int getContactTypeFromPrimitives(
4202f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      boolean isVoicemailNumber,
4212f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      boolean isSpam,
4222f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      boolean isBusiness,
4232f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      int numberPresentation,
4242f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      boolean isConference) {
4252f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    if (isVoicemailNumber) {
4262f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return LetterTileDrawable.TYPE_VOICEMAIL;
4272f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    } else if (isSpam) {
4282f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return LetterTileDrawable.TYPE_SPAM;
4292f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    } else if (isBusiness) {
4302f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return LetterTileDrawable.TYPE_BUSINESS;
4312f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    } else if (numberPresentation == TelecomManager.PRESENTATION_RESTRICTED) {
4322f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return LetterTileDrawable.TYPE_GENERIC_AVATAR;
4332f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    } else if (isConference) {
4342f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return LetterTileDrawable.TYPE_CONFERENCE;
4352f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    } else {
4362f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return LetterTileDrawable.TYPE_DEFAULT;
4372f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    }
4382f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
439ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
440