1 /*
2  * Copyright (C) 2023 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 #include <log/log.h>
18 
19 #include "AFStateMachine.h"
20 
21 namespace android {
22 namespace hardware {
23 namespace camera {
24 namespace provider {
25 namespace implementation {
26 namespace hw {
27 
28 constexpr char kClass[] = "AFStateMachine";
29 
30 using namespace std::chrono_literals;
31 
AFStateMachine(int afDurationMs,float focused,float unfocused)32 AFStateMachine::AFStateMachine(int afDurationMs, float focused, float unfocused)
33     : afDuration(1ms * afDurationMs)
34     , focusedDistance(focused)
35     , unfocusedDistance(unfocused)
36 {}
37 
38 std::pair<camera_metadata_enum_android_control_af_state_t, float>
operator ()(const camera_metadata_enum_android_control_af_mode_t mode,const camera_metadata_enum_android_control_af_trigger_t trigger)39 AFStateMachine::operator()(const camera_metadata_enum_android_control_af_mode_t mode,
40                            const camera_metadata_enum_android_control_af_trigger_t trigger) {
41     switch (mode) {
42     default:
43         ALOGW("%s:%s:%d unexpected mode=%d", kClass, __func__, __LINE__, mode);
44         [[fallthrough]];
45 
46     case ANDROID_CONTROL_AF_MODE_OFF:
47         state = ANDROID_CONTROL_AF_STATE_INACTIVE;
48         return {ANDROID_CONTROL_AF_STATE_INACTIVE, unfocusedDistance};
49 
50     case ANDROID_CONTROL_AF_MODE_AUTO:
51         switch (trigger) {
52         default:
53             ALOGW("%s:%s:%d unexpected trigger=%d", kClass, __func__, __LINE__, trigger);
54             [[fallthrough]];
55 
56         case ANDROID_CONTROL_AF_TRIGGER_IDLE:
57             return doAF();
58 
59         case ANDROID_CONTROL_AF_TRIGGER_START:
60             state = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN;
61             afLockedT = std::chrono::steady_clock::now() + afDuration;
62             return {ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN, unfocusedDistance};
63 
64         case ANDROID_CONTROL_AF_TRIGGER_CANCEL:
65             state = ANDROID_CONTROL_AF_STATE_INACTIVE;
66             return {ANDROID_CONTROL_AF_STATE_INACTIVE, unfocusedDistance};
67         }
68     }
69 }
70 
71 std::pair<camera_metadata_enum_android_control_af_state_t, float>
operator ()()72 AFStateMachine::operator()() {
73     return doAF();
74 }
75 
76 std::pair<camera_metadata_enum_android_control_af_state_t, float>
doAF()77 AFStateMachine::doAF() {
78     switch (state) {
79     default:
80         ALOGW("%s:%s:%d unexpected state=%d", kClass, __func__, __LINE__, state);
81         [[fallthrough]];
82 
83     case ANDROID_CONTROL_AF_STATE_INACTIVE:
84         return {ANDROID_CONTROL_AF_STATE_INACTIVE, unfocusedDistance};
85 
86     case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
87         if (std::chrono::steady_clock::now() >= afLockedT) {
88             state = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED;
89             return {ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED, focusedDistance};
90         } else {
91             return {ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN, unfocusedDistance};
92         }
93 
94     case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
95         return {ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED, focusedDistance};
96     }
97 }
98 
99 }  // namespace hw
100 }  // namespace implementation
101 }  // namespace provider
102 }  // namespace camera
103 }  // namespace hardware
104 }  // namespace android
105