1 /* 2 * Copyright (C) 2014 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 17 package com.android.camera.one.v2.autofocus; 18 19 import android.hardware.camera2.CaptureRequest; 20 import android.hardware.camera2.CaptureResult; 21 22 import com.android.camera.async.Updatable; 23 import com.android.camera.one.v2.camera2proxy.CaptureResultProxy; 24 import com.google.common.base.Objects; 25 import com.google.common.collect.ImmutableSet; 26 import com.google.common.util.concurrent.SettableFuture; 27 28 import java.util.Set; 29 import java.util.concurrent.ExecutionException; 30 import java.util.concurrent.TimeUnit; 31 import java.util.concurrent.TimeoutException; 32 33 import javax.annotation.ParametersAreNonnullByDefault; 34 35 /** 36 * Listens for image metadata and returns the result of an AF scan caused by an 37 * AF_TRIGGER_START. 38 * <p> 39 * This maintains/implements the subset of the finite state machine of 40 * {@link android.hardware.camera2.CaptureResult#CONTROL_AF_STATE} which relates 41 * to AF_TRIGGER. 42 * <p> 43 * That is, it invokes the given callback when a scan is complete, according to 44 * the following sequence: 45 * 46 * <pre> 47 * .* CONTROL_AF_TRIGGER_START .* (STATE_INACTIVE|STATE_FOCUSED_LOCKED|STATE_NOT_FOCUSED_LOCKED) 48 * </pre> 49 * <p> 50 * See the android documentation for {@link CaptureResult#CONTROL_AF_STATE} for 51 * further documentation on the state machine this class implements. 52 */ 53 @ParametersAreNonnullByDefault 54 public final class AFTriggerResult implements Updatable<CaptureResultProxy> { 55 private static final Set<Integer> TRIGGER_DONE_STATES = ImmutableSet.of( 56 CaptureResult.CONTROL_AF_STATE_INACTIVE, 57 CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED, 58 CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED); 59 60 private final TriggerStateMachine mStateMachine; 61 private final SettableFuture<Boolean> mFutureResult; 62 AFTriggerResult()63 public AFTriggerResult() { 64 mFutureResult = SettableFuture.create(); 65 mStateMachine = new TriggerStateMachine( 66 CaptureRequest.CONTROL_AF_TRIGGER_START, 67 TRIGGER_DONE_STATES); 68 } 69 70 @Override update(CaptureResultProxy result)71 public void update(CaptureResultProxy result) { 72 Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); 73 boolean done = mStateMachine.update( 74 result.getFrameNumber(), 75 result.getRequest().get(CaptureRequest.CONTROL_AF_TRIGGER), 76 afState); 77 if (done) { 78 boolean inFocus = Objects.equal(afState, CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED) 79 || Objects.equal(afState, CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED); 80 mFutureResult.set(inFocus); 81 } 82 } 83 84 /** 85 * Blocks until the AF scan is complete. 86 * 87 * @return Whether the scene is in-focus or not, based on the camera driver. 88 * @throws InterruptedException 89 */ get()90 public boolean get() throws InterruptedException { 91 try { 92 return mFutureResult.get(); 93 } catch (ExecutionException impossible) { 94 throw new RuntimeException(impossible); 95 } 96 } 97 98 /** 99 * Blocks until the AF scan is complete. 100 * 101 * @return Whether the scene is in-focus or not, based on the camera driver. 102 * @throws InterruptedException 103 */ get(long timeout, TimeUnit timeUnit)104 public boolean get(long timeout, TimeUnit timeUnit) throws InterruptedException, 105 TimeoutException { 106 try { 107 return mFutureResult.get(timeout, timeUnit); 108 } catch (ExecutionException impossible) { 109 throw new RuntimeException(impossible); 110 } 111 } 112 } 113