Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java |
index 94a7f3df7f0e7521d7ddb30dcf304a1a0a6a6cda..73cc5517833383513a37e2c506ed8f512b7e97eb 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java |
@@ -8,10 +8,12 @@ import android.animation.Animator; |
import android.animation.ObjectAnimator; |
import android.content.Context; |
import android.graphics.Bitmap; |
+import android.graphics.Bitmap.Config; |
import android.graphics.BitmapFactory; |
import android.graphics.Canvas; |
import android.graphics.Matrix; |
import android.graphics.Paint; |
+import android.graphics.drawable.Drawable; |
import android.text.TextUtils; |
import android.util.AttributeSet; |
import android.util.Property; |
@@ -24,9 +26,13 @@ import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; |
import java.lang.ref.WeakReference; |
+import jp.tomorrowkey.android.gifplayer.BaseGifDrawable; |
+import jp.tomorrowkey.android.gifplayer.BaseGifImage; |
+ |
/** |
* This view shows the default search provider's logo and fades in a new logo if one becomes |
- * available. |
+ * available. It also maintains a {@link BaseGifDrawable} that will be played when the user clicks |
+ * this view and we have an animated GIF ready. |
*/ |
public class LogoView extends View implements OnClickListener { |
@@ -36,14 +42,18 @@ public class LogoView extends View implements OnClickListener { |
// The default logo is shared across all NTPs. |
private static WeakReference<Bitmap> sDefaultLogo; |
- private Paint mPaint; |
+ // mLogo and mNewLogo are remembered for cross fading animation. |
private Bitmap mLogo; |
private Bitmap mNewLogo; |
+ private ObjectAnimator mAnimation; |
newt (away)
2015/09/23 20:38:43
It's probably good to rename this to mFadeAnimatio
Ian Wen
2015/09/23 21:59:51
Done.
|
+ |
+ private BaseGifDrawable mGifDrawable; |
newt (away)
2015/09/23 20:38:43
I'd call this mAnimatedLogoDrawable for clarity an
Ian Wen
2015/09/23 21:59:51
Done.
|
+ private Matrix mAnimatedLogoMatrix; |
newt (away)
2015/09/23 20:38:43
nit: put this with the other Matrix objects
Ian Wen
2015/09/23 21:59:51
Done.
|
+ private Paint mPaint; |
private Matrix mLogoMatrix; |
private Matrix mNewLogoMatrix; |
private boolean mLogoIsDefault; |
private boolean mNewLogoIsDefault; |
- private ObjectAnimator mAnimation; |
/** |
* A measure from 0 to 1 of how much the new logo has faded in. 0 shows the old logo, 1 shows |
@@ -99,15 +109,36 @@ public class LogoView extends View implements OnClickListener { |
} |
/** |
- * Jumps to the end of the current logo animation, if any. |
+ * Jumps to the end of the logo cross-fading animation, if any. |
*/ |
- public void endAnimation() { |
+ public void endFadingAnimation() { |
if (mAnimation != null) { |
mAnimation.end(); |
mAnimation = null; |
} |
} |
+ |
+ /** |
+ * @return True after the animated GIF starts playing. False otherwise. |
+ */ |
+ public boolean isAnimatedLogoShowing() { |
+ return mGifDrawable != null && mGifDrawable.isRunning() && mGifDrawable.isValid(); |
+ } |
+ |
+ /** |
+ * Updates the GIF contained in this View and starts playing it. |
newt (away)
2015/09/23 20:38:43
"animated GIF logo"
Ian Wen
2015/09/23 21:59:51
Done.
|
+ */ |
+ public void updateAnimatedLogo(BaseGifImage gifImage) { |
+ mGifDrawable = new BaseGifDrawable(gifImage, Config.ARGB_8888); |
+ mAnimatedLogoMatrix = new Matrix(); |
+ setMatrix(mGifDrawable.getIntrinsicWidth(), mGifDrawable.getIntrinsicHeight(), |
+ mAnimatedLogoMatrix, false); |
+ // Set callback here to ensure #invalidateDrawable() is called. |
+ mGifDrawable.setCallback(this); |
+ mGifDrawable.start(); |
+ } |
+ |
/** |
* Fades in a new logo over the current logo. |
* |
@@ -179,13 +210,17 @@ public class LogoView extends View implements OnClickListener { |
* not fill the entire view but will still be centered. |
*/ |
private void setMatrix(Bitmap image, Matrix matrix, boolean preventUpscaling) { |
newt (away)
2015/09/23 20:38:43
you could just remove this method and update calle
Ian Wen
2015/09/23 21:59:51
Done.
|
- int width = getWidth(); |
- int height = getHeight(); |
int imageWidth = image.getWidth(); |
int imageHeight = image.getHeight(); |
+ setMatrix(imageWidth, imageHeight, matrix, preventUpscaling); |
+ } |
+ |
+ private void setMatrix(int imageWidth, int imageHeight, Matrix matrix, boolean preventUpscale) { |
newt (away)
2015/09/23 20:38:43
s/preventUpscale/preventUpscaling/
preventUpscale
Ian Wen
2015/09/23 21:59:51
Done.
|
+ int width = getWidth(); |
+ int height = getHeight(); |
float scale = Math.min((float) width / imageWidth, (float) height / imageHeight); |
- if (preventUpscaling) scale = Math.min(1.0f, scale); |
+ if (preventUpscale) scale = Math.min(1.0f, scale); |
int imageOffsetX = Math.round((width - imageWidth * scale) * 0.5f); |
int imageOffsetY = Math.round((height - imageHeight * scale) * 0.5f); |
@@ -207,21 +242,47 @@ public class LogoView extends View implements OnClickListener { |
} |
@Override |
+ protected boolean verifyDrawable(Drawable who) { |
+ return (who == mGifDrawable) || super.verifyDrawable(who); |
+ } |
+ |
+ @Override |
+ public void invalidateDrawable(Drawable drawable) { |
+ // Drawable inside of the view does not have complete information about its boundary, making |
newt (away)
2015/09/23 20:38:43
How about: "mGifDrawable doesn't actually know its
Ian Wen
2015/09/23 21:59:51
Done.
|
+ // it unable to only invalidate the area the drawable lives. Instead we invalidate the whole |
+ // view every time the drawable requests a invalidation. See ImageView#invalidateDrawable() |
+ // for more information. |
+ if (drawable == mGifDrawable) invalidate(); |
+ else super.invalidateDrawable(drawable); |
+ } |
+ |
+ @Override |
protected void onDraw(Canvas canvas) { |
- if (mLogo != null && mTransitionAmount < 0.5f) { |
- mPaint.setAlpha((int) (255 * 2 * (0.5f - mTransitionAmount))); |
- canvas.save(); |
- canvas.concat(mLogoMatrix); |
- canvas.drawBitmap(mLogo, 0, 0, mPaint); |
- canvas.restore(); |
- } |
+ if (isAnimatedLogoShowing()) { |
+ if (mAnimation != null) mAnimation.cancel(); |
+ // Free the old bitmaps to allow them to be GC'd. |
+ mLogo = mNewLogo = null; |
newt (away)
2015/09/23 20:38:43
I'd avoid fancy tricks here. Use two separate stat
Ian Wen
2015/09/23 21:59:51
Done.
|
- if (mNewLogo != null && mTransitionAmount > 0.5f) { |
- mPaint.setAlpha((int) (255 * 2 * (mTransitionAmount - 0.5f))); |
canvas.save(); |
- canvas.concat(mNewLogoMatrix); |
- canvas.drawBitmap(mNewLogo, 0, 0, mPaint); |
+ canvas.concat(mAnimatedLogoMatrix); |
+ mGifDrawable.draw(canvas); |
canvas.restore(); |
+ } else { |
+ if (mLogo != null && mTransitionAmount < 0.5f) { |
+ mPaint.setAlpha((int) (255 * 2 * (0.5f - mTransitionAmount))); |
+ canvas.save(); |
+ canvas.concat(mLogoMatrix); |
+ canvas.drawBitmap(mLogo, 0, 0, mPaint); |
+ canvas.restore(); |
+ } |
+ |
+ if (mNewLogo != null && mTransitionAmount > 0.5f) { |
+ mPaint.setAlpha((int) (255 * 2 * (mTransitionAmount - 0.5f))); |
+ canvas.save(); |
+ canvas.concat(mNewLogoMatrix); |
+ canvas.drawBitmap(mNewLogo, 0, 0, mPaint); |
+ canvas.restore(); |
+ } |
} |
} |
@@ -236,7 +297,7 @@ public class LogoView extends View implements OnClickListener { |
@Override |
public void onClick(View view) { |
if (view == this && mManager != null && !isTransitioning()) { |
- mManager.openLogoLink(); |
+ mManager.onLogoClicked(isAnimatedLogoShowing()); |
} |
} |
} |