Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/ntp/LogoView.java

Issue 1343913002: Introduce Animated Logo to Chrome on Android (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: respond to newt's comments Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());
}
}
}

Powered by Google App Engine
This is Rietveld 408576698