blob: 8bcb52fe546149ceda101b928f59022891db6a26 [file] [log] [blame]
Michael Kolb8872c232013-01-29 10:33:22 -08001/*
2 * Copyright (C) 2012 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
17package com.android.camera;
18
19import android.annotation.TargetApi;
20import android.graphics.Matrix;
21import android.graphics.Rect;
22import android.graphics.RectF;
23import android.hardware.Camera.Area;
24import android.hardware.Camera.Parameters;
25import android.os.Handler;
26import android.os.Looper;
27import android.os.Message;
28import android.util.Log;
29
Michael Kolb8872c232013-01-29 10:33:22 -080030import com.android.gallery3d.common.ApiHelper;
31
32import java.util.ArrayList;
33import java.util.List;
34
35/* A class that handles everything about focus in still picture mode.
36 * This also handles the metering area because it is the same as focus area.
37 *
38 * The test cases:
39 * (1) The camera has continuous autofocus. Move the camera. Take a picture when
40 * CAF is not in progress.
41 * (2) The camera has continuous autofocus. Move the camera. Take a picture when
42 * CAF is in progress.
43 * (3) The camera has face detection. Point the camera at some faces. Hold the
44 * shutter. Release to take a picture.
45 * (4) The camera has face detection. Point the camera at some faces. Single tap
46 * the shutter to take a picture.
47 * (5) The camera has autofocus. Single tap the shutter to take a picture.
48 * (6) The camera has autofocus. Hold the shutter. Release to take a picture.
49 * (7) The camera has no autofocus. Single tap the shutter and take a picture.
50 * (8) The camera has autofocus and supports focus area. Touch the screen to
51 * trigger autofocus. Take a picture.
52 * (9) The camera has autofocus and supports focus area. Touch the screen to
53 * trigger autofocus. Wait until it times out.
54 * (10) The camera has no autofocus and supports metering area. Touch the screen
55 * to change metering area.
56 */
57public class FocusOverlayManager {
58 private static final String TAG = "CAM_FocusManager";
59
60 private static final int RESET_TOUCH_FOCUS = 0;
61 private static final int RESET_TOUCH_FOCUS_DELAY = 3000;
62
63 private int mState = STATE_IDLE;
64 private static final int STATE_IDLE = 0; // Focus is not active.
65 private static final int STATE_FOCUSING = 1; // Focus is in progress.
66 // Focus is in progress and the camera should take a picture after focus finishes.
67 private static final int STATE_FOCUSING_SNAP_ON_FINISH = 2;
68 private static final int STATE_SUCCESS = 3; // Focus finishes and succeeds.
69 private static final int STATE_FAIL = 4; // Focus finishes and fails.
70
71 private boolean mInitialized;
72 private boolean mFocusAreaSupported;
73 private boolean mMeteringAreaSupported;
74 private boolean mLockAeAwbNeeded;
75 private boolean mAeAwbLock;
76 private Matrix mMatrix;
77
Michael Kolb8872c232013-01-29 10:33:22 -080078 private int mPreviewWidth; // The width of the preview frame layout.
79 private int mPreviewHeight; // The height of the preview frame layout.
80 private boolean mMirror; // true if the camera is front-facing.
81 private int mDisplayOrientation;
Michael Kolb8872c232013-01-29 10:33:22 -080082 private List<Object> mFocusArea; // focus area in driver format
83 private List<Object> mMeteringArea; // metering area in driver format
84 private String mFocusMode;
85 private String[] mDefaultFocusModes;
86 private String mOverrideFocusMode;
87 private Parameters mParameters;
88 private ComboPreferences mPreferences;
89 private Handler mHandler;
90 Listener mListener;
Michael Kolbe3de7222013-02-18 15:16:44 -080091 private boolean mPreviousMoving;
Michael Kolb0718d482013-02-16 13:13:47 -080092 private boolean mFocusDefault;
Michael Kolb8872c232013-01-29 10:33:22 -080093
Michael Kolbd6954f32013-03-08 20:43:01 -080094 private FocusUI mUI;
95
96 public interface FocusUI {
97 public boolean hasFaces();
98 public void clearFocus();
99 public void setFocusPosition(int x, int y);
100 public void onFocusStarted();
101 public void onFocusSucceeded(boolean timeOut);
102 public void onFocusFailed(boolean timeOut);
103 public void pauseFaceDetection();
104 public void resumeFaceDetection();
105 }
106
Michael Kolb8872c232013-01-29 10:33:22 -0800107 public interface Listener {
108 public void autoFocus();
109 public void cancelAutoFocus();
110 public boolean capture();
111 public void startFaceDetection();
112 public void stopFaceDetection();
113 public void setFocusParameters();
114 }
115
116 private class MainHandler extends Handler {
117 public MainHandler(Looper looper) {
118 super(looper);
119 }
120
121 @Override
122 public void handleMessage(Message msg) {
123 switch (msg.what) {
124 case RESET_TOUCH_FOCUS: {
125 cancelAutoFocus();
126 mListener.startFaceDetection();
127 break;
128 }
129 }
130 }
131 }
132
133 public FocusOverlayManager(ComboPreferences preferences, String[] defaultFocusModes,
134 Parameters parameters, Listener listener,
Michael Kolbd6954f32013-03-08 20:43:01 -0800135 boolean mirror, Looper looper, FocusUI ui) {
Michael Kolb8872c232013-01-29 10:33:22 -0800136 mHandler = new MainHandler(looper);
137 mMatrix = new Matrix();
138 mPreferences = preferences;
139 mDefaultFocusModes = defaultFocusModes;
140 setParameters(parameters);
141 mListener = listener;
142 setMirror(mirror);
Michael Kolb0718d482013-02-16 13:13:47 -0800143 mFocusDefault = true;
Michael Kolbd6954f32013-03-08 20:43:01 -0800144 mUI = ui;
Michael Kolb8872c232013-01-29 10:33:22 -0800145 }
146
147 public void setParameters(Parameters parameters) {
148 // parameters can only be null when onConfigurationChanged is called
149 // before camera is open. We will just return in this case, because
150 // parameters will be set again later with the right parameters after
151 // camera is open.
152 if (parameters == null) return;
153 mParameters = parameters;
154 mFocusAreaSupported = Util.isFocusAreaSupported(parameters);
155 mMeteringAreaSupported = Util.isMeteringAreaSupported(parameters);
156 mLockAeAwbNeeded = (Util.isAutoExposureLockSupported(mParameters) ||
157 Util.isAutoWhiteBalanceLockSupported(mParameters));
158 }
159
160 public void setPreviewSize(int previewWidth, int previewHeight) {
161 if (mPreviewWidth != previewWidth || mPreviewHeight != previewHeight) {
162 mPreviewWidth = previewWidth;
163 mPreviewHeight = previewHeight;
164 setMatrix();
165 }
166 }
167
168 public void setMirror(boolean mirror) {
169 mMirror = mirror;
170 setMatrix();
171 }
172
173 public void setDisplayOrientation(int displayOrientation) {
174 mDisplayOrientation = displayOrientation;
175 setMatrix();
176 }
177
Michael Kolb8872c232013-01-29 10:33:22 -0800178 private void setMatrix() {
179 if (mPreviewWidth != 0 && mPreviewHeight != 0) {
180 Matrix matrix = new Matrix();
181 Util.prepareMatrix(matrix, mMirror, mDisplayOrientation,
182 mPreviewWidth, mPreviewHeight);
183 // In face detection, the matrix converts the driver coordinates to UI
184 // coordinates. In tap focus, the inverted matrix converts the UI
185 // coordinates to driver coordinates.
186 matrix.invert(mMatrix);
Michael Kolbd6954f32013-03-08 20:43:01 -0800187 mInitialized = true;
Michael Kolb8872c232013-01-29 10:33:22 -0800188 }
189 }
190
191 private void lockAeAwbIfNeeded() {
192 if (mLockAeAwbNeeded && !mAeAwbLock) {
193 mAeAwbLock = true;
194 mListener.setFocusParameters();
195 }
196 }
197
198 private void unlockAeAwbIfNeeded() {
199 if (mLockAeAwbNeeded && mAeAwbLock && (mState != STATE_FOCUSING_SNAP_ON_FINISH)) {
200 mAeAwbLock = false;
201 mListener.setFocusParameters();
202 }
203 }
204
205 public void onShutterDown() {
206 if (!mInitialized) return;
207
208 boolean autoFocusCalled = false;
209 if (needAutoFocusCall()) {
210 // Do not focus if touch focus has been triggered.
211 if (mState != STATE_SUCCESS && mState != STATE_FAIL) {
212 autoFocus();
213 autoFocusCalled = true;
214 }
215 }
216
217 if (!autoFocusCalled) lockAeAwbIfNeeded();
218 }
219
220 public void onShutterUp() {
221 if (!mInitialized) return;
222
223 if (needAutoFocusCall()) {
224 // User releases half-pressed focus key.
225 if (mState == STATE_FOCUSING || mState == STATE_SUCCESS
226 || mState == STATE_FAIL) {
227 cancelAutoFocus();
228 }
229 }
230
231 // Unlock AE and AWB after cancelAutoFocus. Camera API does not
232 // guarantee setParameters can be called during autofocus.
233 unlockAeAwbIfNeeded();
234 }
235
236 public void doSnap() {
237 if (!mInitialized) return;
238
239 // If the user has half-pressed the shutter and focus is completed, we
240 // can take the photo right away. If the focus mode is infinity, we can
241 // also take the photo.
242 if (!needAutoFocusCall() || (mState == STATE_SUCCESS || mState == STATE_FAIL)) {
243 capture();
244 } else if (mState == STATE_FOCUSING) {
245 // Half pressing the shutter (i.e. the focus button event) will
246 // already have requested AF for us, so just request capture on
247 // focus here.
248 mState = STATE_FOCUSING_SNAP_ON_FINISH;
249 } else if (mState == STATE_IDLE) {
250 // We didn't do focus. This can happen if the user press focus key
251 // while the snapshot is still in progress. The user probably wants
252 // the next snapshot as soon as possible, so we just do a snapshot
253 // without focusing again.
254 capture();
255 }
256 }
257
258 public void onAutoFocus(boolean focused, boolean shutterButtonPressed) {
259 if (mState == STATE_FOCUSING_SNAP_ON_FINISH) {
260 // Take the picture no matter focus succeeds or fails. No need
261 // to play the AF sound if we're about to play the shutter
262 // sound.
263 if (focused) {
264 mState = STATE_SUCCESS;
265 } else {
266 mState = STATE_FAIL;
267 }
268 updateFocusUI();
269 capture();
270 } else if (mState == STATE_FOCUSING) {
271 // This happens when (1) user is half-pressing the focus key or
272 // (2) touch focus is triggered. Play the focus tone. Do not
273 // take the picture now.
274 if (focused) {
275 mState = STATE_SUCCESS;
276 } else {
277 mState = STATE_FAIL;
278 }
279 updateFocusUI();
280 // If this is triggered by touch focus, cancel focus after a
281 // while.
Michael Kolb0718d482013-02-16 13:13:47 -0800282 if (!mFocusDefault) {
Michael Kolb8872c232013-01-29 10:33:22 -0800283 mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
284 }
285 if (shutterButtonPressed) {
286 // Lock AE & AWB so users can half-press shutter and recompose.
287 lockAeAwbIfNeeded();
288 }
289 } else if (mState == STATE_IDLE) {
290 // User has released the focus key before focus completes.
291 // Do nothing.
292 }
293 }
294
295 public void onAutoFocusMoving(boolean moving) {
296 if (!mInitialized) return;
Michael Kolbd6954f32013-03-08 20:43:01 -0800297
298
Michael Kolb8872c232013-01-29 10:33:22 -0800299 // Ignore if the camera has detected some faces.
Michael Kolbd6954f32013-03-08 20:43:01 -0800300 if (mUI.hasFaces()) {
301 mUI.clearFocus();
Michael Kolb8872c232013-01-29 10:33:22 -0800302 return;
303 }
304
305 // Ignore if we have requested autofocus. This method only handles
306 // continuous autofocus.
307 if (mState != STATE_IDLE) return;
308
Michael Kolbe3de7222013-02-18 15:16:44 -0800309 // animate on false->true trasition only b/8219520
310 if (moving && !mPreviousMoving) {
Michael Kolbd6954f32013-03-08 20:43:01 -0800311 mUI.onFocusStarted();
Michael Kolbe3de7222013-02-18 15:16:44 -0800312 } else if (!moving) {
Michael Kolbd6954f32013-03-08 20:43:01 -0800313 mUI.onFocusSucceeded(true);
Michael Kolb8872c232013-01-29 10:33:22 -0800314 }
Michael Kolbe3de7222013-02-18 15:16:44 -0800315 mPreviousMoving = moving;
Michael Kolb8872c232013-01-29 10:33:22 -0800316 }
317
318 @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
Michael Kolb0718d482013-02-16 13:13:47 -0800319 private void initializeFocusAreas(int x, int y) {
Michael Kolb8872c232013-01-29 10:33:22 -0800320 if (mFocusArea == null) {
321 mFocusArea = new ArrayList<Object>();
322 mFocusArea.add(new Area(new Rect(), 1));
323 }
324
325 // Convert the coordinates to driver format.
Michael Kolb0718d482013-02-16 13:13:47 -0800326 calculateTapArea(x, y, 1f, ((Area) mFocusArea.get(0)).rect);
Michael Kolb8872c232013-01-29 10:33:22 -0800327 }
328
329 @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
Michael Kolb0718d482013-02-16 13:13:47 -0800330 private void initializeMeteringAreas(int x, int y) {
Michael Kolb8872c232013-01-29 10:33:22 -0800331 if (mMeteringArea == null) {
332 mMeteringArea = new ArrayList<Object>();
333 mMeteringArea.add(new Area(new Rect(), 1));
334 }
335
336 // Convert the coordinates to driver format.
337 // AE area is bigger because exposure is sensitive and
338 // easy to over- or underexposure if area is too small.
Michael Kolb0718d482013-02-16 13:13:47 -0800339 calculateTapArea(x, y, 1.5f, ((Area) mMeteringArea.get(0)).rect);
Michael Kolb8872c232013-01-29 10:33:22 -0800340 }
341
342 public void onSingleTapUp(int x, int y) {
343 if (!mInitialized || mState == STATE_FOCUSING_SNAP_ON_FINISH) return;
344
345 // Let users be able to cancel previous touch focus.
Michael Kolb0718d482013-02-16 13:13:47 -0800346 if ((!mFocusDefault) && (mState == STATE_FOCUSING ||
Michael Kolb8872c232013-01-29 10:33:22 -0800347 mState == STATE_SUCCESS || mState == STATE_FAIL)) {
348 cancelAutoFocus();
349 }
Michael Kolb0718d482013-02-16 13:13:47 -0800350 if (mPreviewWidth == 0 || mPreviewHeight == 0) return;
351 mFocusDefault = false;
Michael Kolb8872c232013-01-29 10:33:22 -0800352 // Initialize mFocusArea.
353 if (mFocusAreaSupported) {
Michael Kolb0718d482013-02-16 13:13:47 -0800354 initializeFocusAreas(x, y);
Michael Kolb8872c232013-01-29 10:33:22 -0800355 }
356 // Initialize mMeteringArea.
357 if (mMeteringAreaSupported) {
Michael Kolb0718d482013-02-16 13:13:47 -0800358 initializeMeteringAreas(x, y);
Michael Kolb8872c232013-01-29 10:33:22 -0800359 }
360
361 // Use margin to set the focus indicator to the touched area.
Michael Kolbd6954f32013-03-08 20:43:01 -0800362 mUI.setFocusPosition(x, y);
Michael Kolb8872c232013-01-29 10:33:22 -0800363
364 // Stop face detection because we want to specify focus and metering area.
365 mListener.stopFaceDetection();
366
367 // Set the focus area and metering area.
368 mListener.setFocusParameters();
369 if (mFocusAreaSupported) {
370 autoFocus();
371 } else { // Just show the indicator in all other cases.
372 updateFocusUI();
373 // Reset the metering area in 3 seconds.
374 mHandler.removeMessages(RESET_TOUCH_FOCUS);
375 mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
376 }
377 }
378
379 public void onPreviewStarted() {
380 mState = STATE_IDLE;
381 }
382
383 public void onPreviewStopped() {
384 // If auto focus was in progress, it would have been stopped.
385 mState = STATE_IDLE;
386 resetTouchFocus();
387 updateFocusUI();
388 }
389
390 public void onCameraReleased() {
391 onPreviewStopped();
392 }
393
394 private void autoFocus() {
395 Log.v(TAG, "Start autofocus.");
396 mListener.autoFocus();
397 mState = STATE_FOCUSING;
398 // Pause the face view because the driver will keep sending face
399 // callbacks after the focus completes.
Michael Kolbd6954f32013-03-08 20:43:01 -0800400 mUI.pauseFaceDetection();
Michael Kolb8872c232013-01-29 10:33:22 -0800401 updateFocusUI();
402 mHandler.removeMessages(RESET_TOUCH_FOCUS);
403 }
404
405 private void cancelAutoFocus() {
406 Log.v(TAG, "Cancel autofocus.");
407
408 // Reset the tap area before calling mListener.cancelAutofocus.
409 // Otherwise, focus mode stays at auto and the tap area passed to the
410 // driver is not reset.
411 resetTouchFocus();
412 mListener.cancelAutoFocus();
Michael Kolbd6954f32013-03-08 20:43:01 -0800413 mUI.resumeFaceDetection();
Michael Kolb8872c232013-01-29 10:33:22 -0800414 mState = STATE_IDLE;
415 updateFocusUI();
416 mHandler.removeMessages(RESET_TOUCH_FOCUS);
417 }
418
419 private void capture() {
420 if (mListener.capture()) {
421 mState = STATE_IDLE;
422 mHandler.removeMessages(RESET_TOUCH_FOCUS);
423 }
424 }
425
426 public String getFocusMode() {
427 if (mOverrideFocusMode != null) return mOverrideFocusMode;
Michael Kolb4a40e122013-02-14 08:30:59 -0800428 if (mParameters == null) return Parameters.FOCUS_MODE_AUTO;
Michael Kolb8872c232013-01-29 10:33:22 -0800429 List<String> supportedFocusModes = mParameters.getSupportedFocusModes();
430
Michael Kolb0718d482013-02-16 13:13:47 -0800431 if (mFocusAreaSupported && !mFocusDefault) {
Michael Kolb8872c232013-01-29 10:33:22 -0800432 // Always use autofocus in tap-to-focus.
433 mFocusMode = Parameters.FOCUS_MODE_AUTO;
434 } else {
435 // The default is continuous autofocus.
436 mFocusMode = mPreferences.getString(
437 CameraSettings.KEY_FOCUS_MODE, null);
438
439 // Try to find a supported focus mode from the default list.
440 if (mFocusMode == null) {
441 for (int i = 0; i < mDefaultFocusModes.length; i++) {
442 String mode = mDefaultFocusModes[i];
443 if (Util.isSupported(mode, supportedFocusModes)) {
444 mFocusMode = mode;
445 break;
446 }
447 }
448 }
449 }
450 if (!Util.isSupported(mFocusMode, supportedFocusModes)) {
451 // For some reasons, the driver does not support the current
452 // focus mode. Fall back to auto.
453 if (Util.isSupported(Parameters.FOCUS_MODE_AUTO,
454 mParameters.getSupportedFocusModes())) {
455 mFocusMode = Parameters.FOCUS_MODE_AUTO;
456 } else {
457 mFocusMode = mParameters.getFocusMode();
458 }
459 }
460 return mFocusMode;
461 }
462
463 public List getFocusAreas() {
464 return mFocusArea;
465 }
466
467 public List getMeteringAreas() {
468 return mMeteringArea;
469 }
470
471 public void updateFocusUI() {
472 if (!mInitialized) return;
473 // Show only focus indicator or face indicator.
Michael Kolb8872c232013-01-29 10:33:22 -0800474
475 if (mState == STATE_IDLE) {
Michael Kolb0718d482013-02-16 13:13:47 -0800476 if (mFocusDefault) {
Michael Kolbd6954f32013-03-08 20:43:01 -0800477 mUI.clearFocus();
Michael Kolb8872c232013-01-29 10:33:22 -0800478 } else {
479 // Users touch on the preview and the indicator represents the
480 // metering area. Either focus area is not supported or
481 // autoFocus call is not required.
Michael Kolbd6954f32013-03-08 20:43:01 -0800482 mUI.onFocusStarted();
Michael Kolb8872c232013-01-29 10:33:22 -0800483 }
484 } else if (mState == STATE_FOCUSING || mState == STATE_FOCUSING_SNAP_ON_FINISH) {
Michael Kolbd6954f32013-03-08 20:43:01 -0800485 mUI.onFocusStarted();
Michael Kolb8872c232013-01-29 10:33:22 -0800486 } else {
487 if (Util.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusMode)) {
488 // TODO: check HAL behavior and decide if this can be removed.
Michael Kolbd6954f32013-03-08 20:43:01 -0800489 mUI.onFocusSucceeded(false);
Michael Kolb8872c232013-01-29 10:33:22 -0800490 } else if (mState == STATE_SUCCESS) {
Michael Kolbd6954f32013-03-08 20:43:01 -0800491 mUI.onFocusSucceeded(false);
Michael Kolb8872c232013-01-29 10:33:22 -0800492 } else if (mState == STATE_FAIL) {
Michael Kolbd6954f32013-03-08 20:43:01 -0800493 mUI.onFocusFailed(false);
Michael Kolb8872c232013-01-29 10:33:22 -0800494 }
495 }
496 }
497
498 public void resetTouchFocus() {
499 if (!mInitialized) return;
500
501 // Put focus indicator to the center. clear reset position
Michael Kolbd6954f32013-03-08 20:43:01 -0800502 mUI.clearFocus();
Michael Kolb0718d482013-02-16 13:13:47 -0800503 // Initialize mFocusArea.
504 if (mFocusAreaSupported) {
505 initializeFocusAreas(mPreviewWidth / 2, mPreviewHeight / 2);
506 }
507 // Initialize mMeteringArea.
508 if (mMeteringAreaSupported) {
509 initializeMeteringAreas(mPreviewWidth / 2, mPreviewHeight / 2);
510 }
511 mFocusDefault = true;
Michael Kolb8872c232013-01-29 10:33:22 -0800512 }
513
Michael Kolb0718d482013-02-16 13:13:47 -0800514 private void calculateTapArea(int x, int y, float areaMultiple, Rect rect) {
515 int areaSize = (int) (Math.min(mPreviewWidth, mPreviewHeight) * areaMultiple / 20);
516 int left = Util.clamp(x - areaSize, 0, mPreviewWidth - 2 * areaSize);
517 int top = Util.clamp(y - areaSize, 0, mPreviewHeight - 2 * areaSize);
Michael Kolb8872c232013-01-29 10:33:22 -0800518
Michael Kolb0718d482013-02-16 13:13:47 -0800519 RectF rectF = new RectF(left, top, left + 2 * areaSize, top + 2 * areaSize);
Michael Kolb8872c232013-01-29 10:33:22 -0800520 mMatrix.mapRect(rectF);
521 Util.rectFToRect(rectF, rect);
522 }
523
524 /* package */ int getFocusState() {
525 return mState;
526 }
527
528 public boolean isFocusCompleted() {
529 return mState == STATE_SUCCESS || mState == STATE_FAIL;
530 }
531
532 public boolean isFocusingSnapOnFinish() {
533 return mState == STATE_FOCUSING_SNAP_ON_FINISH;
534 }
535
536 public void removeMessages() {
537 mHandler.removeMessages(RESET_TOUCH_FOCUS);
538 }
539
540 public void overrideFocusMode(String focusMode) {
541 mOverrideFocusMode = focusMode;
542 }
543
544 public void setAeAwbLock(boolean lock) {
545 mAeAwbLock = lock;
546 }
547
548 public boolean getAeAwbLock() {
549 return mAeAwbLock;
550 }
551
552 private boolean needAutoFocusCall() {
553 String focusMode = getFocusMode();
554 return !(focusMode.equals(Parameters.FOCUS_MODE_INFINITY)
555 || focusMode.equals(Parameters.FOCUS_MODE_FIXED)
556 || focusMode.equals(Parameters.FOCUS_MODE_EDOF));
557 }
558}