blob: a82f0f76e3f723fec3bf88ff074fb55377d417ec [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
Shuzhen Wangf9d2c022018-08-21 12:07:35 -070023#include <android/hardware/camera/device/3.5/ICameraDevice.h>
24
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080025#include <algorithm>
Yin-Chia Yeh65405092017-01-13 15:42:28 -080026#include <chrono>
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -070027#include <inttypes.h>
Shuzhen Wangf9d2c022018-08-21 12:07:35 -070028#include <hardware/camera_common.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080029#include <hidl/ServiceManagement.h>
Emilian Peev71c73a22017-03-21 16:35:51 +000030#include <functional>
31#include <camera_metadata_hidden.h>
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080032#include <android-base/parseint.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080033
34namespace android {
35
36using namespace ::android::hardware::camera;
37using namespace ::android::hardware::camera::common::V1_0;
38
39namespace {
40// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
41// service manager
42const std::string kLegacyProviderName("legacy/0");
Yin-Chia Yehd78041a2018-01-20 13:45:38 -080043const std::string kExternalProviderName("external/0");
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080044
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080045} // anonymous namespace
46
47CameraProviderManager::HardwareServiceInteractionProxy
48CameraProviderManager::sHardwareServiceInteractionProxy{};
49
50CameraProviderManager::~CameraProviderManager() {
51}
52
53status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
54 ServiceInteractionProxy* proxy) {
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080055 std::lock_guard<std::mutex> lock(mInterfaceMutex);
56 if (proxy == nullptr) {
57 ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
58 return BAD_VALUE;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080059 }
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080060 mListener = listener;
61 mServiceProxy = proxy;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080062
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080063 // Registering will trigger notifications for all already-known providers
64 bool success = mServiceProxy->registerForNotifications(
65 /* instance name, empty means no filter */ "",
66 this);
67 if (!success) {
68 ALOGE("%s: Unable to register with hardware service manager for notifications "
69 "about camera providers", __FUNCTION__);
70 return INVALID_OPERATION;
Yin-Chia Yeh65405092017-01-13 15:42:28 -080071 }
Emilian Peev5d7e5152017-02-22 15:37:48 +000072
Eino-Ville Talvala65665362017-02-24 13:07:56 -080073 // See if there's a passthrough HAL, but let's not complain if there's not
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -070074 addProviderLocked(kLegacyProviderName, /*expected*/ false);
Yin-Chia Yehd78041a2018-01-20 13:45:38 -080075 addProviderLocked(kExternalProviderName, /*expected*/ false);
Eino-Ville Talvala65665362017-02-24 13:07:56 -080076
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080077 return OK;
78}
79
80int CameraProviderManager::getCameraCount() const {
81 std::lock_guard<std::mutex> lock(mInterfaceMutex);
82 int count = 0;
83 for (auto& provider : mProviders) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080084 count += provider->mUniqueCameraIds.size();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080085 }
86 return count;
87}
88
89std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
90 std::lock_guard<std::mutex> lock(mInterfaceMutex);
91 std::vector<std::string> deviceIds;
92 for (auto& provider : mProviders) {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -070093 for (auto& id : provider->mUniqueCameraIds) {
94 deviceIds.push_back(id);
95 }
96 }
97 return deviceIds;
98}
99
Emilian Peevf53f66e2017-04-11 14:29:43 +0100100std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds() const {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700101 std::lock_guard<std::mutex> lock(mInterfaceMutex);
102 std::vector<std::string> deviceIds;
103 for (auto& provider : mProviders) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700104 std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
105
106 // API1 app doesn't handle logical and physical camera devices well. So
107 // for each [logical, physical1, physical2, ...] id combo, only take the
108 // first id advertised by HAL, and filter out the rest.
109 filterLogicalCameraIdsLocked(providerDeviceIds);
110
111 deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800112 }
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800113
114 std::sort(deviceIds.begin(), deviceIds.end(),
115 [](const std::string& a, const std::string& b) -> bool {
116 uint32_t aUint = 0, bUint = 0;
117 bool aIsUint = base::ParseUint(a, &aUint);
118 bool bIsUint = base::ParseUint(b, &bUint);
119
120 // Uint device IDs first
121 if (aIsUint && bIsUint) {
122 return aUint < bUint;
123 } else if (aIsUint) {
124 return true;
125 } else if (bIsUint) {
126 return false;
127 }
128 // Simple string compare if both id are not uint
129 return a < b;
130 });
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800131 return deviceIds;
132}
133
134bool CameraProviderManager::isValidDevice(const std::string &id, uint16_t majorVersion) const {
135 std::lock_guard<std::mutex> lock(mInterfaceMutex);
136 return isValidDeviceLocked(id, majorVersion);
137}
138
139bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const {
140 for (auto& provider : mProviders) {
141 for (auto& deviceInfo : provider->mDevices) {
142 if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion) {
143 return true;
144 }
145 }
146 }
147 return false;
148}
149
150bool CameraProviderManager::hasFlashUnit(const std::string &id) const {
151 std::lock_guard<std::mutex> lock(mInterfaceMutex);
152
153 auto deviceInfo = findDeviceInfoLocked(id);
154 if (deviceInfo == nullptr) return false;
155
156 return deviceInfo->hasFlashUnit();
157}
158
159status_t CameraProviderManager::getResourceCost(const std::string &id,
160 CameraResourceCost* cost) const {
161 std::lock_guard<std::mutex> lock(mInterfaceMutex);
162
163 auto deviceInfo = findDeviceInfoLocked(id);
164 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
165
166 *cost = deviceInfo->mResourceCost;
167 return OK;
168}
169
170status_t CameraProviderManager::getCameraInfo(const std::string &id,
171 hardware::CameraInfo* info) const {
172 std::lock_guard<std::mutex> lock(mInterfaceMutex);
173
174 auto deviceInfo = findDeviceInfoLocked(id);
175 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
176
177 return deviceInfo->getCameraInfo(info);
178}
179
Emilian Peev35ae8262018-11-08 13:11:32 +0000180status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
181 const hardware::camera::device::V3_4::StreamConfiguration &configuration,
182 bool *status /*out*/) const {
183 std::lock_guard<std::mutex> lock(mInterfaceMutex);
184
185 auto deviceInfo = findDeviceInfoLocked(id);
186 if (deviceInfo == nullptr) {
187 return NAME_NOT_FOUND;
188 }
189
190 return deviceInfo->isSessionConfigurationSupported(configuration, status);
191}
192
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800193status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
194 CameraMetadata* characteristics) const {
195 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700196 return getCameraCharacteristicsLocked(id, characteristics);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800197}
198
199status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
200 hardware::hidl_version *v) {
201 std::lock_guard<std::mutex> lock(mInterfaceMutex);
202
203 hardware::hidl_version maxVersion{0,0};
204 bool found = false;
205 for (auto& provider : mProviders) {
206 for (auto& deviceInfo : provider->mDevices) {
207 if (deviceInfo->mId == id) {
208 if (deviceInfo->mVersion > maxVersion) {
209 maxVersion = deviceInfo->mVersion;
210 found = true;
211 }
212 }
213 }
214 }
215 if (!found) {
216 return NAME_NOT_FOUND;
217 }
218 *v = maxVersion;
219 return OK;
220}
221
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700222bool CameraProviderManager::supportSetTorchMode(const std::string &id) {
223 std::lock_guard<std::mutex> lock(mInterfaceMutex);
224 bool support = false;
225 for (auto& provider : mProviders) {
226 auto deviceInfo = findDeviceInfoLocked(id);
227 if (deviceInfo != nullptr) {
Yin-Chia Yeh73d03742017-09-29 12:01:02 -0700228 auto ret = provider->mInterface->isSetTorchModeSupported(
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700229 [&support](auto status, bool supported) {
230 if (status == Status::OK) {
231 support = supported;
232 }
233 });
Yin-Chia Yeh73d03742017-09-29 12:01:02 -0700234 if (!ret.isOk()) {
235 ALOGE("%s: Transaction error checking torch mode support '%s': %s",
236 __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
237 }
238 break;
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700239 }
240 }
241 return support;
242}
243
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800244status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
245 std::lock_guard<std::mutex> lock(mInterfaceMutex);
246
247 auto deviceInfo = findDeviceInfoLocked(id);
248 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
249
250 return deviceInfo->setTorchMode(enabled);
251}
252
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800253status_t CameraProviderManager::setUpVendorTags() {
Emilian Peev71c73a22017-03-21 16:35:51 +0000254 sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
255
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800256 for (auto& provider : mProviders) {
257 hardware::hidl_vec<VendorTagSection> vts;
258 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700259 hardware::Return<void> ret;
260 ret = provider->mInterface->getVendorTags(
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800261 [&](auto s, const auto& vendorTagSecs) {
262 status = s;
263 if (s == Status::OK) {
264 vts = vendorTagSecs;
265 }
266 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700267 if (!ret.isOk()) {
268 ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
269 __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
270 return DEAD_OBJECT;
271 }
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800272 if (status != Status::OK) {
273 return mapToStatusT(status);
274 }
275
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800276 // Read all vendor tag definitions into a descriptor
277 sp<VendorTagDescriptor> desc;
278 status_t res;
279 if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/desc))
280 != OK) {
281 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
282 "received error %s (%d). Camera clients will not be able to use"
283 "vendor tags", __FUNCTION__, strerror(res), res);
284 return res;
285 }
286
Emilian Peev71c73a22017-03-21 16:35:51 +0000287 tagCache->addVendorDescriptor(provider->mProviderTagid, desc);
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800288 }
Emilian Peev71c73a22017-03-21 16:35:51 +0000289
290 VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
291
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800292 return OK;
293}
294
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800295status_t CameraProviderManager::openSession(const std::string &id,
296 const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
297 /*out*/
298 sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
299
300 std::lock_guard<std::mutex> lock(mInterfaceMutex);
301
302 auto deviceInfo = findDeviceInfoLocked(id,
303 /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
304 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
305
306 auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
307
308 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700309 hardware::Return<void> ret;
310 ret = deviceInfo3->mInterface->open(callback, [&status, &session]
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800311 (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
312 status = s;
313 if (status == Status::OK) {
314 *session = cameraSession;
315 }
316 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700317 if (!ret.isOk()) {
318 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
319 __FUNCTION__, id.c_str(), ret.description().c_str());
320 return DEAD_OBJECT;
321 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800322 return mapToStatusT(status);
323}
324
325status_t CameraProviderManager::openSession(const std::string &id,
326 const sp<hardware::camera::device::V1_0::ICameraDeviceCallback>& callback,
327 /*out*/
328 sp<hardware::camera::device::V1_0::ICameraDevice> *session) {
329
330 std::lock_guard<std::mutex> lock(mInterfaceMutex);
331
332 auto deviceInfo = findDeviceInfoLocked(id,
333 /*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
334 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
335
336 auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
337
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700338 hardware::Return<Status> status = deviceInfo1->mInterface->open(callback);
339 if (!status.isOk()) {
340 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
341 __FUNCTION__, id.c_str(), status.description().c_str());
342 return DEAD_OBJECT;
343 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800344 if (status == Status::OK) {
345 *session = deviceInfo1->mInterface;
346 }
347 return mapToStatusT(status);
348}
349
350
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800351hardware::Return<void> CameraProviderManager::onRegistration(
352 const hardware::hidl_string& /*fqName*/,
353 const hardware::hidl_string& name,
354 bool /*preexisting*/) {
Shuzhen Wang6ba8eb22018-07-08 13:10:44 -0700355 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
Emilian Peevaee727d2017-05-04 16:35:48 +0100356 {
357 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800358
Emilian Peevaee727d2017-05-04 16:35:48 +0100359 addProviderLocked(name);
360 }
361
362 sp<StatusListener> listener = getStatusListener();
363 if (nullptr != listener.get()) {
364 listener->onNewProviderRegistered();
365 }
366
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800367 return hardware::Return<void>();
368}
369
370status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
371 std::lock_guard<std::mutex> lock(mInterfaceMutex);
372
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800373 for (auto& provider : mProviders) {
374 provider->dump(fd, args);
375 }
376 return OK;
377}
378
379CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800380 const std::string& id,
381 hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800382 for (auto& provider : mProviders) {
383 for (auto& deviceInfo : provider->mDevices) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800384 if (deviceInfo->mId == id &&
385 minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800386 return deviceInfo.get();
387 }
388 }
389 }
390 return nullptr;
391}
392
Emilian Peev71c73a22017-03-21 16:35:51 +0000393metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
394 const std::string& id, hardware::hidl_version minVersion,
395 hardware::hidl_version maxVersion) const {
396 metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;
397
398 std::lock_guard<std::mutex> lock(mInterfaceMutex);
399 for (auto& provider : mProviders) {
400 for (auto& deviceInfo : provider->mDevices) {
401 if (deviceInfo->mId == id &&
402 minVersion <= deviceInfo->mVersion &&
403 maxVersion >= deviceInfo->mVersion) {
404 return provider->mProviderTagid;
405 }
406 }
407 }
408
409 return ret;
410}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800411
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700412void CameraProviderManager::ProviderInfo::DeviceInfo3::queryPhysicalCameraIds() {
413 camera_metadata_entry_t entryCap;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700414
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700415 entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700416 for (size_t i = 0; i < entryCap.count; ++i) {
417 uint8_t capability = entryCap.data.u8[i];
418 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700419 mIsLogicalCamera = true;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700420 break;
421 }
422 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700423 if (!mIsLogicalCamera) {
424 return;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700425 }
426
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700427 camera_metadata_entry_t entryIds = mCameraCharacteristics.find(
428 ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700429 const uint8_t* ids = entryIds.data.u8;
430 size_t start = 0;
431 for (size_t i = 0; i < entryIds.count; ++i) {
432 if (ids[i] == '\0') {
433 if (start != i) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700434 mPhysicalIds.push_back((const char*)ids+start);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700435 }
436 start = i+1;
437 }
438 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700439}
440
Shuzhen Wang268a1362018-10-16 16:32:59 -0700441status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupMonochromeTags() {
442 status_t res = OK;
443 auto& c = mCameraCharacteristics;
444
445 // Override static metadata for MONOCHROME camera with older device version
446 if (mVersion.get_major() == 3 && mVersion.get_minor() < 5) {
447 camera_metadata_entry cap = c.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
448 for (size_t i = 0; i < cap.count; i++) {
449 if (cap.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
450 // ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
451 uint8_t cfa = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO;
452 res = c.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &cfa, 1);
453 if (res != OK) {
454 ALOGE("%s: Failed to update COLOR_FILTER_ARRANGEMENT: %s (%d)",
455 __FUNCTION__, strerror(-res), res);
456 return res;
457 }
458
459 // ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
460 const std::vector<uint32_t> sKeys = {
461 ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
462 ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
463 ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
464 ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
465 ANDROID_SENSOR_COLOR_TRANSFORM1,
466 ANDROID_SENSOR_COLOR_TRANSFORM2,
467 ANDROID_SENSOR_FORWARD_MATRIX1,
468 ANDROID_SENSOR_FORWARD_MATRIX2,
469 };
470 res = removeAvailableKeys(c, sKeys,
471 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
472 if (res != OK) {
473 ALOGE("%s: Failed to update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s (%d)",
474 __FUNCTION__, strerror(-res), res);
475 return res;
476 }
477
478 // ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS
479 const std::vector<uint32_t> reqKeys = {
480 ANDROID_COLOR_CORRECTION_MODE,
481 ANDROID_COLOR_CORRECTION_TRANSFORM,
482 ANDROID_COLOR_CORRECTION_GAINS,
483 };
484 res = removeAvailableKeys(c, reqKeys, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
485 if (res != OK) {
486 ALOGE("%s: Failed to update REQUEST_AVAILABLE_REQUEST_KEYS: %s (%d)",
487 __FUNCTION__, strerror(-res), res);
488 return res;
489 }
490
491 // ANDROID_REQUEST_AVAILABLE_RESULT_KEYS
492 const std::vector<uint32_t> resKeys = {
493 ANDROID_SENSOR_GREEN_SPLIT,
494 ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
495 ANDROID_COLOR_CORRECTION_MODE,
496 ANDROID_COLOR_CORRECTION_TRANSFORM,
497 ANDROID_COLOR_CORRECTION_GAINS,
498 };
499 res = removeAvailableKeys(c, resKeys, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
500 if (res != OK) {
501 ALOGE("%s: Failed to update REQUEST_AVAILABLE_RESULT_KEYS: %s (%d)",
502 __FUNCTION__, strerror(-res), res);
503 return res;
504 }
505
506 // ANDROID_SENSOR_BLACK_LEVEL_PATTERN
507 camera_metadata_entry blEntry = c.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN);
508 for (size_t j = 1; j < blEntry.count; j++) {
509 blEntry.data.i32[j] = blEntry.data.i32[0];
510 }
511 }
512 }
513 }
514 return res;
515}
516
517status_t CameraProviderManager::ProviderInfo::DeviceInfo3::removeAvailableKeys(
518 CameraMetadata& c, const std::vector<uint32_t>& keys, uint32_t keyTag) {
519 status_t res = OK;
520
521 camera_metadata_entry keysEntry = c.find(keyTag);
522 if (keysEntry.count == 0) {
523 ALOGE("%s: Failed to find tag %u: %s (%d)", __FUNCTION__, keyTag, strerror(-res), res);
524 return res;
525 }
526 std::vector<int32_t> vKeys;
527 vKeys.reserve(keysEntry.count);
528 for (size_t i = 0; i < keysEntry.count; i++) {
529 if (std::find(keys.begin(), keys.end(), keysEntry.data.i32[i]) == keys.end()) {
530 vKeys.push_back(keysEntry.data.i32[i]);
531 }
532 }
533 res = c.update(keyTag, vKeys.data(), vKeys.size());
534 return res;
535}
536
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700537bool CameraProviderManager::isLogicalCamera(const std::string& id,
538 std::vector<std::string>* physicalCameraIds) {
539 std::lock_guard<std::mutex> lock(mInterfaceMutex);
540
541 auto deviceInfo = findDeviceInfoLocked(id);
542 if (deviceInfo == nullptr) return false;
543
544 if (deviceInfo->mIsLogicalCamera && physicalCameraIds != nullptr) {
545 *physicalCameraIds = deviceInfo->mPhysicalIds;
546 }
547 return deviceInfo->mIsLogicalCamera;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700548}
549
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700550bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) {
551 for (auto& provider : mProviders) {
552 for (auto& deviceInfo : provider->mDevices) {
553 if (deviceInfo->mId == cameraId) {
554 // cameraId is found in public camera IDs advertised by the
555 // provider.
556 return false;
557 }
558 }
559 }
560
561 for (auto& provider : mProviders) {
562 for (auto& deviceInfo : provider->mDevices) {
563 CameraMetadata info;
564 status_t res = deviceInfo->getCameraCharacteristics(&info);
565 if (res != OK) {
566 ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
567 deviceInfo->mId.c_str());
568 return false;
569 }
570
571 std::vector<std::string> physicalIds;
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700572 if (deviceInfo->mIsLogicalCamera) {
573 if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
574 cameraId) != deviceInfo->mPhysicalIds.end()) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700575 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
576 deviceInfo->mVersion.get_major(), deviceInfo->mVersion.get_minor());
577 if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
578 ALOGE("%s: Wrong deviceVersion %x for hiddenPhysicalCameraId %s",
579 __FUNCTION__, deviceVersion, cameraId.c_str());
580 return false;
581 } else {
582 return true;
583 }
584 }
585 }
586 }
587 }
588
589 return false;
590}
591
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700592status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800593 for (const auto& providerInfo : mProviders) {
594 if (providerInfo->mProviderName == newProvider) {
595 ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
596 newProvider.c_str());
597 return ALREADY_EXISTS;
598 }
599 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700600
601 sp<provider::V2_4::ICameraProvider> interface;
602 interface = mServiceProxy->getService(newProvider);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800603
604 if (interface == nullptr) {
605 if (expected) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700606 ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
607 newProvider.c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800608 return BAD_VALUE;
609 } else {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800610 return OK;
611 }
612 }
613
614 sp<ProviderInfo> providerInfo =
615 new ProviderInfo(newProvider, interface, this);
616 status_t res = providerInfo->initialize();
617 if (res != OK) {
618 return res;
619 }
620
621 mProviders.push_back(providerInfo);
622
623 return OK;
624}
625
626status_t CameraProviderManager::removeProvider(const std::string& provider) {
Shuzhen Wang6ba8eb22018-07-08 13:10:44 -0700627 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700628 std::unique_lock<std::mutex> lock(mInterfaceMutex);
629 std::vector<String8> removedDeviceIds;
630 status_t res = NAME_NOT_FOUND;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800631 for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
632 if ((*it)->mProviderName == provider) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700633 removedDeviceIds.reserve((*it)->mDevices.size());
634 for (auto& deviceInfo : (*it)->mDevices) {
635 removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
636 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800637 mProviders.erase(it);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700638 res = OK;
639 break;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800640 }
641 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700642 if (res != OK) {
643 ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
644 provider.c_str());
645 } else {
646 // Inform camera service of loss of presence for all the devices from this provider,
647 // without lock held for reentrancy
648 sp<StatusListener> listener = getStatusListener();
649 if (listener != nullptr) {
650 lock.unlock();
651 for (auto& id : removedDeviceIds) {
652 listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
653 }
654 }
655 }
656 return res;
657}
658
659sp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListener() const {
660 return mListener.promote();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800661}
662
663/**** Methods for ProviderInfo ****/
664
665
666CameraProviderManager::ProviderInfo::ProviderInfo(
667 const std::string &providerName,
668 sp<provider::V2_4::ICameraProvider>& interface,
669 CameraProviderManager *manager) :
670 mProviderName(providerName),
671 mInterface(interface),
Emilian Peev71c73a22017-03-21 16:35:51 +0000672 mProviderTagid(generateVendorTagId(providerName)),
Emilian Peevcdb74a62017-05-11 20:29:52 +0100673 mUniqueDeviceCount(0),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800674 mManager(manager) {
675 (void) mManager;
676}
677
678status_t CameraProviderManager::ProviderInfo::initialize() {
679 status_t res = parseProviderName(mProviderName, &mType, &mId);
680 if (res != OK) {
681 ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
682 return BAD_VALUE;
683 }
Yin-Chia Yeh65405092017-01-13 15:42:28 -0800684 ALOGI("Connecting to new camera provider: %s, isRemote? %d",
685 mProviderName.c_str(), mInterface->isRemote());
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800686 // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
687 // before setCallback returns
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700688 hardware::Return<Status> status = mInterface->setCallback(this);
689 if (!status.isOk()) {
690 ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
691 __FUNCTION__, mProviderName.c_str(), status.description().c_str());
692 return DEAD_OBJECT;
693 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800694 if (status != Status::OK) {
695 ALOGE("%s: Unable to register callbacks with camera provider '%s'",
696 __FUNCTION__, mProviderName.c_str());
697 return mapToStatusT(status);
698 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700699
700 hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
701 if (!linked.isOk()) {
702 ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
703 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
704 return DEAD_OBJECT;
705 } else if (!linked) {
706 ALOGW("%s: Unable to link to provider '%s' death notifications",
707 __FUNCTION__, mProviderName.c_str());
708 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800709
710 // Get initial list of camera devices, if any
711 std::vector<std::string> devices;
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700712 hardware::Return<void> ret = mInterface->getCameraIdList([&status, this, &devices](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800713 Status idStatus,
714 const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
715 status = idStatus;
716 if (status == Status::OK) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700717 for (auto& name : cameraDeviceNames) {
718 uint16_t major, minor;
719 std::string type, id;
720 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
721 if (res != OK) {
722 ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
723 status = Status::INTERNAL_ERROR;
724 } else {
725 devices.push_back(name);
726 mProviderPublicCameraIds.push_back(id);
727 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800728 }
729 } });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700730 if (!ret.isOk()) {
731 ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
732 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
733 return DEAD_OBJECT;
734 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800735 if (status != Status::OK) {
736 ALOGE("%s: Unable to query for camera devices from provider '%s'",
737 __FUNCTION__, mProviderName.c_str());
738 return mapToStatusT(status);
739 }
740
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700741 sp<StatusListener> listener = mManager->getStatusListener();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800742 for (auto& device : devices) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700743 std::string id;
744 status_t res = addDevice(device,
745 hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800746 if (res != OK) {
747 ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
748 __FUNCTION__, device.c_str(), strerror(-res), res);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700749 continue;
750 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800751 }
752
753 ALOGI("Camera provider %s ready with %zu camera devices",
754 mProviderName.c_str(), mDevices.size());
755
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800756 mInitialized = true;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800757 return OK;
758}
759
760const std::string& CameraProviderManager::ProviderInfo::getType() const {
761 return mType;
762}
763
764status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
765 CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
766
767 ALOGI("Enumerating new camera device: %s", name.c_str());
768
769 uint16_t major, minor;
770 std::string type, id;
771
772 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
773 if (res != OK) {
774 return res;
775 }
776 if (type != mType) {
777 ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
778 type.c_str(), mType.c_str());
779 return BAD_VALUE;
780 }
781 if (mManager->isValidDeviceLocked(id, major)) {
782 ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
783 name.c_str(), id.c_str(), major);
784 return BAD_VALUE;
785 }
786
787 std::unique_ptr<DeviceInfo> deviceInfo;
788 switch (major) {
789 case 1:
Emilian Peev71c73a22017-03-21 16:35:51 +0000790 deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
791 id, minor);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800792 break;
793 case 3:
Emilian Peev71c73a22017-03-21 16:35:51 +0000794 deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
795 id, minor);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800796 break;
797 default:
798 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
799 name.c_str(), major);
800 return BAD_VALUE;
801 }
802 if (deviceInfo == nullptr) return BAD_VALUE;
803 deviceInfo->mStatus = initialStatus;
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800804 bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800805
806 mDevices.push_back(std::move(deviceInfo));
807
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800808 mUniqueCameraIds.insert(id);
809 if (isAPI1Compatible) {
Shuzhen Wang975a39e2018-06-27 14:35:46 -0700810 // addDevice can be called more than once for the same camera id if HAL
811 // supports openLegacy.
812 if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
813 id) == mUniqueAPI1CompatibleCameraIds.end()) {
814 mUniqueAPI1CompatibleCameraIds.push_back(id);
815 }
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800816 }
817
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800818 if (parsedId != nullptr) {
819 *parsedId = id;
820 }
821 return OK;
822}
823
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100824void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
825 for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
826 if ((*it)->mId == id) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800827 mUniqueCameraIds.erase(id);
828 if ((*it)->isAPI1Compatible()) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700829 mUniqueAPI1CompatibleCameraIds.erase(std::remove(
830 mUniqueAPI1CompatibleCameraIds.begin(),
831 mUniqueAPI1CompatibleCameraIds.end(), id));
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800832 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100833 mDevices.erase(it);
834 break;
835 }
836 }
837}
838
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800839status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700840 dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
841 mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
842 mDevices.size());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800843
844 for (auto& device : mDevices) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800845 dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
846 device->mVersion.get_major(), device->mVersion.get_minor());
847 dprintf(fd, " Resource cost: %d\n", device->mResourceCost.resourceCost);
848 if (device->mResourceCost.conflictingDevices.size() == 0) {
849 dprintf(fd, " Conflicting devices: None\n");
850 } else {
851 dprintf(fd, " Conflicting devices:\n");
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800852 for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800853 dprintf(fd, " %s\n",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800854 device->mResourceCost.conflictingDevices[i].c_str());
855 }
856 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800857 dprintf(fd, " API1 info:\n");
858 dprintf(fd, " Has a flash unit: %s\n",
859 device->hasFlashUnit() ? "true" : "false");
860 hardware::CameraInfo info;
861 status_t res = device->getCameraInfo(&info);
862 if (res != OK) {
863 dprintf(fd, " <Error reading camera info: %s (%d)>\n",
864 strerror(-res), res);
865 } else {
866 dprintf(fd, " Facing: %s\n",
867 info.facing == hardware::CAMERA_FACING_BACK ? "Back" : "Front");
868 dprintf(fd, " Orientation: %d\n", info.orientation);
869 }
870 CameraMetadata info2;
871 res = device->getCameraCharacteristics(&info2);
872 if (res == INVALID_OPERATION) {
873 dprintf(fd, " API2 not directly supported\n");
874 } else if (res != OK) {
875 dprintf(fd, " <Error reading camera characteristics: %s (%d)>\n",
876 strerror(-res), res);
877 } else {
878 dprintf(fd, " API2 camera characteristics:\n");
879 info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
880 }
Yin-Chia Yeh487785a2018-01-02 12:06:57 -0800881
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700882 // Dump characteristics of non-standalone physical camera
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700883 if (device->mIsLogicalCamera) {
884 for (auto& id : device->mPhysicalIds) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700885 // Skip if physical id is an independent camera
886 if (std::find(mProviderPublicCameraIds.begin(), mProviderPublicCameraIds.end(), id)
887 != mProviderPublicCameraIds.end()) {
888 continue;
889 }
890
891 CameraMetadata physicalInfo;
892 status_t status = device->getPhysicalCameraCharacteristics(id, &physicalInfo);
893 if (status == OK) {
894 dprintf(fd, " Physical camera %s characteristics:\n", id.c_str());
895 physicalInfo.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
896 }
897 }
898 }
899
Yin-Chia Yeh487785a2018-01-02 12:06:57 -0800900 dprintf(fd, "== Camera HAL device %s (v%d.%d) dumpState: ==\n", device->mName.c_str(),
901 device->mVersion.get_major(), device->mVersion.get_minor());
902 res = device->dumpState(fd);
903 if (res != OK) {
904 dprintf(fd, " <Error dumping device %s state: %s (%d)>\n",
905 device->mName.c_str(), strerror(-res), res);
906 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800907 }
908 return OK;
909}
910
911hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
912 const hardware::hidl_string& cameraDeviceName,
913 CameraDeviceStatus newStatus) {
914 sp<StatusListener> listener;
915 std::string id;
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800916 bool initialized = false;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800917 {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700918 std::lock_guard<std::mutex> lock(mLock);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800919 bool known = false;
920 for (auto& deviceInfo : mDevices) {
921 if (deviceInfo->mName == cameraDeviceName) {
922 ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
923 deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
924 deviceInfo->mStatus = newStatus;
925 // TODO: Handle device removal (NOT_PRESENT)
926 id = deviceInfo->mId;
927 known = true;
928 break;
929 }
930 }
931 // Previously unseen device; status must not be NOT_PRESENT
932 if (!known) {
933 if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
934 ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
935 mProviderName.c_str(), cameraDeviceName.c_str());
936 return hardware::Void();
937 }
938 addDevice(cameraDeviceName, newStatus, &id);
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100939 } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
940 removeDevice(id);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800941 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700942 listener = mManager->getStatusListener();
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800943 initialized = mInitialized;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800944 }
945 // Call without lock held to allow reentrancy into provider manager
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800946 // Don't send the callback if providerInfo hasn't been initialized.
947 // CameraService will initialize device status after provider is
948 // initialized
949 if (listener != nullptr && initialized) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800950 listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
951 }
952 return hardware::Void();
953}
954
955hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
956 const hardware::hidl_string& cameraDeviceName,
957 TorchModeStatus newStatus) {
958 sp<StatusListener> listener;
959 std::string id;
960 {
Yin-Chia Yeh52778d42016-12-22 18:20:43 -0800961 std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800962 bool known = false;
963 for (auto& deviceInfo : mDevices) {
964 if (deviceInfo->mName == cameraDeviceName) {
965 ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
966 torchStatusToString(newStatus));
967 id = deviceInfo->mId;
968 known = true;
969 break;
970 }
971 }
972 if (!known) {
973 ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
974 mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
975 return hardware::Void();
976 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700977 listener = mManager->getStatusListener();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800978 }
979 // Call without lock held to allow reentrancy into provider manager
980 if (listener != nullptr) {
981 listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
982 }
983 return hardware::Void();
984}
985
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700986void CameraProviderManager::ProviderInfo::serviceDied(uint64_t cookie,
987 const wp<hidl::base::V1_0::IBase>& who) {
988 (void) who;
989 ALOGI("Camera provider '%s' has died; removing it", mProviderName.c_str());
990 if (cookie != mId) {
991 ALOGW("%s: Unexpected serviceDied cookie %" PRIu64 ", expected %" PRIu32,
992 __FUNCTION__, cookie, mId);
993 }
994 mManager->removeProvider(mProviderName);
995}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800996
997template<class DeviceInfoT>
998std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
999 CameraProviderManager::ProviderInfo::initializeDeviceInfo(
Emilian Peev71c73a22017-03-21 16:35:51 +00001000 const std::string &name, const metadata_vendor_id_t tagId,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001001 const std::string &id, uint16_t minorVersion) const {
1002 Status status;
1003
1004 auto cameraInterface =
1005 getDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
1006 if (cameraInterface == nullptr) return nullptr;
1007
1008 CameraResourceCost resourceCost;
1009 cameraInterface->getResourceCost([&status, &resourceCost](
1010 Status s, CameraResourceCost cost) {
1011 status = s;
1012 resourceCost = cost;
1013 });
1014 if (status != Status::OK) {
1015 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
1016 name.c_str(), statusToString(status));
1017 return nullptr;
1018 }
Shuzhen Wang47283692018-04-24 18:05:02 -07001019
1020 for (auto& conflictName : resourceCost.conflictingDevices) {
1021 uint16_t major, minor;
1022 std::string type, id;
1023 status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
1024 if (res != OK) {
1025 ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
1026 return nullptr;
1027 }
1028 conflictName = id;
1029 }
1030
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001031 return std::unique_ptr<DeviceInfo>(
Emilian Peev71c73a22017-03-21 16:35:51 +00001032 new DeviceInfoT(name, tagId, id, minorVersion, resourceCost,
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001033 mProviderPublicCameraIds, cameraInterface));
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001034}
1035
1036template<class InterfaceT>
1037sp<InterfaceT>
1038CameraProviderManager::ProviderInfo::getDeviceInterface(const std::string &name) const {
1039 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
1040 name.c_str(), InterfaceT::version.get_major());
1041 return nullptr;
1042}
1043
1044template<>
1045sp<device::V1_0::ICameraDevice>
1046CameraProviderManager::ProviderInfo::getDeviceInterface
1047 <device::V1_0::ICameraDevice>(const std::string &name) const {
1048 Status status;
1049 sp<device::V1_0::ICameraDevice> cameraInterface;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001050 hardware::Return<void> ret;
1051 ret = mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001052 Status s, sp<device::V1_0::ICameraDevice> interface) {
1053 status = s;
1054 cameraInterface = interface;
1055 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001056 if (!ret.isOk()) {
1057 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
1058 __FUNCTION__, name.c_str(), ret.description().c_str());
1059 return nullptr;
1060 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001061 if (status != Status::OK) {
1062 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
1063 name.c_str(), statusToString(status));
1064 return nullptr;
1065 }
1066 return cameraInterface;
1067}
1068
1069template<>
1070sp<device::V3_2::ICameraDevice>
1071CameraProviderManager::ProviderInfo::getDeviceInterface
1072 <device::V3_2::ICameraDevice>(const std::string &name) const {
1073 Status status;
1074 sp<device::V3_2::ICameraDevice> cameraInterface;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001075 hardware::Return<void> ret;
1076 ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001077 Status s, sp<device::V3_2::ICameraDevice> interface) {
1078 status = s;
1079 cameraInterface = interface;
1080 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001081 if (!ret.isOk()) {
1082 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
1083 __FUNCTION__, name.c_str(), ret.description().c_str());
1084 return nullptr;
1085 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001086 if (status != Status::OK) {
1087 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
1088 name.c_str(), statusToString(status));
1089 return nullptr;
1090 }
1091 return cameraInterface;
1092}
1093
1094CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
1095
1096template<class InterfaceT>
1097status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
1098 bool enabled) {
1099 Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
1100 return mapToStatusT(s);
1101}
1102
1103CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
Emilian Peev71c73a22017-03-21 16:35:51 +00001104 const metadata_vendor_id_t tagId, const std::string &id,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001105 uint16_t minorVersion,
1106 const CameraResourceCost& resourceCost,
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001107 const std::vector<std::string>& publicCameraIds,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001108 sp<InterfaceT> interface) :
Emilian Peev71c73a22017-03-21 16:35:51 +00001109 DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001110 publicCameraIds, resourceCost),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001111 mInterface(interface) {
1112 // Get default parameters and initialize flash unit availability
1113 // Requires powering on the camera device
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001114 hardware::Return<Status> status = mInterface->open(nullptr);
1115 if (!status.isOk()) {
1116 ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
1117 __FUNCTION__, mId.c_str(), status.description().c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001118 return;
1119 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001120 if (status != Status::OK) {
1121 ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
1122 mId.c_str(), CameraProviderManager::statusToString(status));
1123 return;
1124 }
1125 hardware::Return<void> ret;
1126 ret = mInterface->getParameters([this](const hardware::hidl_string& parms) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001127 mDefaultParameters.unflatten(String8(parms.c_str()));
1128 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001129 if (!ret.isOk()) {
1130 ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
1131 __FUNCTION__, mId.c_str(), status.description().c_str());
1132 return;
1133 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001134 const char *flashMode =
1135 mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
1136 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
1137 mHasFlashUnit = true;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001138 }
1139
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001140 ret = mInterface->close();
1141 if (!ret.isOk()) {
1142 ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
1143 __FUNCTION__, mId.c_str(), status.description().c_str());
1144 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001145}
1146
1147CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
1148
1149status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
1150 return DeviceInfo::setTorchMode(mInterface, enabled);
1151}
1152
1153status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
1154 hardware::CameraInfo *info) const {
1155 if (info == nullptr) return BAD_VALUE;
1156
1157 Status status;
1158 device::V1_0::CameraInfo cInfo;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001159 hardware::Return<void> ret;
1160 ret = mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001161 status = s;
1162 cInfo = camInfo;
1163 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001164 if (!ret.isOk()) {
1165 ALOGE("%s: Transaction error reading camera info from device %s: %s",
1166 __FUNCTION__, mId.c_str(), ret.description().c_str());
1167 return DEAD_OBJECT;
1168 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001169 if (status != Status::OK) {
1170 return mapToStatusT(status);
1171 }
1172
1173 switch(cInfo.facing) {
1174 case device::V1_0::CameraFacing::BACK:
1175 info->facing = hardware::CAMERA_FACING_BACK;
1176 break;
1177 case device::V1_0::CameraFacing::EXTERNAL:
1178 // Map external to front for legacy API
1179 case device::V1_0::CameraFacing::FRONT:
1180 info->facing = hardware::CAMERA_FACING_FRONT;
1181 break;
1182 default:
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001183 ALOGW("%s: Device %s: Unknown camera facing: %d",
1184 __FUNCTION__, mId.c_str(), cInfo.facing);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001185 info->facing = hardware::CAMERA_FACING_BACK;
1186 }
1187 info->orientation = cInfo.orientation;
1188
1189 return OK;
1190}
1191
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08001192status_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) const {
1193 native_handle_t* handle = native_handle_create(1,0);
1194 handle->data[0] = fd;
1195 hardware::Return<Status> s = mInterface->dumpState(handle);
1196 native_handle_delete(handle);
1197 if (!s.isOk()) {
1198 return INVALID_OPERATION;
1199 }
1200 return mapToStatusT(s);
1201}
1202
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001203CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
Emilian Peev71c73a22017-03-21 16:35:51 +00001204 const metadata_vendor_id_t tagId, const std::string &id,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001205 uint16_t minorVersion,
1206 const CameraResourceCost& resourceCost,
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001207 const std::vector<std::string>& publicCameraIds,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001208 sp<InterfaceT> interface) :
Emilian Peev71c73a22017-03-21 16:35:51 +00001209 DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001210 publicCameraIds, resourceCost),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001211 mInterface(interface) {
1212 // Get camera characteristics and initialize flash unit availability
1213 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001214 hardware::Return<void> ret;
1215 ret = mInterface->getCameraCharacteristics([&status, this](Status s,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001216 device::V3_2::CameraMetadata metadata) {
1217 status = s;
1218 if (s == Status::OK) {
1219 camera_metadata_t *buffer =
1220 reinterpret_cast<camera_metadata_t*>(metadata.data());
Yin-Chia Yeh238ef5f2017-04-18 15:01:15 -07001221 size_t expectedSize = metadata.size();
1222 int res = validate_camera_metadata_structure(buffer, &expectedSize);
1223 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
1224 set_camera_metadata_vendor_id(buffer, mProviderTagid);
1225 mCameraCharacteristics = buffer;
1226 } else {
1227 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
1228 status = Status::INTERNAL_ERROR;
1229 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001230 }
1231 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001232 if (!ret.isOk()) {
1233 ALOGE("%s: Transaction error getting camera characteristics for device %s"
1234 " to check for a flash unit: %s", __FUNCTION__, mId.c_str(),
1235 ret.description().c_str());
1236 return;
1237 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001238 if (status != Status::OK) {
1239 ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
1240 __FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
1241 return;
1242 }
Shuzhen Wang268a1362018-10-16 16:32:59 -07001243 status_t res = fixupMonochromeTags();
1244 if (OK != res) {
1245 ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
1246 __FUNCTION__, strerror(-res), res);
1247 return;
1248 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001249 camera_metadata_entry flashAvailable =
1250 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
1251 if (flashAvailable.count == 1 &&
1252 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
1253 mHasFlashUnit = true;
1254 } else {
1255 mHasFlashUnit = false;
1256 }
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001257
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001258 queryPhysicalCameraIds();
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001259 // Get physical camera characteristics if applicable
1260 auto castResult = device::V3_5::ICameraDevice::castFrom(mInterface);
1261 if (!castResult.isOk()) {
1262 ALOGV("%s: Unable to convert ICameraDevice instance to version 3.5", __FUNCTION__);
1263 return;
1264 }
1265 sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult;
1266 if (interface_3_5 == nullptr) {
1267 ALOGE("%s: Converted ICameraDevice instance to nullptr", __FUNCTION__);
1268 return;
1269 }
1270
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001271 if (mIsLogicalCamera) {
1272 for (auto& id : mPhysicalIds) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001273 if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
1274 mPublicCameraIds.end()) {
1275 continue;
1276 }
1277
1278 hardware::hidl_string hidlId(id);
1279 ret = interface_3_5->getPhysicalCameraCharacteristics(hidlId,
1280 [&status, &id, this](Status s, device::V3_2::CameraMetadata metadata) {
1281 status = s;
1282 if (s == Status::OK) {
1283 camera_metadata_t *buffer =
1284 reinterpret_cast<camera_metadata_t*>(metadata.data());
1285 size_t expectedSize = metadata.size();
1286 int res = validate_camera_metadata_structure(buffer, &expectedSize);
1287 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
1288 set_camera_metadata_vendor_id(buffer, mProviderTagid);
1289 mPhysicalCameraCharacteristics[id] = buffer;
1290 } else {
1291 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
1292 status = Status::INTERNAL_ERROR;
1293 }
1294 }
1295 });
1296
1297 if (!ret.isOk()) {
1298 ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
1299 __FUNCTION__, id.c_str(), mId.c_str(), ret.description().c_str());
1300 return;
1301 }
1302 if (status != Status::OK) {
1303 ALOGE("%s: Unable to get physical camera %s characteristics for device %s: %s (%d)",
1304 __FUNCTION__, id.c_str(), mId.c_str(),
1305 CameraProviderManager::statusToString(status), status);
1306 return;
1307 }
1308 }
1309 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001310}
1311
1312CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
1313
1314status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
1315 return DeviceInfo::setTorchMode(mInterface, enabled);
1316}
1317
1318status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
1319 hardware::CameraInfo *info) const {
1320 if (info == nullptr) return BAD_VALUE;
1321
1322 camera_metadata_ro_entry facing =
1323 mCameraCharacteristics.find(ANDROID_LENS_FACING);
1324 if (facing.count == 1) {
1325 switch (facing.data.u8[0]) {
1326 case ANDROID_LENS_FACING_BACK:
1327 info->facing = hardware::CAMERA_FACING_BACK;
1328 break;
1329 case ANDROID_LENS_FACING_EXTERNAL:
1330 // Map external to front for legacy API
1331 case ANDROID_LENS_FACING_FRONT:
1332 info->facing = hardware::CAMERA_FACING_FRONT;
1333 break;
1334 }
1335 } else {
1336 ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
1337 return NAME_NOT_FOUND;
1338 }
1339
1340 camera_metadata_ro_entry orientation =
1341 mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
1342 if (orientation.count == 1) {
1343 info->orientation = orientation.data.i32[0];
1344 } else {
1345 ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
1346 return NAME_NOT_FOUND;
1347 }
1348
1349 return OK;
1350}
Emilian Peevf53f66e2017-04-11 14:29:43 +01001351bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const {
1352 bool isBackwardCompatible = false;
1353 camera_metadata_ro_entry_t caps = mCameraCharacteristics.find(
1354 ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1355 for (size_t i = 0; i < caps.count; i++) {
1356 if (caps.data.u8[i] ==
1357 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1358 isBackwardCompatible = true;
1359 break;
1360 }
1361 }
1362
1363 return isBackwardCompatible;
1364}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001365
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08001366status_t CameraProviderManager::ProviderInfo::DeviceInfo3::dumpState(int fd) const {
1367 native_handle_t* handle = native_handle_create(1,0);
1368 handle->data[0] = fd;
1369 auto ret = mInterface->dumpState(handle);
1370 native_handle_delete(handle);
1371 if (!ret.isOk()) {
1372 return INVALID_OPERATION;
1373 }
1374 return OK;
1375}
1376
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001377status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
1378 CameraMetadata *characteristics) const {
1379 if (characteristics == nullptr) return BAD_VALUE;
1380
1381 *characteristics = mCameraCharacteristics;
1382 return OK;
1383}
1384
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001385status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getPhysicalCameraCharacteristics(
1386 const std::string& physicalCameraId, CameraMetadata *characteristics) const {
1387 if (characteristics == nullptr) return BAD_VALUE;
1388 if (mPhysicalCameraCharacteristics.find(physicalCameraId) ==
1389 mPhysicalCameraCharacteristics.end()) {
1390 return NAME_NOT_FOUND;
1391 }
1392
1393 *characteristics = mPhysicalCameraCharacteristics.at(physicalCameraId);
1394 return OK;
1395}
1396
Emilian Peev35ae8262018-11-08 13:11:32 +00001397status_t CameraProviderManager::ProviderInfo::DeviceInfo3::isSessionConfigurationSupported(
1398 const hardware::camera::device::V3_4::StreamConfiguration &configuration,
1399 bool *status /*out*/) const {
1400 auto castResult = device::V3_5::ICameraDevice::castFrom(mInterface);
1401 sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult;
1402 if (interface_3_5 == nullptr) {
1403 return INVALID_OPERATION;
1404 }
1405
1406 status_t res;
1407 Status callStatus;
1408 auto ret = interface_3_5->isStreamCombinationSupported(configuration,
1409 [&callStatus, &status] (Status s, bool combStatus) {
1410 callStatus = s;
1411 *status = combStatus;
1412 });
1413 if (ret.isOk()) {
1414 switch (callStatus) {
1415 case Status::OK:
1416 // Expected case, do nothing.
1417 res = OK;
1418 break;
1419 case Status::METHOD_NOT_SUPPORTED:
1420 res = INVALID_OPERATION;
1421 break;
1422 default:
1423 ALOGE("%s: Session configuration query failed: %d", __FUNCTION__, callStatus);
1424 res = UNKNOWN_ERROR;
1425 }
1426 } else {
1427 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.description().c_str());
1428 res = UNKNOWN_ERROR;
1429 }
1430
1431 return res;
1432}
1433
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001434status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
1435 std::string *type, uint32_t *id) {
1436 // Format must be "<type>/<id>"
1437#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. " \
1438 "Should match '<type>/<id>' - "
1439
1440 if (!type || !id) return INVALID_OPERATION;
1441
1442 std::string::size_type slashIdx = name.find('/');
1443 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
1444 ALOGE(ERROR_MSG_PREFIX
1445 "does not have / separator between type and id",
1446 __FUNCTION__, name.c_str());
1447 return BAD_VALUE;
1448 }
1449
1450 std::string typeVal = name.substr(0, slashIdx);
1451
1452 char *endPtr;
1453 errno = 0;
1454 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
1455 if (errno != 0) {
1456 ALOGE(ERROR_MSG_PREFIX
1457 "cannot parse provider id as an integer: %s (%d)",
1458 __FUNCTION__, name.c_str(), strerror(errno), errno);
1459 return BAD_VALUE;
1460 }
1461 if (endPtr != name.c_str() + name.size()) {
1462 ALOGE(ERROR_MSG_PREFIX
1463 "provider id has unexpected length",
1464 __FUNCTION__, name.c_str());
1465 return BAD_VALUE;
1466 }
1467 if (idVal < 0) {
1468 ALOGE(ERROR_MSG_PREFIX
1469 "id is negative: %ld",
1470 __FUNCTION__, name.c_str(), idVal);
1471 return BAD_VALUE;
1472 }
1473
1474#undef ERROR_MSG_PREFIX
1475
1476 *type = typeVal;
1477 *id = static_cast<uint32_t>(idVal);
1478
1479 return OK;
1480}
1481
Emilian Peev71c73a22017-03-21 16:35:51 +00001482metadata_vendor_id_t CameraProviderManager::ProviderInfo::generateVendorTagId(
1483 const std::string &name) {
1484 metadata_vendor_id_t ret = std::hash<std::string> {} (name);
1485 // CAMERA_METADATA_INVALID_VENDOR_ID is not a valid hash value
1486 if (CAMERA_METADATA_INVALID_VENDOR_ID == ret) {
1487 ret = 0;
1488 }
1489
1490 return ret;
1491}
1492
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001493status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
1494 uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
1495
1496 // Format must be "device@<major>.<minor>/<type>/<id>"
1497
1498#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
1499 "Should match 'device@<major>.<minor>/<type>/<id>' - "
1500
1501 if (!major || !minor || !type || !id) return INVALID_OPERATION;
1502
1503 // Verify starting prefix
1504 const char expectedPrefix[] = "device@";
1505
1506 if (name.find(expectedPrefix) != 0) {
1507 ALOGE(ERROR_MSG_PREFIX
1508 "does not start with '%s'",
1509 __FUNCTION__, name.c_str(), expectedPrefix);
1510 return BAD_VALUE;
1511 }
1512
1513 // Extract major/minor versions
1514 constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
1515 std::string::size_type dotIdx = name.find('.', atIdx);
1516 if (dotIdx == std::string::npos) {
1517 ALOGE(ERROR_MSG_PREFIX
1518 "does not have @<major>. version section",
1519 __FUNCTION__, name.c_str());
1520 return BAD_VALUE;
1521 }
1522 std::string::size_type typeSlashIdx = name.find('/', dotIdx);
1523 if (typeSlashIdx == std::string::npos) {
1524 ALOGE(ERROR_MSG_PREFIX
1525 "does not have .<minor>/ version section",
1526 __FUNCTION__, name.c_str());
1527 return BAD_VALUE;
1528 }
1529
1530 char *endPtr;
1531 errno = 0;
1532 long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
1533 if (errno != 0) {
1534 ALOGE(ERROR_MSG_PREFIX
1535 "cannot parse major version: %s (%d)",
1536 __FUNCTION__, name.c_str(), strerror(errno), errno);
1537 return BAD_VALUE;
1538 }
1539 if (endPtr != name.c_str() + dotIdx) {
1540 ALOGE(ERROR_MSG_PREFIX
1541 "major version has unexpected length",
1542 __FUNCTION__, name.c_str());
1543 return BAD_VALUE;
1544 }
1545 long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
1546 if (errno != 0) {
1547 ALOGE(ERROR_MSG_PREFIX
1548 "cannot parse minor version: %s (%d)",
1549 __FUNCTION__, name.c_str(), strerror(errno), errno);
1550 return BAD_VALUE;
1551 }
1552 if (endPtr != name.c_str() + typeSlashIdx) {
1553 ALOGE(ERROR_MSG_PREFIX
1554 "minor version has unexpected length",
1555 __FUNCTION__, name.c_str());
1556 return BAD_VALUE;
1557 }
1558 if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
1559 ALOGE(ERROR_MSG_PREFIX
1560 "major/minor version is out of range of uint16_t: %ld.%ld",
1561 __FUNCTION__, name.c_str(), majorVal, minorVal);
1562 return BAD_VALUE;
1563 }
1564
1565 // Extract type and id
1566
1567 std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
1568 if (instanceSlashIdx == std::string::npos) {
1569 ALOGE(ERROR_MSG_PREFIX
1570 "does not have /<type>/ component",
1571 __FUNCTION__, name.c_str());
1572 return BAD_VALUE;
1573 }
1574 std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
1575
1576 if (instanceSlashIdx == name.size() - 1) {
1577 ALOGE(ERROR_MSG_PREFIX
1578 "does not have an /<id> component",
1579 __FUNCTION__, name.c_str());
1580 return BAD_VALUE;
1581 }
1582 std::string idVal = name.substr(instanceSlashIdx + 1);
1583
1584#undef ERROR_MSG_PREFIX
1585
1586 *major = static_cast<uint16_t>(majorVal);
1587 *minor = static_cast<uint16_t>(minorVal);
1588 *type = typeVal;
1589 *id = idVal;
1590
1591 return OK;
1592}
1593
1594
1595
1596CameraProviderManager::ProviderInfo::~ProviderInfo() {
1597 // Destruction of ProviderInfo is only supposed to happen when the respective
1598 // CameraProvider interface dies, so do not unregister callbacks.
1599
1600}
1601
1602status_t CameraProviderManager::mapToStatusT(const Status& s) {
1603 switch(s) {
1604 case Status::OK:
1605 return OK;
1606 case Status::ILLEGAL_ARGUMENT:
1607 return BAD_VALUE;
1608 case Status::CAMERA_IN_USE:
1609 return -EBUSY;
1610 case Status::MAX_CAMERAS_IN_USE:
1611 return -EUSERS;
1612 case Status::METHOD_NOT_SUPPORTED:
1613 return UNKNOWN_TRANSACTION;
1614 case Status::OPERATION_NOT_SUPPORTED:
1615 return INVALID_OPERATION;
1616 case Status::CAMERA_DISCONNECTED:
1617 return DEAD_OBJECT;
1618 case Status::INTERNAL_ERROR:
1619 return INVALID_OPERATION;
1620 }
1621 ALOGW("Unexpected HAL status code %d", s);
1622 return INVALID_OPERATION;
1623}
1624
1625const char* CameraProviderManager::statusToString(const Status& s) {
1626 switch(s) {
1627 case Status::OK:
1628 return "OK";
1629 case Status::ILLEGAL_ARGUMENT:
1630 return "ILLEGAL_ARGUMENT";
1631 case Status::CAMERA_IN_USE:
1632 return "CAMERA_IN_USE";
1633 case Status::MAX_CAMERAS_IN_USE:
1634 return "MAX_CAMERAS_IN_USE";
1635 case Status::METHOD_NOT_SUPPORTED:
1636 return "METHOD_NOT_SUPPORTED";
1637 case Status::OPERATION_NOT_SUPPORTED:
1638 return "OPERATION_NOT_SUPPORTED";
1639 case Status::CAMERA_DISCONNECTED:
1640 return "CAMERA_DISCONNECTED";
1641 case Status::INTERNAL_ERROR:
1642 return "INTERNAL_ERROR";
1643 }
1644 ALOGW("Unexpected HAL status code %d", s);
1645 return "UNKNOWN_ERROR";
1646}
1647
1648const char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
1649 switch(s) {
1650 case CameraDeviceStatus::NOT_PRESENT:
1651 return "NOT_PRESENT";
1652 case CameraDeviceStatus::PRESENT:
1653 return "PRESENT";
1654 case CameraDeviceStatus::ENUMERATING:
1655 return "ENUMERATING";
1656 }
1657 ALOGW("Unexpected HAL device status code %d", s);
1658 return "UNKNOWN_STATUS";
1659}
1660
1661const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
1662 switch(s) {
1663 case TorchModeStatus::NOT_AVAILABLE:
1664 return "NOT_AVAILABLE";
1665 case TorchModeStatus::AVAILABLE_OFF:
1666 return "AVAILABLE_OFF";
1667 case TorchModeStatus::AVAILABLE_ON:
1668 return "AVAILABLE_ON";
1669 }
1670 ALOGW("Unexpected HAL torch mode status code %d", s);
1671 return "UNKNOWN_STATUS";
1672}
1673
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001674
1675status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
1676 const hardware::hidl_vec<hardware::camera::common::V1_0::VendorTagSection>& vts,
1677 /*out*/
1678 sp<VendorTagDescriptor>& descriptor) {
1679
1680 int tagCount = 0;
1681
1682 for (size_t s = 0; s < vts.size(); s++) {
1683 tagCount += vts[s].tags.size();
1684 }
1685
1686 if (tagCount < 0 || tagCount > INT32_MAX) {
1687 ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
1688 return BAD_VALUE;
1689 }
1690
1691 Vector<uint32_t> tagArray;
1692 LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
1693 "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
1694
1695
1696 sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
1697 desc->mTagCount = tagCount;
1698
1699 SortedVector<String8> sections;
1700 KeyedVector<uint32_t, String8> tagToSectionMap;
1701
1702 int idx = 0;
1703 for (size_t s = 0; s < vts.size(); s++) {
1704 const hardware::camera::common::V1_0::VendorTagSection& section = vts[s];
1705 const char *sectionName = section.sectionName.c_str();
1706 if (sectionName == NULL) {
1707 ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
1708 return BAD_VALUE;
1709 }
1710 String8 sectionString(sectionName);
1711 sections.add(sectionString);
1712
1713 for (size_t j = 0; j < section.tags.size(); j++) {
1714 uint32_t tag = section.tags[j].tagId;
1715 if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
1716 ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
1717 return BAD_VALUE;
1718 }
1719
1720 tagArray.editItemAt(idx++) = section.tags[j].tagId;
1721
1722 const char *tagName = section.tags[j].tagName.c_str();
1723 if (tagName == NULL) {
1724 ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
1725 return BAD_VALUE;
1726 }
1727 desc->mTagToNameMap.add(tag, String8(tagName));
1728 tagToSectionMap.add(tag, sectionString);
1729
1730 int tagType = (int) section.tags[j].tagType;
1731 if (tagType < 0 || tagType >= NUM_TYPES) {
1732 ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
1733 return BAD_VALUE;
1734 }
1735 desc->mTagToTypeMap.add(tag, tagType);
1736 }
1737 }
1738
1739 desc->mSections = sections;
1740
1741 for (size_t i = 0; i < tagArray.size(); ++i) {
1742 uint32_t tag = tagArray[i];
1743 String8 sectionString = tagToSectionMap.valueFor(tag);
1744
1745 // Set up tag to section index map
1746 ssize_t index = sections.indexOf(sectionString);
1747 LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
1748 desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
1749
1750 // Set up reverse mapping
1751 ssize_t reverseIndex = -1;
1752 if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
1753 KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
1754 reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
1755 }
1756 desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
1757 }
1758
George Burgess IVa0b84962017-08-29 17:46:19 -07001759 descriptor = std::move(desc);
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001760 return OK;
1761}
1762
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001763status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
1764 CameraMetadata* characteristics) const {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001765 auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {5,0});
1766 if (deviceInfo != nullptr) {
1767 return deviceInfo->getCameraCharacteristics(characteristics);
1768 }
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001769
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001770 // Find hidden physical camera characteristics
1771 for (auto& provider : mProviders) {
1772 for (auto& deviceInfo : provider->mDevices) {
1773 status_t res = deviceInfo->getPhysicalCameraCharacteristics(id, characteristics);
1774 if (res != NAME_NOT_FOUND) return res;
1775 }
1776 }
1777
1778 return NAME_NOT_FOUND;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001779}
1780
1781void CameraProviderManager::filterLogicalCameraIdsLocked(
1782 std::vector<std::string>& deviceIds) const
1783{
1784 std::unordered_set<std::string> removedIds;
1785
1786 for (auto& deviceId : deviceIds) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001787 auto deviceInfo = findDeviceInfoLocked(deviceId);
1788 if (deviceInfo == nullptr) continue;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001789
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001790 if (!deviceInfo->mIsLogicalCamera) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001791 continue;
1792 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001793 // idCombo contains the ids of a logical camera and its physical cameras
1794 std::vector<std::string> idCombo = deviceInfo->mPhysicalIds;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001795 idCombo.push_back(deviceId);
1796
1797 for (auto& id : deviceIds) {
1798 auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
1799 if (foundId == idCombo.end()) {
1800 continue;
1801 }
1802
1803 idCombo.erase(foundId);
1804 removedIds.insert(idCombo.begin(), idCombo.end());
1805 break;
1806 }
1807 }
1808
1809 deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
1810 [&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
1811 deviceIds.end());
1812}
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001813
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001814} // namespace android