xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/CameraFlashlight.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker  *
4*ec779b8eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker  *
8*ec779b8eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker  *
10*ec779b8eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker  * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker  */
16*ec779b8eSAndroid Build Coastguard Worker 
17*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "CameraFlashlight"
18*ec779b8eSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_CAMERA
19*ec779b8eSAndroid Build Coastguard Worker // #define LOG_NDEBUG 0
20*ec779b8eSAndroid Build Coastguard Worker 
21*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
22*ec779b8eSAndroid Build Coastguard Worker #include <utils/Trace.h>
23*ec779b8eSAndroid Build Coastguard Worker #include <cutils/properties.h>
24*ec779b8eSAndroid Build Coastguard Worker 
25*ec779b8eSAndroid Build Coastguard Worker #include "CameraFlashlight.h"
26*ec779b8eSAndroid Build Coastguard Worker #include "camera/CameraMetadata.h"
27*ec779b8eSAndroid Build Coastguard Worker #include "camera/camera2/CaptureRequest.h"
28*ec779b8eSAndroid Build Coastguard Worker 
29*ec779b8eSAndroid Build Coastguard Worker namespace android {
30*ec779b8eSAndroid Build Coastguard Worker 
31*ec779b8eSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////
32*ec779b8eSAndroid Build Coastguard Worker // CameraFlashlight implementation begins
33*ec779b8eSAndroid Build Coastguard Worker // used by camera service to control flashflight.
34*ec779b8eSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////
35*ec779b8eSAndroid Build Coastguard Worker 
CameraFlashlight(sp<CameraProviderManager> providerManager,CameraProviderManager::StatusListener * callbacks)36*ec779b8eSAndroid Build Coastguard Worker CameraFlashlight::CameraFlashlight(sp<CameraProviderManager> providerManager,
37*ec779b8eSAndroid Build Coastguard Worker         CameraProviderManager::StatusListener* callbacks) :
38*ec779b8eSAndroid Build Coastguard Worker         mProviderManager(providerManager),
39*ec779b8eSAndroid Build Coastguard Worker         mCallbacks(callbacks),
40*ec779b8eSAndroid Build Coastguard Worker         mFlashlightMapInitialized(false) {
41*ec779b8eSAndroid Build Coastguard Worker }
42*ec779b8eSAndroid Build Coastguard Worker 
~CameraFlashlight()43*ec779b8eSAndroid Build Coastguard Worker CameraFlashlight::~CameraFlashlight() {
44*ec779b8eSAndroid Build Coastguard Worker }
45*ec779b8eSAndroid Build Coastguard Worker 
createFlashlightControl(const std::string & cameraId)46*ec779b8eSAndroid Build Coastguard Worker status_t CameraFlashlight::createFlashlightControl(const std::string& cameraId) {
47*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__,
48*ec779b8eSAndroid Build Coastguard Worker             cameraId.c_str());
49*ec779b8eSAndroid Build Coastguard Worker     if (mFlashControl != NULL) {
50*ec779b8eSAndroid Build Coastguard Worker         return INVALID_OPERATION;
51*ec779b8eSAndroid Build Coastguard Worker     }
52*ec779b8eSAndroid Build Coastguard Worker 
53*ec779b8eSAndroid Build Coastguard Worker     if (mProviderManager->supportSetTorchMode(cameraId)) {
54*ec779b8eSAndroid Build Coastguard Worker         mFlashControl = new ProviderFlashControl(mProviderManager);
55*ec779b8eSAndroid Build Coastguard Worker     } else {
56*ec779b8eSAndroid Build Coastguard Worker         ALOGE("Flashlight control not supported by this device!");
57*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
58*ec779b8eSAndroid Build Coastguard Worker     }
59*ec779b8eSAndroid Build Coastguard Worker 
60*ec779b8eSAndroid Build Coastguard Worker     return OK;
61*ec779b8eSAndroid Build Coastguard Worker }
62*ec779b8eSAndroid Build Coastguard Worker 
setTorchMode(const std::string & cameraId,bool enabled)63*ec779b8eSAndroid Build Coastguard Worker status_t CameraFlashlight::setTorchMode(const std::string& cameraId, bool enabled) {
64*ec779b8eSAndroid Build Coastguard Worker     if (!mFlashlightMapInitialized) {
65*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: findFlashUnits() must be called before this method.",
66*ec779b8eSAndroid Build Coastguard Worker                __FUNCTION__);
67*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
68*ec779b8eSAndroid Build Coastguard Worker     }
69*ec779b8eSAndroid Build Coastguard Worker 
70*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__,
71*ec779b8eSAndroid Build Coastguard Worker             cameraId.c_str(), enabled);
72*ec779b8eSAndroid Build Coastguard Worker 
73*ec779b8eSAndroid Build Coastguard Worker     status_t res = OK;
74*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock l(mLock);
75*ec779b8eSAndroid Build Coastguard Worker 
76*ec779b8eSAndroid Build Coastguard Worker     if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
77*ec779b8eSAndroid Build Coastguard Worker         // This case is needed to avoid state corruption during the following call sequence:
78*ec779b8eSAndroid Build Coastguard Worker         // CameraService::setTorchMode for camera ID 0 begins, does torch status checks
79*ec779b8eSAndroid Build Coastguard Worker         // CameraService::connect for camera ID 0 begins, calls prepareDeviceOpen, ends
80*ec779b8eSAndroid Build Coastguard Worker         // CameraService::setTorchMode for camera ID 0 continues, calls
81*ec779b8eSAndroid Build Coastguard Worker         //        CameraFlashlight::setTorchMode
82*ec779b8eSAndroid Build Coastguard Worker 
83*ec779b8eSAndroid Build Coastguard Worker         // TODO: Move torch status checks and state updates behind this CameraFlashlight lock
84*ec779b8eSAndroid Build Coastguard Worker         // to avoid other similar race conditions.
85*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Camera device %s is in use, cannot set torch mode.",
86*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, cameraId.c_str());
87*ec779b8eSAndroid Build Coastguard Worker         return -EBUSY;
88*ec779b8eSAndroid Build Coastguard Worker     }
89*ec779b8eSAndroid Build Coastguard Worker 
90*ec779b8eSAndroid Build Coastguard Worker     if (mFlashControl == NULL) {
91*ec779b8eSAndroid Build Coastguard Worker         res = createFlashlightControl(cameraId);
92*ec779b8eSAndroid Build Coastguard Worker         if (res) {
93*ec779b8eSAndroid Build Coastguard Worker             return res;
94*ec779b8eSAndroid Build Coastguard Worker         }
95*ec779b8eSAndroid Build Coastguard Worker         res =  mFlashControl->setTorchMode(cameraId, enabled);
96*ec779b8eSAndroid Build Coastguard Worker         return res;
97*ec779b8eSAndroid Build Coastguard Worker     }
98*ec779b8eSAndroid Build Coastguard Worker 
99*ec779b8eSAndroid Build Coastguard Worker     // if flash control already exists, turning on torch mode may fail if it's
100*ec779b8eSAndroid Build Coastguard Worker     // tied to another camera device for module v2.3 and below.
101*ec779b8eSAndroid Build Coastguard Worker     res = mFlashControl->setTorchMode(cameraId, enabled);
102*ec779b8eSAndroid Build Coastguard Worker     if (res == BAD_INDEX) {
103*ec779b8eSAndroid Build Coastguard Worker         // flash control is tied to another camera device, need to close it and
104*ec779b8eSAndroid Build Coastguard Worker         // try again.
105*ec779b8eSAndroid Build Coastguard Worker         mFlashControl.clear();
106*ec779b8eSAndroid Build Coastguard Worker         res = createFlashlightControl(cameraId);
107*ec779b8eSAndroid Build Coastguard Worker         if (res) {
108*ec779b8eSAndroid Build Coastguard Worker             return res;
109*ec779b8eSAndroid Build Coastguard Worker         }
110*ec779b8eSAndroid Build Coastguard Worker         res = mFlashControl->setTorchMode(cameraId, enabled);
111*ec779b8eSAndroid Build Coastguard Worker     }
112*ec779b8eSAndroid Build Coastguard Worker 
113*ec779b8eSAndroid Build Coastguard Worker     return res;
114*ec779b8eSAndroid Build Coastguard Worker }
115*ec779b8eSAndroid Build Coastguard Worker 
turnOnTorchWithStrengthLevel(const std::string & cameraId,int32_t torchStrength)116*ec779b8eSAndroid Build Coastguard Worker status_t CameraFlashlight::turnOnTorchWithStrengthLevel(const std::string& cameraId,
117*ec779b8eSAndroid Build Coastguard Worker             int32_t torchStrength) {
118*ec779b8eSAndroid Build Coastguard Worker     if (!mFlashlightMapInitialized) {
119*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: findFlashUnits() must be called before this method.",
120*ec779b8eSAndroid Build Coastguard Worker                __FUNCTION__);
121*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
122*ec779b8eSAndroid Build Coastguard Worker     }
123*ec779b8eSAndroid Build Coastguard Worker 
124*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: set torch strength of camera %s to %d", __FUNCTION__,
125*ec779b8eSAndroid Build Coastguard Worker             cameraId.c_str(), torchStrength);
126*ec779b8eSAndroid Build Coastguard Worker     status_t res = OK;
127*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock l(mLock);
128*ec779b8eSAndroid Build Coastguard Worker 
129*ec779b8eSAndroid Build Coastguard Worker     if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
130*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: Camera device %s is in use, cannot be turned ON.",
131*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, cameraId.c_str());
132*ec779b8eSAndroid Build Coastguard Worker         return -EBUSY;
133*ec779b8eSAndroid Build Coastguard Worker     }
134*ec779b8eSAndroid Build Coastguard Worker 
135*ec779b8eSAndroid Build Coastguard Worker     if (mFlashControl == NULL) {
136*ec779b8eSAndroid Build Coastguard Worker         res = createFlashlightControl(cameraId);
137*ec779b8eSAndroid Build Coastguard Worker         if (res) {
138*ec779b8eSAndroid Build Coastguard Worker             return res;
139*ec779b8eSAndroid Build Coastguard Worker         }
140*ec779b8eSAndroid Build Coastguard Worker     }
141*ec779b8eSAndroid Build Coastguard Worker 
142*ec779b8eSAndroid Build Coastguard Worker     res = mFlashControl->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
143*ec779b8eSAndroid Build Coastguard Worker     return res;
144*ec779b8eSAndroid Build Coastguard Worker }
145*ec779b8eSAndroid Build Coastguard Worker 
146*ec779b8eSAndroid Build Coastguard Worker 
getTorchStrengthLevel(const std::string & cameraId,int32_t * torchStrength)147*ec779b8eSAndroid Build Coastguard Worker status_t CameraFlashlight::getTorchStrengthLevel(const std::string& cameraId,
148*ec779b8eSAndroid Build Coastguard Worker             int32_t* torchStrength) {
149*ec779b8eSAndroid Build Coastguard Worker     status_t res = OK;
150*ec779b8eSAndroid Build Coastguard Worker     if (!mFlashlightMapInitialized) {
151*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: findFlashUnits() must be called before this method.",
152*ec779b8eSAndroid Build Coastguard Worker             __FUNCTION__);
153*ec779b8eSAndroid Build Coastguard Worker         return false;
154*ec779b8eSAndroid Build Coastguard Worker     }
155*ec779b8eSAndroid Build Coastguard Worker 
156*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock l(mLock);
157*ec779b8eSAndroid Build Coastguard Worker 
158*ec779b8eSAndroid Build Coastguard Worker     if (mFlashControl == NULL) {
159*ec779b8eSAndroid Build Coastguard Worker         res = createFlashlightControl(cameraId);
160*ec779b8eSAndroid Build Coastguard Worker         if (res) {
161*ec779b8eSAndroid Build Coastguard Worker             return res;
162*ec779b8eSAndroid Build Coastguard Worker         }
163*ec779b8eSAndroid Build Coastguard Worker     }
164*ec779b8eSAndroid Build Coastguard Worker 
165*ec779b8eSAndroid Build Coastguard Worker     res = mFlashControl->getTorchStrengthLevel(cameraId, torchStrength);
166*ec779b8eSAndroid Build Coastguard Worker     return res;
167*ec779b8eSAndroid Build Coastguard Worker }
168*ec779b8eSAndroid Build Coastguard Worker 
findFlashUnits()169*ec779b8eSAndroid Build Coastguard Worker status_t CameraFlashlight::findFlashUnits() {
170*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock l(mLock);
171*ec779b8eSAndroid Build Coastguard Worker     status_t res;
172*ec779b8eSAndroid Build Coastguard Worker 
173*ec779b8eSAndroid Build Coastguard Worker     std::vector<std::string> cameraIds;
174*ec779b8eSAndroid Build Coastguard Worker     std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
175*ec779b8eSAndroid Build Coastguard Worker     int numberOfCameras = static_cast<int>(ids.size());
176*ec779b8eSAndroid Build Coastguard Worker     cameraIds.resize(numberOfCameras);
177*ec779b8eSAndroid Build Coastguard Worker     // No module, must be provider
178*ec779b8eSAndroid Build Coastguard Worker     for (size_t i = 0; i < cameraIds.size(); i++) {
179*ec779b8eSAndroid Build Coastguard Worker         cameraIds[i] = ids[i];
180*ec779b8eSAndroid Build Coastguard Worker     }
181*ec779b8eSAndroid Build Coastguard Worker 
182*ec779b8eSAndroid Build Coastguard Worker     mFlashControl.clear();
183*ec779b8eSAndroid Build Coastguard Worker 
184*ec779b8eSAndroid Build Coastguard Worker     for (auto &id : cameraIds) {
185*ec779b8eSAndroid Build Coastguard Worker         ssize_t index = mHasFlashlightMap.indexOfKey(id);
186*ec779b8eSAndroid Build Coastguard Worker         if (0 <= index) {
187*ec779b8eSAndroid Build Coastguard Worker             continue;
188*ec779b8eSAndroid Build Coastguard Worker         }
189*ec779b8eSAndroid Build Coastguard Worker 
190*ec779b8eSAndroid Build Coastguard Worker         bool hasFlash = false;
191*ec779b8eSAndroid Build Coastguard Worker         res = createFlashlightControl(id);
192*ec779b8eSAndroid Build Coastguard Worker         if (res) {
193*ec779b8eSAndroid Build Coastguard Worker             ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
194*ec779b8eSAndroid Build Coastguard Worker                     id.c_str());
195*ec779b8eSAndroid Build Coastguard Worker         } else {
196*ec779b8eSAndroid Build Coastguard Worker             res = mFlashControl->hasFlashUnit(id, &hasFlash);
197*ec779b8eSAndroid Build Coastguard Worker             if (res == -EUSERS || res == -EBUSY) {
198*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: failed to check if camera %s has a flash unit. Some "
199*ec779b8eSAndroid Build Coastguard Worker                         "camera devices may be opened", __FUNCTION__,
200*ec779b8eSAndroid Build Coastguard Worker                         id.c_str());
201*ec779b8eSAndroid Build Coastguard Worker                 return res;
202*ec779b8eSAndroid Build Coastguard Worker             } else if (res) {
203*ec779b8eSAndroid Build Coastguard Worker                 ALOGE("%s: failed to check if camera %s has a flash unit. %s"
204*ec779b8eSAndroid Build Coastguard Worker                         " (%d)", __FUNCTION__, id.c_str(), strerror(-res),
205*ec779b8eSAndroid Build Coastguard Worker                         res);
206*ec779b8eSAndroid Build Coastguard Worker             }
207*ec779b8eSAndroid Build Coastguard Worker 
208*ec779b8eSAndroid Build Coastguard Worker             mFlashControl.clear();
209*ec779b8eSAndroid Build Coastguard Worker         }
210*ec779b8eSAndroid Build Coastguard Worker         mHasFlashlightMap.add(id, hasFlash);
211*ec779b8eSAndroid Build Coastguard Worker     }
212*ec779b8eSAndroid Build Coastguard Worker 
213*ec779b8eSAndroid Build Coastguard Worker     mFlashlightMapInitialized = true;
214*ec779b8eSAndroid Build Coastguard Worker     return OK;
215*ec779b8eSAndroid Build Coastguard Worker }
216*ec779b8eSAndroid Build Coastguard Worker 
hasFlashUnit(const std::string & cameraId)217*ec779b8eSAndroid Build Coastguard Worker bool CameraFlashlight::hasFlashUnit(const std::string& cameraId) {
218*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock l(mLock);
219*ec779b8eSAndroid Build Coastguard Worker     return hasFlashUnitLocked(cameraId);
220*ec779b8eSAndroid Build Coastguard Worker }
221*ec779b8eSAndroid Build Coastguard Worker 
hasFlashUnitLocked(const std::string & cameraId)222*ec779b8eSAndroid Build Coastguard Worker bool CameraFlashlight::hasFlashUnitLocked(const std::string& cameraId) {
223*ec779b8eSAndroid Build Coastguard Worker     if (!mFlashlightMapInitialized) {
224*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: findFlashUnits() must be called before this method.",
225*ec779b8eSAndroid Build Coastguard Worker                __FUNCTION__);
226*ec779b8eSAndroid Build Coastguard Worker         return false;
227*ec779b8eSAndroid Build Coastguard Worker     }
228*ec779b8eSAndroid Build Coastguard Worker 
229*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
230*ec779b8eSAndroid Build Coastguard Worker     if (index == NAME_NOT_FOUND) {
231*ec779b8eSAndroid Build Coastguard Worker         // Might be external camera
232*ec779b8eSAndroid Build Coastguard Worker         ALOGW("%s: camera %s not present when findFlashUnits() was called",
233*ec779b8eSAndroid Build Coastguard Worker                 __FUNCTION__, cameraId.c_str());
234*ec779b8eSAndroid Build Coastguard Worker         return false;
235*ec779b8eSAndroid Build Coastguard Worker     }
236*ec779b8eSAndroid Build Coastguard Worker 
237*ec779b8eSAndroid Build Coastguard Worker     return mHasFlashlightMap.valueAt(index);
238*ec779b8eSAndroid Build Coastguard Worker }
239*ec779b8eSAndroid Build Coastguard Worker 
isBackwardCompatibleMode(const std::string & cameraId)240*ec779b8eSAndroid Build Coastguard Worker bool CameraFlashlight::isBackwardCompatibleMode(const std::string& cameraId) {
241*ec779b8eSAndroid Build Coastguard Worker     bool backwardCompatibleMode = false;
242*ec779b8eSAndroid Build Coastguard Worker     if (mProviderManager != nullptr &&
243*ec779b8eSAndroid Build Coastguard Worker             !mProviderManager->supportSetTorchMode(cameraId)) {
244*ec779b8eSAndroid Build Coastguard Worker         backwardCompatibleMode = true;
245*ec779b8eSAndroid Build Coastguard Worker     }
246*ec779b8eSAndroid Build Coastguard Worker     return backwardCompatibleMode;
247*ec779b8eSAndroid Build Coastguard Worker }
248*ec779b8eSAndroid Build Coastguard Worker 
prepareDeviceOpen(const std::string & cameraId)249*ec779b8eSAndroid Build Coastguard Worker status_t CameraFlashlight::prepareDeviceOpen(const std::string& cameraId) {
250*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: prepare for device open", __FUNCTION__);
251*ec779b8eSAndroid Build Coastguard Worker 
252*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock l(mLock);
253*ec779b8eSAndroid Build Coastguard Worker     if (!mFlashlightMapInitialized) {
254*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: findFlashUnits() must be called before this method.",
255*ec779b8eSAndroid Build Coastguard Worker                __FUNCTION__);
256*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
257*ec779b8eSAndroid Build Coastguard Worker     }
258*ec779b8eSAndroid Build Coastguard Worker 
259*ec779b8eSAndroid Build Coastguard Worker     if (isBackwardCompatibleMode(cameraId)) {
260*ec779b8eSAndroid Build Coastguard Worker         // framework is going to open a camera device, all flash light control
261*ec779b8eSAndroid Build Coastguard Worker         // should be closed for backward compatible support.
262*ec779b8eSAndroid Build Coastguard Worker         mFlashControl.clear();
263*ec779b8eSAndroid Build Coastguard Worker 
264*ec779b8eSAndroid Build Coastguard Worker         if (mOpenedCameraIds.size() == 0) {
265*ec779b8eSAndroid Build Coastguard Worker             // notify torch unavailable for all cameras with a flash
266*ec779b8eSAndroid Build Coastguard Worker             std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
267*ec779b8eSAndroid Build Coastguard Worker             int numCameras = static_cast<int>(ids.size());
268*ec779b8eSAndroid Build Coastguard Worker             for (int i = 0; i < numCameras; i++) {
269*ec779b8eSAndroid Build Coastguard Worker                 if (hasFlashUnitLocked(ids[i])) {
270*ec779b8eSAndroid Build Coastguard Worker                     mCallbacks->onTorchStatusChanged(
271*ec779b8eSAndroid Build Coastguard Worker                             ids[i], TorchModeStatus::NOT_AVAILABLE);
272*ec779b8eSAndroid Build Coastguard Worker                 }
273*ec779b8eSAndroid Build Coastguard Worker             }
274*ec779b8eSAndroid Build Coastguard Worker         }
275*ec779b8eSAndroid Build Coastguard Worker 
276*ec779b8eSAndroid Build Coastguard Worker         // close flash control that may be opened by calling hasFlashUnitLocked.
277*ec779b8eSAndroid Build Coastguard Worker         mFlashControl.clear();
278*ec779b8eSAndroid Build Coastguard Worker     }
279*ec779b8eSAndroid Build Coastguard Worker 
280*ec779b8eSAndroid Build Coastguard Worker     if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) {
281*ec779b8eSAndroid Build Coastguard Worker         mOpenedCameraIds.add(cameraId);
282*ec779b8eSAndroid Build Coastguard Worker     }
283*ec779b8eSAndroid Build Coastguard Worker 
284*ec779b8eSAndroid Build Coastguard Worker     return OK;
285*ec779b8eSAndroid Build Coastguard Worker }
286*ec779b8eSAndroid Build Coastguard Worker 
deviceClosed(const std::string & cameraId)287*ec779b8eSAndroid Build Coastguard Worker status_t CameraFlashlight::deviceClosed(const std::string& cameraId) {
288*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.c_str());
289*ec779b8eSAndroid Build Coastguard Worker 
290*ec779b8eSAndroid Build Coastguard Worker     Mutex::Autolock l(mLock);
291*ec779b8eSAndroid Build Coastguard Worker     if (!mFlashlightMapInitialized) {
292*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: findFlashUnits() must be called before this method.",
293*ec779b8eSAndroid Build Coastguard Worker                __FUNCTION__);
294*ec779b8eSAndroid Build Coastguard Worker         return NO_INIT;
295*ec779b8eSAndroid Build Coastguard Worker     }
296*ec779b8eSAndroid Build Coastguard Worker 
297*ec779b8eSAndroid Build Coastguard Worker     ssize_t index = mOpenedCameraIds.indexOf(cameraId);
298*ec779b8eSAndroid Build Coastguard Worker     if (index == NAME_NOT_FOUND) {
299*ec779b8eSAndroid Build Coastguard Worker         ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__,
300*ec779b8eSAndroid Build Coastguard Worker                 cameraId.c_str());
301*ec779b8eSAndroid Build Coastguard Worker     } else {
302*ec779b8eSAndroid Build Coastguard Worker         mOpenedCameraIds.removeAt(index);
303*ec779b8eSAndroid Build Coastguard Worker     }
304*ec779b8eSAndroid Build Coastguard Worker 
305*ec779b8eSAndroid Build Coastguard Worker     // Cannot do anything until all cameras are closed.
306*ec779b8eSAndroid Build Coastguard Worker     if (mOpenedCameraIds.size() != 0)
307*ec779b8eSAndroid Build Coastguard Worker         return OK;
308*ec779b8eSAndroid Build Coastguard Worker 
309*ec779b8eSAndroid Build Coastguard Worker     if (isBackwardCompatibleMode(cameraId)) {
310*ec779b8eSAndroid Build Coastguard Worker         // notify torch available for all cameras with a flash
311*ec779b8eSAndroid Build Coastguard Worker         std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
312*ec779b8eSAndroid Build Coastguard Worker         int numCameras = static_cast<int>(ids.size());
313*ec779b8eSAndroid Build Coastguard Worker         for (int i = 0; i < numCameras; i++) {
314*ec779b8eSAndroid Build Coastguard Worker             if (hasFlashUnitLocked(ids[i])) {
315*ec779b8eSAndroid Build Coastguard Worker                 mCallbacks->onTorchStatusChanged(
316*ec779b8eSAndroid Build Coastguard Worker                         ids[i], TorchModeStatus::AVAILABLE_OFF);
317*ec779b8eSAndroid Build Coastguard Worker             }
318*ec779b8eSAndroid Build Coastguard Worker         }
319*ec779b8eSAndroid Build Coastguard Worker     }
320*ec779b8eSAndroid Build Coastguard Worker 
321*ec779b8eSAndroid Build Coastguard Worker     return OK;
322*ec779b8eSAndroid Build Coastguard Worker }
323*ec779b8eSAndroid Build Coastguard Worker // CameraFlashlight implementation ends
324*ec779b8eSAndroid Build Coastguard Worker 
325*ec779b8eSAndroid Build Coastguard Worker 
~FlashControlBase()326*ec779b8eSAndroid Build Coastguard Worker FlashControlBase::~FlashControlBase() {
327*ec779b8eSAndroid Build Coastguard Worker }
328*ec779b8eSAndroid Build Coastguard Worker 
329*ec779b8eSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////
330*ec779b8eSAndroid Build Coastguard Worker // ModuleFlashControl implementation begins
331*ec779b8eSAndroid Build Coastguard Worker // Flash control for camera module v2.4 and above.
332*ec779b8eSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////
ProviderFlashControl(sp<CameraProviderManager> providerManager)333*ec779b8eSAndroid Build Coastguard Worker ProviderFlashControl::ProviderFlashControl(sp<CameraProviderManager> providerManager) :
334*ec779b8eSAndroid Build Coastguard Worker         mProviderManager(providerManager) {
335*ec779b8eSAndroid Build Coastguard Worker }
336*ec779b8eSAndroid Build Coastguard Worker 
~ProviderFlashControl()337*ec779b8eSAndroid Build Coastguard Worker ProviderFlashControl::~ProviderFlashControl() {
338*ec779b8eSAndroid Build Coastguard Worker }
339*ec779b8eSAndroid Build Coastguard Worker 
hasFlashUnit(const std::string & cameraId,bool * hasFlash)340*ec779b8eSAndroid Build Coastguard Worker status_t ProviderFlashControl::hasFlashUnit(const std::string& cameraId, bool *hasFlash) {
341*ec779b8eSAndroid Build Coastguard Worker     if (!hasFlash) {
342*ec779b8eSAndroid Build Coastguard Worker         return BAD_VALUE;
343*ec779b8eSAndroid Build Coastguard Worker     }
344*ec779b8eSAndroid Build Coastguard Worker     *hasFlash = mProviderManager->hasFlashUnit(cameraId);
345*ec779b8eSAndroid Build Coastguard Worker     return OK;
346*ec779b8eSAndroid Build Coastguard Worker }
347*ec779b8eSAndroid Build Coastguard Worker 
setTorchMode(const std::string & cameraId,bool enabled)348*ec779b8eSAndroid Build Coastguard Worker status_t ProviderFlashControl::setTorchMode(const std::string& cameraId, bool enabled) {
349*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__,
350*ec779b8eSAndroid Build Coastguard Worker             cameraId.c_str(), enabled);
351*ec779b8eSAndroid Build Coastguard Worker 
352*ec779b8eSAndroid Build Coastguard Worker     return mProviderManager->setTorchMode(cameraId, enabled);
353*ec779b8eSAndroid Build Coastguard Worker }
354*ec779b8eSAndroid Build Coastguard Worker 
turnOnTorchWithStrengthLevel(const std::string & cameraId,int32_t torchStrength)355*ec779b8eSAndroid Build Coastguard Worker status_t ProviderFlashControl::turnOnTorchWithStrengthLevel(const std::string& cameraId,
356*ec779b8eSAndroid Build Coastguard Worker             int32_t torchStrength) {
357*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: change torch strength level of camera %s to %d", __FUNCTION__,
358*ec779b8eSAndroid Build Coastguard Worker             cameraId.c_str(), torchStrength);
359*ec779b8eSAndroid Build Coastguard Worker 
360*ec779b8eSAndroid Build Coastguard Worker     return mProviderManager->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
361*ec779b8eSAndroid Build Coastguard Worker }
362*ec779b8eSAndroid Build Coastguard Worker 
getTorchStrengthLevel(const std::string & cameraId,int32_t * torchStrength)363*ec779b8eSAndroid Build Coastguard Worker status_t ProviderFlashControl::getTorchStrengthLevel(const std::string& cameraId,
364*ec779b8eSAndroid Build Coastguard Worker             int32_t* torchStrength) {
365*ec779b8eSAndroid Build Coastguard Worker     ALOGV("%s: get torch strength level of camera %s", __FUNCTION__,
366*ec779b8eSAndroid Build Coastguard Worker             cameraId.c_str());
367*ec779b8eSAndroid Build Coastguard Worker 
368*ec779b8eSAndroid Build Coastguard Worker     return mProviderManager->getTorchStrengthLevel(cameraId, torchStrength);
369*ec779b8eSAndroid Build Coastguard Worker }
370*ec779b8eSAndroid Build Coastguard Worker // ProviderFlashControl implementation ends
371*ec779b8eSAndroid Build Coastguard Worker 
372*ec779b8eSAndroid Build Coastguard Worker }
373