Home | History | Annotate | Download | only in autofocus
      1 /*
      2  * Copyright (C) 2015 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.CaptureResult;
     20 import android.support.annotation.Nullable;
     21 
     22 import com.android.camera.async.Updatable;
     23 
     24 import java.util.Set;
     25 
     26 import javax.annotation.ParametersAreNonnullByDefault;
     27 import javax.annotation.concurrent.NotThreadSafe;
     28 
     29 /**
     30  * Tracks the finite state machines used by the camera2 api for AF and AE
     31  * triggers. That is, the state machine waits for a TRIGGER_START followed by
     32  * one of the done states, at which point a callback is invoked and the state
     33  * machine resets.
     34  * <p>
     35  * In other words, this implements the state machine defined by the following
     36  * regex, such that a callback is invoked each time the state machine reaches
     37  * the end.
     38  *
     39  * <pre>
     40  * (.* TRIGGER_START .* [DONE_STATES])+
     41  * </pre>
     42  * <p>
     43  * See the android documentation for {@link CaptureResult#CONTROL_AF_STATE} and
     44  * {@link CaptureResult#CONTROL_AE_STATE} for the transition tables which this
     45  * is based on.
     46  */
     47 @ParametersAreNonnullByDefault
     48 @NotThreadSafe
     49 final class TriggerStateMachine {
     50     private static enum State {
     51         WAITING_FOR_TRIGGER,
     52         TRIGGERED
     53     }
     54 
     55     private final int mTriggerStart;
     56     private final Set<Integer> mDoneStates;
     57     private State mCurrentState;
     58     @Nullable
     59     private Long mLastTriggerFrameNumber;
     60     @Nullable
     61     private Long mLastFinishFrameNumber;
     62 
     63     public TriggerStateMachine(int triggerStart, Set<Integer> doneStates) {
     64         mTriggerStart = triggerStart;
     65         mDoneStates = doneStates;
     66         mCurrentState = State.WAITING_FOR_TRIGGER;
     67         mLastTriggerFrameNumber = null;
     68         mLastFinishFrameNumber = null;
     69     }
     70 
     71     /**
     72      * @return True upon completion of a cycle of the state machine.
     73      */
     74     public boolean update(long frameNumber, @Nullable Integer triggerState, @Nullable Integer
     75             state) {
     76         boolean triggeredNow = triggerState != null && triggerState == mTriggerStart;
     77         boolean doneNow = mDoneStates.contains(state);
     78 
     79         if (mCurrentState == State.WAITING_FOR_TRIGGER) {
     80             if (mLastTriggerFrameNumber == null || frameNumber > mLastTriggerFrameNumber) {
     81                 if (triggeredNow) {
     82                     mCurrentState = State.TRIGGERED;
     83                     mLastTriggerFrameNumber = frameNumber;
     84                 }
     85             }
     86         }
     87 
     88         if (mCurrentState == State.TRIGGERED) {
     89             if (mLastFinishFrameNumber == null || frameNumber > mLastFinishFrameNumber) {
     90                 if (doneNow) {
     91                     mCurrentState = State.WAITING_FOR_TRIGGER;
     92                     mLastFinishFrameNumber = frameNumber;
     93                     return true;
     94                 }
     95             }
     96         }
     97 
     98         return false;
     99     }
    100 }
    101