blob: 8b08f2ddf7de3d152c4bce9ab8749fdc824a8761 [file] [log] [blame]
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001/*
2 * Copyright (C) 2016 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 "CameraProviderManager"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include "CameraProviderManager.h"
22
23#include <android/hidl/manager/1.0/IServiceManager.h>
24#include <hidl/ServiceManagement.h>
25
26namespace android {
27
28using namespace ::android::hardware::camera;
29using namespace ::android::hardware::camera::common::V1_0;
30
31namespace {
32// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
33// service manager
34const std::string kLegacyProviderName("legacy/0");
35
36// Slash-separated list of provider types to consider for use via the old camera API
37const std::string kStandardProviderTypes("internal/legacy");
38
39} // anonymous namespace
40
41CameraProviderManager::HardwareServiceInteractionProxy
42CameraProviderManager::sHardwareServiceInteractionProxy{};
43
44CameraProviderManager::~CameraProviderManager() {
45}
46
47status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
48 ServiceInteractionProxy* proxy) {
49 std::lock_guard<std::mutex> lock(mInterfaceMutex);
50 if (proxy == nullptr) {
51 ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
52 return BAD_VALUE;
53 }
54 mListener = listener;
55 mServiceProxy = proxy;
56
57 // Registering will trigger notifications for all already-known providers
58 bool success = mServiceProxy->registerForNotifications(
59 /* instance name, empty means no filter */ "",
60 this);
61 if (!success) {
62 ALOGE("%s: Unable to register with hardware service manager for notifications "
63 "about camera providers", __FUNCTION__);
64 return INVALID_OPERATION;
65 }
66
67 // Also see if there's a passthrough HAL, but let's not complain if there's not
68 addProvider(kLegacyProviderName, /*expected*/ false);
69
70 return OK;
71}
72
73int CameraProviderManager::getCameraCount() const {
74 std::lock_guard<std::mutex> lock(mInterfaceMutex);
75 int count = 0;
76 for (auto& provider : mProviders) {
77 count += provider->mDevices.size();
78 }
79 return count;
80}
81
82int CameraProviderManager::getStandardCameraCount() const {
83 std::lock_guard<std::mutex> lock(mInterfaceMutex);
84 int count = 0;
85 for (auto& provider : mProviders) {
86 if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
87 count += provider->mDevices.size();
88 }
89 }
90 return count;
91}
92
93std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
94 std::lock_guard<std::mutex> lock(mInterfaceMutex);
95 std::vector<std::string> deviceIds;
96 for (auto& provider : mProviders) {
97 for (auto& deviceInfo : provider->mDevices) {
98 deviceIds.push_back(deviceInfo->mId);
99 }
100 }
101 return deviceIds;
102}
103
104bool CameraProviderManager::isValidDevice(const std::string &id, uint16_t majorVersion) const {
105 std::lock_guard<std::mutex> lock(mInterfaceMutex);
106 return isValidDeviceLocked(id, majorVersion);
107}
108
109bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const {
110 for (auto& provider : mProviders) {
111 for (auto& deviceInfo : provider->mDevices) {
112 if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion) {
113 return true;
114 }
115 }
116 }
117 return false;
118}
119
120bool CameraProviderManager::hasFlashUnit(const std::string &id) const {
121 std::lock_guard<std::mutex> lock(mInterfaceMutex);
122
123 auto deviceInfo = findDeviceInfoLocked(id);
124 if (deviceInfo == nullptr) return false;
125
126 return deviceInfo->hasFlashUnit();
127}
128
129status_t CameraProviderManager::getResourceCost(const std::string &id,
130 CameraResourceCost* cost) const {
131 std::lock_guard<std::mutex> lock(mInterfaceMutex);
132
133 auto deviceInfo = findDeviceInfoLocked(id);
134 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
135
136 *cost = deviceInfo->mResourceCost;
137 return OK;
138}
139
140status_t CameraProviderManager::getCameraInfo(const std::string &id,
141 hardware::CameraInfo* info) const {
142 std::lock_guard<std::mutex> lock(mInterfaceMutex);
143
144 auto deviceInfo = findDeviceInfoLocked(id);
145 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
146
147 return deviceInfo->getCameraInfo(info);
148}
149
150status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
151 CameraMetadata* characteristics) const {
152 std::lock_guard<std::mutex> lock(mInterfaceMutex);
153
154 auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ hardware::hidl_version{3,0});
155 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
156
157 return deviceInfo->getCameraCharacteristics(characteristics);
158}
159
160status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
161 hardware::hidl_version *v) {
162 std::lock_guard<std::mutex> lock(mInterfaceMutex);
163
164 hardware::hidl_version maxVersion{0,0};
165 bool found = false;
166 for (auto& provider : mProviders) {
167 for (auto& deviceInfo : provider->mDevices) {
168 if (deviceInfo->mId == id) {
169 if (deviceInfo->mVersion > maxVersion) {
170 maxVersion = deviceInfo->mVersion;
171 found = true;
172 }
173 }
174 }
175 }
176 if (!found) {
177 return NAME_NOT_FOUND;
178 }
179 *v = maxVersion;
180 return OK;
181}
182
183
184status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
185 std::lock_guard<std::mutex> lock(mInterfaceMutex);
186
187 auto deviceInfo = findDeviceInfoLocked(id);
188 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
189
190 return deviceInfo->setTorchMode(enabled);
191}
192
193hardware::Return<void> CameraProviderManager::onRegistration(
194 const hardware::hidl_string& /*fqName*/,
195 const hardware::hidl_string& name,
196 bool /*preexisting*/) {
197 std::lock_guard<std::mutex> lock(mInterfaceMutex);
198
199 addProvider(name);
200 return hardware::Return<void>();
201}
202
203status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
204 std::lock_guard<std::mutex> lock(mInterfaceMutex);
205
206 dprintf(fd, "Available camera providers and devices:\n");
207 for (auto& provider : mProviders) {
208 provider->dump(fd, args);
209 }
210 return OK;
211}
212
213CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
214 const std::string& id, hardware::hidl_version minVersion) const {
215 for (auto& provider : mProviders) {
216 for (auto& deviceInfo : provider->mDevices) {
217 if (deviceInfo->mId == id && minVersion <= deviceInfo->mVersion) {
218 return deviceInfo.get();
219 }
220 }
221 }
222 return nullptr;
223}
224
225
226status_t CameraProviderManager::addProvider(const std::string& newProvider, bool expected) {
227 for (const auto& providerInfo : mProviders) {
228 if (providerInfo->mProviderName == newProvider) {
229 ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
230 newProvider.c_str());
231 return ALREADY_EXISTS;
232 }
233 }
234 sp<provider::V2_4::ICameraProvider> interface =
235 mServiceProxy->getService(newProvider);
236
237 if (interface == nullptr) {
238 if (expected) {
239 ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
240 newProvider.c_str());
241 return BAD_VALUE;
242 } else {
243 // Not guaranteed to be found, so not an error if it wasn't
244 return OK;
245 }
246 }
247
248 sp<ProviderInfo> providerInfo =
249 new ProviderInfo(newProvider, interface, this);
250 status_t res = providerInfo->initialize();
251 if (res != OK) {
252 return res;
253 }
254
255 mProviders.push_back(providerInfo);
256
257 return OK;
258}
259
260status_t CameraProviderManager::removeProvider(const std::string& provider) {
261 for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
262 if ((*it)->mProviderName == provider) {
263 mProviders.erase(it);
264 return OK;
265 }
266 }
267 ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
268 provider.c_str());
269 return NAME_NOT_FOUND;
270}
271
272/**** Methods for ProviderInfo ****/
273
274
275CameraProviderManager::ProviderInfo::ProviderInfo(
276 const std::string &providerName,
277 sp<provider::V2_4::ICameraProvider>& interface,
278 CameraProviderManager *manager) :
279 mProviderName(providerName),
280 mInterface(interface),
281 mManager(manager) {
282 (void) mManager;
283}
284
285status_t CameraProviderManager::ProviderInfo::initialize() {
286 status_t res = parseProviderName(mProviderName, &mType, &mId);
287 if (res != OK) {
288 ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
289 return BAD_VALUE;
290 }
291 ALOGI("Connecting to new camera provider: %s", mProviderName.c_str());
292 Status status = mInterface->setCallback(this);
293 if (status != Status::OK) {
294 ALOGE("%s: Unable to register callbacks with camera provider '%s'",
295 __FUNCTION__, mProviderName.c_str());
296 return mapToStatusT(status);
297 }
298 // TODO: Register for hw binder death notifications as well
299
300 // Get initial list of camera devices, if any
301 std::vector<std::string> devices;
302 mInterface->getCameraIdList([&status, &devices](
303 Status idStatus,
304 const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
305 status = idStatus;
306 if (status == Status::OK) {
307 for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
308 devices.push_back(cameraDeviceNames[i]);
309 }
310 } });
311
312 if (status != Status::OK) {
313 ALOGE("%s: Unable to query for camera devices from provider '%s'",
314 __FUNCTION__, mProviderName.c_str());
315 return mapToStatusT(status);
316 }
317
318 for (auto& device : devices) {
319 status_t res = addDevice(device);
320 if (res != OK) {
321 ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
322 __FUNCTION__, device.c_str(), strerror(-res), res);
323 }
324 }
325
326 ALOGI("Camera provider %s ready with %zu camera devices",
327 mProviderName.c_str(), mDevices.size());
328
329 return OK;
330}
331
332const std::string& CameraProviderManager::ProviderInfo::getType() const {
333 return mType;
334}
335
336status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
337 CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
338
339 ALOGI("Enumerating new camera device: %s", name.c_str());
340
341 uint16_t major, minor;
342 std::string type, id;
343
344 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
345 if (res != OK) {
346 return res;
347 }
348 if (type != mType) {
349 ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
350 type.c_str(), mType.c_str());
351 return BAD_VALUE;
352 }
353 if (mManager->isValidDeviceLocked(id, major)) {
354 ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
355 name.c_str(), id.c_str(), major);
356 return BAD_VALUE;
357 }
358
359 std::unique_ptr<DeviceInfo> deviceInfo;
360 switch (major) {
361 case 1:
362 deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, id, minor);
363 break;
364 case 3:
365 deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, id, minor);
366 break;
367 default:
368 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
369 name.c_str(), major);
370 return BAD_VALUE;
371 }
372 if (deviceInfo == nullptr) return BAD_VALUE;
373 deviceInfo->mStatus = initialStatus;
374
375 mDevices.push_back(std::move(deviceInfo));
376
377 if (parsedId != nullptr) {
378 *parsedId = id;
379 }
380 return OK;
381}
382
383status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
384 dprintf(fd, " %s: v%d.%d, %zu devices:\n", mProviderName.c_str(),
385 mInterface->version.get_major(), mInterface->version.get_minor(), mDevices.size());
386
387 for (auto& device : mDevices) {
388 dprintf(fd, " %s: Resource cost: %d\n", device->mName.c_str(),
389 device->mResourceCost.resourceCost);
390 if (device->mResourceCost.conflictingDevices.size() > 0) {
391 dprintf(fd, " Conflicting devices:\n");
392 for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
393 dprintf(fd, " %s\n",
394 device->mResourceCost.conflictingDevices[i].c_str());
395 }
396 }
397 }
398 return OK;
399}
400
401hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
402 const hardware::hidl_string& cameraDeviceName,
403 CameraDeviceStatus newStatus) {
404 sp<StatusListener> listener;
405 std::string id;
406 {
407 std::lock_guard<std::mutex> lock(mManager->mInterfaceMutex);
408 bool known = false;
409 for (auto& deviceInfo : mDevices) {
410 if (deviceInfo->mName == cameraDeviceName) {
411 ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
412 deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
413 deviceInfo->mStatus = newStatus;
414 // TODO: Handle device removal (NOT_PRESENT)
415 id = deviceInfo->mId;
416 known = true;
417 break;
418 }
419 }
420 // Previously unseen device; status must not be NOT_PRESENT
421 if (!known) {
422 if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
423 ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
424 mProviderName.c_str(), cameraDeviceName.c_str());
425 return hardware::Void();
426 }
427 addDevice(cameraDeviceName, newStatus, &id);
428 }
429 listener = mManager->mListener.promote();
430 }
431 // Call without lock held to allow reentrancy into provider manager
432 if (listener != nullptr) {
433 listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
434 }
435 return hardware::Void();
436}
437
438hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
439 const hardware::hidl_string& cameraDeviceName,
440 TorchModeStatus newStatus) {
441 sp<StatusListener> listener;
442 std::string id;
443 {
444 std::lock_guard<std::mutex> lock(mManager->mInterfaceMutex);
445 bool known = false;
446 for (auto& deviceInfo : mDevices) {
447 if (deviceInfo->mName == cameraDeviceName) {
448 ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
449 torchStatusToString(newStatus));
450 id = deviceInfo->mId;
451 known = true;
452 break;
453 }
454 }
455 if (!known) {
456 ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
457 mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
458 return hardware::Void();
459 }
460 listener = mManager->mListener.promote();
461 }
462 // Call without lock held to allow reentrancy into provider manager
463 if (listener != nullptr) {
464 listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
465 }
466 return hardware::Void();
467}
468
469
470template<class DeviceInfoT>
471std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
472 CameraProviderManager::ProviderInfo::initializeDeviceInfo(
473 const std::string &name,
474 const std::string &id, uint16_t minorVersion) const {
475 Status status;
476
477 auto cameraInterface =
478 getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
479 if (cameraInterface == nullptr) return nullptr;
480
481 CameraResourceCost resourceCost;
482 cameraInterface->getResourceCost([&status, &resourceCost](
483 Status s, CameraResourceCost cost) {
484 status = s;
485 resourceCost = cost;
486 });
487 if (status != Status::OK) {
488 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
489 name.c_str(), statusToString(status));
490 return nullptr;
491 }
492 return std::unique_ptr<DeviceInfo>(
493 new DeviceInfoT(name, id, minorVersion, resourceCost, cameraInterface));
494}
495
496template<class InterfaceT>
497sp<InterfaceT>
498CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
499 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
500 name.c_str(), InterfaceT::version.get_major());
501 return nullptr;
502}
503
504template<>
505sp<device::V1_0::ICameraDevice>
506CameraProviderManager::ProviderInfo::getDeviceInterface
507 <device::V1_0::ICameraDevice>(const std::string &name) const {
508 Status status;
509 sp<device::V1_0::ICameraDevice> cameraInterface;
510 mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
511 Status s, sp<device::V1_0::ICameraDevice> interface) {
512 status = s;
513 cameraInterface = interface;
514 });
515 if (status != Status::OK) {
516 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
517 name.c_str(), statusToString(status));
518 return nullptr;
519 }
520 return cameraInterface;
521}
522
523template<>
524sp<device::V3_2::ICameraDevice>
525CameraProviderManager::ProviderInfo::getDeviceInterface
526 <device::V3_2::ICameraDevice>(const std::string &name) const {
527 Status status;
528 sp<device::V3_2::ICameraDevice> cameraInterface;
529 mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
530 Status s, sp<device::V3_2::ICameraDevice> interface) {
531 status = s;
532 cameraInterface = interface;
533 });
534 if (status != Status::OK) {
535 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
536 name.c_str(), statusToString(status));
537 return nullptr;
538 }
539 return cameraInterface;
540}
541
542CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
543
544template<class InterfaceT>
545status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
546 bool enabled) {
547 Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
548 return mapToStatusT(s);
549}
550
551CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
552 const std::string &id,
553 uint16_t minorVersion,
554 const CameraResourceCost& resourceCost,
555 sp<InterfaceT> interface) :
556 DeviceInfo(name, id, hardware::hidl_version{1, minorVersion}, resourceCost),
557 mInterface(interface) {
558 // Get default parameters and initialize flash unit availability
559 // Requires powering on the camera device
560 Status status = mInterface->open(nullptr);
561 if (status != Status::OK) {
562 ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s (%d)", __FUNCTION__,
563 mId.c_str(), CameraProviderManager::statusToString(status), status);
564 return;
565 }
566 mInterface->getParameters([this](const hardware::hidl_string& parms) {
567 mDefaultParameters.unflatten(String8(parms.c_str()));
568 });
569
570 const char *flashMode =
571 mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
572 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
573 mHasFlashUnit = true;
574 } else {
575 mHasFlashUnit = false;
576 }
577
578 mInterface->close();
579}
580
581CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
582
583status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
584 return DeviceInfo::setTorchMode(mInterface, enabled);
585}
586
587status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
588 hardware::CameraInfo *info) const {
589 if (info == nullptr) return BAD_VALUE;
590
591 Status status;
592 device::V1_0::CameraInfo cInfo;
593 mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
594 status = s;
595 cInfo = camInfo;
596 });
597 if (status != Status::OK) {
598 return mapToStatusT(status);
599 }
600
601 switch(cInfo.facing) {
602 case device::V1_0::CameraFacing::BACK:
603 info->facing = hardware::CAMERA_FACING_BACK;
604 break;
605 case device::V1_0::CameraFacing::EXTERNAL:
606 // Map external to front for legacy API
607 case device::V1_0::CameraFacing::FRONT:
608 info->facing = hardware::CAMERA_FACING_FRONT;
609 break;
610 default:
611 ALOGW("%s: Unknown camera facing: %d", __FUNCTION__, cInfo.facing);
612 info->facing = hardware::CAMERA_FACING_BACK;
613 }
614 info->orientation = cInfo.orientation;
615
616 return OK;
617}
618
619CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
620 const std::string &id,
621 uint16_t minorVersion,
622 const CameraResourceCost& resourceCost,
623 sp<InterfaceT> interface) :
624 DeviceInfo(name, id, hardware::hidl_version{3, minorVersion}, resourceCost),
625 mInterface(interface) {
626 // Get camera characteristics and initialize flash unit availability
627 Status status;
628 mInterface->getCameraCharacteristics([&status, this](Status s,
629 device::V3_2::CameraMetadata metadata) {
630 status = s;
631 if (s == Status::OK) {
632 camera_metadata_t *buffer =
633 reinterpret_cast<camera_metadata_t*>(metadata.data());
634 mCameraCharacteristics = buffer;
635 }
636 });
637 if (status != Status::OK) {
638 ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
639 __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
640 return;
641 }
642 camera_metadata_entry flashAvailable =
643 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
644 if (flashAvailable.count == 1 &&
645 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
646 mHasFlashUnit = true;
647 } else {
648 mHasFlashUnit = false;
649 }
650}
651
652CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
653
654status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
655 return DeviceInfo::setTorchMode(mInterface, enabled);
656}
657
658status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
659 hardware::CameraInfo *info) const {
660 if (info == nullptr) return BAD_VALUE;
661
662 camera_metadata_ro_entry facing =
663 mCameraCharacteristics.find(ANDROID_LENS_FACING);
664 if (facing.count == 1) {
665 switch (facing.data.u8[0]) {
666 case ANDROID_LENS_FACING_BACK:
667 info->facing = hardware::CAMERA_FACING_BACK;
668 break;
669 case ANDROID_LENS_FACING_EXTERNAL:
670 // Map external to front for legacy API
671 case ANDROID_LENS_FACING_FRONT:
672 info->facing = hardware::CAMERA_FACING_FRONT;
673 break;
674 }
675 } else {
676 ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
677 return NAME_NOT_FOUND;
678 }
679
680 camera_metadata_ro_entry orientation =
681 mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
682 if (orientation.count == 1) {
683 info->orientation = orientation.data.i32[0];
684 } else {
685 ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
686 return NAME_NOT_FOUND;
687 }
688
689 return OK;
690}
691
692status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
693 CameraMetadata *characteristics) const {
694 if (characteristics == nullptr) return BAD_VALUE;
695
696 *characteristics = mCameraCharacteristics;
697 return OK;
698}
699
700status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
701 std::string *type, uint32_t *id) {
702 // Format must be "<type>/<id>"
703#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. " \
704 "Should match '<type>/<id>' - "
705
706 if (!type || !id) return INVALID_OPERATION;
707
708 std::string::size_type slashIdx = name.find('/');
709 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
710 ALOGE(ERROR_MSG_PREFIX
711 "does not have / separator between type and id",
712 __FUNCTION__, name.c_str());
713 return BAD_VALUE;
714 }
715
716 std::string typeVal = name.substr(0, slashIdx);
717
718 char *endPtr;
719 errno = 0;
720 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
721 if (errno != 0) {
722 ALOGE(ERROR_MSG_PREFIX
723 "cannot parse provider id as an integer: %s (%d)",
724 __FUNCTION__, name.c_str(), strerror(errno), errno);
725 return BAD_VALUE;
726 }
727 if (endPtr != name.c_str() + name.size()) {
728 ALOGE(ERROR_MSG_PREFIX
729 "provider id has unexpected length",
730 __FUNCTION__, name.c_str());
731 return BAD_VALUE;
732 }
733 if (idVal < 0) {
734 ALOGE(ERROR_MSG_PREFIX
735 "id is negative: %ld",
736 __FUNCTION__, name.c_str(), idVal);
737 return BAD_VALUE;
738 }
739
740#undef ERROR_MSG_PREFIX
741
742 *type = typeVal;
743 *id = static_cast<uint32_t>(idVal);
744
745 return OK;
746}
747
748status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
749 uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
750
751 // Format must be "device@<major>.<minor>/<type>/<id>"
752
753#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
754 "Should match 'device@<major>.<minor>/<type>/<id>' - "
755
756 if (!major || !minor || !type || !id) return INVALID_OPERATION;
757
758 // Verify starting prefix
759 const char expectedPrefix[] = "device@";
760
761 if (name.find(expectedPrefix) != 0) {
762 ALOGE(ERROR_MSG_PREFIX
763 "does not start with '%s'",
764 __FUNCTION__, name.c_str(), expectedPrefix);
765 return BAD_VALUE;
766 }
767
768 // Extract major/minor versions
769 constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
770 std::string::size_type dotIdx = name.find('.', atIdx);
771 if (dotIdx == std::string::npos) {
772 ALOGE(ERROR_MSG_PREFIX
773 "does not have @<major>. version section",
774 __FUNCTION__, name.c_str());
775 return BAD_VALUE;
776 }
777 std::string::size_type typeSlashIdx = name.find('/', dotIdx);
778 if (typeSlashIdx == std::string::npos) {
779 ALOGE(ERROR_MSG_PREFIX
780 "does not have .<minor>/ version section",
781 __FUNCTION__, name.c_str());
782 return BAD_VALUE;
783 }
784
785 char *endPtr;
786 errno = 0;
787 long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
788 if (errno != 0) {
789 ALOGE(ERROR_MSG_PREFIX
790 "cannot parse major version: %s (%d)",
791 __FUNCTION__, name.c_str(), strerror(errno), errno);
792 return BAD_VALUE;
793 }
794 if (endPtr != name.c_str() + dotIdx) {
795 ALOGE(ERROR_MSG_PREFIX
796 "major version has unexpected length",
797 __FUNCTION__, name.c_str());
798 return BAD_VALUE;
799 }
800 long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
801 if (errno != 0) {
802 ALOGE(ERROR_MSG_PREFIX
803 "cannot parse minor version: %s (%d)",
804 __FUNCTION__, name.c_str(), strerror(errno), errno);
805 return BAD_VALUE;
806 }
807 if (endPtr != name.c_str() + typeSlashIdx) {
808 ALOGE(ERROR_MSG_PREFIX
809 "minor version has unexpected length",
810 __FUNCTION__, name.c_str());
811 return BAD_VALUE;
812 }
813 if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
814 ALOGE(ERROR_MSG_PREFIX
815 "major/minor version is out of range of uint16_t: %ld.%ld",
816 __FUNCTION__, name.c_str(), majorVal, minorVal);
817 return BAD_VALUE;
818 }
819
820 // Extract type and id
821
822 std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
823 if (instanceSlashIdx == std::string::npos) {
824 ALOGE(ERROR_MSG_PREFIX
825 "does not have /<type>/ component",
826 __FUNCTION__, name.c_str());
827 return BAD_VALUE;
828 }
829 std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
830
831 if (instanceSlashIdx == name.size() - 1) {
832 ALOGE(ERROR_MSG_PREFIX
833 "does not have an /<id> component",
834 __FUNCTION__, name.c_str());
835 return BAD_VALUE;
836 }
837 std::string idVal = name.substr(instanceSlashIdx + 1);
838
839#undef ERROR_MSG_PREFIX
840
841 *major = static_cast<uint16_t>(majorVal);
842 *minor = static_cast<uint16_t>(minorVal);
843 *type = typeVal;
844 *id = idVal;
845
846 return OK;
847}
848
849
850
851CameraProviderManager::ProviderInfo::~ProviderInfo() {
852 // Destruction of ProviderInfo is only supposed to happen when the respective
853 // CameraProvider interface dies, so do not unregister callbacks.
854
855}
856
857status_t CameraProviderManager::mapToStatusT(const Status& s) {
858 switch(s) {
859 case Status::OK:
860 return OK;
861 case Status::ILLEGAL_ARGUMENT:
862 return BAD_VALUE;
863 case Status::CAMERA_IN_USE:
864 return -EBUSY;
865 case Status::MAX_CAMERAS_IN_USE:
866 return -EUSERS;
867 case Status::METHOD_NOT_SUPPORTED:
868 return UNKNOWN_TRANSACTION;
869 case Status::OPERATION_NOT_SUPPORTED:
870 return INVALID_OPERATION;
871 case Status::CAMERA_DISCONNECTED:
872 return DEAD_OBJECT;
873 case Status::INTERNAL_ERROR:
874 return INVALID_OPERATION;
875 }
876 ALOGW("Unexpected HAL status code %d", s);
877 return INVALID_OPERATION;
878}
879
880const char* CameraProviderManager::statusToString(const Status& s) {
881 switch(s) {
882 case Status::OK:
883 return "OK";
884 case Status::ILLEGAL_ARGUMENT:
885 return "ILLEGAL_ARGUMENT";
886 case Status::CAMERA_IN_USE:
887 return "CAMERA_IN_USE";
888 case Status::MAX_CAMERAS_IN_USE:
889 return "MAX_CAMERAS_IN_USE";
890 case Status::METHOD_NOT_SUPPORTED:
891 return "METHOD_NOT_SUPPORTED";
892 case Status::OPERATION_NOT_SUPPORTED:
893 return "OPERATION_NOT_SUPPORTED";
894 case Status::CAMERA_DISCONNECTED:
895 return "CAMERA_DISCONNECTED";
896 case Status::INTERNAL_ERROR:
897 return "INTERNAL_ERROR";
898 }
899 ALOGW("Unexpected HAL status code %d", s);
900 return "UNKNOWN_ERROR";
901}
902
903const char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
904 switch(s) {
905 case CameraDeviceStatus::NOT_PRESENT:
906 return "NOT_PRESENT";
907 case CameraDeviceStatus::PRESENT:
908 return "PRESENT";
909 case CameraDeviceStatus::ENUMERATING:
910 return "ENUMERATING";
911 }
912 ALOGW("Unexpected HAL device status code %d", s);
913 return "UNKNOWN_STATUS";
914}
915
916const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
917 switch(s) {
918 case TorchModeStatus::NOT_AVAILABLE:
919 return "NOT_AVAILABLE";
920 case TorchModeStatus::AVAILABLE_OFF:
921 return "AVAILABLE_OFF";
922 case TorchModeStatus::AVAILABLE_ON:
923 return "AVAILABLE_ON";
924 }
925 ALOGW("Unexpected HAL torch mode status code %d", s);
926 return "UNKNOWN_STATUS";
927}
928
929} // namespace android