blob: 65633db49dc8d4e1e9c2073e3011992192707502 [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
Yin-Chia Yeh65405092017-01-13 15:42:28 -080023#include <chrono>
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -070024#include <inttypes.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080025#include <hidl/ServiceManagement.h>
Emilian Peev71c73a22017-03-21 16:35:51 +000026#include <functional>
27#include <camera_metadata_hidden.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080028
29namespace android {
30
31using namespace ::android::hardware::camera;
32using namespace ::android::hardware::camera::common::V1_0;
33
34namespace {
35// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
36// service manager
37const std::string kLegacyProviderName("legacy/0");
38
39// Slash-separated list of provider types to consider for use via the old camera API
40const std::string kStandardProviderTypes("internal/legacy");
41
42} // anonymous namespace
43
44CameraProviderManager::HardwareServiceInteractionProxy
45CameraProviderManager::sHardwareServiceInteractionProxy{};
46
47CameraProviderManager::~CameraProviderManager() {
48}
49
50status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
51 ServiceInteractionProxy* proxy) {
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080052 std::lock_guard<std::mutex> lock(mInterfaceMutex);
53 if (proxy == nullptr) {
54 ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
55 return BAD_VALUE;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080056 }
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080057 mListener = listener;
58 mServiceProxy = proxy;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080059
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080060 // Registering will trigger notifications for all already-known providers
61 bool success = mServiceProxy->registerForNotifications(
62 /* instance name, empty means no filter */ "",
63 this);
64 if (!success) {
65 ALOGE("%s: Unable to register with hardware service manager for notifications "
66 "about camera providers", __FUNCTION__);
67 return INVALID_OPERATION;
Yin-Chia Yeh65405092017-01-13 15:42:28 -080068 }
Emilian Peev5d7e5152017-02-22 15:37:48 +000069
Eino-Ville Talvala65665362017-02-24 13:07:56 -080070 // See if there's a passthrough HAL, but let's not complain if there's not
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -070071 addProviderLocked(kLegacyProviderName, /*expected*/ false);
Eino-Ville Talvala65665362017-02-24 13:07:56 -080072
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080073 return OK;
74}
75
76int CameraProviderManager::getCameraCount() const {
77 std::lock_guard<std::mutex> lock(mInterfaceMutex);
78 int count = 0;
79 for (auto& provider : mProviders) {
Yin-Chia Yehe8e9e192017-03-16 15:23:51 -070080 count += provider->mUniqueDeviceCount;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080081 }
82 return count;
83}
84
Emilian Peevf53f66e2017-04-11 14:29:43 +010085int CameraProviderManager::getAPI1CompatibleCameraCount() const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080086 std::lock_guard<std::mutex> lock(mInterfaceMutex);
87 int count = 0;
88 for (auto& provider : mProviders) {
89 if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
Emilian Peevf53f66e2017-04-11 14:29:43 +010090 for (auto& device : provider->mDevices) {
91 if (device->isAPI1Compatible()) {
92 count++;
93 }
94 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080095 }
96 }
97 return count;
98}
99
100std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
101 std::lock_guard<std::mutex> lock(mInterfaceMutex);
102 std::vector<std::string> deviceIds;
103 for (auto& provider : mProviders) {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700104 for (auto& id : provider->mUniqueCameraIds) {
105 deviceIds.push_back(id);
106 }
107 }
108 return deviceIds;
109}
110
Emilian Peevf53f66e2017-04-11 14:29:43 +0100111std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds() const {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700112 std::lock_guard<std::mutex> lock(mInterfaceMutex);
113 std::vector<std::string> deviceIds;
114 for (auto& provider : mProviders) {
115 if (kStandardProviderTypes.find(provider->getType()) != std::string::npos) {
Emilian Peevf53f66e2017-04-11 14:29:43 +0100116 for (auto& device : provider->mDevices) {
117 if (device->isAPI1Compatible()) {
118 deviceIds.push_back(device->mId);
119 }
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700120 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800121 }
122 }
123 return deviceIds;
124}
125
126bool CameraProviderManager::isValidDevice(const std::string &id, uint16_t majorVersion) const {
127 std::lock_guard<std::mutex> lock(mInterfaceMutex);
128 return isValidDeviceLocked(id, majorVersion);
129}
130
131bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const {
132 for (auto& provider : mProviders) {
133 for (auto& deviceInfo : provider->mDevices) {
134 if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion) {
135 return true;
136 }
137 }
138 }
139 return false;
140}
141
142bool CameraProviderManager::hasFlashUnit(const std::string &id) const {
143 std::lock_guard<std::mutex> lock(mInterfaceMutex);
144
145 auto deviceInfo = findDeviceInfoLocked(id);
146 if (deviceInfo == nullptr) return false;
147
148 return deviceInfo->hasFlashUnit();
149}
150
151status_t CameraProviderManager::getResourceCost(const std::string &id,
152 CameraResourceCost* cost) const {
153 std::lock_guard<std::mutex> lock(mInterfaceMutex);
154
155 auto deviceInfo = findDeviceInfoLocked(id);
156 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
157
158 *cost = deviceInfo->mResourceCost;
159 return OK;
160}
161
162status_t CameraProviderManager::getCameraInfo(const std::string &id,
163 hardware::CameraInfo* info) const {
164 std::lock_guard<std::mutex> lock(mInterfaceMutex);
165
166 auto deviceInfo = findDeviceInfoLocked(id);
167 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
168
169 return deviceInfo->getCameraInfo(info);
170}
171
172status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
173 CameraMetadata* characteristics) const {
174 std::lock_guard<std::mutex> lock(mInterfaceMutex);
175
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800176 auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800177 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
178
179 return deviceInfo->getCameraCharacteristics(characteristics);
180}
181
182status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
183 hardware::hidl_version *v) {
184 std::lock_guard<std::mutex> lock(mInterfaceMutex);
185
186 hardware::hidl_version maxVersion{0,0};
187 bool found = false;
188 for (auto& provider : mProviders) {
189 for (auto& deviceInfo : provider->mDevices) {
190 if (deviceInfo->mId == id) {
191 if (deviceInfo->mVersion > maxVersion) {
192 maxVersion = deviceInfo->mVersion;
193 found = true;
194 }
195 }
196 }
197 }
198 if (!found) {
199 return NAME_NOT_FOUND;
200 }
201 *v = maxVersion;
202 return OK;
203}
204
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700205bool CameraProviderManager::supportSetTorchMode(const std::string &id) {
206 std::lock_guard<std::mutex> lock(mInterfaceMutex);
207 bool support = false;
208 for (auto& provider : mProviders) {
209 auto deviceInfo = findDeviceInfoLocked(id);
210 if (deviceInfo != nullptr) {
211 provider->mInterface->isSetTorchModeSupported(
212 [&support](auto status, bool supported) {
213 if (status == Status::OK) {
214 support = supported;
215 }
216 });
217 }
218 }
219 return support;
220}
221
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800222status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
223 std::lock_guard<std::mutex> lock(mInterfaceMutex);
224
225 auto deviceInfo = findDeviceInfoLocked(id);
226 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
227
228 return deviceInfo->setTorchMode(enabled);
229}
230
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800231status_t CameraProviderManager::setUpVendorTags() {
Emilian Peev71c73a22017-03-21 16:35:51 +0000232 sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
233
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800234 for (auto& provider : mProviders) {
235 hardware::hidl_vec<VendorTagSection> vts;
236 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700237 hardware::Return<void> ret;
238 ret = provider->mInterface->getVendorTags(
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800239 [&](auto s, const auto& vendorTagSecs) {
240 status = s;
241 if (s == Status::OK) {
242 vts = vendorTagSecs;
243 }
244 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700245 if (!ret.isOk()) {
246 ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
247 __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
248 return DEAD_OBJECT;
249 }
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800250 if (status != Status::OK) {
251 return mapToStatusT(status);
252 }
253
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800254 // Read all vendor tag definitions into a descriptor
255 sp<VendorTagDescriptor> desc;
256 status_t res;
257 if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/desc))
258 != OK) {
259 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
260 "received error %s (%d). Camera clients will not be able to use"
261 "vendor tags", __FUNCTION__, strerror(res), res);
262 return res;
263 }
264
Emilian Peev71c73a22017-03-21 16:35:51 +0000265 tagCache->addVendorDescriptor(provider->mProviderTagid, desc);
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800266 }
Emilian Peev71c73a22017-03-21 16:35:51 +0000267
268 VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
269
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800270 return OK;
271}
272
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800273status_t CameraProviderManager::openSession(const std::string &id,
274 const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
275 /*out*/
276 sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
277
278 std::lock_guard<std::mutex> lock(mInterfaceMutex);
279
280 auto deviceInfo = findDeviceInfoLocked(id,
281 /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
282 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
283
284 auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
285
286 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700287 hardware::Return<void> ret;
288 ret = deviceInfo3->mInterface->open(callback, [&status, &session]
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800289 (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
290 status = s;
291 if (status == Status::OK) {
292 *session = cameraSession;
293 }
294 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700295 if (!ret.isOk()) {
296 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
297 __FUNCTION__, id.c_str(), ret.description().c_str());
298 return DEAD_OBJECT;
299 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800300 return mapToStatusT(status);
301}
302
303status_t CameraProviderManager::openSession(const std::string &id,
304 const sp<hardware::camera::device::V1_0::ICameraDeviceCallback>& callback,
305 /*out*/
306 sp<hardware::camera::device::V1_0::ICameraDevice> *session) {
307
308 std::lock_guard<std::mutex> lock(mInterfaceMutex);
309
310 auto deviceInfo = findDeviceInfoLocked(id,
311 /*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
312 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
313
314 auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
315
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700316 hardware::Return<Status> status = deviceInfo1->mInterface->open(callback);
317 if (!status.isOk()) {
318 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
319 __FUNCTION__, id.c_str(), status.description().c_str());
320 return DEAD_OBJECT;
321 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800322 if (status == Status::OK) {
323 *session = deviceInfo1->mInterface;
324 }
325 return mapToStatusT(status);
326}
327
328
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800329hardware::Return<void> CameraProviderManager::onRegistration(
330 const hardware::hidl_string& /*fqName*/,
331 const hardware::hidl_string& name,
332 bool /*preexisting*/) {
Emilian Peevaee727d2017-05-04 16:35:48 +0100333 {
334 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800335
Emilian Peevaee727d2017-05-04 16:35:48 +0100336 addProviderLocked(name);
337 }
338
339 sp<StatusListener> listener = getStatusListener();
340 if (nullptr != listener.get()) {
341 listener->onNewProviderRegistered();
342 }
343
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800344 return hardware::Return<void>();
345}
346
347status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
348 std::lock_guard<std::mutex> lock(mInterfaceMutex);
349
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800350 for (auto& provider : mProviders) {
351 provider->dump(fd, args);
352 }
353 return OK;
354}
355
356CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800357 const std::string& id,
358 hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800359 for (auto& provider : mProviders) {
360 for (auto& deviceInfo : provider->mDevices) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800361 if (deviceInfo->mId == id &&
362 minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800363 return deviceInfo.get();
364 }
365 }
366 }
367 return nullptr;
368}
369
Emilian Peev71c73a22017-03-21 16:35:51 +0000370metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
371 const std::string& id, hardware::hidl_version minVersion,
372 hardware::hidl_version maxVersion) const {
373 metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;
374
375 std::lock_guard<std::mutex> lock(mInterfaceMutex);
376 for (auto& provider : mProviders) {
377 for (auto& deviceInfo : provider->mDevices) {
378 if (deviceInfo->mId == id &&
379 minVersion <= deviceInfo->mVersion &&
380 maxVersion >= deviceInfo->mVersion) {
381 return provider->mProviderTagid;
382 }
383 }
384 }
385
386 return ret;
387}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800388
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700389status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800390 for (const auto& providerInfo : mProviders) {
391 if (providerInfo->mProviderName == newProvider) {
392 ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
393 newProvider.c_str());
394 return ALREADY_EXISTS;
395 }
396 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700397
398 sp<provider::V2_4::ICameraProvider> interface;
399 interface = mServiceProxy->getService(newProvider);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800400
401 if (interface == nullptr) {
402 if (expected) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700403 ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
404 newProvider.c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800405 return BAD_VALUE;
406 } else {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800407 return OK;
408 }
409 }
410
411 sp<ProviderInfo> providerInfo =
412 new ProviderInfo(newProvider, interface, this);
413 status_t res = providerInfo->initialize();
414 if (res != OK) {
415 return res;
416 }
417
418 mProviders.push_back(providerInfo);
419
420 return OK;
421}
422
423status_t CameraProviderManager::removeProvider(const std::string& provider) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700424 std::unique_lock<std::mutex> lock(mInterfaceMutex);
425 std::vector<String8> removedDeviceIds;
426 status_t res = NAME_NOT_FOUND;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800427 for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
428 if ((*it)->mProviderName == provider) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700429 removedDeviceIds.reserve((*it)->mDevices.size());
430 for (auto& deviceInfo : (*it)->mDevices) {
431 removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
432 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800433 mProviders.erase(it);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700434 res = OK;
435 break;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800436 }
437 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700438 if (res != OK) {
439 ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
440 provider.c_str());
441 } else {
442 // Inform camera service of loss of presence for all the devices from this provider,
443 // without lock held for reentrancy
444 sp<StatusListener> listener = getStatusListener();
445 if (listener != nullptr) {
446 lock.unlock();
447 for (auto& id : removedDeviceIds) {
448 listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
449 }
450 }
451 }
452 return res;
453}
454
455sp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListener() const {
456 return mListener.promote();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800457}
458
459/**** Methods for ProviderInfo ****/
460
461
462CameraProviderManager::ProviderInfo::ProviderInfo(
463 const std::string &providerName,
464 sp<provider::V2_4::ICameraProvider>& interface,
465 CameraProviderManager *manager) :
466 mProviderName(providerName),
467 mInterface(interface),
Emilian Peev71c73a22017-03-21 16:35:51 +0000468 mProviderTagid(generateVendorTagId(providerName)),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800469 mManager(manager) {
470 (void) mManager;
471}
472
473status_t CameraProviderManager::ProviderInfo::initialize() {
474 status_t res = parseProviderName(mProviderName, &mType, &mId);
475 if (res != OK) {
476 ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
477 return BAD_VALUE;
478 }
Yin-Chia Yeh65405092017-01-13 15:42:28 -0800479 ALOGI("Connecting to new camera provider: %s, isRemote? %d",
480 mProviderName.c_str(), mInterface->isRemote());
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700481 hardware::Return<Status> status = mInterface->setCallback(this);
482 if (!status.isOk()) {
483 ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
484 __FUNCTION__, mProviderName.c_str(), status.description().c_str());
485 return DEAD_OBJECT;
486 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800487 if (status != Status::OK) {
488 ALOGE("%s: Unable to register callbacks with camera provider '%s'",
489 __FUNCTION__, mProviderName.c_str());
490 return mapToStatusT(status);
491 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700492
493 hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
494 if (!linked.isOk()) {
495 ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
496 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
497 return DEAD_OBJECT;
498 } else if (!linked) {
499 ALOGW("%s: Unable to link to provider '%s' death notifications",
500 __FUNCTION__, mProviderName.c_str());
501 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800502
503 // Get initial list of camera devices, if any
504 std::vector<std::string> devices;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700505 hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800506 Status idStatus,
507 const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
508 status = idStatus;
509 if (status == Status::OK) {
510 for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
511 devices.push_back(cameraDeviceNames[i]);
512 }
513 } });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700514 if (!ret.isOk()) {
515 ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
516 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
517 return DEAD_OBJECT;
518 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800519 if (status != Status::OK) {
520 ALOGE("%s: Unable to query for camera devices from provider '%s'",
521 __FUNCTION__, mProviderName.c_str());
522 return mapToStatusT(status);
523 }
524
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700525 sp<StatusListener> listener = mManager->getStatusListener();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800526 for (auto& device : devices) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700527 std::string id;
528 status_t res = addDevice(device,
529 hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800530 if (res != OK) {
531 ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
532 __FUNCTION__, device.c_str(), strerror(-res), res);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700533 continue;
534 }
535 if (listener != nullptr) {
536 listener->onDeviceStatusChanged(String8(id.c_str()), CameraDeviceStatus::PRESENT);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800537 }
538 }
539
Yin-Chia Yehe8e9e192017-03-16 15:23:51 -0700540 for (auto& device : mDevices) {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700541 mUniqueCameraIds.insert(device->mId);
Yin-Chia Yehe8e9e192017-03-16 15:23:51 -0700542 }
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700543 mUniqueDeviceCount = mUniqueCameraIds.size();
Yin-Chia Yehe8e9e192017-03-16 15:23:51 -0700544
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800545 ALOGI("Camera provider %s ready with %zu camera devices",
546 mProviderName.c_str(), mDevices.size());
547
548 return OK;
549}
550
551const std::string& CameraProviderManager::ProviderInfo::getType() const {
552 return mType;
553}
554
555status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
556 CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
557
558 ALOGI("Enumerating new camera device: %s", name.c_str());
559
560 uint16_t major, minor;
561 std::string type, id;
562
563 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
564 if (res != OK) {
565 return res;
566 }
567 if (type != mType) {
568 ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
569 type.c_str(), mType.c_str());
570 return BAD_VALUE;
571 }
572 if (mManager->isValidDeviceLocked(id, major)) {
573 ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
574 name.c_str(), id.c_str(), major);
575 return BAD_VALUE;
576 }
577
578 std::unique_ptr<DeviceInfo> deviceInfo;
579 switch (major) {
580 case 1:
Emilian Peev71c73a22017-03-21 16:35:51 +0000581 deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
582 id, minor);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800583 break;
584 case 3:
Emilian Peev71c73a22017-03-21 16:35:51 +0000585 deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
586 id, minor);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800587 break;
588 default:
589 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
590 name.c_str(), major);
591 return BAD_VALUE;
592 }
593 if (deviceInfo == nullptr) return BAD_VALUE;
594 deviceInfo->mStatus = initialStatus;
595
596 mDevices.push_back(std::move(deviceInfo));
597
598 if (parsedId != nullptr) {
599 *parsedId = id;
600 }
601 return OK;
602}
603
604status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700605 dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
606 mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
607 mDevices.size());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800608
609 for (auto& device : mDevices) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800610 dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
611 device->mVersion.get_major(), device->mVersion.get_minor());
612 dprintf(fd, " Resource cost: %d\n", device->mResourceCost.resourceCost);
613 if (device->mResourceCost.conflictingDevices.size() == 0) {
614 dprintf(fd, " Conflicting devices: None\n");
615 } else {
616 dprintf(fd, " Conflicting devices:\n");
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800617 for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800618 dprintf(fd, " %s\n",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800619 device->mResourceCost.conflictingDevices[i].c_str());
620 }
621 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800622 dprintf(fd, " API1 info:\n");
623 dprintf(fd, " Has a flash unit: %s\n",
624 device->hasFlashUnit() ? "true" : "false");
625 hardware::CameraInfo info;
626 status_t res = device->getCameraInfo(&info);
627 if (res != OK) {
628 dprintf(fd, " <Error reading camera info: %s (%d)>\n",
629 strerror(-res), res);
630 } else {
631 dprintf(fd, " Facing: %s\n",
632 info.facing == hardware::CAMERA_FACING_BACK ? "Back" : "Front");
633 dprintf(fd, " Orientation: %d\n", info.orientation);
634 }
635 CameraMetadata info2;
636 res = device->getCameraCharacteristics(&info2);
637 if (res == INVALID_OPERATION) {
638 dprintf(fd, " API2 not directly supported\n");
639 } else if (res != OK) {
640 dprintf(fd, " <Error reading camera characteristics: %s (%d)>\n",
641 strerror(-res), res);
642 } else {
643 dprintf(fd, " API2 camera characteristics:\n");
644 info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
645 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800646 }
647 return OK;
648}
649
650hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
651 const hardware::hidl_string& cameraDeviceName,
652 CameraDeviceStatus newStatus) {
653 sp<StatusListener> listener;
654 std::string id;
655 {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700656 std::lock_guard<std::mutex> lock(mLock);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800657 bool known = false;
658 for (auto& deviceInfo : mDevices) {
659 if (deviceInfo->mName == cameraDeviceName) {
660 ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
661 deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
662 deviceInfo->mStatus = newStatus;
663 // TODO: Handle device removal (NOT_PRESENT)
664 id = deviceInfo->mId;
665 known = true;
666 break;
667 }
668 }
669 // Previously unseen device; status must not be NOT_PRESENT
670 if (!known) {
671 if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
672 ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
673 mProviderName.c_str(), cameraDeviceName.c_str());
674 return hardware::Void();
675 }
676 addDevice(cameraDeviceName, newStatus, &id);
677 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700678 listener = mManager->getStatusListener();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800679 }
680 // Call without lock held to allow reentrancy into provider manager
681 if (listener != nullptr) {
682 listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
683 }
684 return hardware::Void();
685}
686
687hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
688 const hardware::hidl_string& cameraDeviceName,
689 TorchModeStatus newStatus) {
690 sp<StatusListener> listener;
691 std::string id;
692 {
Yin-Chia Yeh52778d42016-12-22 18:20:43 -0800693 std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800694 bool known = false;
695 for (auto& deviceInfo : mDevices) {
696 if (deviceInfo->mName == cameraDeviceName) {
697 ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
698 torchStatusToString(newStatus));
699 id = deviceInfo->mId;
700 known = true;
701 break;
702 }
703 }
704 if (!known) {
705 ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
706 mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
707 return hardware::Void();
708 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700709 listener = mManager->getStatusListener();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800710 }
711 // Call without lock held to allow reentrancy into provider manager
712 if (listener != nullptr) {
713 listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
714 }
715 return hardware::Void();
716}
717
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700718void CameraProviderManager::ProviderInfo::serviceDied(uint64_t cookie,
719 const wp<hidl::base::V1_0::IBase>& who) {
720 (void) who;
721 ALOGI("Camera provider '%s' has died; removing it", mProviderName.c_str());
722 if (cookie != mId) {
723 ALOGW("%s: Unexpected serviceDied cookie %" PRIu64 ", expected %" PRIu32,
724 __FUNCTION__, cookie, mId);
725 }
726 mManager->removeProvider(mProviderName);
727}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800728
729template<class DeviceInfoT>
730std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
731 CameraProviderManager::ProviderInfo::initializeDeviceInfo(
Emilian Peev71c73a22017-03-21 16:35:51 +0000732 const std::string &name, const metadata_vendor_id_t tagId,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800733 const std::string &id, uint16_t minorVersion) const {
734 Status status;
735
736 auto cameraInterface =
737 getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
738 if (cameraInterface == nullptr) return nullptr;
739
740 CameraResourceCost resourceCost;
741 cameraInterface->getResourceCost([&status, &resourceCost](
742 Status s, CameraResourceCost cost) {
743 status = s;
744 resourceCost = cost;
745 });
746 if (status != Status::OK) {
747 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
748 name.c_str(), statusToString(status));
749 return nullptr;
750 }
751 return std::unique_ptr<DeviceInfo>(
Emilian Peev71c73a22017-03-21 16:35:51 +0000752 new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,
753 cameraInterface));
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800754}
755
756template<class InterfaceT>
757sp<InterfaceT>
758CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
759 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
760 name.c_str(), InterfaceT::version.get_major());
761 return nullptr;
762}
763
764template<>
765sp<device::V1_0::ICameraDevice>
766CameraProviderManager::ProviderInfo::getDeviceInterface
767 <device::V1_0::ICameraDevice>(const std::string &name) const {
768 Status status;
769 sp<device::V1_0::ICameraDevice> cameraInterface;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700770 hardware::Return<void> ret;
771 ret = mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800772 Status s, sp<device::V1_0::ICameraDevice> interface) {
773 status = s;
774 cameraInterface = interface;
775 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700776 if (!ret.isOk()) {
777 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
778 __FUNCTION__, name.c_str(), ret.description().c_str());
779 return nullptr;
780 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800781 if (status != Status::OK) {
782 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
783 name.c_str(), statusToString(status));
784 return nullptr;
785 }
786 return cameraInterface;
787}
788
789template<>
790sp<device::V3_2::ICameraDevice>
791CameraProviderManager::ProviderInfo::getDeviceInterface
792 <device::V3_2::ICameraDevice>(const std::string &name) const {
793 Status status;
794 sp<device::V3_2::ICameraDevice> cameraInterface;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700795 hardware::Return<void> ret;
796 ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800797 Status s, sp<device::V3_2::ICameraDevice> interface) {
798 status = s;
799 cameraInterface = interface;
800 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700801 if (!ret.isOk()) {
802 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
803 __FUNCTION__, name.c_str(), ret.description().c_str());
804 return nullptr;
805 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800806 if (status != Status::OK) {
807 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
808 name.c_str(), statusToString(status));
809 return nullptr;
810 }
811 return cameraInterface;
812}
813
814CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
815
816template<class InterfaceT>
817status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
818 bool enabled) {
819 Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
820 return mapToStatusT(s);
821}
822
823CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
Emilian Peev71c73a22017-03-21 16:35:51 +0000824 const metadata_vendor_id_t tagId, const std::string &id,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800825 uint16_t minorVersion,
826 const CameraResourceCost& resourceCost,
827 sp<InterfaceT> interface) :
Emilian Peev71c73a22017-03-21 16:35:51 +0000828 DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
829 resourceCost),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800830 mInterface(interface) {
831 // Get default parameters and initialize flash unit availability
832 // Requires powering on the camera device
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700833 hardware::Return<Status> status = mInterface->open(nullptr);
834 if (!status.isOk()) {
835 ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
836 __FUNCTION__, mId.c_str(), status.description().c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800837 return;
838 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700839 if (status != Status::OK) {
840 ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
841 mId.c_str(), CameraProviderManager::statusToString(status));
842 return;
843 }
844 hardware::Return<void> ret;
845 ret = mInterface->getParameters([this](const hardware::hidl_string& parms) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800846 mDefaultParameters.unflatten(String8(parms.c_str()));
847 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700848 if (!ret.isOk()) {
849 ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
850 __FUNCTION__, mId.c_str(), status.description().c_str());
851 return;
852 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800853 const char *flashMode =
854 mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
855 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
856 mHasFlashUnit = true;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800857 }
858
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700859 ret = mInterface->close();
860 if (!ret.isOk()) {
861 ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
862 __FUNCTION__, mId.c_str(), status.description().c_str());
863 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800864}
865
866CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
867
868status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
869 return DeviceInfo::setTorchMode(mInterface, enabled);
870}
871
872status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
873 hardware::CameraInfo *info) const {
874 if (info == nullptr) return BAD_VALUE;
875
876 Status status;
877 device::V1_0::CameraInfo cInfo;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700878 hardware::Return<void> ret;
879 ret = mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800880 status = s;
881 cInfo = camInfo;
882 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700883 if (!ret.isOk()) {
884 ALOGE("%s: Transaction error reading camera info from device %s: %s",
885 __FUNCTION__, mId.c_str(), ret.description().c_str());
886 return DEAD_OBJECT;
887 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800888 if (status != Status::OK) {
889 return mapToStatusT(status);
890 }
891
892 switch(cInfo.facing) {
893 case device::V1_0::CameraFacing::BACK:
894 info->facing = hardware::CAMERA_FACING_BACK;
895 break;
896 case device::V1_0::CameraFacing::EXTERNAL:
897 // Map external to front for legacy API
898 case device::V1_0::CameraFacing::FRONT:
899 info->facing = hardware::CAMERA_FACING_FRONT;
900 break;
901 default:
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700902 ALOGW("%s: Device %s: Unknown camera facing: %d",
903 __FUNCTION__, mId.c_str(), cInfo.facing);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800904 info->facing = hardware::CAMERA_FACING_BACK;
905 }
906 info->orientation = cInfo.orientation;
907
908 return OK;
909}
910
911CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
Emilian Peev71c73a22017-03-21 16:35:51 +0000912 const metadata_vendor_id_t tagId, const std::string &id,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800913 uint16_t minorVersion,
914 const CameraResourceCost& resourceCost,
915 sp<InterfaceT> interface) :
Emilian Peev71c73a22017-03-21 16:35:51 +0000916 DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
917 resourceCost),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800918 mInterface(interface) {
919 // Get camera characteristics and initialize flash unit availability
920 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700921 hardware::Return<void> ret;
922 ret = mInterface->getCameraCharacteristics([&status, this](Status s,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800923 device::V3_2::CameraMetadata metadata) {
924 status = s;
925 if (s == Status::OK) {
926 camera_metadata_t *buffer =
927 reinterpret_cast<camera_metadata_t*>(metadata.data());
Yin-Chia Yeh238ef5f2017-04-18 15:01:15 -0700928 size_t expectedSize = metadata.size();
929 int res = validate_camera_metadata_structure(buffer, &expectedSize);
930 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
931 set_camera_metadata_vendor_id(buffer, mProviderTagid);
932 mCameraCharacteristics = buffer;
933 } else {
934 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
935 status = Status::INTERNAL_ERROR;
936 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800937 }
938 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700939 if (!ret.isOk()) {
940 ALOGE("%s: Transaction error getting camera characteristics for device %s"
941 " to check for a flash unit: %s", __FUNCTION__, mId.c_str(),
942 ret.description().c_str());
943 return;
944 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800945 if (status != Status::OK) {
946 ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
947 __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
948 return;
949 }
950 camera_metadata_entry flashAvailable =
951 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
952 if (flashAvailable.count == 1 &&
953 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
954 mHasFlashUnit = true;
955 } else {
956 mHasFlashUnit = false;
957 }
958}
959
960CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
961
962status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
963 return DeviceInfo::setTorchMode(mInterface, enabled);
964}
965
966status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
967 hardware::CameraInfo *info) const {
968 if (info == nullptr) return BAD_VALUE;
969
970 camera_metadata_ro_entry facing =
971 mCameraCharacteristics.find(ANDROID_LENS_FACING);
972 if (facing.count == 1) {
973 switch (facing.data.u8[0]) {
974 case ANDROID_LENS_FACING_BACK:
975 info->facing = hardware::CAMERA_FACING_BACK;
976 break;
977 case ANDROID_LENS_FACING_EXTERNAL:
978 // Map external to front for legacy API
979 case ANDROID_LENS_FACING_FRONT:
980 info->facing = hardware::CAMERA_FACING_FRONT;
981 break;
982 }
983 } else {
984 ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
985 return NAME_NOT_FOUND;
986 }
987
988 camera_metadata_ro_entry orientation =
989 mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
990 if (orientation.count == 1) {
991 info->orientation = orientation.data.i32[0];
992 } else {
993 ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
994 return NAME_NOT_FOUND;
995 }
996
997 return OK;
998}
Emilian Peevf53f66e2017-04-11 14:29:43 +0100999bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const {
1000 bool isBackwardCompatible = false;
1001 camera_metadata_ro_entry_t caps = mCameraCharacteristics.find(
1002 ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1003 for (size_t i = 0; i < caps.count; i++) {
1004 if (caps.data.u8[i] ==
1005 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1006 isBackwardCompatible = true;
1007 break;
1008 }
1009 }
1010
1011 return isBackwardCompatible;
1012}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001013
1014status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
1015 CameraMetadata *characteristics) const {
1016 if (characteristics == nullptr) return BAD_VALUE;
1017
1018 *characteristics = mCameraCharacteristics;
1019 return OK;
1020}
1021
1022status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
1023 std::string *type, uint32_t *id) {
1024 // Format must be "<type>/<id>"
1025#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. " \
1026 "Should match '<type>/<id>' - "
1027
1028 if (!type || !id) return INVALID_OPERATION;
1029
1030 std::string::size_type slashIdx = name.find('/');
1031 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
1032 ALOGE(ERROR_MSG_PREFIX
1033 "does not have / separator between type and id",
1034 __FUNCTION__, name.c_str());
1035 return BAD_VALUE;
1036 }
1037
1038 std::string typeVal = name.substr(0, slashIdx);
1039
1040 char *endPtr;
1041 errno = 0;
1042 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
1043 if (errno != 0) {
1044 ALOGE(ERROR_MSG_PREFIX
1045 "cannot parse provider id as an integer: %s (%d)",
1046 __FUNCTION__, name.c_str(), strerror(errno), errno);
1047 return BAD_VALUE;
1048 }
1049 if (endPtr != name.c_str() + name.size()) {
1050 ALOGE(ERROR_MSG_PREFIX
1051 "provider id has unexpected length",
1052 __FUNCTION__, name.c_str());
1053 return BAD_VALUE;
1054 }
1055 if (idVal < 0) {
1056 ALOGE(ERROR_MSG_PREFIX
1057 "id is negative: %ld",
1058 __FUNCTION__, name.c_str(), idVal);
1059 return BAD_VALUE;
1060 }
1061
1062#undef ERROR_MSG_PREFIX
1063
1064 *type = typeVal;
1065 *id = static_cast<uint32_t>(idVal);
1066
1067 return OK;
1068}
1069
Emilian Peev71c73a22017-03-21 16:35:51 +00001070metadata_vendor_id_t CameraProviderManager::ProviderInfo::generateVendorTagId(
1071 const std::string &name) {
1072 metadata_vendor_id_t ret = std::hash<std::string> {} (name);
1073 // CAMERA_METADATA_INVALID_VENDOR_ID is not a valid hash value
1074 if (CAMERA_METADATA_INVALID_VENDOR_ID == ret) {
1075 ret = 0;
1076 }
1077
1078 return ret;
1079}
1080
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001081status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
1082 uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
1083
1084 // Format must be "device@<major>.<minor>/<type>/<id>"
1085
1086#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
1087 "Should match 'device@<major>.<minor>/<type>/<id>' - "
1088
1089 if (!major || !minor || !type || !id) return INVALID_OPERATION;
1090
1091 // Verify starting prefix
1092 const char expectedPrefix[] = "device@";
1093
1094 if (name.find(expectedPrefix) != 0) {
1095 ALOGE(ERROR_MSG_PREFIX
1096 "does not start with '%s'",
1097 __FUNCTION__, name.c_str(), expectedPrefix);
1098 return BAD_VALUE;
1099 }
1100
1101 // Extract major/minor versions
1102 constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
1103 std::string::size_type dotIdx = name.find('.', atIdx);
1104 if (dotIdx == std::string::npos) {
1105 ALOGE(ERROR_MSG_PREFIX
1106 "does not have @<major>. version section",
1107 __FUNCTION__, name.c_str());
1108 return BAD_VALUE;
1109 }
1110 std::string::size_type typeSlashIdx = name.find('/', dotIdx);
1111 if (typeSlashIdx == std::string::npos) {
1112 ALOGE(ERROR_MSG_PREFIX
1113 "does not have .<minor>/ version section",
1114 __FUNCTION__, name.c_str());
1115 return BAD_VALUE;
1116 }
1117
1118 char *endPtr;
1119 errno = 0;
1120 long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
1121 if (errno != 0) {
1122 ALOGE(ERROR_MSG_PREFIX
1123 "cannot parse major version: %s (%d)",
1124 __FUNCTION__, name.c_str(), strerror(errno), errno);
1125 return BAD_VALUE;
1126 }
1127 if (endPtr != name.c_str() + dotIdx) {
1128 ALOGE(ERROR_MSG_PREFIX
1129 "major version has unexpected length",
1130 __FUNCTION__, name.c_str());
1131 return BAD_VALUE;
1132 }
1133 long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
1134 if (errno != 0) {
1135 ALOGE(ERROR_MSG_PREFIX
1136 "cannot parse minor version: %s (%d)",
1137 __FUNCTION__, name.c_str(), strerror(errno), errno);
1138 return BAD_VALUE;
1139 }
1140 if (endPtr != name.c_str() + typeSlashIdx) {
1141 ALOGE(ERROR_MSG_PREFIX
1142 "minor version has unexpected length",
1143 __FUNCTION__, name.c_str());
1144 return BAD_VALUE;
1145 }
1146 if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
1147 ALOGE(ERROR_MSG_PREFIX
1148 "major/minor version is out of range of uint16_t: %ld.%ld",
1149 __FUNCTION__, name.c_str(), majorVal, minorVal);
1150 return BAD_VALUE;
1151 }
1152
1153 // Extract type and id
1154
1155 std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
1156 if (instanceSlashIdx == std::string::npos) {
1157 ALOGE(ERROR_MSG_PREFIX
1158 "does not have /<type>/ component",
1159 __FUNCTION__, name.c_str());
1160 return BAD_VALUE;
1161 }
1162 std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
1163
1164 if (instanceSlashIdx == name.size() - 1) {
1165 ALOGE(ERROR_MSG_PREFIX
1166 "does not have an /<id> component",
1167 __FUNCTION__, name.c_str());
1168 return BAD_VALUE;
1169 }
1170 std::string idVal = name.substr(instanceSlashIdx + 1);
1171
1172#undef ERROR_MSG_PREFIX
1173
1174 *major = static_cast<uint16_t>(majorVal);
1175 *minor = static_cast<uint16_t>(minorVal);
1176 *type = typeVal;
1177 *id = idVal;
1178
1179 return OK;
1180}
1181
1182
1183
1184CameraProviderManager::ProviderInfo::~ProviderInfo() {
1185 // Destruction of ProviderInfo is only supposed to happen when the respective
1186 // CameraProvider interface dies, so do not unregister callbacks.
1187
1188}
1189
1190status_t CameraProviderManager::mapToStatusT(const Status& s) {
1191 switch(s) {
1192 case Status::OK:
1193 return OK;
1194 case Status::ILLEGAL_ARGUMENT:
1195 return BAD_VALUE;
1196 case Status::CAMERA_IN_USE:
1197 return -EBUSY;
1198 case Status::MAX_CAMERAS_IN_USE:
1199 return -EUSERS;
1200 case Status::METHOD_NOT_SUPPORTED:
1201 return UNKNOWN_TRANSACTION;
1202 case Status::OPERATION_NOT_SUPPORTED:
1203 return INVALID_OPERATION;
1204 case Status::CAMERA_DISCONNECTED:
1205 return DEAD_OBJECT;
1206 case Status::INTERNAL_ERROR:
1207 return INVALID_OPERATION;
1208 }
1209 ALOGW("Unexpected HAL status code %d", s);
1210 return INVALID_OPERATION;
1211}
1212
1213const char* CameraProviderManager::statusToString(const Status& s) {
1214 switch(s) {
1215 case Status::OK:
1216 return "OK";
1217 case Status::ILLEGAL_ARGUMENT:
1218 return "ILLEGAL_ARGUMENT";
1219 case Status::CAMERA_IN_USE:
1220 return "CAMERA_IN_USE";
1221 case Status::MAX_CAMERAS_IN_USE:
1222 return "MAX_CAMERAS_IN_USE";
1223 case Status::METHOD_NOT_SUPPORTED:
1224 return "METHOD_NOT_SUPPORTED";
1225 case Status::OPERATION_NOT_SUPPORTED:
1226 return "OPERATION_NOT_SUPPORTED";
1227 case Status::CAMERA_DISCONNECTED:
1228 return "CAMERA_DISCONNECTED";
1229 case Status::INTERNAL_ERROR:
1230 return "INTERNAL_ERROR";
1231 }
1232 ALOGW("Unexpected HAL status code %d", s);
1233 return "UNKNOWN_ERROR";
1234}
1235
1236const char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
1237 switch(s) {
1238 case CameraDeviceStatus::NOT_PRESENT:
1239 return "NOT_PRESENT";
1240 case CameraDeviceStatus::PRESENT:
1241 return "PRESENT";
1242 case CameraDeviceStatus::ENUMERATING:
1243 return "ENUMERATING";
1244 }
1245 ALOGW("Unexpected HAL device status code %d", s);
1246 return "UNKNOWN_STATUS";
1247}
1248
1249const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
1250 switch(s) {
1251 case TorchModeStatus::NOT_AVAILABLE:
1252 return "NOT_AVAILABLE";
1253 case TorchModeStatus::AVAILABLE_OFF:
1254 return "AVAILABLE_OFF";
1255 case TorchModeStatus::AVAILABLE_ON:
1256 return "AVAILABLE_ON";
1257 }
1258 ALOGW("Unexpected HAL torch mode status code %d", s);
1259 return "UNKNOWN_STATUS";
1260}
1261
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001262
1263status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
1264 const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
1265 /*out*/
1266 sp<VendorTagDescriptor>& descriptor) {
1267
1268 int tagCount = 0;
1269
1270 for (size_t s = 0; s < vts.size(); s++) {
1271 tagCount += vts[s].tags.size();
1272 }
1273
1274 if (tagCount < 0 || tagCount > INT32_MAX) {
1275 ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
1276 return BAD_VALUE;
1277 }
1278
1279 Vector<uint32_t> tagArray;
1280 LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
1281 "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
1282
1283
1284 sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
1285 desc->mTagCount = tagCount;
1286
1287 SortedVector<String8> sections;
1288 KeyedVector<uint32_t, String8> tagToSectionMap;
1289
1290 int idx = 0;
1291 for (size_t s = 0; s < vts.size(); s++) {
1292 const hardware::camera::common::V1_0::VendorTagSection& section = vts[s];
1293 const char *sectionName = section.sectionName.c_str();
1294 if (sectionName == NULL) {
1295 ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
1296 return BAD_VALUE;
1297 }
1298 String8 sectionString(sectionName);
1299 sections.add(sectionString);
1300
1301 for (size_t j = 0; j < section.tags.size(); j++) {
1302 uint32_t tag = section.tags[j].tagId;
1303 if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
1304 ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
1305 return BAD_VALUE;
1306 }
1307
1308 tagArray.editItemAt(idx++) = section.tags[j].tagId;
1309
1310 const char *tagName = section.tags[j].tagName.c_str();
1311 if (tagName == NULL) {
1312 ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
1313 return BAD_VALUE;
1314 }
1315 desc->mTagToNameMap.add(tag, String8(tagName));
1316 tagToSectionMap.add(tag, sectionString);
1317
1318 int tagType = (int) section.tags[j].tagType;
1319 if (tagType < 0 || tagType >= NUM_TYPES) {
1320 ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
1321 return BAD_VALUE;
1322 }
1323 desc->mTagToTypeMap.add(tag, tagType);
1324 }
1325 }
1326
1327 desc->mSections = sections;
1328
1329 for (size_t i = 0; i < tagArray.size(); ++i) {
1330 uint32_t tag = tagArray[i];
1331 String8 sectionString = tagToSectionMap.valueFor(tag);
1332
1333 // Set up tag to section index map
1334 ssize_t index = sections.indexOf(sectionString);
1335 LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
1336 desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
1337
1338 // Set up reverse mapping
1339 ssize_t reverseIndex = -1;
1340 if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
1341 KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
1342 reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
1343 }
1344 desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
1345 }
1346
1347 descriptor = desc;
1348 return OK;
1349}
1350
1351
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001352} // namespace android