blob: d9d8a3d2001dd1e72c5f46cc2d89a0f2aa8cecf8 [file] [log] [blame]
Chien-Yu Chen3068d732015-02-09 13:29:57 -08001/*
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#define LOG_TAG "CameraFlashlight"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
Chien-Yu Chen88da5262015-02-17 13:56:46 -080019// #define LOG_NDEBUG 0
Chien-Yu Chen3068d732015-02-09 13:29:57 -080020
21#include <utils/Log.h>
22#include <utils/Trace.h>
23#include <cutils/properties.h>
24
25#include "camera/CameraMetadata.h"
26#include "CameraFlashlight.h"
27#include "gui/IGraphicBufferConsumer.h"
28#include "gui/BufferQueue.h"
29#include "camera/camera2/CaptureRequest.h"
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -080030#include "device3/Camera3Device.h"
Chien-Yu Chen3068d732015-02-09 13:29:57 -080031
32
33namespace android {
34
Chien-Yu Chen88da5262015-02-17 13:56:46 -080035/////////////////////////////////////////////////////////////////////
36// CameraFlashlight implementation begins
37// used by camera service to control flashflight.
38/////////////////////////////////////////////////////////////////////
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080039
40CameraFlashlight::CameraFlashlight(sp<CameraProviderManager> providerManager,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080041 CameraProviderManager::StatusListener* callbacks) :
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080042 mProviderManager(providerManager),
43 mCallbacks(callbacks),
Chien-Yu Chen88da5262015-02-17 13:56:46 -080044 mFlashlightMapInitialized(false) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -080045}
46
47CameraFlashlight::~CameraFlashlight() {
48}
49
Austin Borger1c1bee02023-06-01 16:51:35 -070050status_t CameraFlashlight::createFlashlightControl(const std::string& cameraId) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -080051 ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -070052 cameraId.c_str());
Chien-Yu Chen3068d732015-02-09 13:29:57 -080053 if (mFlashControl != NULL) {
54 return INVALID_OPERATION;
55 }
56
Austin Borger1c1bee02023-06-01 16:51:35 -070057 if (mProviderManager->supportSetTorchMode(cameraId)) {
Emilian Peevf53f66e2017-04-11 14:29:43 +010058 mFlashControl = new ProviderFlashControl(mProviderManager);
Chien-Yu Chen3068d732015-02-09 13:29:57 -080059 } else {
Eino-Ville Talvalaa976df82019-06-13 18:01:58 -070060 ALOGE("Flashlight control not supported by this device!");
61 return NO_INIT;
Chien-Yu Chen3068d732015-02-09 13:29:57 -080062 }
63
64 return OK;
65}
66
Austin Borger1c1bee02023-06-01 16:51:35 -070067status_t CameraFlashlight::setTorchMode(const std::string& cameraId, bool enabled) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -080068 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -070069 ALOGE("%s: findFlashUnits() must be called before this method.",
70 __FUNCTION__);
Chien-Yu Chen3068d732015-02-09 13:29:57 -080071 return NO_INIT;
72 }
73
74 ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -070075 cameraId.c_str(), enabled);
Chien-Yu Chen3068d732015-02-09 13:29:57 -080076
77 status_t res = OK;
78 Mutex::Autolock l(mLock);
79
Ruben Brunkcc776712015-02-17 20:18:47 -080080 if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
81 // This case is needed to avoid state corruption during the following call sequence:
82 // CameraService::setTorchMode for camera ID 0 begins, does torch status checks
83 // CameraService::connect for camera ID 0 begins, calls prepareDeviceOpen, ends
84 // CameraService::setTorchMode for camera ID 0 continues, calls
85 // CameraFlashlight::setTorchMode
86
87 // TODO: Move torch status checks and state updates behind this CameraFlashlight lock
88 // to avoid other similar race conditions.
89 ALOGE("%s: Camera device %s is in use, cannot set torch mode.",
Austin Borger1c1bee02023-06-01 16:51:35 -070090 __FUNCTION__, cameraId.c_str());
Ruben Brunkcc776712015-02-17 20:18:47 -080091 return -EBUSY;
92 }
93
Chien-Yu Chen3068d732015-02-09 13:29:57 -080094 if (mFlashControl == NULL) {
95 res = createFlashlightControl(cameraId);
96 if (res) {
97 return res;
98 }
99 res = mFlashControl->setTorchMode(cameraId, enabled);
100 return res;
101 }
102
103 // if flash control already exists, turning on torch mode may fail if it's
104 // tied to another camera device for module v2.3 and below.
105 res = mFlashControl->setTorchMode(cameraId, enabled);
106 if (res == BAD_INDEX) {
107 // flash control is tied to another camera device, need to close it and
108 // try again.
109 mFlashControl.clear();
110 res = createFlashlightControl(cameraId);
111 if (res) {
112 return res;
113 }
114 res = mFlashControl->setTorchMode(cameraId, enabled);
115 }
116
117 return res;
118}
119
Austin Borger1c1bee02023-06-01 16:51:35 -0700120status_t CameraFlashlight::turnOnTorchWithStrengthLevel(const std::string& cameraId,
Rucha Katakwar38284522021-11-10 11:25:21 -0800121 int32_t torchStrength) {
122 if (!mFlashlightMapInitialized) {
123 ALOGE("%s: findFlashUnits() must be called before this method.",
124 __FUNCTION__);
125 return NO_INIT;
126 }
127
128 ALOGV("%s: set torch strength of camera %s to %d", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -0700129 cameraId.c_str(), torchStrength);
Rucha Katakwar38284522021-11-10 11:25:21 -0800130 status_t res = OK;
131 Mutex::Autolock l(mLock);
132
133 if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
134 ALOGE("%s: Camera device %s is in use, cannot be turned ON.",
Austin Borger1c1bee02023-06-01 16:51:35 -0700135 __FUNCTION__, cameraId.c_str());
Rucha Katakwar38284522021-11-10 11:25:21 -0800136 return -EBUSY;
137 }
138
139 if (mFlashControl == NULL) {
140 res = createFlashlightControl(cameraId);
141 if (res) {
142 return res;
143 }
144 }
145
146 res = mFlashControl->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
147 return res;
148}
149
150
Austin Borger1c1bee02023-06-01 16:51:35 -0700151status_t CameraFlashlight::getTorchStrengthLevel(const std::string& cameraId,
Rucha Katakwar38284522021-11-10 11:25:21 -0800152 int32_t* torchStrength) {
153 status_t res = OK;
154 if (!mFlashlightMapInitialized) {
155 ALOGE("%s: findFlashUnits() must be called before this method.",
156 __FUNCTION__);
157 return false;
158 }
159
160 Mutex::Autolock l(mLock);
161
162 if (mFlashControl == NULL) {
163 res = createFlashlightControl(cameraId);
164 if (res) {
165 return res;
166 }
167 }
168
169 res = mFlashControl->getTorchStrengthLevel(cameraId, torchStrength);
170 return res;
171}
172
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800173status_t CameraFlashlight::findFlashUnits() {
174 Mutex::Autolock l(mLock);
175 status_t res;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800176
Austin Borger1c1bee02023-06-01 16:51:35 -0700177 std::vector<std::string> cameraIds;
Yin-Chia Yeh98c72a82018-08-28 11:20:16 -0700178 std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
Yin-Chia Yeh6b1f6112018-02-28 13:05:59 -0800179 int numberOfCameras = static_cast<int>(ids.size());
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700180 cameraIds.resize(numberOfCameras);
Emilian Peevf53f66e2017-04-11 14:29:43 +0100181 // No module, must be provider
Emilian Peevf53f66e2017-04-11 14:29:43 +0100182 for (size_t i = 0; i < cameraIds.size(); i++) {
Austin Borger1c1bee02023-06-01 16:51:35 -0700183 cameraIds[i] = ids[i];
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800184 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800185
Emilian Peevaee727d2017-05-04 16:35:48 +0100186 mFlashControl.clear();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800187
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800188 for (auto &id : cameraIds) {
Emilian Peevaee727d2017-05-04 16:35:48 +0100189 ssize_t index = mHasFlashlightMap.indexOfKey(id);
190 if (0 <= index) {
191 continue;
192 }
193
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800194 bool hasFlash = false;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800195 res = createFlashlightControl(id);
196 if (res) {
197 ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -0700198 id.c_str());
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800199 } else {
200 res = mFlashControl->hasFlashUnit(id, &hasFlash);
201 if (res == -EUSERS || res == -EBUSY) {
202 ALOGE("%s: failed to check if camera %s has a flash unit. Some "
203 "camera devices may be opened", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -0700204 id.c_str());
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800205 return res;
206 } else if (res) {
207 ALOGE("%s: failed to check if camera %s has a flash unit. %s"
Austin Borger1c1bee02023-06-01 16:51:35 -0700208 " (%d)", __FUNCTION__, id.c_str(), strerror(-res),
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800209 res);
210 }
211
212 mFlashControl.clear();
213 }
214 mHasFlashlightMap.add(id, hasFlash);
215 }
216
217 mFlashlightMapInitialized = true;
218 return OK;
219}
220
Austin Borger1c1bee02023-06-01 16:51:35 -0700221bool CameraFlashlight::hasFlashUnit(const std::string& cameraId) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800222 Mutex::Autolock l(mLock);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800223 return hasFlashUnitLocked(cameraId);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800224}
225
Austin Borger1c1bee02023-06-01 16:51:35 -0700226bool CameraFlashlight::hasFlashUnitLocked(const std::string& cameraId) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800227 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -0700228 ALOGE("%s: findFlashUnits() must be called before this method.",
229 __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800230 return false;
231 }
232
233 ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
234 if (index == NAME_NOT_FOUND) {
Yin-Chia Yeh6b1f6112018-02-28 13:05:59 -0800235 // Might be external camera
236 ALOGW("%s: camera %s not present when findFlashUnits() was called",
Austin Borger1c1bee02023-06-01 16:51:35 -0700237 __FUNCTION__, cameraId.c_str());
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800238 return false;
239 }
240
241 return mHasFlashlightMap.valueAt(index);
242}
243
Austin Borger1c1bee02023-06-01 16:51:35 -0700244bool CameraFlashlight::isBackwardCompatibleMode(const std::string& cameraId) {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700245 bool backwardCompatibleMode = false;
Emilian Peevf53f66e2017-04-11 14:29:43 +0100246 if (mProviderManager != nullptr &&
Austin Borger1c1bee02023-06-01 16:51:35 -0700247 !mProviderManager->supportSetTorchMode(cameraId)) {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700248 backwardCompatibleMode = true;
249 }
250 return backwardCompatibleMode;
251}
252
Austin Borger1c1bee02023-06-01 16:51:35 -0700253status_t CameraFlashlight::prepareDeviceOpen(const std::string& cameraId) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800254 ALOGV("%s: prepare for device open", __FUNCTION__);
255
256 Mutex::Autolock l(mLock);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800257 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -0700258 ALOGE("%s: findFlashUnits() must be called before this method.",
259 __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800260 return NO_INIT;
261 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800262
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700263 if (isBackwardCompatibleMode(cameraId)) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800264 // framework is going to open a camera device, all flash light control
265 // should be closed for backward compatible support.
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800266 mFlashControl.clear();
267
268 if (mOpenedCameraIds.size() == 0) {
269 // notify torch unavailable for all cameras with a flash
Yin-Chia Yeh98c72a82018-08-28 11:20:16 -0700270 std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
Yin-Chia Yeh6b1f6112018-02-28 13:05:59 -0800271 int numCameras = static_cast<int>(ids.size());
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800272 for (int i = 0; i < numCameras; i++) {
Austin Borger1c1bee02023-06-01 16:51:35 -0700273 if (hasFlashUnitLocked(ids[i])) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800274 mCallbacks->onTorchStatusChanged(
Austin Borger1c1bee02023-06-01 16:51:35 -0700275 ids[i], TorchModeStatus::NOT_AVAILABLE);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800276 }
277 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800278 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800279
280 // close flash control that may be opened by calling hasFlashUnitLocked.
281 mFlashControl.clear();
282 }
283
284 if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) {
285 mOpenedCameraIds.add(cameraId);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800286 }
287
288 return OK;
289}
290
Austin Borger1c1bee02023-06-01 16:51:35 -0700291status_t CameraFlashlight::deviceClosed(const std::string& cameraId) {
292 ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.c_str());
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800293
294 Mutex::Autolock l(mLock);
295 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -0700296 ALOGE("%s: findFlashUnits() must be called before this method.",
297 __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800298 return NO_INIT;
299 }
300
301 ssize_t index = mOpenedCameraIds.indexOf(cameraId);
302 if (index == NAME_NOT_FOUND) {
303 ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -0700304 cameraId.c_str());
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800305 } else {
306 mOpenedCameraIds.removeAt(index);
307 }
308
309 // Cannot do anything until all cameras are closed.
310 if (mOpenedCameraIds.size() != 0)
311 return OK;
312
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700313 if (isBackwardCompatibleMode(cameraId)) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800314 // notify torch available for all cameras with a flash
Yin-Chia Yeh98c72a82018-08-28 11:20:16 -0700315 std::vector<std::string> ids = mProviderManager->getCameraDeviceIds();
Yin-Chia Yeh6b1f6112018-02-28 13:05:59 -0800316 int numCameras = static_cast<int>(ids.size());
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800317 for (int i = 0; i < numCameras; i++) {
Austin Borger1c1bee02023-06-01 16:51:35 -0700318 if (hasFlashUnitLocked(ids[i])) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800319 mCallbacks->onTorchStatusChanged(
Austin Borger1c1bee02023-06-01 16:51:35 -0700320 ids[i], TorchModeStatus::AVAILABLE_OFF);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800321 }
322 }
323 }
324
325 return OK;
326}
327// CameraFlashlight implementation ends
328
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800329
330FlashControlBase::~FlashControlBase() {
331}
332
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800333/////////////////////////////////////////////////////////////////////
334// ModuleFlashControl implementation begins
335// Flash control for camera module v2.4 and above.
336/////////////////////////////////////////////////////////////////////
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800337ProviderFlashControl::ProviderFlashControl(sp<CameraProviderManager> providerManager) :
338 mProviderManager(providerManager) {
339}
340
341ProviderFlashControl::~ProviderFlashControl() {
342}
343
Austin Borger1c1bee02023-06-01 16:51:35 -0700344status_t ProviderFlashControl::hasFlashUnit(const std::string& cameraId, bool *hasFlash) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800345 if (!hasFlash) {
346 return BAD_VALUE;
347 }
Austin Borger1c1bee02023-06-01 16:51:35 -0700348 *hasFlash = mProviderManager->hasFlashUnit(cameraId);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800349 return OK;
350}
351
Austin Borger1c1bee02023-06-01 16:51:35 -0700352status_t ProviderFlashControl::setTorchMode(const std::string& cameraId, bool enabled) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800353 ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -0700354 cameraId.c_str(), enabled);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800355
Austin Borger1c1bee02023-06-01 16:51:35 -0700356 return mProviderManager->setTorchMode(cameraId, enabled);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800357}
Rucha Katakwar38284522021-11-10 11:25:21 -0800358
Austin Borger1c1bee02023-06-01 16:51:35 -0700359status_t ProviderFlashControl::turnOnTorchWithStrengthLevel(const std::string& cameraId,
Rucha Katakwar38284522021-11-10 11:25:21 -0800360 int32_t torchStrength) {
361 ALOGV("%s: change torch strength level of camera %s to %d", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -0700362 cameraId.c_str(), torchStrength);
Rucha Katakwar38284522021-11-10 11:25:21 -0800363
Austin Borger1c1bee02023-06-01 16:51:35 -0700364 return mProviderManager->turnOnTorchWithStrengthLevel(cameraId, torchStrength);
Rucha Katakwar38284522021-11-10 11:25:21 -0800365}
366
Austin Borger1c1bee02023-06-01 16:51:35 -0700367status_t ProviderFlashControl::getTorchStrengthLevel(const std::string& cameraId,
Rucha Katakwar38284522021-11-10 11:25:21 -0800368 int32_t* torchStrength) {
369 ALOGV("%s: get torch strength level of camera %s", __FUNCTION__,
Austin Borger1c1bee02023-06-01 16:51:35 -0700370 cameraId.c_str());
Rucha Katakwar38284522021-11-10 11:25:21 -0800371
Austin Borger1c1bee02023-06-01 16:51:35 -0700372 return mProviderManager->getTorchStrengthLevel(cameraId, torchStrength);
Rucha Katakwar38284522021-11-10 11:25:21 -0800373}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800374// ProviderFlashControl implementation ends
375
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800376}