blob: e06a81fb239cf6fc6f45a5650c789dc7b785319b [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,
41 camera_module_callbacks_t* 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
Chien-Yu Chen88da5262015-02-17 13:56:46 -080050status_t CameraFlashlight::createFlashlightControl(const String8& cameraId) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -080051 ALOGV("%s: creating a flash light control for camera %s", __FUNCTION__,
52 cameraId.string());
53 if (mFlashControl != NULL) {
54 return INVALID_OPERATION;
55 }
56
Emilian Peevf53f66e2017-04-11 14:29:43 +010057 if (mProviderManager->supportSetTorchMode(cameraId.string())) {
58 mFlashControl = new ProviderFlashControl(mProviderManager);
Chien-Yu Chen3068d732015-02-09 13:29:57 -080059 } else {
Emilian Peevf53f66e2017-04-11 14:29:43 +010060 // Only HAL1 devices do not support setTorchMode
61 mFlashControl =
62 new CameraHardwareInterfaceFlashControl(mProviderManager, *mCallbacks);
Chien-Yu Chen3068d732015-02-09 13:29:57 -080063 }
64
65 return OK;
66}
67
Chien-Yu Chen88da5262015-02-17 13:56:46 -080068status_t CameraFlashlight::setTorchMode(const String8& cameraId, bool enabled) {
69 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -070070 ALOGE("%s: findFlashUnits() must be called before this method.",
71 __FUNCTION__);
Chien-Yu Chen3068d732015-02-09 13:29:57 -080072 return NO_INIT;
73 }
74
75 ALOGV("%s: set torch mode of camera %s to %d", __FUNCTION__,
76 cameraId.string(), enabled);
77
78 status_t res = OK;
79 Mutex::Autolock l(mLock);
80
Ruben Brunkcc776712015-02-17 20:18:47 -080081 if (mOpenedCameraIds.indexOf(cameraId) != NAME_NOT_FOUND) {
82 // This case is needed to avoid state corruption during the following call sequence:
83 // CameraService::setTorchMode for camera ID 0 begins, does torch status checks
84 // CameraService::connect for camera ID 0 begins, calls prepareDeviceOpen, ends
85 // CameraService::setTorchMode for camera ID 0 continues, calls
86 // CameraFlashlight::setTorchMode
87
88 // TODO: Move torch status checks and state updates behind this CameraFlashlight lock
89 // to avoid other similar race conditions.
90 ALOGE("%s: Camera device %s is in use, cannot set torch mode.",
91 __FUNCTION__, cameraId.string());
92 return -EBUSY;
93 }
94
Chien-Yu Chen3068d732015-02-09 13:29:57 -080095 if (mFlashControl == NULL) {
96 res = createFlashlightControl(cameraId);
97 if (res) {
98 return res;
99 }
100 res = mFlashControl->setTorchMode(cameraId, enabled);
101 return res;
102 }
103
104 // if flash control already exists, turning on torch mode may fail if it's
105 // tied to another camera device for module v2.3 and below.
106 res = mFlashControl->setTorchMode(cameraId, enabled);
107 if (res == BAD_INDEX) {
108 // flash control is tied to another camera device, need to close it and
109 // try again.
110 mFlashControl.clear();
111 res = createFlashlightControl(cameraId);
112 if (res) {
113 return res;
114 }
115 res = mFlashControl->setTorchMode(cameraId, enabled);
116 }
117
118 return res;
119}
120
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700121int CameraFlashlight::getNumberOfCameras() {
Emilian Peevf53f66e2017-04-11 14:29:43 +0100122 return mProviderManager->getAPI1CompatibleCameraCount();
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700123}
124
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800125status_t CameraFlashlight::findFlashUnits() {
126 Mutex::Autolock l(mLock);
127 status_t res;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800128
129 std::vector<String8> cameraIds;
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700130 int numberOfCameras = getNumberOfCameras();
131 cameraIds.resize(numberOfCameras);
Emilian Peevf53f66e2017-04-11 14:29:43 +0100132 // No module, must be provider
133 std::vector<std::string> ids = mProviderManager->getAPI1CompatibleCameraDeviceIds();
134 for (size_t i = 0; i < cameraIds.size(); i++) {
135 cameraIds[i] = String8(ids[i].c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800136 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800137
Emilian Peevaee727d2017-05-04 16:35:48 +0100138 mFlashControl.clear();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800139
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800140 for (auto &id : cameraIds) {
Emilian Peevaee727d2017-05-04 16:35:48 +0100141 ssize_t index = mHasFlashlightMap.indexOfKey(id);
142 if (0 <= index) {
143 continue;
144 }
145
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800146 bool hasFlash = false;
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800147 res = createFlashlightControl(id);
148 if (res) {
149 ALOGE("%s: failed to create flash control for %s", __FUNCTION__,
150 id.string());
151 } else {
152 res = mFlashControl->hasFlashUnit(id, &hasFlash);
153 if (res == -EUSERS || res == -EBUSY) {
154 ALOGE("%s: failed to check if camera %s has a flash unit. Some "
155 "camera devices may be opened", __FUNCTION__,
156 id.string());
157 return res;
158 } else if (res) {
159 ALOGE("%s: failed to check if camera %s has a flash unit. %s"
160 " (%d)", __FUNCTION__, id.string(), strerror(-res),
161 res);
162 }
163
164 mFlashControl.clear();
165 }
166 mHasFlashlightMap.add(id, hasFlash);
167 }
168
169 mFlashlightMapInitialized = true;
170 return OK;
171}
172
173bool CameraFlashlight::hasFlashUnit(const String8& cameraId) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800174 Mutex::Autolock l(mLock);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800175 return hasFlashUnitLocked(cameraId);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800176}
177
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800178bool CameraFlashlight::hasFlashUnitLocked(const String8& cameraId) {
179 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -0700180 ALOGE("%s: findFlashUnits() must be called before this method.",
181 __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800182 return false;
183 }
184
185 ssize_t index = mHasFlashlightMap.indexOfKey(cameraId);
186 if (index == NAME_NOT_FOUND) {
187 ALOGE("%s: camera %s not present when findFlashUnits() was called",
188 __FUNCTION__, cameraId.string());
189 return false;
190 }
191
192 return mHasFlashlightMap.valueAt(index);
193}
194
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700195bool CameraFlashlight::isBackwardCompatibleMode(const String8& cameraId) {
196 bool backwardCompatibleMode = false;
Emilian Peevf53f66e2017-04-11 14:29:43 +0100197 if (mProviderManager != nullptr &&
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700198 !mProviderManager->supportSetTorchMode(cameraId.string())) {
199 backwardCompatibleMode = true;
200 }
201 return backwardCompatibleMode;
202}
203
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800204status_t CameraFlashlight::prepareDeviceOpen(const String8& cameraId) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800205 ALOGV("%s: prepare for device open", __FUNCTION__);
206
207 Mutex::Autolock l(mLock);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800208 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -0700209 ALOGE("%s: findFlashUnits() must be called before this method.",
210 __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800211 return NO_INIT;
212 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800213
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700214 if (isBackwardCompatibleMode(cameraId)) {
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800215 // framework is going to open a camera device, all flash light control
216 // should be closed for backward compatible support.
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800217 mFlashControl.clear();
218
219 if (mOpenedCameraIds.size() == 0) {
220 // notify torch unavailable for all cameras with a flash
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700221 int numCameras = getNumberOfCameras();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800222 for (int i = 0; i < numCameras; i++) {
223 if (hasFlashUnitLocked(String8::format("%d", i))) {
224 mCallbacks->torch_mode_status_change(mCallbacks,
225 String8::format("%d", i).string(),
226 TORCH_MODE_STATUS_NOT_AVAILABLE);
227 }
228 }
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800229 }
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800230
231 // close flash control that may be opened by calling hasFlashUnitLocked.
232 mFlashControl.clear();
233 }
234
235 if (mOpenedCameraIds.indexOf(cameraId) == NAME_NOT_FOUND) {
236 mOpenedCameraIds.add(cameraId);
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800237 }
238
239 return OK;
240}
241
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800242status_t CameraFlashlight::deviceClosed(const String8& cameraId) {
243 ALOGV("%s: device %s is closed", __FUNCTION__, cameraId.string());
244
245 Mutex::Autolock l(mLock);
246 if (!mFlashlightMapInitialized) {
Ranjith Kagathi Ananda32ab9fd2015-10-08 16:41:09 -0700247 ALOGE("%s: findFlashUnits() must be called before this method.",
248 __FUNCTION__);
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800249 return NO_INIT;
250 }
251
252 ssize_t index = mOpenedCameraIds.indexOf(cameraId);
253 if (index == NAME_NOT_FOUND) {
254 ALOGE("%s: couldn't find camera %s in the opened list", __FUNCTION__,
255 cameraId.string());
256 } else {
257 mOpenedCameraIds.removeAt(index);
258 }
259
260 // Cannot do anything until all cameras are closed.
261 if (mOpenedCameraIds.size() != 0)
262 return OK;
263
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700264 if (isBackwardCompatibleMode(cameraId)) {
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800265 // notify torch available for all cameras with a flash
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700266 int numCameras = getNumberOfCameras();
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800267 for (int i = 0; i < numCameras; i++) {
268 if (hasFlashUnitLocked(String8::format("%d", i))) {
269 mCallbacks->torch_mode_status_change(mCallbacks,
270 String8::format("%d", i).string(),
271 TORCH_MODE_STATUS_AVAILABLE_OFF);
272 }
273 }
274 }
275
276 return OK;
277}
278// CameraFlashlight implementation ends
279
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800280
281FlashControlBase::~FlashControlBase() {
282}
283
Chien-Yu Chen88da5262015-02-17 13:56:46 -0800284/////////////////////////////////////////////////////////////////////
285// ModuleFlashControl implementation begins
286// Flash control for camera module v2.4 and above.
287/////////////////////////////////////////////////////////////////////
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800288ProviderFlashControl::ProviderFlashControl(sp<CameraProviderManager> providerManager) :
289 mProviderManager(providerManager) {
290}
291
292ProviderFlashControl::~ProviderFlashControl() {
293}
294
295status_t ProviderFlashControl::hasFlashUnit(const String8& cameraId, bool *hasFlash) {
296 if (!hasFlash) {
297 return BAD_VALUE;
298 }
299 *hasFlash = mProviderManager->hasFlashUnit(cameraId.string());
300 return OK;
301}
302
303status_t ProviderFlashControl::setTorchMode(const String8& cameraId, bool enabled) {
304 ALOGV("%s: set camera %s torch mode to %d", __FUNCTION__,
305 cameraId.string(), enabled);
306
307 return mProviderManager->setTorchMode(cameraId.string(), enabled);
308}
309// ProviderFlashControl implementation ends
310
311/////////////////////////////////////////////////////////////////////
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800312// CameraHardwareInterfaceFlashControl implementation begins
313// Flash control for camera module <= v2.3 and camera HAL v1
314/////////////////////////////////////////////////////////////////////
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800315
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700316CameraHardwareInterfaceFlashControl::CameraHardwareInterfaceFlashControl(
317 sp<CameraProviderManager> manager,
318 const camera_module_callbacks_t& callbacks) :
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700319 mProviderManager(manager),
320 mCallbacks(&callbacks),
321 mTorchEnabled(false) {
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800322}
323
324CameraHardwareInterfaceFlashControl::~CameraHardwareInterfaceFlashControl() {
325 disconnectCameraDevice();
326
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700327 mSurface.clear();
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800328 mSurfaceTexture.clear();
329 mProducer.clear();
330 mConsumer.clear();
331
332 if (mTorchEnabled) {
333 if (mCallbacks) {
334 ALOGV("%s: notify the framework that torch was turned off",
335 __FUNCTION__);
336 mCallbacks->torch_mode_status_change(mCallbacks,
337 mCameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
338 }
339 }
340}
341
342status_t CameraHardwareInterfaceFlashControl::setTorchMode(
343 const String8& cameraId, bool enabled) {
344 Mutex::Autolock l(mLock);
345
346 // pre-check
347 status_t res;
348 if (enabled) {
349 bool hasFlash = false;
Chien-Yu Chen6dcc7062016-04-18 11:14:48 -0700350 // Check if it has a flash unit and leave camera device open.
351 res = hasFlashUnitLocked(cameraId, &hasFlash, /*keepDeviceOpen*/true);
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800352 // invalid camera?
353 if (res) {
354 // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
355 // another camera device.
356 return res == BAD_INDEX ? BAD_INDEX : -EINVAL;
357 }
358 // no flash unit?
359 if (!hasFlash) {
Chien-Yu Chen6dcc7062016-04-18 11:14:48 -0700360 // Disconnect camera device if it has no flash.
361 disconnectCameraDevice();
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800362 return -ENOSYS;
363 }
364 } else if (mDevice == NULL || cameraId != mCameraId) {
365 // disabling the torch mode of an un-opened or different device.
366 return OK;
367 } else {
368 // disabling the torch mode of currently opened device
369 disconnectCameraDevice();
370 mTorchEnabled = false;
371 mCallbacks->torch_mode_status_change(mCallbacks,
372 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_OFF);
373 return OK;
374 }
375
376 res = startPreviewAndTorch();
377 if (res) {
378 return res;
379 }
380
381 mTorchEnabled = true;
382 mCallbacks->torch_mode_status_change(mCallbacks,
383 cameraId.string(), TORCH_MODE_STATUS_AVAILABLE_ON);
384 return OK;
385}
386
387status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
388 const String8& cameraId, bool *hasFlash) {
389 Mutex::Autolock l(mLock);
Chien-Yu Chen6dcc7062016-04-18 11:14:48 -0700390 // Close device after checking if it has a flash unit.
391 return hasFlashUnitLocked(cameraId, hasFlash, /*keepDeviceOpen*/false);
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800392}
393
394status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
Chien-Yu Chen6dcc7062016-04-18 11:14:48 -0700395 const String8& cameraId, bool *hasFlash, bool keepDeviceOpen) {
396 bool closeCameraDevice = false;
397
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800398 if (!hasFlash) {
399 return BAD_VALUE;
400 }
401
402 status_t res;
403 if (mDevice == NULL) {
Chien-Yu Chen6dcc7062016-04-18 11:14:48 -0700404 // Connect to camera device to query if it has a flash unit.
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800405 res = connectCameraDevice(cameraId);
406 if (res) {
407 return res;
408 }
Chien-Yu Chen6dcc7062016-04-18 11:14:48 -0700409 // Close camera device only when it is just opened and the caller doesn't want to keep
410 // the camera device open.
411 closeCameraDevice = !keepDeviceOpen;
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800412 }
413
414 if (cameraId != mCameraId) {
415 return BAD_INDEX;
416 }
417
418 const char *flashMode =
419 mParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
420 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
421 *hasFlash = true;
422 } else {
423 *hasFlash = false;
424 }
425
Chien-Yu Chen6dcc7062016-04-18 11:14:48 -0700426 if (closeCameraDevice) {
427 res = disconnectCameraDevice();
428 if (res != OK) {
429 ALOGE("%s: Failed to disconnect camera device. %s (%d)", __FUNCTION__,
430 strerror(-res), res);
431 return res;
432 }
433 }
434
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800435 return OK;
436}
437
438status_t CameraHardwareInterfaceFlashControl::startPreviewAndTorch() {
439 status_t res = OK;
440 res = mDevice->startPreview();
441 if (res) {
442 ALOGE("%s: start preview failed. %s (%d)", __FUNCTION__,
443 strerror(-res), res);
444 return res;
445 }
446
447 mParameters.set(CameraParameters::KEY_FLASH_MODE,
448 CameraParameters::FLASH_MODE_TORCH);
449
450 return mDevice->setParameters(mParameters);
451}
452
453status_t CameraHardwareInterfaceFlashControl::getSmallestSurfaceSize(
454 int32_t *width, int32_t *height) {
455 if (!width || !height) {
456 return BAD_VALUE;
457 }
458
459 int32_t w = INT32_MAX;
460 int32_t h = 1;
461 Vector<Size> sizes;
462
463 mParameters.getSupportedPreviewSizes(sizes);
464 for (size_t i = 0; i < sizes.size(); i++) {
465 Size s = sizes[i];
466 if (w * h > s.width * s.height) {
467 w = s.width;
468 h = s.height;
469 }
470 }
471
472 if (w == INT32_MAX) {
473 return NAME_NOT_FOUND;
474 }
475
476 *width = w;
477 *height = h;
478
479 return OK;
480}
481
482status_t CameraHardwareInterfaceFlashControl::initializePreviewWindow(
Chih-Hung Hsieh8b0b9712016-08-09 14:25:53 -0700483 const sp<CameraHardwareInterface>& device, int32_t width, int32_t height) {
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800484 status_t res;
485 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
486
487 mSurfaceTexture = new GLConsumer(mConsumer, 0, GLConsumer::TEXTURE_EXTERNAL,
488 true, true);
489 if (mSurfaceTexture == NULL) {
490 return NO_MEMORY;
491 }
492
493 int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
494 res = mSurfaceTexture->setDefaultBufferSize(width, height);
495 if (res) {
496 return res;
497 }
498 res = mSurfaceTexture->setDefaultBufferFormat(format);
499 if (res) {
500 return res;
501 }
502
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700503 mSurface = new Surface(mProducer, /*useAsync*/ true);
504 if (mSurface == NULL) {
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800505 return NO_MEMORY;
506 }
507
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700508 res = native_window_api_connect(mSurface.get(), NATIVE_WINDOW_API_CAMERA);
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800509 if (res) {
510 ALOGE("%s: Unable to connect to native window", __FUNCTION__);
511 return res;
512 }
513
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700514 return device->setPreviewWindow(mSurface);
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800515}
516
517status_t CameraHardwareInterfaceFlashControl::connectCameraDevice(
518 const String8& cameraId) {
519 sp<CameraHardwareInterface> device =
520 new CameraHardwareInterface(cameraId.string());
521
Emilian Peevf53f66e2017-04-11 14:29:43 +0100522 status_t res = device->initialize(mProviderManager);
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800523 if (res) {
524 ALOGE("%s: initializing camera %s failed", __FUNCTION__,
525 cameraId.string());
526 return res;
527 }
528
529 // need to set __get_memory in set_callbacks().
Yin-Chia Yehb5df5472017-03-20 19:32:19 -0700530 device->setCallbacks(NULL, NULL, NULL, NULL, NULL);
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800531
532 mParameters = device->getParameters();
533
534 int32_t width, height;
535 res = getSmallestSurfaceSize(&width, &height);
536 if (res) {
537 ALOGE("%s: failed to get smallest surface size for camera %s",
538 __FUNCTION__, cameraId.string());
539 return res;
540 }
541
542 res = initializePreviewWindow(device, width, height);
543 if (res) {
544 ALOGE("%s: failed to initialize preview window for camera %s",
545 __FUNCTION__, cameraId.string());
546 return res;
547 }
548
549 mCameraId = cameraId;
550 mDevice = device;
551 return OK;
552}
553
554status_t CameraHardwareInterfaceFlashControl::disconnectCameraDevice() {
555 if (mDevice == NULL) {
556 return OK;
557 }
558
Jim Kaye3d1c4782016-04-12 17:24:46 -0700559 if (mParameters.get(CameraParameters::KEY_FLASH_MODE)) {
560 // There is a flash, turn if off.
561 // (If there isn't one, leave the parameter null)
562 mParameters.set(CameraParameters::KEY_FLASH_MODE,
563 CameraParameters::FLASH_MODE_OFF);
564 mDevice->setParameters(mParameters);
565 }
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800566 mDevice->stopPreview();
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700567 status_t res = native_window_api_disconnect(mSurface.get(),
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800568 NATIVE_WINDOW_API_CAMERA);
569 if (res) {
570 ALOGW("%s: native_window_api_disconnect failed: %s (%d)",
571 __FUNCTION__, strerror(-res), res);
572 }
573 mDevice->setPreviewWindow(NULL);
574 mDevice->release();
Oleksiy Avramchenko8a4a0ac2015-09-14 11:00:33 +0200575 mDevice = NULL;
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800576
577 return OK;
578}
579// CameraHardwareInterfaceFlashControl implementation ends
580
Chien-Yu Chen3068d732015-02-09 13:29:57 -0800581}