Process the AF triggers from the request as a camera1 autofocus routine.
This method should be called after the parameters are {@link LegacyRequestMapper mapped}
with the request.
Callbacks are processed in the background, and the next call to {@link #mapResultTriggers}
will have the latest AF state as reflected by the camera1 callbacks.
None of the arguments will be mutated.
checkNotNull(captureRequest, "captureRequest must not be null");
/*
* control.afTrigger
*/
int afTrigger = ParamsUtils.getOrDefault(captureRequest, CONTROL_AF_TRIGGER,
CONTROL_AF_TRIGGER_IDLE);
final String afMode = parameters.getFocusMode();
if (!Objects.equals(mAfModePrevious, afMode)) {
if (VERBOSE) {
Log.v(TAG, "processRequestTriggers - AF mode switched from " + mAfModePrevious +
" to " + afMode);
}
// Switching modes always goes back to INACTIVE; ignore callbacks from previous modes
synchronized (mLock) {
++mAfRun;
mAfState = CONTROL_AF_STATE_INACTIVE;
}
mCamera.cancelAutoFocus();
}
mAfModePrevious = afMode;
// Passive AF Scanning
{
final int currentAfRun;
synchronized (mLock) {
currentAfRun = mAfRun;
}
Camera.AutoFocusMoveCallback afMoveCallback = new Camera.AutoFocusMoveCallback() {
@Override
public void onAutoFocusMoving(boolean start, Camera camera) {
synchronized (mLock) {
int latestAfRun = mAfRun;
if (VERBOSE) {
Log.v(TAG,
"onAutoFocusMoving - start " + start + " latest AF run " +
latestAfRun + ", last AF run " + currentAfRun
);
}
if (currentAfRun != latestAfRun) {
Log.d(TAG,
"onAutoFocusMoving - ignoring move callbacks from old af run"
+ currentAfRun
);
return;
}
int newAfState = start ?
CONTROL_AF_STATE_PASSIVE_SCAN :
CONTROL_AF_STATE_PASSIVE_FOCUSED;
// We never send CONTROL_AF_STATE_PASSIVE_UNFOCUSED
switch (afMode) {
case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
break;
// This callback should never be sent in any other AF mode
default:
Log.w(TAG, "onAutoFocus - got unexpected onAutoFocus in mode "
+ afMode);
}
mAfState = newAfState;
}
}
};
// Only set move callback if we can call autofocus.
switch (afMode) {
case Parameters.FOCUS_MODE_AUTO:
case Parameters.FOCUS_MODE_MACRO:
case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
mCamera.setAutoFocusMoveCallback(afMoveCallback);
}
}
// AF Locking
switch (afTrigger) {
case CONTROL_AF_TRIGGER_START:
int afStateAfterStart;
switch (afMode) {
case Parameters.FOCUS_MODE_AUTO:
case Parameters.FOCUS_MODE_MACRO:
afStateAfterStart = CONTROL_AF_STATE_ACTIVE_SCAN;
break;
case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
afStateAfterStart = CONTROL_AF_STATE_PASSIVE_SCAN;
break;
default:
// EDOF, INFINITY
afStateAfterStart = CONTROL_AF_STATE_INACTIVE;
}
final int currentAfRun;
synchronized (mLock) {
currentAfRun = ++mAfRun;
mAfState = afStateAfterStart;
}
if (VERBOSE) {
Log.v(TAG, "processRequestTriggers - got AF_TRIGGER_START, " +
"new AF run is " + currentAfRun);
}
// Avoid calling autofocus unless we are in a state that supports calling this.
if (afStateAfterStart == CONTROL_AF_STATE_INACTIVE) {
break;
}
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
synchronized (mLock) {
int latestAfRun = mAfRun;
if (VERBOSE) {
Log.v(TAG, "onAutoFocus - success " + success + " latest AF run " +
latestAfRun + ", last AF run " + currentAfRun);
}
// Ignore old auto-focus results, since another trigger was requested
if (latestAfRun != currentAfRun) {
Log.d(TAG, String.format("onAutoFocus - ignoring AF callback " +
"(old run %d, new run %d)", currentAfRun, latestAfRun));
return;
}
int newAfState = success ?
CONTROL_AF_STATE_FOCUSED_LOCKED :
CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
switch (afMode) {
case Parameters.FOCUS_MODE_AUTO:
case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
case Parameters.FOCUS_MODE_MACRO:
break;
// This callback should never be sent in any other AF mode
default:
Log.w(TAG, "onAutoFocus - got unexpected onAutoFocus in mode "
+ afMode);
}
mAfState = newAfState;
}
}
});
break;
case CONTROL_AF_TRIGGER_CANCEL:
synchronized (mLock) {
int updatedAfRun;
synchronized (mLock) {
updatedAfRun = ++mAfRun;
mAfState = CONTROL_AF_STATE_INACTIVE;
}
mCamera.cancelAutoFocus();
if (VERBOSE) {
Log.v(TAG, "processRequestTriggers - got AF_TRIGGER_CANCEL, " +
"new AF run is " + updatedAfRun);
}
}
break;
case CONTROL_AF_TRIGGER_IDLE:
// No action necessary. The callbacks will handle transitions.
break;
default:
Log.w(TAG, "processRequestTriggers - ignoring unknown control.afTrigger = "
+ afTrigger);
}