blob: 8b27c67a5fd9e5ac58aa18de5a3a536af59ec4df [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
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800154 auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800155 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
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800183status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
184 std::lock_guard<std::mutex> lock(mInterfaceMutex);
185
186 auto deviceInfo = findDeviceInfoLocked(id);
187 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
188
189 return deviceInfo->setTorchMode(enabled);
190}
191
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800192status_t CameraProviderManager::openSession(const std::string &id,
193 const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
194 /*out*/
195 sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
196
197 std::lock_guard<std::mutex> lock(mInterfaceMutex);
198
199 auto deviceInfo = findDeviceInfoLocked(id,
200 /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
201 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
202
203 auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
204
205 Status status;
206 deviceInfo3->mInterface->open(callback, [&status, &session]
207 (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
208 status = s;
209 if (status == Status::OK) {
210 *session = cameraSession;
211 }
212 });
213 return mapToStatusT(status);
214}
215
216status_t CameraProviderManager::openSession(const std::string &id,
217 const sp<hardware::camera::device::V1_0::ICameraDeviceCallback>& callback,
218 /*out*/
219 sp<hardware::camera::device::V1_0::ICameraDevice> *session) {
220
221 std::lock_guard<std::mutex> lock(mInterfaceMutex);
222
223 auto deviceInfo = findDeviceInfoLocked(id,
224 /*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
225 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
226
227 auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
228
229 Status status = deviceInfo1->mInterface->open(callback);
230 if (status == Status::OK) {
231 *session = deviceInfo1->mInterface;
232 }
233 return mapToStatusT(status);
234}
235
236
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800237hardware::Return<void> CameraProviderManager::onRegistration(
238 const hardware::hidl_string& /*fqName*/,
239 const hardware::hidl_string& name,
240 bool /*preexisting*/) {
241 std::lock_guard<std::mutex> lock(mInterfaceMutex);
242
243 addProvider(name);
244 return hardware::Return<void>();
245}
246
247status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
248 std::lock_guard<std::mutex> lock(mInterfaceMutex);
249
250 dprintf(fd, "Available camera providers and devices:\n");
251 for (auto& provider : mProviders) {
252 provider->dump(fd, args);
253 }
254 return OK;
255}
256
257CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800258 const std::string& id,
259 hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800260 for (auto& provider : mProviders) {
261 for (auto& deviceInfo : provider->mDevices) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800262 if (deviceInfo->mId == id &&
263 minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800264 return deviceInfo.get();
265 }
266 }
267 }
268 return nullptr;
269}
270
271
272status_t CameraProviderManager::addProvider(const std::string& newProvider, bool expected) {
273 for (const auto& providerInfo : mProviders) {
274 if (providerInfo->mProviderName == newProvider) {
275 ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
276 newProvider.c_str());
277 return ALREADY_EXISTS;
278 }
279 }
280 sp<provider::V2_4::ICameraProvider> interface =
281 mServiceProxy->getService(newProvider);
282
283 if (interface == nullptr) {
284 if (expected) {
285 ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
286 newProvider.c_str());
287 return BAD_VALUE;
288 } else {
289 // Not guaranteed to be found, so not an error if it wasn't
290 return OK;
291 }
292 }
293
294 sp<ProviderInfo> providerInfo =
295 new ProviderInfo(newProvider, interface, this);
296 status_t res = providerInfo->initialize();
297 if (res != OK) {
298 return res;
299 }
300
301 mProviders.push_back(providerInfo);
302
303 return OK;
304}
305
306status_t CameraProviderManager::removeProvider(const std::string& provider) {
307 for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
308 if ((*it)->mProviderName == provider) {
309 mProviders.erase(it);
310 return OK;
311 }
312 }
313 ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
314 provider.c_str());
315 return NAME_NOT_FOUND;
316}
317
318/**** Methods for ProviderInfo ****/
319
320
321CameraProviderManager::ProviderInfo::ProviderInfo(
322 const std::string &providerName,
323 sp<provider::V2_4::ICameraProvider>& interface,
324 CameraProviderManager *manager) :
325 mProviderName(providerName),
326 mInterface(interface),
327 mManager(manager) {
328 (void) mManager;
329}
330
331status_t CameraProviderManager::ProviderInfo::initialize() {
332 status_t res = parseProviderName(mProviderName, &mType, &mId);
333 if (res != OK) {
334 ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
335 return BAD_VALUE;
336 }
337 ALOGI("Connecting to new camera provider: %s", mProviderName.c_str());
338 Status status = mInterface->setCallback(this);
339 if (status != Status::OK) {
340 ALOGE("%s: Unable to register callbacks with camera provider '%s'",
341 __FUNCTION__, mProviderName.c_str());
342 return mapToStatusT(status);
343 }
344 // TODO: Register for hw binder death notifications as well
345
346 // Get initial list of camera devices, if any
347 std::vector<std::string> devices;
348 mInterface->getCameraIdList([&status, &devices](
349 Status idStatus,
350 const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
351 status = idStatus;
352 if (status == Status::OK) {
353 for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
354 devices.push_back(cameraDeviceNames[i]);
355 }
356 } });
357
358 if (status != Status::OK) {
359 ALOGE("%s: Unable to query for camera devices from provider '%s'",
360 __FUNCTION__, mProviderName.c_str());
361 return mapToStatusT(status);
362 }
363
364 for (auto& device : devices) {
365 status_t res = addDevice(device);
366 if (res != OK) {
367 ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
368 __FUNCTION__, device.c_str(), strerror(-res), res);
369 }
370 }
371
372 ALOGI("Camera provider %s ready with %zu camera devices",
373 mProviderName.c_str(), mDevices.size());
374
375 return OK;
376}
377
378const std::string& CameraProviderManager::ProviderInfo::getType() const {
379 return mType;
380}
381
382status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
383 CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
384
385 ALOGI("Enumerating new camera device: %s", name.c_str());
386
387 uint16_t major, minor;
388 std::string type, id;
389
390 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
391 if (res != OK) {
392 return res;
393 }
394 if (type != mType) {
395 ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
396 type.c_str(), mType.c_str());
397 return BAD_VALUE;
398 }
399 if (mManager->isValidDeviceLocked(id, major)) {
400 ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
401 name.c_str(), id.c_str(), major);
402 return BAD_VALUE;
403 }
404
405 std::unique_ptr<DeviceInfo> deviceInfo;
406 switch (major) {
407 case 1:
408 deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, id, minor);
409 break;
410 case 3:
411 deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, id, minor);
412 break;
413 default:
414 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
415 name.c_str(), major);
416 return BAD_VALUE;
417 }
418 if (deviceInfo == nullptr) return BAD_VALUE;
419 deviceInfo->mStatus = initialStatus;
420
421 mDevices.push_back(std::move(deviceInfo));
422
423 if (parsedId != nullptr) {
424 *parsedId = id;
425 }
426 return OK;
427}
428
429status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
430 dprintf(fd, " %s: v%d.%d, %zu devices:\n", mProviderName.c_str(),
431 mInterface->version.get_major(), mInterface->version.get_minor(), mDevices.size());
432
433 for (auto& device : mDevices) {
434 dprintf(fd, " %s: Resource cost: %d\n", device->mName.c_str(),
435 device->mResourceCost.resourceCost);
436 if (device->mResourceCost.conflictingDevices.size() > 0) {
437 dprintf(fd, " Conflicting devices:\n");
438 for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
439 dprintf(fd, " %s\n",
440 device->mResourceCost.conflictingDevices[i].c_str());
441 }
442 }
443 }
444 return OK;
445}
446
447hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
448 const hardware::hidl_string& cameraDeviceName,
449 CameraDeviceStatus newStatus) {
450 sp<StatusListener> listener;
451 std::string id;
452 {
453 std::lock_guard<std::mutex> lock(mManager->mInterfaceMutex);
454 bool known = false;
455 for (auto& deviceInfo : mDevices) {
456 if (deviceInfo->mName == cameraDeviceName) {
457 ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
458 deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
459 deviceInfo->mStatus = newStatus;
460 // TODO: Handle device removal (NOT_PRESENT)
461 id = deviceInfo->mId;
462 known = true;
463 break;
464 }
465 }
466 // Previously unseen device; status must not be NOT_PRESENT
467 if (!known) {
468 if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
469 ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
470 mProviderName.c_str(), cameraDeviceName.c_str());
471 return hardware::Void();
472 }
473 addDevice(cameraDeviceName, newStatus, &id);
474 }
475 listener = mManager->mListener.promote();
476 }
477 // Call without lock held to allow reentrancy into provider manager
478 if (listener != nullptr) {
479 listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
480 }
481 return hardware::Void();
482}
483
484hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
485 const hardware::hidl_string& cameraDeviceName,
486 TorchModeStatus newStatus) {
487 sp<StatusListener> listener;
488 std::string id;
489 {
490 std::lock_guard<std::mutex> lock(mManager->mInterfaceMutex);
491 bool known = false;
492 for (auto& deviceInfo : mDevices) {
493 if (deviceInfo->mName == cameraDeviceName) {
494 ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
495 torchStatusToString(newStatus));
496 id = deviceInfo->mId;
497 known = true;
498 break;
499 }
500 }
501 if (!known) {
502 ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
503 mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
504 return hardware::Void();
505 }
506 listener = mManager->mListener.promote();
507 }
508 // Call without lock held to allow reentrancy into provider manager
509 if (listener != nullptr) {
510 listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
511 }
512 return hardware::Void();
513}
514
515
516template<class DeviceInfoT>
517std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
518 CameraProviderManager::ProviderInfo::initializeDeviceInfo(
519 const std::string &name,
520 const std::string &id, uint16_t minorVersion) const {
521 Status status;
522
523 auto cameraInterface =
524 getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
525 if (cameraInterface == nullptr) return nullptr;
526
527 CameraResourceCost resourceCost;
528 cameraInterface->getResourceCost([&status, &resourceCost](
529 Status s, CameraResourceCost cost) {
530 status = s;
531 resourceCost = cost;
532 });
533 if (status != Status::OK) {
534 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
535 name.c_str(), statusToString(status));
536 return nullptr;
537 }
538 return std::unique_ptr<DeviceInfo>(
539 new DeviceInfoT(name, id, minorVersion, resourceCost, cameraInterface));
540}
541
542template<class InterfaceT>
543sp<InterfaceT>
544CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
545 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
546 name.c_str(), InterfaceT::version.get_major());
547 return nullptr;
548}
549
550template<>
551sp<device::V1_0::ICameraDevice>
552CameraProviderManager::ProviderInfo::getDeviceInterface
553 <device::V1_0::ICameraDevice>(const std::string &name) const {
554 Status status;
555 sp<device::V1_0::ICameraDevice> cameraInterface;
556 mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
557 Status s, sp<device::V1_0::ICameraDevice> interface) {
558 status = s;
559 cameraInterface = interface;
560 });
561 if (status != Status::OK) {
562 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
563 name.c_str(), statusToString(status));
564 return nullptr;
565 }
566 return cameraInterface;
567}
568
569template<>
570sp<device::V3_2::ICameraDevice>
571CameraProviderManager::ProviderInfo::getDeviceInterface
572 <device::V3_2::ICameraDevice>(const std::string &name) const {
573 Status status;
574 sp<device::V3_2::ICameraDevice> cameraInterface;
575 mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
576 Status s, sp<device::V3_2::ICameraDevice> interface) {
577 status = s;
578 cameraInterface = interface;
579 });
580 if (status != Status::OK) {
581 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
582 name.c_str(), statusToString(status));
583 return nullptr;
584 }
585 return cameraInterface;
586}
587
588CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
589
590template<class InterfaceT>
591status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
592 bool enabled) {
593 Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
594 return mapToStatusT(s);
595}
596
597CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
598 const std::string &id,
599 uint16_t minorVersion,
600 const CameraResourceCost& resourceCost,
601 sp<InterfaceT> interface) :
602 DeviceInfo(name, id, hardware::hidl_version{1, minorVersion}, resourceCost),
603 mInterface(interface) {
604 // Get default parameters and initialize flash unit availability
605 // Requires powering on the camera device
606 Status status = mInterface->open(nullptr);
607 if (status != Status::OK) {
608 ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s (%d)", __FUNCTION__,
609 mId.c_str(), CameraProviderManager::statusToString(status), status);
610 return;
611 }
612 mInterface->getParameters([this](const hardware::hidl_string& parms) {
613 mDefaultParameters.unflatten(String8(parms.c_str()));
614 });
615
616 const char *flashMode =
617 mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
618 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
619 mHasFlashUnit = true;
620 } else {
621 mHasFlashUnit = false;
622 }
623
624 mInterface->close();
625}
626
627CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
628
629status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
630 return DeviceInfo::setTorchMode(mInterface, enabled);
631}
632
633status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
634 hardware::CameraInfo *info) const {
635 if (info == nullptr) return BAD_VALUE;
636
637 Status status;
638 device::V1_0::CameraInfo cInfo;
639 mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
640 status = s;
641 cInfo = camInfo;
642 });
643 if (status != Status::OK) {
644 return mapToStatusT(status);
645 }
646
647 switch(cInfo.facing) {
648 case device::V1_0::CameraFacing::BACK:
649 info->facing = hardware::CAMERA_FACING_BACK;
650 break;
651 case device::V1_0::CameraFacing::EXTERNAL:
652 // Map external to front for legacy API
653 case device::V1_0::CameraFacing::FRONT:
654 info->facing = hardware::CAMERA_FACING_FRONT;
655 break;
656 default:
657 ALOGW("%s: Unknown camera facing: %d", __FUNCTION__, cInfo.facing);
658 info->facing = hardware::CAMERA_FACING_BACK;
659 }
660 info->orientation = cInfo.orientation;
661
662 return OK;
663}
664
665CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
666 const std::string &id,
667 uint16_t minorVersion,
668 const CameraResourceCost& resourceCost,
669 sp<InterfaceT> interface) :
670 DeviceInfo(name, id, hardware::hidl_version{3, minorVersion}, resourceCost),
671 mInterface(interface) {
672 // Get camera characteristics and initialize flash unit availability
673 Status status;
674 mInterface->getCameraCharacteristics([&status, this](Status s,
675 device::V3_2::CameraMetadata metadata) {
676 status = s;
677 if (s == Status::OK) {
678 camera_metadata_t *buffer =
679 reinterpret_cast<camera_metadata_t*>(metadata.data());
680 mCameraCharacteristics = buffer;
681 }
682 });
683 if (status != Status::OK) {
684 ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
685 __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
686 return;
687 }
688 camera_metadata_entry flashAvailable =
689 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
690 if (flashAvailable.count == 1 &&
691 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
692 mHasFlashUnit = true;
693 } else {
694 mHasFlashUnit = false;
695 }
696}
697
698CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
699
700status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
701 return DeviceInfo::setTorchMode(mInterface, enabled);
702}
703
704status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
705 hardware::CameraInfo *info) const {
706 if (info == nullptr) return BAD_VALUE;
707
708 camera_metadata_ro_entry facing =
709 mCameraCharacteristics.find(ANDROID_LENS_FACING);
710 if (facing.count == 1) {
711 switch (facing.data.u8[0]) {
712 case ANDROID_LENS_FACING_BACK:
713 info->facing = hardware::CAMERA_FACING_BACK;
714 break;
715 case ANDROID_LENS_FACING_EXTERNAL:
716 // Map external to front for legacy API
717 case ANDROID_LENS_FACING_FRONT:
718 info->facing = hardware::CAMERA_FACING_FRONT;
719 break;
720 }
721 } else {
722 ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
723 return NAME_NOT_FOUND;
724 }
725
726 camera_metadata_ro_entry orientation =
727 mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
728 if (orientation.count == 1) {
729 info->orientation = orientation.data.i32[0];
730 } else {
731 ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
732 return NAME_NOT_FOUND;
733 }
734
735 return OK;
736}
737
738status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
739 CameraMetadata *characteristics) const {
740 if (characteristics == nullptr) return BAD_VALUE;
741
742 *characteristics = mCameraCharacteristics;
743 return OK;
744}
745
746status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
747 std::string *type, uint32_t *id) {
748 // Format must be "<type>/<id>"
749#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. " \
750 "Should match '<type>/<id>' - "
751
752 if (!type || !id) return INVALID_OPERATION;
753
754 std::string::size_type slashIdx = name.find('/');
755 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
756 ALOGE(ERROR_MSG_PREFIX
757 "does not have / separator between type and id",
758 __FUNCTION__, name.c_str());
759 return BAD_VALUE;
760 }
761
762 std::string typeVal = name.substr(0, slashIdx);
763
764 char *endPtr;
765 errno = 0;
766 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
767 if (errno != 0) {
768 ALOGE(ERROR_MSG_PREFIX
769 "cannot parse provider id as an integer: %s (%d)",
770 __FUNCTION__, name.c_str(), strerror(errno), errno);
771 return BAD_VALUE;
772 }
773 if (endPtr != name.c_str() + name.size()) {
774 ALOGE(ERROR_MSG_PREFIX
775 "provider id has unexpected length",
776 __FUNCTION__, name.c_str());
777 return BAD_VALUE;
778 }
779 if (idVal < 0) {
780 ALOGE(ERROR_MSG_PREFIX
781 "id is negative: %ld",
782 __FUNCTION__, name.c_str(), idVal);
783 return BAD_VALUE;
784 }
785
786#undef ERROR_MSG_PREFIX
787
788 *type = typeVal;
789 *id = static_cast<uint32_t>(idVal);
790
791 return OK;
792}
793
794status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
795 uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
796
797 // Format must be "device@<major>.<minor>/<type>/<id>"
798
799#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
800 "Should match 'device@<major>.<minor>/<type>/<id>' - "
801
802 if (!major || !minor || !type || !id) return INVALID_OPERATION;
803
804 // Verify starting prefix
805 const char expectedPrefix[] = "device@";
806
807 if (name.find(expectedPrefix) != 0) {
808 ALOGE(ERROR_MSG_PREFIX
809 "does not start with '%s'",
810 __FUNCTION__, name.c_str(), expectedPrefix);
811 return BAD_VALUE;
812 }
813
814 // Extract major/minor versions
815 constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
816 std::string::size_type dotIdx = name.find('.', atIdx);
817 if (dotIdx == std::string::npos) {
818 ALOGE(ERROR_MSG_PREFIX
819 "does not have @<major>. version section",
820 __FUNCTION__, name.c_str());
821 return BAD_VALUE;
822 }
823 std::string::size_type typeSlashIdx = name.find('/', dotIdx);
824 if (typeSlashIdx == std::string::npos) {
825 ALOGE(ERROR_MSG_PREFIX
826 "does not have .<minor>/ version section",
827 __FUNCTION__, name.c_str());
828 return BAD_VALUE;
829 }
830
831 char *endPtr;
832 errno = 0;
833 long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
834 if (errno != 0) {
835 ALOGE(ERROR_MSG_PREFIX
836 "cannot parse major version: %s (%d)",
837 __FUNCTION__, name.c_str(), strerror(errno), errno);
838 return BAD_VALUE;
839 }
840 if (endPtr != name.c_str() + dotIdx) {
841 ALOGE(ERROR_MSG_PREFIX
842 "major version has unexpected length",
843 __FUNCTION__, name.c_str());
844 return BAD_VALUE;
845 }
846 long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
847 if (errno != 0) {
848 ALOGE(ERROR_MSG_PREFIX
849 "cannot parse minor version: %s (%d)",
850 __FUNCTION__, name.c_str(), strerror(errno), errno);
851 return BAD_VALUE;
852 }
853 if (endPtr != name.c_str() + typeSlashIdx) {
854 ALOGE(ERROR_MSG_PREFIX
855 "minor version has unexpected length",
856 __FUNCTION__, name.c_str());
857 return BAD_VALUE;
858 }
859 if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
860 ALOGE(ERROR_MSG_PREFIX
861 "major/minor version is out of range of uint16_t: %ld.%ld",
862 __FUNCTION__, name.c_str(), majorVal, minorVal);
863 return BAD_VALUE;
864 }
865
866 // Extract type and id
867
868 std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
869 if (instanceSlashIdx == std::string::npos) {
870 ALOGE(ERROR_MSG_PREFIX
871 "does not have /<type>/ component",
872 __FUNCTION__, name.c_str());
873 return BAD_VALUE;
874 }
875 std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
876
877 if (instanceSlashIdx == name.size() - 1) {
878 ALOGE(ERROR_MSG_PREFIX
879 "does not have an /<id> component",
880 __FUNCTION__, name.c_str());
881 return BAD_VALUE;
882 }
883 std::string idVal = name.substr(instanceSlashIdx + 1);
884
885#undef ERROR_MSG_PREFIX
886
887 *major = static_cast<uint16_t>(majorVal);
888 *minor = static_cast<uint16_t>(minorVal);
889 *type = typeVal;
890 *id = idVal;
891
892 return OK;
893}
894
895
896
897CameraProviderManager::ProviderInfo::~ProviderInfo() {
898 // Destruction of ProviderInfo is only supposed to happen when the respective
899 // CameraProvider interface dies, so do not unregister callbacks.
900
901}
902
903status_t CameraProviderManager::mapToStatusT(const Status& s) {
904 switch(s) {
905 case Status::OK:
906 return OK;
907 case Status::ILLEGAL_ARGUMENT:
908 return BAD_VALUE;
909 case Status::CAMERA_IN_USE:
910 return -EBUSY;
911 case Status::MAX_CAMERAS_IN_USE:
912 return -EUSERS;
913 case Status::METHOD_NOT_SUPPORTED:
914 return UNKNOWN_TRANSACTION;
915 case Status::OPERATION_NOT_SUPPORTED:
916 return INVALID_OPERATION;
917 case Status::CAMERA_DISCONNECTED:
918 return DEAD_OBJECT;
919 case Status::INTERNAL_ERROR:
920 return INVALID_OPERATION;
921 }
922 ALOGW("Unexpected HAL status code %d", s);
923 return INVALID_OPERATION;
924}
925
926const char* CameraProviderManager::statusToString(const Status& s) {
927 switch(s) {
928 case Status::OK:
929 return "OK";
930 case Status::ILLEGAL_ARGUMENT:
931 return "ILLEGAL_ARGUMENT";
932 case Status::CAMERA_IN_USE:
933 return "CAMERA_IN_USE";
934 case Status::MAX_CAMERAS_IN_USE:
935 return "MAX_CAMERAS_IN_USE";
936 case Status::METHOD_NOT_SUPPORTED:
937 return "METHOD_NOT_SUPPORTED";
938 case Status::OPERATION_NOT_SUPPORTED:
939 return "OPERATION_NOT_SUPPORTED";
940 case Status::CAMERA_DISCONNECTED:
941 return "CAMERA_DISCONNECTED";
942 case Status::INTERNAL_ERROR:
943 return "INTERNAL_ERROR";
944 }
945 ALOGW("Unexpected HAL status code %d", s);
946 return "UNKNOWN_ERROR";
947}
948
949const char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
950 switch(s) {
951 case CameraDeviceStatus::NOT_PRESENT:
952 return "NOT_PRESENT";
953 case CameraDeviceStatus::PRESENT:
954 return "PRESENT";
955 case CameraDeviceStatus::ENUMERATING:
956 return "ENUMERATING";
957 }
958 ALOGW("Unexpected HAL device status code %d", s);
959 return "UNKNOWN_STATUS";
960}
961
962const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
963 switch(s) {
964 case TorchModeStatus::NOT_AVAILABLE:
965 return "NOT_AVAILABLE";
966 case TorchModeStatus::AVAILABLE_OFF:
967 return "AVAILABLE_OFF";
968 case TorchModeStatus::AVAILABLE_ON:
969 return "AVAILABLE_ON";
970 }
971 ALOGW("Unexpected HAL torch mode status code %d", s);
972 return "UNKNOWN_STATUS";
973}
974
975} // namespace android