1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.glwallpaper; 18 19 import android.animation.Animator; 20 import android.animation.AnimatorListenerAdapter; 21 import android.animation.ValueAnimator; 22 23 import com.android.systemui.Interpolators; 24 25 /** 26 * Use ValueAnimator and appropriate interpolator to control the progress of reveal transition. 27 * The transition will happen while getting awake and quit events. 28 */ 29 class ImageRevealHelper { 30 private static final String TAG = ImageRevealHelper.class.getSimpleName(); 31 private static final float MAX_REVEAL = 0f; 32 private static final float MIN_REVEAL = 1f; 33 34 private final ValueAnimator mAnimator; 35 private final RevealStateListener mRevealListener; 36 private float mReveal = MAX_REVEAL; 37 private boolean mAwake = false; 38 ImageRevealHelper(RevealStateListener listener)39 ImageRevealHelper(RevealStateListener listener) { 40 mRevealListener = listener; 41 mAnimator = ValueAnimator.ofFloat(); 42 mAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); 43 mAnimator.addUpdateListener(animator -> { 44 mReveal = (float) animator.getAnimatedValue(); 45 if (mRevealListener != null) { 46 mRevealListener.onRevealStateChanged(); 47 } 48 }); 49 mAnimator.addListener(new AnimatorListenerAdapter() { 50 private boolean mIsCanceled; 51 52 @Override 53 public void onAnimationCancel(Animator animation) { 54 mIsCanceled = true; 55 } 56 57 @Override 58 public void onAnimationEnd(Animator animation) { 59 if (!mIsCanceled && mRevealListener != null) { 60 mRevealListener.onRevealEnd(); 61 } 62 mIsCanceled = false; 63 } 64 65 @Override 66 public void onAnimationStart(Animator animation) { 67 if (mRevealListener != null) { 68 mRevealListener.onRevealStart(true /* animate */); 69 } 70 } 71 }); 72 } 73 animate()74 private void animate() { 75 mAnimator.cancel(); 76 mAnimator.setFloatValues(mReveal, mAwake ? MAX_REVEAL : MIN_REVEAL); 77 mAnimator.start(); 78 } 79 getReveal()80 public float getReveal() { 81 return mReveal; 82 } 83 updateAwake(boolean awake, long duration)84 void updateAwake(boolean awake, long duration) { 85 mAwake = awake; 86 mAnimator.setDuration(duration); 87 if (duration == 0) { 88 // We are transiting from home to aod or aod to home directly, 89 // we don't need to do transition in these cases. 90 mReveal = mAwake ? MAX_REVEAL : MIN_REVEAL; 91 mRevealListener.onRevealStart(false /* animate */); 92 mRevealListener.onRevealStateChanged(); 93 mRevealListener.onRevealEnd(); 94 } else { 95 animate(); 96 } 97 } 98 99 /** 100 * A listener to trace value changes of reveal. 101 */ 102 public interface RevealStateListener { 103 104 /** 105 * Called back while reveal status changes. 106 */ onRevealStateChanged()107 void onRevealStateChanged(); 108 109 /** 110 * Called back while reveal starts. 111 */ onRevealStart(boolean animate)112 void onRevealStart(boolean animate); 113 114 /** 115 * Called back while reveal ends. 116 */ onRevealEnd()117 void onRevealEnd(); 118 } 119 } 120