1 /*
2  * Copyright (C) 2014 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.camera.ui.focus;
18 
19 import android.graphics.Canvas;
20 import android.graphics.Paint;
21 
22 import com.android.camera.debug.Log.Tag;
23 import com.android.camera.ui.motion.InterpolateUtils;
24 import com.android.camera.ui.motion.Invalidator;
25 
26 /**
27  * Passive focus ring animation renderer.
28  */
29 class AutoFocusRing extends FocusRingRenderer {
30     private static final Tag TAG = new Tag("AutoFocusRing");
31 
32     /**
33      * The auto focus ring encapsulates the animation logic for visualizing
34      * a focus event when triggered by the camera subsystem.
35      *
36      * @param invalidator the object to invalidate while running.
37      * @param ringPaint the paint to draw the ring with.
38      * @param enterDurationMillis the fade in time in milliseconds.
39      * @param exitDurationMillis the fade out time in milliseconds.
40      */
AutoFocusRing(Invalidator invalidator, Paint ringPaint, float enterDurationMillis, float exitDurationMillis)41     public AutoFocusRing(Invalidator invalidator, Paint ringPaint, float enterDurationMillis,
42           float exitDurationMillis) {
43         super(invalidator, ringPaint, enterDurationMillis, exitDurationMillis);
44     }
45 
46     @Override
draw(long t, long dt, Canvas canvas)47     public void draw(long t, long dt, Canvas canvas) {
48         float ringRadius = mRingRadius.update(dt);
49         processStates(t);
50 
51         if (!isActive()) {
52             return;
53         }
54 
55         mInvalidator.invalidate();
56         int ringAlpha = 255;
57 
58         if (mFocusState == FocusState.STATE_ENTER) {
59             float rFade = InterpolateUtils.unitRatio(t, mEnterStartMillis, mEnterDurationMillis);
60             ringAlpha = (int) InterpolateUtils
61                   .lerp(0, 255, mEnterOpacityCurve.valueAt(rFade));
62         } else if (mFocusState == FocusState.STATE_FADE_OUT) {
63             float rFade = InterpolateUtils.unitRatio(t, mExitStartMillis, mExitDurationMillis);
64             ringAlpha = (int) InterpolateUtils
65                   .lerp(255, 0, mExitOpacityCurve.valueAt(rFade));
66         } else if (mFocusState == FocusState.STATE_HARD_STOP) {
67             float rFade = InterpolateUtils
68                   .unitRatio(t, mHardExitStartMillis, mHardExitDurationMillis);
69             ringAlpha = (int) InterpolateUtils
70                   .lerp(255, 0, mExitOpacityCurve.valueAt(rFade));
71         } else if (mFocusState == FocusState.STATE_INACTIVE) {
72             ringAlpha = 0;
73         }
74 
75         mRingPaint.setAlpha(ringAlpha);
76         canvas.drawCircle(getCenterX(), getCenterY(), ringRadius, mRingPaint);
77     }
78 
processStates(long t)79     private void processStates(long t) {
80         if (mFocusState == FocusState.STATE_INACTIVE) {
81             return;
82         }
83 
84         if (mFocusState == FocusState.STATE_ENTER && t > mEnterStartMillis + mEnterDurationMillis) {
85             mFocusState = FocusState.STATE_ACTIVE;
86         }
87 
88         if (mFocusState == FocusState.STATE_ACTIVE && !mRingRadius.isActive()) {
89             mFocusState = FocusState.STATE_FADE_OUT;
90             mExitStartMillis = t;
91         }
92 
93         if (mFocusState == FocusState.STATE_FADE_OUT && t > mExitStartMillis + mExitDurationMillis) {
94             mFocusState = FocusState.STATE_INACTIVE;
95         }
96 
97         if (mFocusState == FocusState.STATE_HARD_STOP
98               && t > mHardExitStartMillis + mHardExitDurationMillis) {
99             mFocusState = FocusState.STATE_INACTIVE;
100         }
101     }
102 }
103