summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormaxwelb <maxwelb@google.com>2017-07-10 13:33:40 -0700
committerEric Erfanian <erfanian@google.com>2017-07-10 13:36:47 -0700
commit9ef68bd518def395a5b9cbc8b8d4646c9d27e8d6 (patch)
tree67496cf4485559ded1a2b4b0c158380be0858656
parent503b8f44e36ca00b9b5797f637023b9f743dc9dd (diff)
downloadandroid_packages_apps_Dialer-9ef68bd518def395a5b9cbc8b8d4646c9d27e8d6.tar.gz
android_packages_apps_Dialer-9ef68bd518def395a5b9cbc8b8d4646c9d27e8d6.tar.bz2
android_packages_apps_Dialer-9ef68bd518def395a5b9cbc8b8d4646c9d27e8d6.zip
Remove letter tile's manual asset caching
In b/63143138 we discovered an issue with the LetterTileDrawable code. The class has static fields that are shared across both the main and background threads, which aren't threadsafe. We attempted to make the code threadsafe in cl/160696979, but that ended up causing issues as well. This CL takes a different approach. Rather than trying to make the code threadsafe, it instead removes the shared fields and makes them final and initialized in the constructor. This is inherently threadsafe since threads cannot interact with the object until it is constructed. Now that the objects aren't shared, we would potentially use more memory, since each LetterTileDrawable will now hold onto an instance of the formally shared object. This was not determined to be an issue in practice, see the data and conclusion in (go/lettertiledrawable-caching). Bug: 63143138 Test: LetterTileDrawableTest (can't verify everything :/ ) PiperOrigin-RevId: 161432711 Change-Id: I443bef01ffac405f5e14e9d981ce1d5a8f3f8fec
-rw-r--r--java/com/android/contacts/common/lettertiles/LetterTileDrawable.java122
1 files changed, 56 insertions, 66 deletions
diff --git a/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java b/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java
index 5c401fe38..73809c467 100644
--- a/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java
+++ b/java/com/android/contacts/common/lettertiles/LetterTileDrawable.java
@@ -34,7 +34,6 @@ import android.support.annotation.Nullable;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import com.android.contacts.common.R;
-import com.android.contacts.common.lettertiles.LetterTileDrawable.ContactType;
import com.android.dialer.common.Assert;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -88,24 +87,24 @@ public class LetterTileDrawable extends Drawable {
private static final float VECTOR_ICON_SCALE = 0.7f;
/** Reusable components to avoid new allocations */
- private static final Paint sPaint = new Paint();
+ private final Paint mPaint = new Paint();
+
+ private final Rect mRect = new Rect();
+ private final char[] mFirstChar = new char[1];
- private static final Rect sRect = new Rect();
- private static final char[] sFirstChar = new char[1];
/** Letter tile */
- private static TypedArray sColors;
-
- private static int sSpamColor;
- private static int sDefaultColor;
- private static int sTileFontColor;
- private static float sLetterToTileRatio;
- private static Drawable sDefaultPersonAvatar;
- private static Drawable sDefaultBusinessAvatar;
- private static Drawable sDefaultVoicemailAvatar;
- private static Drawable sDefaultSpamAvatar;
- private static Drawable sDefaultConferenceAvatar;
-
- private final Paint mPaint;
+ @NonNull private final TypedArray mColors;
+
+ private final int mSpamColor;
+ private final int mDefaultColor;
+ private final int mTileFontColor;
+ private final float mLetterToTileRatio;
+ @NonNull private final Drawable mDefaultPersonAvatar;
+ @NonNull private final Drawable mDefaultBusinessAvatar;
+ @NonNull private final Drawable mDefaultVoicemailAvatar;
+ @NonNull private final Drawable mDefaultSpamAvatar;
+ @NonNull private final Drawable mDefaultConferenceAvatar;
+
@ContactType private int mContactType = TYPE_DEFAULT;
private float mScale = 1.0f;
private float mOffset = 0.0f;
@@ -117,33 +116,25 @@ public class LetterTileDrawable extends Drawable {
private String mDisplayName;
public LetterTileDrawable(final Resources res) {
- if (sColors == null) {
- sColors = res.obtainTypedArray(R.array.letter_tile_colors);
- sSpamColor = res.getColor(R.color.spam_contact_background);
- sDefaultColor = res.getColor(R.color.letter_tile_default_color);
- sTileFontColor = res.getColor(R.color.letter_tile_font_color);
- sLetterToTileRatio = res.getFraction(R.dimen.letter_to_tile_ratio, 1, 1);
- sDefaultPersonAvatar =
- res.getDrawable(R.drawable.product_logo_avatar_anonymous_white_color_120, null);
- Assert.isNotNull(sDefaultPersonAvatar, "sDefaultPersonAvatar is null");
- sDefaultBusinessAvatar = res.getDrawable(R.drawable.quantum_ic_business_vd_theme_24, null);
- Assert.isNotNull(sDefaultBusinessAvatar, "sDefaultBusinessAvatar is null");
- sDefaultVoicemailAvatar = res.getDrawable(R.drawable.quantum_ic_voicemail_vd_theme_24, null);
- Assert.isNotNull(sDefaultVoicemailAvatar, "sDefaultVoicemailAvatar is null");
- sDefaultSpamAvatar = res.getDrawable(R.drawable.quantum_ic_report_vd_theme_24, null);
- Assert.isNotNull(sDefaultSpamAvatar, "sDefaultSpamAvatar is null");
- sDefaultConferenceAvatar = res.getDrawable(R.drawable.quantum_ic_group_vd_theme_24, null);
- Assert.isNotNull(sDefaultConferenceAvatar, "sDefaultConferenceAvatar is null");
-
- sPaint.setTypeface(
- Typeface.create(res.getString(R.string.letter_tile_letter_font_family), Typeface.NORMAL));
- sPaint.setTextAlign(Align.CENTER);
- sPaint.setAntiAlias(true);
- }
- mPaint = new Paint();
+ mColors = res.obtainTypedArray(R.array.letter_tile_colors);
+ mSpamColor = res.getColor(R.color.spam_contact_background);
+ mDefaultColor = res.getColor(R.color.letter_tile_default_color);
+ mTileFontColor = res.getColor(R.color.letter_tile_font_color);
+ mLetterToTileRatio = res.getFraction(R.dimen.letter_to_tile_ratio, 1, 1);
+ mDefaultPersonAvatar =
+ res.getDrawable(R.drawable.product_logo_avatar_anonymous_white_color_120, null);
+ mDefaultBusinessAvatar = res.getDrawable(R.drawable.quantum_ic_business_vd_theme_24, null);
+ mDefaultVoicemailAvatar = res.getDrawable(R.drawable.quantum_ic_voicemail_vd_theme_24, null);
+ mDefaultSpamAvatar = res.getDrawable(R.drawable.quantum_ic_report_vd_theme_24, null);
+ mDefaultConferenceAvatar = res.getDrawable(R.drawable.quantum_ic_group_vd_theme_24, null);
+
+ mPaint.setTypeface(
+ Typeface.create(res.getString(R.string.letter_tile_letter_font_family), Typeface.NORMAL));
+ mPaint.setTextAlign(Align.CENTER);
+ mPaint.setAntiAlias(true);
mPaint.setFilterBitmap(true);
mPaint.setDither(true);
- mColor = sDefaultColor;
+ mColor = mDefaultColor;
}
private Rect getScaledBounds(float scale, float offset) {
@@ -165,20 +156,20 @@ public class LetterTileDrawable extends Drawable {
switch (contactType) {
case TYPE_BUSINESS:
mScale = VECTOR_ICON_SCALE;
- return sDefaultBusinessAvatar;
+ return mDefaultBusinessAvatar;
case TYPE_VOICEMAIL:
mScale = VECTOR_ICON_SCALE;
- return sDefaultVoicemailAvatar;
+ return mDefaultVoicemailAvatar;
case TYPE_SPAM:
mScale = VECTOR_ICON_SCALE;
- return sDefaultSpamAvatar;
+ return mDefaultSpamAvatar;
case TYPE_CONFERENCE:
mScale = VECTOR_ICON_SCALE;
- return sDefaultConferenceAvatar;
+ return mDefaultConferenceAvatar;
case TYPE_PERSON:
case TYPE_GENERIC_AVATAR:
default:
- return sDefaultPersonAvatar;
+ return mDefaultPersonAvatar;
}
}
@@ -206,39 +197,38 @@ public class LetterTileDrawable extends Drawable {
private void drawLetterTile(final Canvas canvas) {
// Draw background color.
- sPaint.setColor(mColor);
- sPaint.setAlpha(mPaint.getAlpha());
+ mPaint.setColor(mColor);
final Rect bounds = getBounds();
final int minDimension = Math.min(bounds.width(), bounds.height());
if (mIsCircle) {
- canvas.drawCircle(bounds.centerX(), bounds.centerY(), minDimension / 2, sPaint);
+ canvas.drawCircle(bounds.centerX(), bounds.centerY(), minDimension / 2, mPaint);
} else {
- canvas.drawRect(bounds, sPaint);
+ canvas.drawRect(bounds, mPaint);
}
// Draw letter/digit only if the first character is an english letter or there's a override
if (mLetter != null) {
// Draw letter or digit.
- sFirstChar[0] = mLetter;
+ mFirstChar[0] = mLetter;
// Scale text by canvas bounds and user selected scaling factor
- sPaint.setTextSize(mScale * sLetterToTileRatio * minDimension);
- sPaint.getTextBounds(sFirstChar, 0, 1, sRect);
- sPaint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
- sPaint.setColor(sTileFontColor);
- sPaint.setAlpha(ALPHA);
+ mPaint.setTextSize(mScale * mLetterToTileRatio * minDimension);
+ mPaint.getTextBounds(mFirstChar, 0, 1, mRect);
+ mPaint.setTypeface(Typeface.create("sans-serif", Typeface.NORMAL));
+ mPaint.setColor(mTileFontColor);
+ mPaint.setAlpha(ALPHA);
// Draw the letter in the canvas, vertically shifted up or down by the user-defined
// offset
canvas.drawText(
- sFirstChar,
+ mFirstChar,
0,
1,
bounds.centerX(),
- bounds.centerY() + mOffset * bounds.height() - sRect.exactCenterY(),
- sPaint);
+ bounds.centerY() + mOffset * bounds.height() - mRect.exactCenterY(),
+ mPaint);
} else {
// Draw the default image if there is no letter/digit to be drawn
Drawable drawable = getDrawableForContactType(mContactType);
@@ -248,7 +238,7 @@ public class LetterTileDrawable extends Drawable {
}
drawable.setBounds(getScaledBounds(mScale, mOffset));
- drawable.setAlpha(drawable == sDefaultSpamAvatar ? SPAM_ALPHA : ALPHA);
+ drawable.setAlpha(drawable == mDefaultSpamAvatar ? SPAM_ALPHA : ALPHA);
drawable.draw(canvas);
}
}
@@ -265,20 +255,20 @@ public class LetterTileDrawable extends Drawable {
/** Returns a deterministic color based on the provided contact identifier string. */
private int pickColor(final String identifier) {
if (mContactType == TYPE_SPAM) {
- return sSpamColor;
+ return mSpamColor;
}
if (mContactType == TYPE_VOICEMAIL
|| mContactType == TYPE_BUSINESS
|| TextUtils.isEmpty(identifier)) {
- return sDefaultColor;
+ return mDefaultColor;
}
// String.hashCode() implementation is not supposed to change across java versions, so
// this should guarantee the same email address always maps to the same color.
// The email should already have been normalized by the ContactRequest.
- final int color = Math.abs(identifier.hashCode()) % sColors.length();
- return sColors.getColor(color, sDefaultColor);
+ final int color = Math.abs(identifier.hashCode()) % mColors.length();
+ return mColors.getColor(color, mDefaultColor);
}
@Override
@@ -354,7 +344,7 @@ public class LetterTileDrawable extends Drawable {
return this;
}
- public LetterTileDrawable setContactType(@ContactType int contactType) {
+ private LetterTileDrawable setContactType(@ContactType int contactType) {
mContactType = contactType;
return this;
}