1875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall/* 2875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * Copyright (C) 2014 The Android Open Source Project 3875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * 4875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * Licensed under the Apache License, Version 2.0 (the "License"); 5875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * you may not use this file except in compliance with the License. 6875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * You may obtain a copy of the License at 7875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * 8875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * http://www.apache.org/licenses/LICENSE-2.0 9875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * 10875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * Unless required by applicable law or agreed to in writing, software 11875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * distributed under the License is distributed on an "AS IS" BASIS, 12875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * See the License for the specific language governing permissions and 14875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * limitations under the License. 15875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall */ 16875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 17875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallpackage com.android.camera.one.v2.autofocus; 18875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 19875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallimport android.hardware.camera2.CaptureRequest; 20875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallimport android.hardware.camera2.CaptureResult; 21875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 22875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallimport com.android.camera.async.Updatable; 23875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallimport com.android.camera.one.v2.camera2proxy.CaptureResultProxy; 246c3a702472798d446049bd6241851f3ae8775b57Puneet Lallimport com.google.common.base.Objects; 25875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallimport com.google.common.collect.ImmutableSet; 266c3a702472798d446049bd6241851f3ae8775b57Puneet Lallimport com.google.common.util.concurrent.SettableFuture; 27875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 28875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallimport java.util.Set; 296c3a702472798d446049bd6241851f3ae8775b57Puneet Lallimport java.util.concurrent.ExecutionException; 306c3a702472798d446049bd6241851f3ae8775b57Puneet Lallimport java.util.concurrent.TimeUnit; 316c3a702472798d446049bd6241851f3ae8775b57Puneet Lallimport java.util.concurrent.TimeoutException; 32875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 33875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lallimport javax.annotation.ParametersAreNonnullByDefault; 34875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 35875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall/** 366c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * Listens for image metadata and returns the result of an AE scan caused by an 376c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * AE_TRIGGER_START. The result of indicates whether flash is required. 386c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * <p> 39875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * Maintains the current state of auto-exposure scans resulting from explicit 40875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * precapture trigger requests. This maintains the subset of the finite state 41875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * machine of {@link CaptureResult#CONTROL_AE_STATE} which relates to 42875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * CONTROL_AE_PRECAPTURE_TRIGGER 43875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * <p> 44875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * That is, it invokes the given callback when a scan is complete, according to 45875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * the following sequence: 46875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * 47875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * <pre> 48875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * .* CONTROL_AE_PRECAPTURE_TRIGGER_START .* 49875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * (STATE_INACTIVE|STATE_FLASH_REQUIRED|STATE_CONVERGED|STATE_LOCKED) 50875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * </pre> 51875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * <p> 52875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * See the android documentation for {@link CaptureResult#CONTROL_AE_STATE} for 53875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall * further documentation on the state machine this class implements. 54875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall */ 55875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall@ParametersAreNonnullByDefault 566c3a702472798d446049bd6241851f3ae8775b57Puneet Lallpublic final class AETriggerResult implements Updatable<CaptureResultProxy> { 57875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall private static final Set<Integer> TRIGGER_DONE_STATES = ImmutableSet.of( 586c3a702472798d446049bd6241851f3ae8775b57Puneet Lall CaptureResult.CONTROL_AE_STATE_INACTIVE, 596c3a702472798d446049bd6241851f3ae8775b57Puneet Lall CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED, 606c3a702472798d446049bd6241851f3ae8775b57Puneet Lall CaptureResult.CONTROL_AE_STATE_CONVERGED, 616c3a702472798d446049bd6241851f3ae8775b57Puneet Lall CaptureResult.CONTROL_AE_STATE_LOCKED); 62875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 63875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall private final TriggerStateMachine mStateMachine; 646c3a702472798d446049bd6241851f3ae8775b57Puneet Lall private final SettableFuture<Boolean> mFutureResult; 65875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 666c3a702472798d446049bd6241851f3ae8775b57Puneet Lall public AETriggerResult() { 67875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall mStateMachine = new TriggerStateMachine( 68875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START, 696c3a702472798d446049bd6241851f3ae8775b57Puneet Lall TRIGGER_DONE_STATES); 706c3a702472798d446049bd6241851f3ae8775b57Puneet Lall mFutureResult = SettableFuture.create(); 71875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall } 72875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall 73875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall @Override 74875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall public void update(CaptureResultProxy result) { 756c3a702472798d446049bd6241851f3ae8775b57Puneet Lall Integer state = result.get(CaptureResult.CONTROL_AE_STATE); 766c3a702472798d446049bd6241851f3ae8775b57Puneet Lall boolean done = mStateMachine.update( 77875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall result.getFrameNumber(), 78875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall result.getRequest().get(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER), 796c3a702472798d446049bd6241851f3ae8775b57Puneet Lall state); 806c3a702472798d446049bd6241851f3ae8775b57Puneet Lall if (done) { 816c3a702472798d446049bd6241851f3ae8775b57Puneet Lall boolean flashRequired = Objects.equal(state, CaptureResult 826c3a702472798d446049bd6241851f3ae8775b57Puneet Lall .CONTROL_AE_STATE_FLASH_REQUIRED); 836c3a702472798d446049bd6241851f3ae8775b57Puneet Lall mFutureResult.set(flashRequired); 846c3a702472798d446049bd6241851f3ae8775b57Puneet Lall } 856c3a702472798d446049bd6241851f3ae8775b57Puneet Lall } 866c3a702472798d446049bd6241851f3ae8775b57Puneet Lall 876c3a702472798d446049bd6241851f3ae8775b57Puneet Lall /** 886c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * Blocks until the AE scan is complete. 896c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * 906c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * @return Whether the scene requires flash to be properly exposed. 916c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * @throws InterruptedException 926c3a702472798d446049bd6241851f3ae8775b57Puneet Lall */ 936c3a702472798d446049bd6241851f3ae8775b57Puneet Lall public boolean get() throws InterruptedException { 946c3a702472798d446049bd6241851f3ae8775b57Puneet Lall try { 956c3a702472798d446049bd6241851f3ae8775b57Puneet Lall return mFutureResult.get(); 966c3a702472798d446049bd6241851f3ae8775b57Puneet Lall } catch (ExecutionException impossible) { 976c3a702472798d446049bd6241851f3ae8775b57Puneet Lall throw new RuntimeException(impossible); 986c3a702472798d446049bd6241851f3ae8775b57Puneet Lall } 996c3a702472798d446049bd6241851f3ae8775b57Puneet Lall } 1006c3a702472798d446049bd6241851f3ae8775b57Puneet Lall 1016c3a702472798d446049bd6241851f3ae8775b57Puneet Lall /** 1026c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * Blocks until the AE scan is complete. 1036c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * 1046c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * @return Whether the scene requires flash to be properly exposed. 1056c3a702472798d446049bd6241851f3ae8775b57Puneet Lall * @throws InterruptedException 1066c3a702472798d446049bd6241851f3ae8775b57Puneet Lall */ 1076c3a702472798d446049bd6241851f3ae8775b57Puneet Lall public boolean get(long timeout, TimeUnit timeUnit) throws InterruptedException, 1086c3a702472798d446049bd6241851f3ae8775b57Puneet Lall TimeoutException { 1096c3a702472798d446049bd6241851f3ae8775b57Puneet Lall try { 1106c3a702472798d446049bd6241851f3ae8775b57Puneet Lall return mFutureResult.get(timeout, timeUnit); 1116c3a702472798d446049bd6241851f3ae8775b57Puneet Lall } catch (ExecutionException impossible) { 1126c3a702472798d446049bd6241851f3ae8775b57Puneet Lall throw new RuntimeException(impossible); 1136c3a702472798d446049bd6241851f3ae8775b57Puneet Lall } 114875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall } 115875d9fff24e283efa5d95ad75c3fab074e489fa4Puneet Lall} 116