• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 androidx.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 
TriggerStateMachine(int triggerStart, Set<Integer> doneStates)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      */
update(long frameNumber, @Nullable Integer triggerState, @Nullable Integer state)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