blob: cb965b60d48d279d7982fd60aa403e890baec198 [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 {
Yin-Chia Yeh52778d42016-12-22 18:20:43 -0800430 dprintf(fd, " %s: %zu devices:\n", mProviderName.c_str(), mDevices.size());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800431
432 for (auto& device : mDevices) {
433 dprintf(fd, " %s: Resource cost: %d\n", device->mName.c_str(),
434 device->mResourceCost.resourceCost);
435 if (device->mResourceCost.conflictingDevices.size() > 0) {
436 dprintf(fd, " Conflicting devices:\n");
437 for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
438 dprintf(fd, " %s\n",
439 device->mResourceCost.conflictingDevices[i].c_str());
440 }
441 }
442 }
443 return OK;
444}
445
446hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
447 const hardware::hidl_string& cameraDeviceName,
448 CameraDeviceStatus newStatus) {
449 sp<StatusListener> listener;
450 std::string id;
451 {
Yin-Chia Yeh52778d42016-12-22 18:20:43 -0800452 std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800453 bool known = false;
454 for (auto& deviceInfo : mDevices) {
455 if (deviceInfo->mName == cameraDeviceName) {
456 ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
457 deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
458 deviceInfo->mStatus = newStatus;
459 // TODO: Handle device removal (NOT_PRESENT)
460 id = deviceInfo->mId;
461 known = true;
462 break;
463 }
464 }
465 // Previously unseen device; status must not be NOT_PRESENT
466 if (!known) {
467 if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
468 ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
469 mProviderName.c_str(), cameraDeviceName.c_str());
470 return hardware::Void();
471 }
472 addDevice(cameraDeviceName, newStatus, &id);
473 }
474 listener = mManager->mListener.promote();
475 }
476 // Call without lock held to allow reentrancy into provider manager
477 if (listener != nullptr) {
478 listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
479 }
480 return hardware::Void();
481}
482
483hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
484 const hardware::hidl_string& cameraDeviceName,
485 TorchModeStatus newStatus) {
486 sp<StatusListener> listener;
487 std::string id;
488 {
Yin-Chia Yeh52778d42016-12-22 18:20:43 -0800489 std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800490 bool known = false;
491 for (auto& deviceInfo : mDevices) {
492 if (deviceInfo->mName == cameraDeviceName) {
493 ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
494 torchStatusToString(newStatus));
495 id = deviceInfo->mId;
496 known = true;
497 break;
498 }
499 }
500 if (!known) {
501 ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
502 mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
503 return hardware::Void();
504 }
505 listener = mManager->mListener.promote();
506 }
507 // Call without lock held to allow reentrancy into provider manager
508 if (listener != nullptr) {
509 listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
510 }
511 return hardware::Void();
512}
513
514
515template<class DeviceInfoT>
516std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
517 CameraProviderManager::ProviderInfo::initializeDeviceInfo(
518 const std::string &name,
519 const std::string &id, uint16_t minorVersion) const {
520 Status status;
521
522 auto cameraInterface =
523 getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
524 if (cameraInterface == nullptr) return nullptr;
525
526 CameraResourceCost resourceCost;
527 cameraInterface->getResourceCost([&status, &resourceCost](
528 Status s, CameraResourceCost cost) {
529 status = s;
530 resourceCost = cost;
531 });
532 if (status != Status::OK) {
533 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
534 name.c_str(), statusToString(status));
535 return nullptr;
536 }
537 return std::unique_ptr<DeviceInfo>(
538 new DeviceInfoT(name, id, minorVersion, resourceCost, cameraInterface));
539}
540
541template<class InterfaceT>
542sp<InterfaceT>
543CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
544 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
545 name.c_str(), InterfaceT::version.get_major());
546 return nullptr;
547}
548
549template<>
550sp<device::V1_0::ICameraDevice>
551CameraProviderManager::ProviderInfo::getDeviceInterface
552 <device::V1_0::ICameraDevice>(const std::string &name) const {
553 Status status;
554 sp<device::V1_0::ICameraDevice> cameraInterface;
555 mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
556 Status s, sp<device::V1_0::ICameraDevice> interface) {
557 status = s;
558 cameraInterface = interface;
559 });
560 if (status != Status::OK) {
561 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
562 name.c_str(), statusToString(status));
563 return nullptr;
564 }
565 return cameraInterface;
566}
567
568template<>
569sp<device::V3_2::ICameraDevice>
570CameraProviderManager::ProviderInfo::getDeviceInterface
571 <device::V3_2::ICameraDevice>(const std::string &name) const {
572 Status status;
573 sp<device::V3_2::ICameraDevice> cameraInterface;
574 mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
575 Status s, sp<device::V3_2::ICameraDevice> interface) {
576 status = s;
577 cameraInterface = interface;
578 });
579 if (status != Status::OK) {
580 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
581 name.c_str(), statusToString(status));
582 return nullptr;
583 }
584 return cameraInterface;
585}
586
587CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
588
589template<class InterfaceT>
590status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
591 bool enabled) {
592 Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
593 return mapToStatusT(s);
594}
595
596CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
597 const std::string &id,
598 uint16_t minorVersion,
599 const CameraResourceCost& resourceCost,
600 sp<InterfaceT> interface) :
601 DeviceInfo(name, id, hardware::hidl_version{1, minorVersion}, resourceCost),
602 mInterface(interface) {
603 // Get default parameters and initialize flash unit availability
604 // Requires powering on the camera device
605 Status status = mInterface->open(nullptr);
606 if (status != Status::OK) {
607 ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s (%d)", __FUNCTION__,
608 mId.c_str(), CameraProviderManager::statusToString(status), status);
609 return;
610 }
611 mInterface->getParameters([this](const hardware::hidl_string& parms) {
612 mDefaultParameters.unflatten(String8(parms.c_str()));
613 });
614
615 const char *flashMode =
616 mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
617 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
618 mHasFlashUnit = true;
619 } else {
620 mHasFlashUnit = false;
621 }
622
623 mInterface->close();
624}
625
626CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
627
628status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
629 return DeviceInfo::setTorchMode(mInterface, enabled);
630}
631
632status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
633 hardware::CameraInfo *info) const {
634 if (info == nullptr) return BAD_VALUE;
635
636 Status status;
637 device::V1_0::CameraInfo cInfo;
638 mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
639 status = s;
640 cInfo = camInfo;
641 });
642 if (status != Status::OK) {
643 return mapToStatusT(status);
644 }
645
646 switch(cInfo.facing) {
647 case device::V1_0::CameraFacing::BACK:
648 info->facing = hardware::CAMERA_FACING_BACK;
649 break;
650 case device::V1_0::CameraFacing::EXTERNAL:
651 // Map external to front for legacy API
652 case device::V1_0::CameraFacing::FRONT:
653 info->facing = hardware::CAMERA_FACING_FRONT;
654 break;
655 default:
656 ALOGW("%s: Unknown camera facing: %d", __FUNCTION__, cInfo.facing);
657 info->facing = hardware::CAMERA_FACING_BACK;
658 }
659 info->orientation = cInfo.orientation;
660
661 return OK;
662}
663
664CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
665 const std::string &id,
666 uint16_t minorVersion,
667 const CameraResourceCost& resourceCost,
668 sp<InterfaceT> interface) :
669 DeviceInfo(name, id, hardware::hidl_version{3, minorVersion}, resourceCost),
670 mInterface(interface) {
671 // Get camera characteristics and initialize flash unit availability
672 Status status;
673 mInterface->getCameraCharacteristics([&status, this](Status s,
674 device::V3_2::CameraMetadata metadata) {
675 status = s;
676 if (s == Status::OK) {
677 camera_metadata_t *buffer =
678 reinterpret_cast<camera_metadata_t*>(metadata.data());
679 mCameraCharacteristics = buffer;
680 }
681 });
682 if (status != Status::OK) {
683 ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
684 __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
685 return;
686 }
687 camera_metadata_entry flashAvailable =
688 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
689 if (flashAvailable.count == 1 &&
690 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
691 mHasFlashUnit = true;
692 } else {
693 mHasFlashUnit = false;
694 }
695}
696
697CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
698
699status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
700 return DeviceInfo::setTorchMode(mInterface, enabled);
701}
702
703status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
704 hardware::CameraInfo *info) const {
705 if (info == nullptr) return BAD_VALUE;
706
707 camera_metadata_ro_entry facing =
708 mCameraCharacteristics.find(ANDROID_LENS_FACING);
709 if (facing.count == 1) {
710 switch (facing.data.u8[0]) {
711 case ANDROID_LENS_FACING_BACK:
712 info->facing = hardware::CAMERA_FACING_BACK;
713 break;
714 case ANDROID_LENS_FACING_EXTERNAL:
715 // Map external to front for legacy API
716 case ANDROID_LENS_FACING_FRONT:
717 info->facing = hardware::CAMERA_FACING_FRONT;
718 break;
719 }
720 } else {
721 ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
722 return NAME_NOT_FOUND;
723 }
724
725 camera_metadata_ro_entry orientation =
726 mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
727 if (orientation.count == 1) {
728 info->orientation = orientation.data.i32[0];
729 } else {
730 ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
731 return NAME_NOT_FOUND;
732 }
733
734 return OK;
735}
736
737status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
738 CameraMetadata *characteristics) const {
739 if (characteristics == nullptr) return BAD_VALUE;
740
741 *characteristics = mCameraCharacteristics;
742 return OK;
743}
744
745status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
746 std::string *type, uint32_t *id) {
747 // Format must be "<type>/<id>"
748#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. " \
749 "Should match '<type>/<id>' - "
750
751 if (!type || !id) return INVALID_OPERATION;
752
753 std::string::size_type slashIdx = name.find('/');
754 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
755 ALOGE(ERROR_MSG_PREFIX
756 "does not have / separator between type and id",
757 __FUNCTION__, name.c_str());
758 return BAD_VALUE;
759 }
760
761 std::string typeVal = name.substr(0, slashIdx);
762
763 char *endPtr;
764 errno = 0;
765 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
766 if (errno != 0) {
767 ALOGE(ERROR_MSG_PREFIX
768 "cannot parse provider id as an integer: %s (%d)",
769 __FUNCTION__, name.c_str(), strerror(errno), errno);
770 return BAD_VALUE;
771 }
772 if (endPtr != name.c_str() + name.size()) {
773 ALOGE(ERROR_MSG_PREFIX
774 "provider id has unexpected length",
775 __FUNCTION__, name.c_str());
776 return BAD_VALUE;
777 }
778 if (idVal < 0) {
779 ALOGE(ERROR_MSG_PREFIX
780 "id is negative: %ld",
781 __FUNCTION__, name.c_str(), idVal);
782 return BAD_VALUE;
783 }
784
785#undef ERROR_MSG_PREFIX
786
787 *type = typeVal;
788 *id = static_cast<uint32_t>(idVal);
789
790 return OK;
791}
792
793status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
794 uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
795
796 // Format must be "device@<major>.<minor>/<type>/<id>"
797
798#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
799 "Should match 'device@<major>.<minor>/<type>/<id>' - "
800
801 if (!major || !minor || !type || !id) return INVALID_OPERATION;
802
803 // Verify starting prefix
804 const char expectedPrefix[] = "device@";
805
806 if (name.find(expectedPrefix) != 0) {
807 ALOGE(ERROR_MSG_PREFIX
808 "does not start with '%s'",
809 __FUNCTION__, name.c_str(), expectedPrefix);
810 return BAD_VALUE;
811 }
812
813 // Extract major/minor versions
814 constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
815 std::string::size_type dotIdx = name.find('.', atIdx);
816 if (dotIdx == std::string::npos) {
817 ALOGE(ERROR_MSG_PREFIX
818 "does not have @<major>. version section",
819 __FUNCTION__, name.c_str());
820 return BAD_VALUE;
821 }
822 std::string::size_type typeSlashIdx = name.find('/', dotIdx);
823 if (typeSlashIdx == std::string::npos) {
824 ALOGE(ERROR_MSG_PREFIX
825 "does not have .<minor>/ version section",
826 __FUNCTION__, name.c_str());
827 return BAD_VALUE;
828 }
829
830 char *endPtr;
831 errno = 0;
832 long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
833 if (errno != 0) {
834 ALOGE(ERROR_MSG_PREFIX
835 "cannot parse major version: %s (%d)",
836 __FUNCTION__, name.c_str(), strerror(errno), errno);
837 return BAD_VALUE;
838 }
839 if (endPtr != name.c_str() + dotIdx) {
840 ALOGE(ERROR_MSG_PREFIX
841 "major version has unexpected length",
842 __FUNCTION__, name.c_str());
843 return BAD_VALUE;
844 }
845 long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
846 if (errno != 0) {
847 ALOGE(ERROR_MSG_PREFIX
848 "cannot parse minor version: %s (%d)",
849 __FUNCTION__, name.c_str(), strerror(errno), errno);
850 return BAD_VALUE;
851 }
852 if (endPtr != name.c_str() + typeSlashIdx) {
853 ALOGE(ERROR_MSG_PREFIX
854 "minor version has unexpected length",
855 __FUNCTION__, name.c_str());
856 return BAD_VALUE;
857 }
858 if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
859 ALOGE(ERROR_MSG_PREFIX
860 "major/minor version is out of range of uint16_t: %ld.%ld",
861 __FUNCTION__, name.c_str(), majorVal, minorVal);
862 return BAD_VALUE;
863 }
864
865 // Extract type and id
866
867 std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
868 if (instanceSlashIdx == std::string::npos) {
869 ALOGE(ERROR_MSG_PREFIX
870 "does not have /<type>/ component",
871 __FUNCTION__, name.c_str());
872 return BAD_VALUE;
873 }
874 std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
875
876 if (instanceSlashIdx == name.size() - 1) {
877 ALOGE(ERROR_MSG_PREFIX
878 "does not have an /<id> component",
879 __FUNCTION__, name.c_str());
880 return BAD_VALUE;
881 }
882 std::string idVal = name.substr(instanceSlashIdx + 1);
883
884#undef ERROR_MSG_PREFIX
885
886 *major = static_cast<uint16_t>(majorVal);
887 *minor = static_cast<uint16_t>(minorVal);
888 *type = typeVal;
889 *id = idVal;
890
891 return OK;
892}
893
894
895
896CameraProviderManager::ProviderInfo::~ProviderInfo() {
897 // Destruction of ProviderInfo is only supposed to happen when the respective
898 // CameraProvider interface dies, so do not unregister callbacks.
899
900}
901
902status_t CameraProviderManager::mapToStatusT(const Status& s) {
903 switch(s) {
904 case Status::OK:
905 return OK;
906 case Status::ILLEGAL_ARGUMENT:
907 return BAD_VALUE;
908 case Status::CAMERA_IN_USE:
909 return -EBUSY;
910 case Status::MAX_CAMERAS_IN_USE:
911 return -EUSERS;
912 case Status::METHOD_NOT_SUPPORTED:
913 return UNKNOWN_TRANSACTION;
914 case Status::OPERATION_NOT_SUPPORTED:
915 return INVALID_OPERATION;
916 case Status::CAMERA_DISCONNECTED:
917 return DEAD_OBJECT;
918 case Status::INTERNAL_ERROR:
919 return INVALID_OPERATION;
920 }
921 ALOGW("Unexpected HAL status code %d", s);
922 return INVALID_OPERATION;
923}
924
925const char* CameraProviderManager::statusToString(const Status& s) {
926 switch(s) {
927 case Status::OK:
928 return "OK";
929 case Status::ILLEGAL_ARGUMENT:
930 return "ILLEGAL_ARGUMENT";
931 case Status::CAMERA_IN_USE:
932 return "CAMERA_IN_USE";
933 case Status::MAX_CAMERAS_IN_USE:
934 return "MAX_CAMERAS_IN_USE";
935 case Status::METHOD_NOT_SUPPORTED:
936 return "METHOD_NOT_SUPPORTED";
937 case Status::OPERATION_NOT_SUPPORTED:
938 return "OPERATION_NOT_SUPPORTED";
939 case Status::CAMERA_DISCONNECTED:
940 return "CAMERA_DISCONNECTED";
941 case Status::INTERNAL_ERROR:
942 return "INTERNAL_ERROR";
943 }
944 ALOGW("Unexpected HAL status code %d", s);
945 return "UNKNOWN_ERROR";
946}
947
948const char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
949 switch(s) {
950 case CameraDeviceStatus::NOT_PRESENT:
951 return "NOT_PRESENT";
952 case CameraDeviceStatus::PRESENT:
953 return "PRESENT";
954 case CameraDeviceStatus::ENUMERATING:
955 return "ENUMERATING";
956 }
957 ALOGW("Unexpected HAL device status code %d", s);
958 return "UNKNOWN_STATUS";
959}
960
961const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
962 switch(s) {
963 case TorchModeStatus::NOT_AVAILABLE:
964 return "NOT_AVAILABLE";
965 case TorchModeStatus::AVAILABLE_OFF:
966 return "AVAILABLE_OFF";
967 case TorchModeStatus::AVAILABLE_ON:
968 return "AVAILABLE_ON";
969 }
970 ALOGW("Unexpected HAL torch mode status code %d", s);
971 return "UNKNOWN_STATUS";
972}
973
974} // namespace android