1482de029dc20e0a577388a602985fb31c3200309Doris Liu/*
2482de029dc20e0a577388a602985fb31c3200309Doris Liu * Copyright (C) 2013 The Android Open Source Project
3482de029dc20e0a577388a602985fb31c3200309Doris Liu *
4482de029dc20e0a577388a602985fb31c3200309Doris Liu * Licensed under the Apache License, Version 2.0 (the "License");
5482de029dc20e0a577388a602985fb31c3200309Doris Liu * you may not use this file except in compliance with the License.
6482de029dc20e0a577388a602985fb31c3200309Doris Liu * You may obtain a copy of the License at
7482de029dc20e0a577388a602985fb31c3200309Doris Liu *
8482de029dc20e0a577388a602985fb31c3200309Doris Liu *      http://www.apache.org/licenses/LICENSE-2.0
9482de029dc20e0a577388a602985fb31c3200309Doris Liu *
10482de029dc20e0a577388a602985fb31c3200309Doris Liu * Unless required by applicable law or agreed to in writing, software
11482de029dc20e0a577388a602985fb31c3200309Doris Liu * distributed under the License is distributed on an "AS IS" BASIS,
12482de029dc20e0a577388a602985fb31c3200309Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13482de029dc20e0a577388a602985fb31c3200309Doris Liu * See the License for the specific language governing permissions and
14482de029dc20e0a577388a602985fb31c3200309Doris Liu * limitations under the License.
15482de029dc20e0a577388a602985fb31c3200309Doris Liu */
16482de029dc20e0a577388a602985fb31c3200309Doris Liu
17482de029dc20e0a577388a602985fb31c3200309Doris Liupackage com.android.camera.ui;
18482de029dc20e0a577388a602985fb31c3200309Doris Liu
19482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.animation.ValueAnimator;
20482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.content.Context;
21e2f5fdda4b19da650a7616853990624969d0f384Andy Huibersimport android.content.res.Resources;
22482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.graphics.Canvas;
23e2f5fdda4b19da650a7616853990624969d0f384Andy Huibersimport android.graphics.Paint;
24482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.graphics.Rect;
25482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.graphics.drawable.Drawable;
26482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.util.AttributeSet;
27482de029dc20e0a577388a602985fb31c3200309Doris Liuimport android.view.View;
28482de029dc20e0a577388a602985fb31c3200309Doris Liu
29482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera.FocusOverlayManager;
30e2f5fdda4b19da650a7616853990624969d0f384Andy Huibersimport com.android.camera.debug.DebugPropertyHelper;
3110c5816e1ff3d30e4c4996643ba05d63d522b81aAndy Huibersimport com.android.camera.debug.Log;
32482de029dc20e0a577388a602985fb31c3200309Doris Liuimport com.android.camera2.R;
33482de029dc20e0a577388a602985fb31c3200309Doris Liu
34482de029dc20e0a577388a602985fb31c3200309Doris Liu/**
3515b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu * Displays a focus indicator.
36482de029dc20e0a577388a602985fb31c3200309Doris Liu */
37482de029dc20e0a577388a602985fb31c3200309Doris Liupublic class FocusOverlay extends View implements FocusOverlayManager.FocusUI {
3810c5816e1ff3d30e4c4996643ba05d63d522b81aAndy Huibers    private static final Log.Tag TAG = new Log.Tag("FocusOverlay");
39482de029dc20e0a577388a602985fb31c3200309Doris Liu
40e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    /** System Properties switch to enable debugging focus UI. */
41e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private static final boolean CAPTURE_DEBUG_UI = DebugPropertyHelper.showCaptureDebugUI();
42e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
43482de029dc20e0a577388a602985fb31c3200309Doris Liu    private final static int FOCUS_DURATION_MS = 500;
44482de029dc20e0a577388a602985fb31c3200309Doris Liu    private final static int FOCUS_INDICATOR_ROTATION_DEGREES = 50;
4515b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu
4615b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu    private final Drawable mFocusIndicator;
47e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private Drawable mFocusOuterRing;
4815b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu    private final Rect mBounds = new Rect();
4915b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu    private final ValueAnimator mFocusAnimation = new ValueAnimator();
5015b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu
51ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    private Paint mDebugSolidPaint;
52ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    private Paint mDebugCornersPaint;
53ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    private Paint mDebugTextPaint;
54e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private int mDebugStartColor;
55e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private int mDebugSuccessColor;
56e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private int mDebugFailColor;
57ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    private Rect mFocusDebugSolidRect;
58ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    private Rect mFocusDebugCornersRect;
59e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    private boolean mIsPassiveScan;
60ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    private String mDebugMessage;
61e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
62482de029dc20e0a577388a602985fb31c3200309Doris Liu    private int mPositionX;
63482de029dc20e0a577388a602985fb31c3200309Doris Liu    private int mPositionY;
64482de029dc20e0a577388a602985fb31c3200309Doris Liu    private int mAngle;
65dfe96eac810876659f831d2c9054f33b698916e7Doris Liu    private final int mFocusIndicatorSize;
66482de029dc20e0a577388a602985fb31c3200309Doris Liu    private boolean mShowIndicator;
67dfe96eac810876659f831d2c9054f33b698916e7Doris Liu    private final int mFocusOuterRingSize;
68482de029dc20e0a577388a602985fb31c3200309Doris Liu
69482de029dc20e0a577388a602985fb31c3200309Doris Liu    public FocusOverlay(Context context, AttributeSet attrs) {
70482de029dc20e0a577388a602985fb31c3200309Doris Liu        super(context, attrs);
71c5d230b407a4e8cbc029f1eaeb5f759f8ae2d0a9Doris Liu        mFocusIndicator = getResources().getDrawable(R.drawable.focus_ring_touch_inner);
72dfe96eac810876659f831d2c9054f33b698916e7Doris Liu        mFocusIndicatorSize = getResources().getDimensionPixelSize(R.dimen.focus_inner_ring_size);
73c5d230b407a4e8cbc029f1eaeb5f759f8ae2d0a9Doris Liu        mFocusOuterRing = getResources().getDrawable(R.drawable.focus_ring_touch_outer);
74dfe96eac810876659f831d2c9054f33b698916e7Doris Liu        mFocusOuterRingSize = getResources().getDimensionPixelSize(R.dimen.focus_outer_ring_size);
75e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
76e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        if (CAPTURE_DEBUG_UI) {
77e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            Resources res = getResources();
78e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            mDebugStartColor = res.getColor(R.color.focus_debug);
79e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            mDebugSuccessColor = res.getColor(R.color.focus_debug_success);
80e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            mDebugFailColor = res.getColor(R.color.focus_debug_fail);
81ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugTextPaint= new Paint();
82ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugTextPaint.setColor(res.getColor(R.color.focus_debug_text));
83ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugTextPaint.setStyle(Paint.Style.FILL);
84ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint = new Paint();
85ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint.setColor(res.getColor(R.color.focus_debug));
86ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint.setAntiAlias(true);
87ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint.setStyle(Paint.Style.STROKE);
88ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint.setStrokeWidth(res.getDimension(R.dimen.focus_debug_stroke));
89ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugCornersPaint = new Paint(mDebugSolidPaint);
90ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugCornersPaint.setColor(res.getColor(R.color.focus_debug));
91ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mFocusDebugSolidRect = new Rect();
92ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mFocusDebugCornersRect = new Rect();
93e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        }
94482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
95482de029dc20e0a577388a602985fb31c3200309Doris Liu
96482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
97482de029dc20e0a577388a602985fb31c3200309Doris Liu    public boolean hasFaces() {
9815b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu        // TODO: Add face detection support.
99482de029dc20e0a577388a602985fb31c3200309Doris Liu        return false;
100482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
101482de029dc20e0a577388a602985fb31c3200309Doris Liu
102482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
103482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void clearFocus() {
104482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = false;
105e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        if (CAPTURE_DEBUG_UI) {
106e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            setVisibility(INVISIBLE);
107e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        }
108482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
109482de029dc20e0a577388a602985fb31c3200309Doris Liu
110482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
111c0fe0b6915004303a550047e68a2124edae9fdb2Andy Huibers    public void setFocusPosition(int x, int y, boolean isPassiveScan) {
112e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        setFocusPosition(x, y, isPassiveScan, 0, 0);
113e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    }
114e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
115e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    @Override
116e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers    public void setFocusPosition(int x, int y, boolean isPassiveScan, int aFsize, int aEsize) {
117e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        mIsPassiveScan = isPassiveScan;
118482de029dc20e0a577388a602985fb31c3200309Doris Liu        mPositionX = x;
119482de029dc20e0a577388a602985fb31c3200309Doris Liu        mPositionY = y;
120482de029dc20e0a577388a602985fb31c3200309Doris Liu        mBounds.set(x - mFocusIndicatorSize / 2, y - mFocusIndicatorSize / 2,
121482de029dc20e0a577388a602985fb31c3200309Doris Liu                x + mFocusIndicatorSize / 2, y + mFocusIndicatorSize / 2);
122482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusIndicator.setBounds(mBounds);
123dfe96eac810876659f831d2c9054f33b698916e7Doris Liu        mFocusOuterRing.setBounds(x - mFocusOuterRingSize / 2, y - mFocusOuterRingSize / 2,
124dfe96eac810876659f831d2c9054f33b698916e7Doris Liu                x + mFocusOuterRingSize / 2, y + mFocusOuterRingSize / 2);
125e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
126e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        if (CAPTURE_DEBUG_UI) {
127e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            mFocusOuterRing.setBounds(0, 0, 0, 0);
128ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            if (isPassiveScan) {
129ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                // Use AE rect only.
130ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                mFocusDebugSolidRect.setEmpty();
131ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                int avg = (aFsize + aEsize) / 2;
132ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                mFocusDebugCornersRect.set(x - avg / 2, y - avg / 2, x + avg / 2, y + avg / 2);
133e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            } else {
134ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                mFocusDebugSolidRect.set(x - aFsize / 2, y - aFsize / 2, x + aFsize / 2,
135ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                        y + aFsize / 2);
136ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                // If AE region is different size than AF region and active scan.
137ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                if (aFsize != aEsize) {
138ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                    mFocusDebugCornersRect.set(x - aEsize / 2, y - aEsize / 2, x + aEsize / 2,
139ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                            y + aEsize / 2);
140ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                } else {
141ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                    mFocusDebugCornersRect.setEmpty();
142ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                }
143e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers            }
144ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint.setColor(mDebugStartColor);
145ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugCornersPaint.setColor(mDebugStartColor);
146e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        }
147e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers
148af65683681dbbb98063363ee776f5d357a7b5de5Doris Liu        if (getVisibility() != VISIBLE) {
149af65683681dbbb98063363ee776f5d357a7b5de5Doris Liu            setVisibility(VISIBLE);
150af65683681dbbb98063363ee776f5d357a7b5de5Doris Liu        }
151b868274c9dc8d9c772ec89fb5955215cc7911087Andy Huibers        invalidate();
152482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
153482de029dc20e0a577388a602985fb31c3200309Doris Liu
154ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    /**
155ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * This is called in:
156ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <ul>
157ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API1 non-CAF after autoFocus().</li>
158ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API1 CAF mode for onAutoFocusMoving(true).</li>
159ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API2 for transition to ACTIVE_SCANNING or PASSIVE_SCANNING.</li>
160ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <ul>
161ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * TODO after PhotoModule/GcamModule deprecation: Do not use this for CAF.
162ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     */
163482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
164482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void onFocusStarted() {
165482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = true;
166482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.setIntValues(0, FOCUS_INDICATOR_ROTATION_DEGREES);
167482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.setDuration(FOCUS_DURATION_MS);
168482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
169482de029dc20e0a577388a602985fb31c3200309Doris Liu            @Override
170482de029dc20e0a577388a602985fb31c3200309Doris Liu            public void onAnimationUpdate(ValueAnimator animation) {
171482de029dc20e0a577388a602985fb31c3200309Doris Liu                mAngle = (Integer) animation.getAnimatedValue();
172482de029dc20e0a577388a602985fb31c3200309Doris Liu                invalidate();
173482de029dc20e0a577388a602985fb31c3200309Doris Liu            }
174482de029dc20e0a577388a602985fb31c3200309Doris Liu        });
175482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.start();
176ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        if (CAPTURE_DEBUG_UI) {
177ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugMessage = null;
178ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        }
179482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
180482de029dc20e0a577388a602985fb31c3200309Doris Liu
181ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    /**
182ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * This is called in:
183ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <ul>
184ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API1 non-CAF for onAutoFocus(true).</li>
185ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API2 non-CAF for transition to FOCUSED_LOCKED.</li>
186ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API1 CAF mode for onAutoFocusMoving(false).</li>
187ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <ul>
188ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * TODO after PhotoModule/GcamModule deprecation: Do not use this for CAF.
189ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     */
190482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
191e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling    public void onFocusSucceeded() {
192482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.cancel();
193482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = false;
194e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        if (CAPTURE_DEBUG_UI && !mIsPassiveScan) {
195ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint.setColor(mDebugSuccessColor);
196e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        }
197482de029dc20e0a577388a602985fb31c3200309Doris Liu        invalidate();
198482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
199482de029dc20e0a577388a602985fb31c3200309Doris Liu
200ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    /**
201ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * This is called in:
202ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <ul>
203ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API1 non-CAF for onAutoFocus(false).</li>
204ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <li>API2 non-CAF for transition to NOT_FOCUSED_LOCKED.</li>
205ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * <ul>
206ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     */
207482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
208e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling    public void onFocusFailed() {
209482de029dc20e0a577388a602985fb31c3200309Doris Liu        mFocusAnimation.cancel();
210482de029dc20e0a577388a602985fb31c3200309Doris Liu        mShowIndicator = false;
211e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        if (CAPTURE_DEBUG_UI && !mIsPassiveScan) {
212ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugSolidPaint.setColor(mDebugFailColor);
213ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        }
214ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        invalidate();
215ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    }
216ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers
217ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    /**
218ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * This is called in:
219ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     * API2 for CAF state changes to PASSIVE_FOCUSED or PASSIVE_UNFOCUSED.
220ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers     */
221ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    @Override
222ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    public void setPassiveFocusSuccess(boolean success) {
223ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        mFocusAnimation.cancel();
224ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        mShowIndicator = false;
225ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        if (CAPTURE_DEBUG_UI) {
226ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugCornersPaint.setColor(success ? mDebugSuccessColor : mDebugFailColor);
227e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        }
228482de029dc20e0a577388a602985fb31c3200309Doris Liu        invalidate();
229482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
230482de029dc20e0a577388a602985fb31c3200309Doris Liu
231482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
232ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    public void showDebugMessage(String message) {
233ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        if (CAPTURE_DEBUG_UI) {
234ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            mDebugMessage = message;
235ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        }
236ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    }
237ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers
238ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers    @Override
239482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void pauseFaceDetection() {
24015b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu        // TODO: Add face detection support.
241482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
242482de029dc20e0a577388a602985fb31c3200309Doris Liu
243482de029dc20e0a577388a602985fb31c3200309Doris Liu    @Override
244482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void resumeFaceDetection() {
24515b9961c5ca49fc6ac9d036e7a967797987e46eeDoris Liu        // TODO: Add face detection support.
246482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
247482de029dc20e0a577388a602985fb31c3200309Doris Liu
248e2914fddcd6d4f78d812ef818d43364d9aa469d4Sascha Haeberling    @Override
249482de029dc20e0a577388a602985fb31c3200309Doris Liu    public void onDraw(Canvas canvas) {
250482de029dc20e0a577388a602985fb31c3200309Doris Liu        super.onDraw(canvas);
251482de029dc20e0a577388a602985fb31c3200309Doris Liu
252c0fe0b6915004303a550047e68a2124edae9fdb2Andy Huibers        if (mShowIndicator) {
253dfe96eac810876659f831d2c9054f33b698916e7Doris Liu            mFocusOuterRing.draw(canvas);
254482de029dc20e0a577388a602985fb31c3200309Doris Liu            canvas.save();
255482de029dc20e0a577388a602985fb31c3200309Doris Liu            canvas.rotate(mAngle, mPositionX, mPositionY);
256482de029dc20e0a577388a602985fb31c3200309Doris Liu            mFocusIndicator.draw(canvas);
257482de029dc20e0a577388a602985fb31c3200309Doris Liu            canvas.restore();
258482de029dc20e0a577388a602985fb31c3200309Doris Liu        }
259ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers        if (CAPTURE_DEBUG_UI) {
260ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            canvas.drawRect(mFocusDebugSolidRect, mDebugSolidPaint);
261ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            float delta = 0.1f * mFocusDebugCornersRect.width();
262ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            float left = mFocusDebugCornersRect.left;
263ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            float top = mFocusDebugCornersRect.top;
264ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            float right = mFocusDebugCornersRect.right;
265ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            float bot = mFocusDebugCornersRect.bottom;
266ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers
267ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            canvas.drawLines(new float[]{left, top + delta, left, top, left, top, left + delta, top}, mDebugCornersPaint);
268ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            canvas.drawLines(new float[]{right, top + delta, right, top, right, top, right - delta, top}, mDebugCornersPaint);
269ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            canvas.drawLines(new float[]{left, bot - delta, left, bot, left, bot, left + delta, bot}, mDebugCornersPaint);
270ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            canvas.drawLines(new float[]{right, bot - delta, right, bot, right, bot, right - delta, bot}, mDebugCornersPaint);
271ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers
272ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            if (mDebugMessage != null) {
273ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                mDebugTextPaint.setTextSize(40);
274ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers                canvas.drawText(mDebugMessage, left - 4, bot + 44, mDebugTextPaint);
275ca3c564536f154b83e380e37382bc7b9f6049302Andy Huibers            }
276e2f5fdda4b19da650a7616853990624969d0f384Andy Huibers        }
277482de029dc20e0a577388a602985fb31c3200309Doris Liu    }
278482de029dc20e0a577388a602985fb31c3200309Doris Liu}
279