1ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/*
2ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Copyright (C) 2016 The Android Open Source Project
3ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
4ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
5ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * you may not use this file except in compliance with the License.
6ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * You may obtain a copy of the License at
7ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
8ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
9ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
10ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Unless required by applicable law or agreed to in writing, software
11ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
12ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * See the License for the specific language governing permissions and
14ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * limitations under the License.
15ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
16ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
17ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpackage com.android.dialer.callcomposer.camera.camerafocus;
18ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
19ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Matrix;
20ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.Rect;
21ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.graphics.RectF;
22ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.hardware.Camera.Area;
23ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.hardware.Camera.Parameters;
24ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Handler;
25ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Looper;
26ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport android.os.Message;
27ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.Assert;
28ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport com.android.dialer.common.LogUtil;
29ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.ArrayList;
30ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianimport java.util.List;
31ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
32ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian/**
33ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * A class that handles everything about focus in still picture mode. This also handles the metering
34ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * area because it is the same as focus area.
35ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian *
36ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * <p>The test cases: (1) The camera has continuous autofocus. Move the camera. Take a picture when
37ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * CAF is not in progress. (2) The camera has continuous autofocus. Move the camera. Take a picture
38ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * when CAF is in progress. (3) The camera has face detection. Point the camera at some faces. Hold
39ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * the shutter. Release to take a picture. (4) The camera has face detection. Point the camera at
40ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * some faces. Single tap the shutter to take a picture. (5) The camera has autofocus. Single tap
41ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * the shutter to take a picture. (6) The camera has autofocus. Hold the shutter. Release to take a
42ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * picture. (7) The camera has no autofocus. Single tap the shutter and take a picture. (8) The
43ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * camera has autofocus and supports focus area. Touch the screen to trigger autofocus. Take a
44ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * picture. (9) The camera has autofocus and supports focus area. Touch the screen to trigger
45ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * autofocus. Wait until it times out. (10) The camera has no autofocus and supports metering area.
46ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian * Touch the screen to change metering area.
47ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian */
48ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanianpublic class FocusOverlayManager {
49ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String TRUE = "true";
50ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String AUTO_EXPOSURE_LOCK_SUPPORTED = "auto-exposure-lock-supported";
51ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final String AUTO_WHITE_BALANCE_LOCK_SUPPORTED =
52ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      "auto-whitebalance-lock-supported";
53ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
54ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int RESET_TOUCH_FOCUS = 0;
55ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int RESET_TOUCH_FOCUS_DELAY = 3000;
56ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
57ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int mState = STATE_IDLE;
58ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int STATE_IDLE = 0; // Focus is not active.
59ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int STATE_FOCUSING = 1; // Focus is in progress.
60ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  // Focus is in progress and the camera should take a picture after focus finishes.
61ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
62ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
63ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private static final int STATE_FAIL = 4; // Focus finishes and fails.
64ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
65ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mInitialized;
66ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mFocusAreaSupported;
67ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mMeteringAreaSupported;
68ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mLockAeAwbNeeded;
69ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mAeAwbLock;
70ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Matrix mMatrix;
71ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
72ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private PieRenderer mPieRenderer;
73ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
74ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int mPreviewWidth; // The width of the preview frame layout.
75ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int mPreviewHeight; // The height of the preview frame layout.
76ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean mMirror; // true if the camera is front-facing.
77ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private List<Area> mFocusArea; // focus area in driver format
78ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private List<Area> mMeteringArea; // metering area in driver format
79ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private String mFocusMode;
80ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Parameters mParameters;
81ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Handler mHandler;
82ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private Listener mListener;
83ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
84ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  /** Listener used for the focus indicator to communicate back to the camera. */
85ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public interface Listener {
86ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    void autoFocus();
87ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
88ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    void cancelAutoFocus();
89ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
90ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    boolean capture();
91ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
92ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    void setFocusParameters();
93ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
94ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
95ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private class MainHandler extends Handler {
96ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public MainHandler(Looper looper) {
97ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      super(looper);
98ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
99ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
100ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    @Override
101ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    public void handleMessage(Message msg) {
102ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      switch (msg.what) {
103ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        case RESET_TOUCH_FOCUS:
104ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          {
105ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            cancelAutoFocus();
106ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian            break;
107ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian          }
108ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
109ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
110ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
111ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
112ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public FocusOverlayManager(Listener listener, Looper looper) {
113ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mHandler = new MainHandler(looper);
114ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mMatrix = new Matrix();
115ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mListener = listener;
116ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
117ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
118ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setFocusRenderer(PieRenderer renderer) {
119ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPieRenderer = renderer;
120ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mInitialized = (mMatrix != null);
121ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
122ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
123ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setParameters(Parameters parameters) {
124ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // parameters can only be null when onConfigurationChanged is called
125ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // before camera is open. We will just return in this case, because
126ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // parameters will be set again later with the right parameters after
127ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // camera is open.
128ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (parameters == null) {
129ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
130ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
131ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mParameters = parameters;
132ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mFocusAreaSupported = isFocusAreaSupported(parameters);
133ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mMeteringAreaSupported = isMeteringAreaSupported(parameters);
134ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mLockAeAwbNeeded =
135ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        (isAutoExposureLockSupported(mParameters) || isAutoWhiteBalanceLockSupported(mParameters));
136ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
137ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
138ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setPreviewSize(int previewWidth, int previewHeight) {
139ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPreviewWidth != previewWidth || mPreviewHeight != previewHeight) {
140ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPreviewWidth = previewWidth;
141ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPreviewHeight = previewHeight;
142ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      setMatrix();
143ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
144ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
145ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
146ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void setMirror(boolean mirror) {
147ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mMirror = mirror;
148ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    setMatrix();
149ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
150ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
151ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void setMatrix() {
152ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mPreviewWidth != 0 && mPreviewHeight != 0) {
153ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Matrix matrix = new Matrix();
154ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      prepareMatrix(matrix, mMirror, mPreviewWidth, mPreviewHeight);
155ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // In face detection, the matrix converts the driver coordinates to UI
156ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // coordinates. In tap focus, the inverted matrix converts the UI
157ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // coordinates to driver coordinates.
158ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      matrix.invert(mMatrix);
159ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mInitialized = (mPieRenderer != null);
160ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
161ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
162ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
163ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void lockAeAwbIfNeeded() {
164ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mLockAeAwbNeeded && !mAeAwbLock) {
165ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mAeAwbLock = true;
166ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mListener.setFocusParameters();
167ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
168ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
169ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
170ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onAutoFocus(boolean focused, boolean shutterButtonPressed) {
171ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mState == STATE_FOCUSING_SNAP_ON_FINISH) {
172ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Take the picture no matter focus succeeds or fails. No need
173ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // to play the AF sound if we're about to play the shutter
174ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // sound.
175ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (focused) {
176ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mState = STATE_SUCCESS;
177ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
178ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mState = STATE_FAIL;
179ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
180ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updateFocusUI();
181ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      capture();
182ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (mState == STATE_FOCUSING) {
183ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // This happens when (1) user is half-pressing the focus key or
184ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // (2) touch focus is triggered. Play the focus tone. Do not
185ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // take the picture now.
186ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (focused) {
187ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mState = STATE_SUCCESS;
188ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
189ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mState = STATE_FAIL;
190ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
191ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updateFocusUI();
192ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // If this is triggered by touch focus, cancel focus after a
193ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // while.
194ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (mFocusArea != null) {
195ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
196ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
197ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (shutterButtonPressed) {
198ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // Lock AE & AWB so users can half-press shutter and recompose.
199ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        lockAeAwbIfNeeded();
200ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
201ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (mState == STATE_IDLE) {
202ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // User has released the focus key before focus completes.
203ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Do nothing.
204ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
205ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
206ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
207ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onAutoFocusMoving(boolean moving) {
208ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!mInitialized) {
209ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
210ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
211ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
212ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Ignore if we have requested autofocus. This method only handles
213ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // continuous autofocus.
214ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mState != STATE_IDLE) {
215ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
216ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
217ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
218ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (moving) {
219ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPieRenderer.showStart();
220ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
221ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mPieRenderer.showSuccess(true);
222ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
223ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
224ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
225ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void initializeFocusAreas(
226ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int focusWidth, int focusHeight, int x, int y, int previewWidth, int previewHeight) {
227ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mFocusArea == null) {
228ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mFocusArea = new ArrayList<>();
229ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mFocusArea.add(new Area(new Rect(), 1));
230ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
231ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
232ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Convert the coordinates to driver format.
233ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    calculateTapArea(
234ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusWidth, focusHeight, 1f, x, y, previewWidth, previewHeight, mFocusArea.get(0).rect);
235ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
236ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
237ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void initializeMeteringAreas(
238ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int focusWidth, int focusHeight, int x, int y, int previewWidth, int previewHeight) {
239ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mMeteringArea == null) {
240ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mMeteringArea = new ArrayList<>();
241ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mMeteringArea.add(new Area(new Rect(), 1));
242ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
243ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
244ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Convert the coordinates to driver format.
245ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // AE area is bigger because exposure is sensitive and
246ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // easy to over- or underexposure if area is too small.
247ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    calculateTapArea(
248ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusWidth,
249ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusHeight,
250ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        1.5f,
251ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        x,
252ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        y,
253ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        previewWidth,
254ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        previewHeight,
255ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mMeteringArea.get(0).rect);
256ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
257ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
258ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onSingleTapUp(int x, int y) {
259ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
260ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
261ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
262ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
263ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Let users be able to cancel previous touch focus.
264ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if ((mFocusArea != null)
265ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && (mState == STATE_FOCUSING || mState == STATE_SUCCESS || mState == STATE_FAIL)) {
266ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      cancelAutoFocus();
267ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
268ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Initialize variables.
269ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int focusWidth = mPieRenderer.getSize();
270ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int focusHeight = mPieRenderer.getSize();
271ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (focusWidth == 0 || mPieRenderer.getWidth() == 0 || mPieRenderer.getHeight() == 0) {
272ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
273ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
274ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int previewWidth = mPreviewWidth;
275ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int previewHeight = mPreviewHeight;
276ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Initialize mFocusArea.
277ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mFocusAreaSupported) {
278ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      initializeFocusAreas(focusWidth, focusHeight, x, y, previewWidth, previewHeight);
279ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
280ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Initialize mMeteringArea.
281ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mMeteringAreaSupported) {
282ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      initializeMeteringAreas(focusWidth, focusHeight, x, y, previewWidth, previewHeight);
283ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
284ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
285ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Use margin to set the focus indicator to the touched area.
286ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPieRenderer.setFocus(x, y);
287ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
288ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Set the focus area and metering area.
289ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mListener.setFocusParameters();
290ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mFocusAreaSupported) {
291ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      autoFocus();
292ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else { // Just show the indicator in all other cases.
293ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      updateFocusUI();
294ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Reset the metering area in 3 seconds.
295ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mHandler.removeMessages(RESET_TOUCH_FOCUS);
296ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
297ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
298ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
299ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
300ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onPreviewStarted() {
301ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mState = STATE_IDLE;
302ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
303ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
304ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onPreviewStopped() {
305ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // If auto focus was in progress, it would have been stopped.
306ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mState = STATE_IDLE;
307ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    resetTouchFocus();
308ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updateFocusUI();
309ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
310ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
311ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void onCameraReleased() {
312ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    onPreviewStopped();
313ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
314ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
315ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void autoFocus() {
316ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v("FocusOverlayManager.autoFocus", "Start autofocus.");
317ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mListener.autoFocus();
318ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mState = STATE_FOCUSING;
319ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updateFocusUI();
320ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mHandler.removeMessages(RESET_TOUCH_FOCUS);
321ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
322ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
323ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public void cancelAutoFocus() {
324ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    LogUtil.v("FocusOverlayManager.cancelAutoFocus", "Cancel autofocus.");
325ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
326ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Reset the tap area before calling mListener.cancelAutofocus.
327ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Otherwise, focus mode stays at auto and the tap area passed to the
328ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // driver is not reset.
329ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    resetTouchFocus();
330ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mListener.cancelAutoFocus();
331ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mState = STATE_IDLE;
332ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    updateFocusUI();
333ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mHandler.removeMessages(RESET_TOUCH_FOCUS);
334ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
335ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
336ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void capture() {
337ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mListener.capture()) {
338ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mState = STATE_IDLE;
339ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mHandler.removeMessages(RESET_TOUCH_FOCUS);
340ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
341ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
342ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
343ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public String getFocusMode() {
344ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    List<String> supportedFocusModes = mParameters.getSupportedFocusModes();
345ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
346ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mFocusAreaSupported && mFocusArea != null) {
347ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // Always use autofocus in tap-to-focus.
348ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mFocusMode = Parameters.FOCUS_MODE_AUTO;
349ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
350ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      mFocusMode = Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
351ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
352ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
353ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!isSupported(mFocusMode, supportedFocusModes)) {
354ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // For some reasons, the driver does not support the current
355ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      // focus mode. Fall back to auto.
356ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (isSupported(Parameters.FOCUS_MODE_AUTO, mParameters.getSupportedFocusModes())) {
357ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mFocusMode = Parameters.FOCUS_MODE_AUTO;
358ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
359ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        mFocusMode = mParameters.getFocusMode();
360ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
361ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
362ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mFocusMode;
363ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
364ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
365ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public List<Area> getFocusAreas() {
366ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mFocusArea;
367ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
368ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
369ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  public List<Area> getMeteringAreas() {
370ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return mMeteringArea;
371ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
372ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
373ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void updateFocusUI() {
374ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!mInitialized) {
375ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
376ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
377ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    FocusIndicator focusIndicator = mPieRenderer;
378ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
379ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (mState == STATE_IDLE) {
380ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (mFocusArea == null) {
381ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusIndicator.clear();
382ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else {
383ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // Users touch on the preview and the indicator represents the
384ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // metering area. Either focus area is not supported or
385ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        // autoFocus call is not required.
386ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusIndicator.showStart();
387ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
388ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
389ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      focusIndicator.showStart();
390ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    } else {
391ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) {
39210ae593a59aa50963e1d3159747da2d65ca79bedEric Erfanian        // TODO: check HAL behavior and decide if this can be removed.
393ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusIndicator.showSuccess(false);
394ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else if (mState == STATE_SUCCESS) {
395ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusIndicator.showSuccess(false);
396ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      } else if (mState == STATE_FAIL) {
397ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        focusIndicator.showFail(false);
398ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      }
399ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
400ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
401ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
402ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void resetTouchFocus() {
403ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (!mInitialized) {
404ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return;
405ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
406ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
407ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Put focus indicator to the center. clear reset position
408ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mPieRenderer.clear();
409ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
410ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mFocusArea = null;
411ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mMeteringArea = null;
412ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
413ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
414ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void calculateTapArea(
415ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int focusWidth,
416ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int focusHeight,
417ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      float areaMultiple,
418ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int x,
419ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int y,
420ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int previewWidth,
421ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      int previewHeight,
422ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      Rect rect) {
423ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int areaWidth = (int) (focusWidth * areaMultiple);
424ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int areaHeight = (int) (focusHeight * areaMultiple);
425ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final int maxW = previewWidth - areaWidth;
426ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int left = maxW > 0 ? clamp(x - areaWidth / 2, 0, maxW) : 0;
427ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    final int maxH = previewHeight - areaHeight;
428ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    int top = maxH > 0 ? clamp(y - areaHeight / 2, 0, maxH) : 0;
429ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
430ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    RectF rectF = new RectF(left, top, left + areaWidth, top + areaHeight);
431ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    mMatrix.mapRect(rectF);
432ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    rectFToRect(rectF, rect);
433ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
434ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
435ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private int clamp(int x, int min, int max) {
436ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    Assert.checkArgument(max >= min);
437ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (x > max) {
438ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return max;
439ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
440ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    if (x < min) {
441ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian      return min;
442ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    }
443ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return x;
444ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
445ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
446ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isAutoExposureLockSupported(Parameters params) {
447ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return TRUE.equals(params.get(AUTO_EXPOSURE_LOCK_SUPPORTED));
448ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
449ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
450ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isAutoWhiteBalanceLockSupported(Parameters params) {
451ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return TRUE.equals(params.get(AUTO_WHITE_BALANCE_LOCK_SUPPORTED));
452ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
453ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
454ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isSupported(String value, List<String> supported) {
455ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return supported != null && supported.indexOf(value) >= 0;
456ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
457ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
458ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isMeteringAreaSupported(Parameters params) {
459ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return params.getMaxNumMeteringAreas() > 0;
460ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
461ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
462ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private boolean isFocusAreaSupported(Parameters params) {
463ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    return (params.getMaxNumFocusAreas() > 0
464ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian        && isSupported(Parameters.FOCUS_MODE_AUTO, params.getSupportedFocusModes()));
465ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
466ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
467ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void prepareMatrix(Matrix matrix, boolean mirror, int viewWidth, int viewHeight) {
468ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Need mirror for front camera.
469ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    matrix.setScale(mirror ? -1 : 1, 1);
470ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // Camera driver coordinates range from (-1000, -1000) to (1000, 1000).
471ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    // UI coordinates range from (0, 0) to (width, height).
472ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    matrix.postScale(viewWidth / 2000f, viewHeight / 2000f);
473ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    matrix.postTranslate(viewWidth / 2f, viewHeight / 2f);
474ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
475ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian
476ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  private void rectFToRect(RectF rectF, Rect rect) {
477ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    rect.left = Math.round(rectF.left);
478ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    rect.top = Math.round(rectF.top);
479ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    rect.right = Math.round(rectF.right);
480ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian    rect.bottom = Math.round(rectF.bottom);
481ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian  }
482ccca31529c07970e89419fb85a9e8153a5396838Eric Erfanian}
483