diff options
author | maxwelb <maxwelb@google.com> | 2017-07-10 13:33:40 -0700 |
---|---|---|
committer | Eric Erfanian <erfanian@google.com> | 2017-07-10 13:36:47 -0700 |
commit | 9ef68bd518def395a5b9cbc8b8d4646c9d27e8d6 (patch) | |
tree | 67496cf4485559ded1a2b4b0c158380be0858656 /java/com | |
parent | 503b8f44e36ca00b9b5797f637023b9f743dc9dd (diff) |
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
Diffstat (limited to 'java/com')
-rw-r--r-- | java/com/android/contacts/common/lettertiles/LetterTileDrawable.java | 122 |
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; } |