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

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: 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..ae7006ba8fab3ef4832ff09c66ca17d38c95ba49 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 logo 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 BaseGifDrawable mAnimatedLogoDrawable;
+
+ private ObjectAnimator mFadeAnimation;
+ private Paint mPaint;
private Matrix mLogoMatrix;
private Matrix mNewLogoMatrix;
+ private Matrix mAnimatedLogoMatrix;
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,16 +109,37 @@ 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() {
- if (mAnimation != null) {
- mAnimation.end();
- mAnimation = null;
+ public void endFadeAnimation() {
+ if (mFadeAnimation != null) {
+ mFadeAnimation.end();
+ mFadeAnimation = null;
}
}
/**
+ * @return True after the animated GIF logo starts playing. False otherwise.
+ */
+ public boolean isAnimatedLogoShowing() {
+ return mAnimatedLogoDrawable != null && mAnimatedLogoDrawable.isRunning()
+ && mAnimatedLogoDrawable.isValid();
+ }
+
+ /**
+ * Starts playing the given animated GIF logo.
+ */
+ public void playAnimatedLogo(BaseGifImage gifImage) {
+ mAnimatedLogoDrawable = new BaseGifDrawable(gifImage, Config.ARGB_8888);
+ mAnimatedLogoMatrix = new Matrix();
+ setMatrix(mAnimatedLogoDrawable.getIntrinsicWidth(),
+ mAnimatedLogoDrawable.getIntrinsicHeight(), mAnimatedLogoMatrix, false);
+ // Set callback here to ensure #invalidateDrawable() is called.
+ mAnimatedLogoDrawable.setCallback(this);
+ mAnimatedLogoDrawable.start();
+ }
+
+ /**
* Fades in a new logo over the current logo.
*
* @param logo The new logo to fade in. May be null to reset to the default logo.
@@ -124,16 +155,16 @@ public class LogoView extends View implements OnClickListener {
}
private void updateLogo(Bitmap logo, final String contentDescription, boolean isDefaultLogo) {
- if (mAnimation != null) mAnimation.end();
+ if (mFadeAnimation != null) mFadeAnimation.end();
mNewLogo = logo;
mNewLogoMatrix = new Matrix();
mNewLogoIsDefault = isDefaultLogo;
- setMatrix(mNewLogo, mNewLogoMatrix, mNewLogoIsDefault);
+ setMatrix(mNewLogo.getWidth(), mNewLogo.getHeight(), mNewLogoMatrix, mNewLogoIsDefault);
- mAnimation = ObjectAnimator.ofFloat(this, mTransitionProperty, 0f, 1f);
- mAnimation.setDuration(LOGO_TRANSITION_TIME_MS);
- mAnimation.addListener(new Animator.AnimatorListener() {
+ mFadeAnimation = ObjectAnimator.ofFloat(this, mTransitionProperty, 0f, 1f);
+ mFadeAnimation.setDuration(LOGO_TRANSITION_TIME_MS);
+ mFadeAnimation.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@@ -150,7 +181,7 @@ public class LogoView extends View implements OnClickListener {
mNewLogo = null;
mNewLogoMatrix = null;
mTransitionAmount = 0f;
- mAnimation = null;
+ mFadeAnimation = null;
setContentDescription(contentDescription);
setClickable(!mNewLogoIsDefault);
}
@@ -161,7 +192,7 @@ public class LogoView extends View implements OnClickListener {
invalidate();
}
});
- mAnimation.start();
+ mFadeAnimation.start();
}
/**
@@ -178,11 +209,10 @@ public class LogoView extends View implements OnClickListener {
* @param preventUpscaling Whether the image should not be scaled up. If true, the image might
* not fill the entire view but will still be centered.
*/
- private void setMatrix(Bitmap image, Matrix matrix, boolean preventUpscaling) {
+ private void setMatrix(int imageWidth, int imageHeight, Matrix matrix,
+ boolean preventUpscaling) {
int width = getWidth();
int height = getHeight();
- int imageWidth = image.getWidth();
- int imageHeight = image.getHeight();
float scale = Math.min((float) width / imageWidth, (float) height / imageHeight);
if (preventUpscaling) scale = Math.min(1.0f, scale);
@@ -207,36 +237,72 @@ public class LogoView extends View implements OnClickListener {
}
@Override
+ protected boolean verifyDrawable(Drawable who) {
+ return (who == mAnimatedLogoDrawable) || super.verifyDrawable(who);
+ }
+
+ @Override
+ public void invalidateDrawable(Drawable drawable) {
+ // mAnimatedLogoDrawable doesn't actually know its bounds, so super.invalidateDrawable()
+ // doesn't invalidate the right area. Instead invalidate the entire view; the drawable takes
+ // up most of the view anyway so this is just as efficient.
+ // @see ImageView#invalidateDrawable().
+ if (drawable == mAnimatedLogoDrawable) 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 (mFadeAnimation != null) mFadeAnimation.cancel();
+ // Free the old bitmaps to allow them to be GC'd.
+ mLogo = null;
+ mNewLogo = null;
- 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);
+ mAnimatedLogoDrawable.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();
+ }
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw || h != oldh) {
- if (mLogo != null) setMatrix(mLogo, mLogoMatrix, mLogoIsDefault);
- if (mNewLogo != null) setMatrix(mNewLogo, mNewLogoMatrix, mNewLogoIsDefault);
+ if (mAnimatedLogoDrawable != null) {
+ setMatrix(mAnimatedLogoDrawable.getIntrinsicWidth(),
+ mAnimatedLogoDrawable.getIntrinsicHeight(), mAnimatedLogoMatrix, false);
+ }
+ if (mLogo != null) {
+ setMatrix(mLogo.getWidth(), mLogo.getHeight(), mLogoMatrix, mLogoIsDefault);
+ }
+ if (mNewLogo != null) {
+ setMatrix(mNewLogo.getWidth(), mNewLogo.getHeight(), mNewLogoMatrix,
+ mNewLogoIsDefault);
+ }
}
}
@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