自动对焦在两种场景下实现,分别是按下快门或轻触preview时,下面就简单分析两种情况下的代码执行流程。
1. 按下快门时
Camera.java:
@Override
public void onShutterButtonFocus(boolean pressed) {
if (mPausing || collapseCameraControls() || mCameraState == SNAPSHOT_IN_PROGRESS) return;
// Do not do focus if there is not enough storage.
if (pressed && !canTakePicture()) return;
if (pressed) {
mFocusManager.onShutterDown();
} else {
mFocusManager.onShutterUp();
}
}
FocusManager.java
public void onShutterDown() {
if (!mInitialized) return;
// Lock AE and AWB so users can half-press shutter and recompose.
if (mLockAeAwbNeeded && !mAeAwbLock) {
mAeAwbLock = true;
mListener.setFocusParameters();
}
if (needAutoFocusCall()) {
// Do not focus if touch focus has been triggered.
if (mState != STATE_SUCCESS && mState != STATE_FAIL) {
autoFocus();
}
}
}
FocusManager.java
private void autoFocus() {
Log.v(TAG, "Start autofocus.");
mListener.autoFocus();
mState = STATE_FOCUSING;
// Pause the face view because the driver will keep sending face
// callbacks after the focus completes.
if (mFaceView != null) mFaceView.pause();
updateFocusUI();
mHandler.removeMessages(RESET_TOUCH_FOCUS);
}
由于Camera.java
实现了FocusManager.Listener接口,所以mListener.autoFocus()的实现在Camera.java中。
Camera.java
@Override
public void autoFocus() {
mFocusStartTime = System.currentTimeMillis();
mCameraDevice.autoFocus(mAutoFocusCallback);
setCameraState(FOCUSING);
}
mCameraDevice.autoFocus(mAutoFocusCallback)调用了frameworks/base/core/java/android/hardware/Camera.java,代码执行至框架层了。
public final void autoFocus(AutoFocusCallback cb)
{
mAutoFocusCallback = cb;
native_autoFocus();
}
2.轻触preview
Camera.java
// Preview area is touched. Handle touch focus.
@Override
public boolean onTouch(View v, MotionEvent e) {
if (mPausing || mCameraDevice == null || !mFirstTimeInitialized
|| mCameraState == SNAPSHOT_IN_PROGRESS) {
return false;
}
// Do not trigger touch focus if popup window is opened.
if (collapseCameraControls()) return false;
// Check if metering area or focus area is supported.
if (!mFocusAreaSupported && !mMeteringAreaSupported) return false;
return mFocusManager.onTouch(e);
}
FocusManager.java
public boolean onTouch(MotionEvent e)中调用了autoFocus()
// Set the focus area and metering area.
mListener.setFocusParameters();
if (mFocusAreaSupported && (e.getAction() == MotionEvent.ACTION_UP)) {
autoFocus();
} else { // Just show the indicator in all other cases.
updateFocusUI();
// Reset the metering area in 3 seconds.
mHandler.removeMessages(RESET_TOUCH_FOCUS);
mHandler.sendEmptyMessageDelayed(RESET_TOUCH_FOCUS, RESET_TOUCH_FOCUS_DELAY);
}
下面的代码流程与shutter中后半部分相似,在此不再赘述。