blob: a9cbe7292627ea7f35a9620fe0fa543ef0928b62 [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>
Peter Kalauskasa29c1352018-10-10 12:05:42 -070027#include <future>
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -070028#include <inttypes.h>
Shuzhen Wangf9d2c022018-08-21 12:07:35 -070029#include <hardware/camera_common.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080030#include <hidl/ServiceManagement.h>
Emilian Peev71c73a22017-03-21 16:35:51 +000031#include <functional>
32#include <camera_metadata_hidden.h>
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080033#include <android-base/parseint.h>
Peter Kalauskasa29c1352018-10-10 12:05:42 -070034#include <android-base/logging.h>
35#include <cutils/properties.h>
36#include <hwbinder/IPCThreadState.h>
37#include <utils/Trace.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080038
39namespace android {
40
41using namespace ::android::hardware::camera;
42using namespace ::android::hardware::camera::common::V1_0;
Peter Kalauskasa29c1352018-10-10 12:05:42 -070043using std::literals::chrono_literals::operator""s;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080044
45namespace {
46// Hardcoded name for the passthrough HAL implementation, since it can't be discovered via the
47// service manager
48const std::string kLegacyProviderName("legacy/0");
Yin-Chia Yehd78041a2018-01-20 13:45:38 -080049const std::string kExternalProviderName("external/0");
Peter Kalauskasa29c1352018-10-10 12:05:42 -070050const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
51
52// The extra amount of time to hold a reference to an ICameraProvider after it is no longer needed.
53// Hold the reference for this extra time so that if the camera is unreferenced and then referenced
54// again quickly, we do not let the HAL exit and then need to immediately restart it. An example
55// when this could happen is switching from a front-facing to a rear-facing camera. If the HAL were
56// to exit during the camera switch, the camera could appear janky to the user.
57const std::chrono::system_clock::duration kCameraKeepAliveDelay = 3s;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080058
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080059} // anonymous namespace
60
61CameraProviderManager::HardwareServiceInteractionProxy
62CameraProviderManager::sHardwareServiceInteractionProxy{};
63
64CameraProviderManager::~CameraProviderManager() {
65}
66
67status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
68 ServiceInteractionProxy* proxy) {
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080069 std::lock_guard<std::mutex> lock(mInterfaceMutex);
70 if (proxy == nullptr) {
71 ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
72 return BAD_VALUE;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080073 }
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080074 mListener = listener;
75 mServiceProxy = proxy;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080076
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -080077 // Registering will trigger notifications for all already-known providers
78 bool success = mServiceProxy->registerForNotifications(
79 /* instance name, empty means no filter */ "",
80 this);
81 if (!success) {
82 ALOGE("%s: Unable to register with hardware service manager for notifications "
83 "about camera providers", __FUNCTION__);
84 return INVALID_OPERATION;
Yin-Chia Yeh65405092017-01-13 15:42:28 -080085 }
Emilian Peev5d7e5152017-02-22 15:37:48 +000086
Eino-Ville Talvala65665362017-02-24 13:07:56 -080087 // See if there's a passthrough HAL, but let's not complain if there's not
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -070088 addProviderLocked(kLegacyProviderName, /*expected*/ false);
Yin-Chia Yehd78041a2018-01-20 13:45:38 -080089 addProviderLocked(kExternalProviderName, /*expected*/ false);
Eino-Ville Talvala65665362017-02-24 13:07:56 -080090
Peter Kalauskasa29c1352018-10-10 12:05:42 -070091 IPCThreadState::self()->flushCommands();
92
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080093 return OK;
94}
95
96int CameraProviderManager::getCameraCount() const {
97 std::lock_guard<std::mutex> lock(mInterfaceMutex);
98 int count = 0;
99 for (auto& provider : mProviders) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800100 count += provider->mUniqueCameraIds.size();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800101 }
102 return count;
103}
104
105std::vector<std::string> CameraProviderManager::getCameraDeviceIds() const {
106 std::lock_guard<std::mutex> lock(mInterfaceMutex);
107 std::vector<std::string> deviceIds;
108 for (auto& provider : mProviders) {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700109 for (auto& id : provider->mUniqueCameraIds) {
110 deviceIds.push_back(id);
111 }
112 }
113 return deviceIds;
114}
115
Emilian Peevf53f66e2017-04-11 14:29:43 +0100116std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds() const {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700117 std::lock_guard<std::mutex> lock(mInterfaceMutex);
118 std::vector<std::string> deviceIds;
119 for (auto& provider : mProviders) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700120 std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
121
122 // API1 app doesn't handle logical and physical camera devices well. So
123 // for each [logical, physical1, physical2, ...] id combo, only take the
124 // first id advertised by HAL, and filter out the rest.
125 filterLogicalCameraIdsLocked(providerDeviceIds);
126
127 deviceIds.insert(deviceIds.end(), providerDeviceIds.begin(), providerDeviceIds.end());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800128 }
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800129
130 std::sort(deviceIds.begin(), deviceIds.end(),
131 [](const std::string& a, const std::string& b) -> bool {
132 uint32_t aUint = 0, bUint = 0;
133 bool aIsUint = base::ParseUint(a, &aUint);
134 bool bIsUint = base::ParseUint(b, &bUint);
135
136 // Uint device IDs first
137 if (aIsUint && bIsUint) {
138 return aUint < bUint;
139 } else if (aIsUint) {
140 return true;
141 } else if (bIsUint) {
142 return false;
143 }
144 // Simple string compare if both id are not uint
145 return a < b;
146 });
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800147 return deviceIds;
148}
149
150bool CameraProviderManager::isValidDevice(const std::string &id, uint16_t majorVersion) const {
151 std::lock_guard<std::mutex> lock(mInterfaceMutex);
152 return isValidDeviceLocked(id, majorVersion);
153}
154
155bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const {
156 for (auto& provider : mProviders) {
157 for (auto& deviceInfo : provider->mDevices) {
158 if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion) {
159 return true;
160 }
161 }
162 }
163 return false;
164}
165
166bool CameraProviderManager::hasFlashUnit(const std::string &id) const {
167 std::lock_guard<std::mutex> lock(mInterfaceMutex);
168
169 auto deviceInfo = findDeviceInfoLocked(id);
170 if (deviceInfo == nullptr) return false;
171
172 return deviceInfo->hasFlashUnit();
173}
174
175status_t CameraProviderManager::getResourceCost(const std::string &id,
176 CameraResourceCost* cost) const {
177 std::lock_guard<std::mutex> lock(mInterfaceMutex);
178
179 auto deviceInfo = findDeviceInfoLocked(id);
180 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
181
182 *cost = deviceInfo->mResourceCost;
183 return OK;
184}
185
186status_t CameraProviderManager::getCameraInfo(const std::string &id,
187 hardware::CameraInfo* info) const {
188 std::lock_guard<std::mutex> lock(mInterfaceMutex);
189
190 auto deviceInfo = findDeviceInfoLocked(id);
191 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
192
193 return deviceInfo->getCameraInfo(info);
194}
195
Emilian Peev35ae8262018-11-08 13:11:32 +0000196status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
197 const hardware::camera::device::V3_4::StreamConfiguration &configuration,
198 bool *status /*out*/) const {
199 std::lock_guard<std::mutex> lock(mInterfaceMutex);
200
201 auto deviceInfo = findDeviceInfoLocked(id);
202 if (deviceInfo == nullptr) {
203 return NAME_NOT_FOUND;
204 }
205
206 return deviceInfo->isSessionConfigurationSupported(configuration, status);
207}
208
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800209status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
210 CameraMetadata* characteristics) const {
211 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700212 return getCameraCharacteristicsLocked(id, characteristics);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800213}
214
215status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
216 hardware::hidl_version *v) {
217 std::lock_guard<std::mutex> lock(mInterfaceMutex);
218
219 hardware::hidl_version maxVersion{0,0};
220 bool found = false;
221 for (auto& provider : mProviders) {
222 for (auto& deviceInfo : provider->mDevices) {
223 if (deviceInfo->mId == id) {
224 if (deviceInfo->mVersion > maxVersion) {
225 maxVersion = deviceInfo->mVersion;
226 found = true;
227 }
228 }
229 }
230 }
231 if (!found) {
232 return NAME_NOT_FOUND;
233 }
234 *v = maxVersion;
235 return OK;
236}
237
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700238bool CameraProviderManager::supportSetTorchMode(const std::string &id) const {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700239 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700240 for (auto& provider : mProviders) {
241 auto deviceInfo = findDeviceInfoLocked(id);
242 if (deviceInfo != nullptr) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700243 return provider->mSetTorchModeSupported;
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700244 }
245 }
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700246 return false;
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700247}
248
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800249status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
250 std::lock_guard<std::mutex> lock(mInterfaceMutex);
251
252 auto deviceInfo = findDeviceInfoLocked(id);
253 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
254
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700255 // Pass the camera ID to start interface so that it will save it to the map of ICameraProviders
256 // that are currently in use.
257 const sp<provider::V2_4::ICameraProvider> interface =
258 deviceInfo->mParentProvider->startProviderInterface();
259 if (interface == nullptr) {
260 return DEAD_OBJECT;
261 }
262 saveRef(DeviceMode::TORCH, deviceInfo->mId, interface);
263
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800264 return deviceInfo->setTorchMode(enabled);
265}
266
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800267status_t CameraProviderManager::setUpVendorTags() {
Emilian Peev71c73a22017-03-21 16:35:51 +0000268 sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
269
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800270 for (auto& provider : mProviders) {
Peter Kalauskas1b3c9072018-11-07 12:41:53 -0800271 tagCache->addVendorDescriptor(provider->mProviderTagid, provider->mVendorTagDescriptor);
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800272 }
Emilian Peev71c73a22017-03-21 16:35:51 +0000273
274 VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
275
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800276 return OK;
277}
278
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800279status_t CameraProviderManager::openSession(const std::string &id,
Peter Kalauskasb7bd4382018-11-15 17:19:48 -0800280 const sp<device::V3_2::ICameraDeviceCallback>& callback,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800281 /*out*/
Peter Kalauskasb7bd4382018-11-15 17:19:48 -0800282 sp<device::V3_2::ICameraDeviceSession> *session) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800283
284 std::lock_guard<std::mutex> lock(mInterfaceMutex);
285
286 auto deviceInfo = findDeviceInfoLocked(id,
287 /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
288 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
289
290 auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700291 const sp<provider::V2_4::ICameraProvider> provider =
292 deviceInfo->mParentProvider->startProviderInterface();
293 if (provider == nullptr) {
294 return DEAD_OBJECT;
295 }
296 saveRef(DeviceMode::CAMERA, id, provider);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800297
298 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700299 hardware::Return<void> ret;
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700300 auto interface = deviceInfo3->startDeviceInterface<
301 CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
302 if (interface == nullptr) {
303 return DEAD_OBJECT;
304 }
305
306 ret = interface->open(callback, [&status, &session]
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800307 (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
308 status = s;
309 if (status == Status::OK) {
310 *session = cameraSession;
311 }
312 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700313 if (!ret.isOk()) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700314 removeRef(DeviceMode::CAMERA, id);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700315 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
316 __FUNCTION__, id.c_str(), ret.description().c_str());
317 return DEAD_OBJECT;
318 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800319 return mapToStatusT(status);
320}
321
322status_t CameraProviderManager::openSession(const std::string &id,
Peter Kalauskasb7bd4382018-11-15 17:19:48 -0800323 const sp<device::V1_0::ICameraDeviceCallback>& callback,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800324 /*out*/
Peter Kalauskasb7bd4382018-11-15 17:19:48 -0800325 sp<device::V1_0::ICameraDevice> *session) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800326
327 std::lock_guard<std::mutex> lock(mInterfaceMutex);
328
329 auto deviceInfo = findDeviceInfoLocked(id,
330 /*minVersion*/ {1,0}, /*maxVersion*/ {2,0});
331 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
332
333 auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700334 const sp<provider::V2_4::ICameraProvider> provider =
335 deviceInfo->mParentProvider->startProviderInterface();
336 if (provider == nullptr) {
337 return DEAD_OBJECT;
338 }
339 saveRef(DeviceMode::CAMERA, id, provider);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800340
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700341 auto interface = deviceInfo1->startDeviceInterface<
342 CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT>();
343 if (interface == nullptr) {
344 return DEAD_OBJECT;
345 }
346 hardware::Return<Status> status = interface->open(callback);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700347 if (!status.isOk()) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700348 removeRef(DeviceMode::CAMERA, id);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700349 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
350 __FUNCTION__, id.c_str(), status.description().c_str());
351 return DEAD_OBJECT;
352 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800353 if (status == Status::OK) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700354 *session = interface;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800355 }
356 return mapToStatusT(status);
357}
358
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700359void CameraProviderManager::saveRef(DeviceMode usageType, const std::string &cameraId,
360 sp<provider::V2_4::ICameraProvider> provider) {
361 if (!kEnableLazyHal) {
362 return;
363 }
364 ALOGI("Saving camera provider %s for camera device %s", provider->descriptor, cameraId.c_str());
365 std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
366 std::unordered_map<std::string, sp<provider::V2_4::ICameraProvider>> *primaryMap, *alternateMap;
367 if (usageType == DeviceMode::TORCH) {
368 primaryMap = &mTorchProviderByCameraId;
369 alternateMap = &mCameraProviderByCameraId;
370 } else {
371 primaryMap = &mCameraProviderByCameraId;
372 alternateMap = &mTorchProviderByCameraId;
373 }
374 auto id = cameraId.c_str();
375 (*primaryMap)[id] = provider;
376 auto search = alternateMap->find(id);
377 if (search != alternateMap->end()) {
378 ALOGW("%s: Camera device %s is using both torch mode and camera mode simultaneously. "
379 "That should not be possible", __FUNCTION__, id);
380 }
381 ALOGV("%s: Camera device %s connected", __FUNCTION__, id);
382}
383
384void CameraProviderManager::removeRef(DeviceMode usageType, const std::string &cameraId) {
385 if (!kEnableLazyHal) {
386 return;
387 }
388 ALOGI("Removing camera device %s", cameraId.c_str());
389 std::unordered_map<std::string, sp<provider::V2_4::ICameraProvider>> *providerMap;
390 if (usageType == DeviceMode::TORCH) {
391 providerMap = &mTorchProviderByCameraId;
392 } else {
393 providerMap = &mCameraProviderByCameraId;
394 }
395 std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
396 auto search = providerMap->find(cameraId.c_str());
397 if (search != providerMap->end()) {
398 auto ptr = search->second;
399 auto future = std::async(std::launch::async, [ptr] {
400 std::this_thread::sleep_for(kCameraKeepAliveDelay);
401 IPCThreadState::self()->flushCommands();
402 });
403 providerMap->erase(cameraId.c_str());
404 } else {
405 ALOGE("%s: Asked to remove reference for camera %s, but no reference to it was found. This "
406 "could mean removeRef was called twice for the same camera ID.", __FUNCTION__,
407 cameraId.c_str());
408 }
409}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800410
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800411hardware::Return<void> CameraProviderManager::onRegistration(
412 const hardware::hidl_string& /*fqName*/,
413 const hardware::hidl_string& name,
414 bool /*preexisting*/) {
Shuzhen Wang6ba8eb22018-07-08 13:10:44 -0700415 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
Emilian Peevaee727d2017-05-04 16:35:48 +0100416 {
417 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800418
Emilian Peevaee727d2017-05-04 16:35:48 +0100419 addProviderLocked(name);
420 }
421
422 sp<StatusListener> listener = getStatusListener();
423 if (nullptr != listener.get()) {
424 listener->onNewProviderRegistered();
425 }
426
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700427 IPCThreadState::self()->flushCommands();
428
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800429 return hardware::Return<void>();
430}
431
432status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
433 std::lock_guard<std::mutex> lock(mInterfaceMutex);
434
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800435 for (auto& provider : mProviders) {
436 provider->dump(fd, args);
437 }
438 return OK;
439}
440
441CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800442 const std::string& id,
443 hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800444 for (auto& provider : mProviders) {
445 for (auto& deviceInfo : provider->mDevices) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800446 if (deviceInfo->mId == id &&
447 minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800448 return deviceInfo.get();
449 }
450 }
451 }
452 return nullptr;
453}
454
Emilian Peev71c73a22017-03-21 16:35:51 +0000455metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
456 const std::string& id, hardware::hidl_version minVersion,
457 hardware::hidl_version maxVersion) const {
458 metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;
459
460 std::lock_guard<std::mutex> lock(mInterfaceMutex);
461 for (auto& provider : mProviders) {
462 for (auto& deviceInfo : provider->mDevices) {
463 if (deviceInfo->mId == id &&
464 minVersion <= deviceInfo->mVersion &&
465 maxVersion >= deviceInfo->mVersion) {
466 return provider->mProviderTagid;
467 }
468 }
469 }
470
471 return ret;
472}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800473
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700474void CameraProviderManager::ProviderInfo::DeviceInfo3::queryPhysicalCameraIds() {
475 camera_metadata_entry_t entryCap;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700476
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700477 entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700478 for (size_t i = 0; i < entryCap.count; ++i) {
479 uint8_t capability = entryCap.data.u8[i];
480 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700481 mIsLogicalCamera = true;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700482 break;
483 }
484 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700485 if (!mIsLogicalCamera) {
486 return;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700487 }
488
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700489 camera_metadata_entry_t entryIds = mCameraCharacteristics.find(
490 ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700491 const uint8_t* ids = entryIds.data.u8;
492 size_t start = 0;
493 for (size_t i = 0; i < entryIds.count; ++i) {
494 if (ids[i] == '\0') {
495 if (start != i) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700496 mPhysicalIds.push_back((const char*)ids+start);
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700497 }
498 start = i+1;
499 }
500 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700501}
502
Shuzhen Wang268a1362018-10-16 16:32:59 -0700503status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupMonochromeTags() {
504 status_t res = OK;
505 auto& c = mCameraCharacteristics;
506
507 // Override static metadata for MONOCHROME camera with older device version
508 if (mVersion.get_major() == 3 && mVersion.get_minor() < 5) {
509 camera_metadata_entry cap = c.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
510 for (size_t i = 0; i < cap.count; i++) {
511 if (cap.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
512 // ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
513 uint8_t cfa = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO;
514 res = c.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &cfa, 1);
515 if (res != OK) {
516 ALOGE("%s: Failed to update COLOR_FILTER_ARRANGEMENT: %s (%d)",
517 __FUNCTION__, strerror(-res), res);
518 return res;
519 }
520
521 // ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
522 const std::vector<uint32_t> sKeys = {
523 ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
524 ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
525 ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
526 ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
527 ANDROID_SENSOR_COLOR_TRANSFORM1,
528 ANDROID_SENSOR_COLOR_TRANSFORM2,
529 ANDROID_SENSOR_FORWARD_MATRIX1,
530 ANDROID_SENSOR_FORWARD_MATRIX2,
531 };
532 res = removeAvailableKeys(c, sKeys,
533 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
534 if (res != OK) {
535 ALOGE("%s: Failed to update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s (%d)",
536 __FUNCTION__, strerror(-res), res);
537 return res;
538 }
539
540 // ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS
541 const std::vector<uint32_t> reqKeys = {
542 ANDROID_COLOR_CORRECTION_MODE,
543 ANDROID_COLOR_CORRECTION_TRANSFORM,
544 ANDROID_COLOR_CORRECTION_GAINS,
545 };
546 res = removeAvailableKeys(c, reqKeys, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
547 if (res != OK) {
548 ALOGE("%s: Failed to update REQUEST_AVAILABLE_REQUEST_KEYS: %s (%d)",
549 __FUNCTION__, strerror(-res), res);
550 return res;
551 }
552
553 // ANDROID_REQUEST_AVAILABLE_RESULT_KEYS
554 const std::vector<uint32_t> resKeys = {
555 ANDROID_SENSOR_GREEN_SPLIT,
556 ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
557 ANDROID_COLOR_CORRECTION_MODE,
558 ANDROID_COLOR_CORRECTION_TRANSFORM,
559 ANDROID_COLOR_CORRECTION_GAINS,
560 };
561 res = removeAvailableKeys(c, resKeys, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
562 if (res != OK) {
563 ALOGE("%s: Failed to update REQUEST_AVAILABLE_RESULT_KEYS: %s (%d)",
564 __FUNCTION__, strerror(-res), res);
565 return res;
566 }
567
568 // ANDROID_SENSOR_BLACK_LEVEL_PATTERN
569 camera_metadata_entry blEntry = c.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN);
570 for (size_t j = 1; j < blEntry.count; j++) {
571 blEntry.data.i32[j] = blEntry.data.i32[0];
572 }
573 }
574 }
575 }
576 return res;
577}
578
579status_t CameraProviderManager::ProviderInfo::DeviceInfo3::removeAvailableKeys(
580 CameraMetadata& c, const std::vector<uint32_t>& keys, uint32_t keyTag) {
581 status_t res = OK;
582
583 camera_metadata_entry keysEntry = c.find(keyTag);
584 if (keysEntry.count == 0) {
585 ALOGE("%s: Failed to find tag %u: %s (%d)", __FUNCTION__, keyTag, strerror(-res), res);
586 return res;
587 }
588 std::vector<int32_t> vKeys;
589 vKeys.reserve(keysEntry.count);
590 for (size_t i = 0; i < keysEntry.count; i++) {
591 if (std::find(keys.begin(), keys.end(), keysEntry.data.i32[i]) == keys.end()) {
592 vKeys.push_back(keysEntry.data.i32[i]);
593 }
594 }
595 res = c.update(keyTag, vKeys.data(), vKeys.size());
596 return res;
597}
598
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700599bool CameraProviderManager::isLogicalCamera(const std::string& id,
600 std::vector<std::string>* physicalCameraIds) {
601 std::lock_guard<std::mutex> lock(mInterfaceMutex);
602
603 auto deviceInfo = findDeviceInfoLocked(id);
604 if (deviceInfo == nullptr) return false;
605
606 if (deviceInfo->mIsLogicalCamera && physicalCameraIds != nullptr) {
607 *physicalCameraIds = deviceInfo->mPhysicalIds;
608 }
609 return deviceInfo->mIsLogicalCamera;
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700610}
611
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700612bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) {
613 for (auto& provider : mProviders) {
614 for (auto& deviceInfo : provider->mDevices) {
615 if (deviceInfo->mId == cameraId) {
616 // cameraId is found in public camera IDs advertised by the
617 // provider.
618 return false;
619 }
620 }
621 }
622
623 for (auto& provider : mProviders) {
624 for (auto& deviceInfo : provider->mDevices) {
625 CameraMetadata info;
626 status_t res = deviceInfo->getCameraCharacteristics(&info);
627 if (res != OK) {
628 ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
629 deviceInfo->mId.c_str());
630 return false;
631 }
632
633 std::vector<std::string> physicalIds;
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700634 if (deviceInfo->mIsLogicalCamera) {
635 if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
636 cameraId) != deviceInfo->mPhysicalIds.end()) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700637 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
638 deviceInfo->mVersion.get_major(), deviceInfo->mVersion.get_minor());
639 if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
640 ALOGE("%s: Wrong deviceVersion %x for hiddenPhysicalCameraId %s",
641 __FUNCTION__, deviceVersion, cameraId.c_str());
642 return false;
643 } else {
644 return true;
645 }
646 }
647 }
648 }
649 }
650
651 return false;
652}
653
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700654status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800655 for (const auto& providerInfo : mProviders) {
656 if (providerInfo->mProviderName == newProvider) {
657 ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
658 newProvider.c_str());
659 return ALREADY_EXISTS;
660 }
661 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700662
663 sp<provider::V2_4::ICameraProvider> interface;
664 interface = mServiceProxy->getService(newProvider);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800665
666 if (interface == nullptr) {
667 if (expected) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700668 ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
669 newProvider.c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800670 return BAD_VALUE;
671 } else {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800672 return OK;
673 }
674 }
675
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700676 sp<ProviderInfo> providerInfo = new ProviderInfo(newProvider, this);
677 status_t res = providerInfo->initialize(interface);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800678 if (res != OK) {
679 return res;
680 }
681
682 mProviders.push_back(providerInfo);
683
684 return OK;
685}
686
687status_t CameraProviderManager::removeProvider(const std::string& provider) {
Shuzhen Wang6ba8eb22018-07-08 13:10:44 -0700688 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700689 std::unique_lock<std::mutex> lock(mInterfaceMutex);
690 std::vector<String8> removedDeviceIds;
691 status_t res = NAME_NOT_FOUND;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800692 for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
693 if ((*it)->mProviderName == provider) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700694 removedDeviceIds.reserve((*it)->mDevices.size());
695 for (auto& deviceInfo : (*it)->mDevices) {
696 removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
697 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800698 mProviders.erase(it);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700699 res = OK;
700 break;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800701 }
702 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700703 if (res != OK) {
704 ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
705 provider.c_str());
706 } else {
707 // Inform camera service of loss of presence for all the devices from this provider,
708 // without lock held for reentrancy
709 sp<StatusListener> listener = getStatusListener();
710 if (listener != nullptr) {
711 lock.unlock();
712 for (auto& id : removedDeviceIds) {
713 listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
714 }
715 }
716 }
717 return res;
718}
719
720sp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListener() const {
721 return mListener.promote();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800722}
723
724/**** Methods for ProviderInfo ****/
725
726
727CameraProviderManager::ProviderInfo::ProviderInfo(
728 const std::string &providerName,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800729 CameraProviderManager *manager) :
730 mProviderName(providerName),
Emilian Peev71c73a22017-03-21 16:35:51 +0000731 mProviderTagid(generateVendorTagId(providerName)),
Emilian Peevcdb74a62017-05-11 20:29:52 +0100732 mUniqueDeviceCount(0),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800733 mManager(manager) {
734 (void) mManager;
735}
736
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700737status_t CameraProviderManager::ProviderInfo::initialize(
738 sp<provider::V2_4::ICameraProvider>& interface) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800739 status_t res = parseProviderName(mProviderName, &mType, &mId);
740 if (res != OK) {
741 ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
742 return BAD_VALUE;
743 }
Yin-Chia Yeh65405092017-01-13 15:42:28 -0800744 ALOGI("Connecting to new camera provider: %s, isRemote? %d",
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700745 mProviderName.c_str(), interface->isRemote());
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800746 // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
747 // before setCallback returns
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700748 hardware::Return<Status> status = interface->setCallback(this);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700749 if (!status.isOk()) {
750 ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
751 __FUNCTION__, mProviderName.c_str(), status.description().c_str());
752 return DEAD_OBJECT;
753 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800754 if (status != Status::OK) {
755 ALOGE("%s: Unable to register callbacks with camera provider '%s'",
756 __FUNCTION__, mProviderName.c_str());
757 return mapToStatusT(status);
758 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700759
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700760 hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700761 if (!linked.isOk()) {
762 ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
763 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
764 return DEAD_OBJECT;
765 } else if (!linked) {
766 ALOGW("%s: Unable to link to provider '%s' death notifications",
767 __FUNCTION__, mProviderName.c_str());
768 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800769
770 // Get initial list of camera devices, if any
771 std::vector<std::string> devices;
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700772 hardware::Return<void> ret = interface->getCameraIdList([&status, this, &devices](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800773 Status idStatus,
774 const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
775 status = idStatus;
776 if (status == Status::OK) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700777 for (auto& name : cameraDeviceNames) {
778 uint16_t major, minor;
779 std::string type, id;
780 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
781 if (res != OK) {
782 ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
783 status = Status::INTERNAL_ERROR;
784 } else {
785 devices.push_back(name);
786 mProviderPublicCameraIds.push_back(id);
787 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800788 }
789 } });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700790 if (!ret.isOk()) {
791 ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
792 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
793 return DEAD_OBJECT;
794 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800795 if (status != Status::OK) {
796 ALOGE("%s: Unable to query for camera devices from provider '%s'",
797 __FUNCTION__, mProviderName.c_str());
798 return mapToStatusT(status);
799 }
800
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700801 ret = interface->isSetTorchModeSupported(
802 [this](auto status, bool supported) {
803 if (status == Status::OK) {
804 mSetTorchModeSupported = supported;
805 }
806 });
807 if (!ret.isOk()) {
808 ALOGE("%s: Transaction error checking torch mode support '%s': %s",
809 __FUNCTION__, mProviderName.c_str(), ret.description().c_str());
810 return DEAD_OBJECT;
811 }
812
813 mIsRemote = interface->isRemote();
814
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700815 sp<StatusListener> listener = mManager->getStatusListener();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800816 for (auto& device : devices) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700817 std::string id;
Peter Kalauskasb7bd4382018-11-15 17:19:48 -0800818 status_t res = addDevice(device, common::V1_0::CameraDeviceStatus::PRESENT, &id);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800819 if (res != OK) {
820 ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
821 __FUNCTION__, device.c_str(), strerror(-res), res);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700822 continue;
823 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800824 }
825
Peter Kalauskas1b3c9072018-11-07 12:41:53 -0800826 res = setUpVendorTags();
827 if (res != OK) {
828 ALOGE("%s: Unable to set up vendor tags from provider '%s'",
829 __FUNCTION__, mProviderName.c_str());
830 return res;
831 }
832
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800833 ALOGI("Camera provider %s ready with %zu camera devices",
834 mProviderName.c_str(), mDevices.size());
835
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800836 mInitialized = true;
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700837 if (!kEnableLazyHal) {
838 // Save HAL reference indefinitely
839 mSavedInterface = interface;
840 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800841 return OK;
842}
843
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700844const sp<provider::V2_4::ICameraProvider>
845CameraProviderManager::ProviderInfo::startProviderInterface() {
846 ATRACE_CALL();
847 ALOGI("Request to start camera provider: %s", mProviderName.c_str());
848 if (mSavedInterface != nullptr) {
849 return mSavedInterface;
850 }
851 auto interface = mActiveInterface.promote();
852 if (interface == nullptr) {
853 ALOGI("Could not promote, calling getService(%s)", mProviderName.c_str());
854 interface = mManager->mServiceProxy->getService(mProviderName);
855 interface->setCallback(this);
856 hardware::Return<bool> linked = interface->linkToDeath(this, /*cookie*/ mId);
857 if (!linked.isOk()) {
858 ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
859 __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
860 mManager->removeProvider(mProviderName);
861 return nullptr;
862 } else if (!linked) {
863 ALOGW("%s: Unable to link to provider '%s' death notifications",
864 __FUNCTION__, mProviderName.c_str());
865 }
866 mActiveInterface = interface;
867 } else {
868 ALOGI("Camera provider (%s) already in use. Re-using instance.", mProviderName.c_str());
869 }
870 return interface;
871}
872
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800873const std::string& CameraProviderManager::ProviderInfo::getType() const {
874 return mType;
875}
876
877status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,
878 CameraDeviceStatus initialStatus, /*out*/ std::string* parsedId) {
879
880 ALOGI("Enumerating new camera device: %s", name.c_str());
881
882 uint16_t major, minor;
883 std::string type, id;
884
885 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
886 if (res != OK) {
887 return res;
888 }
889 if (type != mType) {
890 ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
891 type.c_str(), mType.c_str());
892 return BAD_VALUE;
893 }
894 if (mManager->isValidDeviceLocked(id, major)) {
895 ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
896 name.c_str(), id.c_str(), major);
897 return BAD_VALUE;
898 }
899
900 std::unique_ptr<DeviceInfo> deviceInfo;
901 switch (major) {
902 case 1:
Emilian Peev71c73a22017-03-21 16:35:51 +0000903 deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,
904 id, minor);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800905 break;
906 case 3:
Emilian Peev71c73a22017-03-21 16:35:51 +0000907 deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,
908 id, minor);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800909 break;
910 default:
911 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
912 name.c_str(), major);
913 return BAD_VALUE;
914 }
915 if (deviceInfo == nullptr) return BAD_VALUE;
916 deviceInfo->mStatus = initialStatus;
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800917 bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800918
919 mDevices.push_back(std::move(deviceInfo));
920
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800921 mUniqueCameraIds.insert(id);
922 if (isAPI1Compatible) {
Shuzhen Wang975a39e2018-06-27 14:35:46 -0700923 // addDevice can be called more than once for the same camera id if HAL
924 // supports openLegacy.
925 if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
926 id) == mUniqueAPI1CompatibleCameraIds.end()) {
927 mUniqueAPI1CompatibleCameraIds.push_back(id);
928 }
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800929 }
930
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800931 if (parsedId != nullptr) {
932 *parsedId = id;
933 }
934 return OK;
935}
936
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100937void CameraProviderManager::ProviderInfo::removeDevice(std::string id) {
938 for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
939 if ((*it)->mId == id) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800940 mUniqueCameraIds.erase(id);
941 if ((*it)->isAPI1Compatible()) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700942 mUniqueAPI1CompatibleCameraIds.erase(std::remove(
943 mUniqueAPI1CompatibleCameraIds.begin(),
944 mUniqueAPI1CompatibleCameraIds.end(), id));
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800945 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100946 mDevices.erase(it);
947 break;
948 }
949 }
950}
951
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800952status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700953 dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700954 mProviderName.c_str(), mIsRemote ? "remote" : "passthrough",
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700955 mDevices.size());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800956
957 for (auto& device : mDevices) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800958 dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
959 device->mVersion.get_major(), device->mVersion.get_minor());
960 dprintf(fd, " Resource cost: %d\n", device->mResourceCost.resourceCost);
961 if (device->mResourceCost.conflictingDevices.size() == 0) {
962 dprintf(fd, " Conflicting devices: None\n");
963 } else {
964 dprintf(fd, " Conflicting devices:\n");
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800965 for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800966 dprintf(fd, " %s\n",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800967 device->mResourceCost.conflictingDevices[i].c_str());
968 }
969 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800970 dprintf(fd, " API1 info:\n");
971 dprintf(fd, " Has a flash unit: %s\n",
972 device->hasFlashUnit() ? "true" : "false");
973 hardware::CameraInfo info;
974 status_t res = device->getCameraInfo(&info);
975 if (res != OK) {
976 dprintf(fd, " <Error reading camera info: %s (%d)>\n",
977 strerror(-res), res);
978 } else {
979 dprintf(fd, " Facing: %s\n",
980 info.facing == hardware::CAMERA_FACING_BACK ? "Back" : "Front");
981 dprintf(fd, " Orientation: %d\n", info.orientation);
982 }
983 CameraMetadata info2;
984 res = device->getCameraCharacteristics(&info2);
985 if (res == INVALID_OPERATION) {
986 dprintf(fd, " API2 not directly supported\n");
987 } else if (res != OK) {
988 dprintf(fd, " <Error reading camera characteristics: %s (%d)>\n",
989 strerror(-res), res);
990 } else {
991 dprintf(fd, " API2 camera characteristics:\n");
992 info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
993 }
Yin-Chia Yeh487785a2018-01-02 12:06:57 -0800994
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700995 // Dump characteristics of non-standalone physical camera
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700996 if (device->mIsLogicalCamera) {
997 for (auto& id : device->mPhysicalIds) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -0700998 // Skip if physical id is an independent camera
999 if (std::find(mProviderPublicCameraIds.begin(), mProviderPublicCameraIds.end(), id)
1000 != mProviderPublicCameraIds.end()) {
1001 continue;
1002 }
1003
1004 CameraMetadata physicalInfo;
1005 status_t status = device->getPhysicalCameraCharacteristics(id, &physicalInfo);
1006 if (status == OK) {
1007 dprintf(fd, " Physical camera %s characteristics:\n", id.c_str());
1008 physicalInfo.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
1009 }
1010 }
1011 }
1012
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08001013 dprintf(fd, "== Camera HAL device %s (v%d.%d) dumpState: ==\n", device->mName.c_str(),
1014 device->mVersion.get_major(), device->mVersion.get_minor());
1015 res = device->dumpState(fd);
1016 if (res != OK) {
1017 dprintf(fd, " <Error dumping device %s state: %s (%d)>\n",
1018 device->mName.c_str(), strerror(-res), res);
1019 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001020 }
1021 return OK;
1022}
1023
1024hardware::Return<void> CameraProviderManager::ProviderInfo::cameraDeviceStatusChange(
1025 const hardware::hidl_string& cameraDeviceName,
1026 CameraDeviceStatus newStatus) {
1027 sp<StatusListener> listener;
1028 std::string id;
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001029 bool initialized = false;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001030 {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001031 std::lock_guard<std::mutex> lock(mLock);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001032 bool known = false;
1033 for (auto& deviceInfo : mDevices) {
1034 if (deviceInfo->mName == cameraDeviceName) {
1035 ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
1036 deviceStatusToString(newStatus), deviceStatusToString(deviceInfo->mStatus));
1037 deviceInfo->mStatus = newStatus;
1038 // TODO: Handle device removal (NOT_PRESENT)
1039 id = deviceInfo->mId;
1040 known = true;
1041 break;
1042 }
1043 }
1044 // Previously unseen device; status must not be NOT_PRESENT
1045 if (!known) {
1046 if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
1047 ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
1048 mProviderName.c_str(), cameraDeviceName.c_str());
1049 return hardware::Void();
1050 }
1051 addDevice(cameraDeviceName, newStatus, &id);
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +01001052 } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
1053 removeDevice(id);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001054 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001055 listener = mManager->getStatusListener();
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001056 initialized = mInitialized;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001057 }
1058 // Call without lock held to allow reentrancy into provider manager
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08001059 // Don't send the callback if providerInfo hasn't been initialized.
1060 // CameraService will initialize device status after provider is
1061 // initialized
1062 if (listener != nullptr && initialized) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001063 listener->onDeviceStatusChanged(String8(id.c_str()), newStatus);
1064 }
1065 return hardware::Void();
1066}
1067
1068hardware::Return<void> CameraProviderManager::ProviderInfo::torchModeStatusChange(
1069 const hardware::hidl_string& cameraDeviceName,
1070 TorchModeStatus newStatus) {
1071 sp<StatusListener> listener;
1072 std::string id;
1073 {
Yin-Chia Yeh52778d42016-12-22 18:20:43 -08001074 std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001075 bool known = false;
1076 for (auto& deviceInfo : mDevices) {
1077 if (deviceInfo->mName == cameraDeviceName) {
1078 ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
1079 torchStatusToString(newStatus));
1080 id = deviceInfo->mId;
1081 known = true;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001082 if (TorchModeStatus::AVAILABLE_ON != newStatus) {
1083 mManager->removeRef(DeviceMode::TORCH, id);
1084 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001085 break;
1086 }
1087 }
1088 if (!known) {
1089 ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
1090 mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
1091 return hardware::Void();
1092 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001093 listener = mManager->getStatusListener();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001094 }
1095 // Call without lock held to allow reentrancy into provider manager
1096 if (listener != nullptr) {
1097 listener->onTorchStatusChanged(String8(id.c_str()), newStatus);
1098 }
1099 return hardware::Void();
1100}
1101
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001102void CameraProviderManager::ProviderInfo::serviceDied(uint64_t cookie,
1103 const wp<hidl::base::V1_0::IBase>& who) {
1104 (void) who;
1105 ALOGI("Camera provider '%s' has died; removing it", mProviderName.c_str());
1106 if (cookie != mId) {
1107 ALOGW("%s: Unexpected serviceDied cookie %" PRIu64 ", expected %" PRIu32,
1108 __FUNCTION__, cookie, mId);
1109 }
1110 mManager->removeProvider(mProviderName);
1111}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001112
Peter Kalauskas1b3c9072018-11-07 12:41:53 -08001113status_t CameraProviderManager::ProviderInfo::setUpVendorTags() {
1114 if (mVendorTagDescriptor != nullptr)
1115 return OK;
1116
1117 hardware::hidl_vec<VendorTagSection> vts;
1118 Status status;
1119 hardware::Return<void> ret;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001120 const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
1121 if (interface == nullptr) {
1122 return DEAD_OBJECT;
1123 }
1124 ret = interface->getVendorTags(
Peter Kalauskas1b3c9072018-11-07 12:41:53 -08001125 [&](auto s, const auto& vendorTagSecs) {
1126 status = s;
1127 if (s == Status::OK) {
1128 vts = vendorTagSecs;
1129 }
1130 });
1131 if (!ret.isOk()) {
1132 ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
1133 __FUNCTION__, mProviderName.c_str(), ret.description().c_str());
1134 return DEAD_OBJECT;
1135 }
1136 if (status != Status::OK) {
1137 return mapToStatusT(status);
1138 }
1139
1140 // Read all vendor tag definitions into a descriptor
1141 status_t res;
1142 if ((res = HidlVendorTagDescriptor::createDescriptorFromHidl(vts, /*out*/mVendorTagDescriptor))
1143 != OK) {
1144 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
1145 "received error %s (%d). Camera clients will not be able to use"
1146 "vendor tags", __FUNCTION__, strerror(res), res);
1147 return res;
1148 }
1149
1150 return OK;
1151}
1152
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001153template<class DeviceInfoT>
1154std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
1155 CameraProviderManager::ProviderInfo::initializeDeviceInfo(
Emilian Peev71c73a22017-03-21 16:35:51 +00001156 const std::string &name, const metadata_vendor_id_t tagId,
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001157 const std::string &id, uint16_t minorVersion) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001158 Status status;
1159
1160 auto cameraInterface =
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001161 startDeviceInterface<typename DeviceInfoT::InterfaceT>(name);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001162 if (cameraInterface == nullptr) return nullptr;
1163
1164 CameraResourceCost resourceCost;
1165 cameraInterface->getResourceCost([&status, &resourceCost](
1166 Status s, CameraResourceCost cost) {
1167 status = s;
1168 resourceCost = cost;
1169 });
1170 if (status != Status::OK) {
1171 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
1172 name.c_str(), statusToString(status));
1173 return nullptr;
1174 }
Shuzhen Wang47283692018-04-24 18:05:02 -07001175
1176 for (auto& conflictName : resourceCost.conflictingDevices) {
1177 uint16_t major, minor;
1178 std::string type, id;
1179 status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
1180 if (res != OK) {
1181 ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
1182 return nullptr;
1183 }
1184 conflictName = id;
1185 }
1186
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001187 return std::unique_ptr<DeviceInfo>(
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001188 new DeviceInfoT(name, tagId, id, minorVersion, resourceCost, this,
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001189 mProviderPublicCameraIds, cameraInterface));
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001190}
1191
1192template<class InterfaceT>
1193sp<InterfaceT>
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001194CameraProviderManager::ProviderInfo::startDeviceInterface(const std::string &name) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001195 ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,
1196 name.c_str(), InterfaceT::version.get_major());
1197 return nullptr;
1198}
1199
1200template<>
1201sp<device::V1_0::ICameraDevice>
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001202CameraProviderManager::ProviderInfo::startDeviceInterface
1203 <device::V1_0::ICameraDevice>(const std::string &name) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001204 Status status;
1205 sp<device::V1_0::ICameraDevice> cameraInterface;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001206 hardware::Return<void> ret;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001207 const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
1208 if (interface == nullptr) {
1209 return nullptr;
1210 }
1211 ret = interface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001212 Status s, sp<device::V1_0::ICameraDevice> interface) {
1213 status = s;
1214 cameraInterface = interface;
1215 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001216 if (!ret.isOk()) {
1217 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
1218 __FUNCTION__, name.c_str(), ret.description().c_str());
1219 return nullptr;
1220 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001221 if (status != Status::OK) {
1222 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
1223 name.c_str(), statusToString(status));
1224 return nullptr;
1225 }
1226 return cameraInterface;
1227}
1228
1229template<>
1230sp<device::V3_2::ICameraDevice>
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001231CameraProviderManager::ProviderInfo::startDeviceInterface
1232 <device::V3_2::ICameraDevice>(const std::string &name) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001233 Status status;
1234 sp<device::V3_2::ICameraDevice> cameraInterface;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001235 hardware::Return<void> ret;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001236 const sp<provider::V2_4::ICameraProvider> interface = startProviderInterface();
1237 if (interface == nullptr) {
1238 return nullptr;
1239 }
1240 ret = interface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001241 Status s, sp<device::V3_2::ICameraDevice> interface) {
1242 status = s;
1243 cameraInterface = interface;
1244 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001245 if (!ret.isOk()) {
1246 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
1247 __FUNCTION__, name.c_str(), ret.description().c_str());
1248 return nullptr;
1249 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001250 if (status != Status::OK) {
1251 ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
1252 name.c_str(), statusToString(status));
1253 return nullptr;
1254 }
1255 return cameraInterface;
1256}
1257
1258CameraProviderManager::ProviderInfo::DeviceInfo::~DeviceInfo() {}
1259
1260template<class InterfaceT>
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001261sp<InterfaceT> CameraProviderManager::ProviderInfo::DeviceInfo::startDeviceInterface() {
1262 sp<InterfaceT> device;
1263 ATRACE_CALL();
1264 if (mSavedInterface == nullptr) {
1265 device = mParentProvider->startDeviceInterface<InterfaceT>(mName);
1266 } else {
1267 device = (InterfaceT *) mSavedInterface.get();
1268 }
1269 return device;
1270}
1271
1272template<class InterfaceT>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001273status_t CameraProviderManager::ProviderInfo::DeviceInfo::setTorchMode(InterfaceT& interface,
1274 bool enabled) {
1275 Status s = interface->setTorchMode(enabled ? TorchMode::ON : TorchMode::OFF);
1276 return mapToStatusT(s);
1277}
1278
1279CameraProviderManager::ProviderInfo::DeviceInfo1::DeviceInfo1(const std::string& name,
Emilian Peev71c73a22017-03-21 16:35:51 +00001280 const metadata_vendor_id_t tagId, const std::string &id,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001281 uint16_t minorVersion,
1282 const CameraResourceCost& resourceCost,
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001283 sp<ProviderInfo> parentProvider,
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001284 const std::vector<std::string>& publicCameraIds,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001285 sp<InterfaceT> interface) :
Emilian Peev71c73a22017-03-21 16:35:51 +00001286 DeviceInfo(name, tagId, id, hardware::hidl_version{1, minorVersion},
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001287 publicCameraIds, resourceCost, parentProvider) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001288 // Get default parameters and initialize flash unit availability
1289 // Requires powering on the camera device
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001290 hardware::Return<Status> status = interface->open(nullptr);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001291 if (!status.isOk()) {
1292 ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001293 __FUNCTION__, id.c_str(), status.description().c_str());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001294 return;
1295 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001296 if (status != Status::OK) {
1297 ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001298 id.c_str(), CameraProviderManager::statusToString(status));
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001299 return;
1300 }
1301 hardware::Return<void> ret;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001302 ret = interface->getParameters([this](const hardware::hidl_string& parms) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001303 mDefaultParameters.unflatten(String8(parms.c_str()));
1304 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001305 if (!ret.isOk()) {
1306 ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001307 __FUNCTION__, id.c_str(), status.description().c_str());
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001308 return;
1309 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001310 const char *flashMode =
1311 mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
1312 if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
1313 mHasFlashUnit = true;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001314 }
1315
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001316 status_t res = cacheCameraInfo(interface);
1317 if (res != OK) {
1318 ALOGE("%s: Could not cache CameraInfo", __FUNCTION__);
1319 return;
1320 }
1321
1322 ret = interface->close();
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001323 if (!ret.isOk()) {
1324 ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001325 __FUNCTION__, id.c_str(), status.description().c_str());
1326 }
1327
1328 if (!kEnableLazyHal) {
1329 // Save HAL reference indefinitely
1330 mSavedInterface = interface;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001331 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001332}
1333
1334CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
1335
1336status_t CameraProviderManager::ProviderInfo::DeviceInfo1::setTorchMode(bool enabled) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001337 return setTorchModeForDevice<InterfaceT>(enabled);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001338}
1339
1340status_t CameraProviderManager::ProviderInfo::DeviceInfo1::getCameraInfo(
1341 hardware::CameraInfo *info) const {
1342 if (info == nullptr) return BAD_VALUE;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001343 *info = mInfo;
1344 return OK;
1345}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001346
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001347status_t CameraProviderManager::ProviderInfo::DeviceInfo1::cacheCameraInfo(
1348 sp<CameraProviderManager::ProviderInfo::DeviceInfo1::InterfaceT> interface) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001349 Status status;
1350 device::V1_0::CameraInfo cInfo;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001351 hardware::Return<void> ret;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001352 ret = interface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001353 status = s;
1354 cInfo = camInfo;
1355 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001356 if (!ret.isOk()) {
1357 ALOGE("%s: Transaction error reading camera info from device %s: %s",
1358 __FUNCTION__, mId.c_str(), ret.description().c_str());
1359 return DEAD_OBJECT;
1360 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001361 if (status != Status::OK) {
1362 return mapToStatusT(status);
1363 }
1364
1365 switch(cInfo.facing) {
1366 case device::V1_0::CameraFacing::BACK:
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001367 mInfo.facing = hardware::CAMERA_FACING_BACK;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001368 break;
1369 case device::V1_0::CameraFacing::EXTERNAL:
1370 // Map external to front for legacy API
1371 case device::V1_0::CameraFacing::FRONT:
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001372 mInfo.facing = hardware::CAMERA_FACING_FRONT;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001373 break;
1374 default:
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001375 ALOGW("%s: Device %s: Unknown camera facing: %d",
1376 __FUNCTION__, mId.c_str(), cInfo.facing);
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001377 mInfo.facing = hardware::CAMERA_FACING_BACK;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001378 }
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001379 mInfo.orientation = cInfo.orientation;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001380
1381 return OK;
1382}
1383
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001384status_t CameraProviderManager::ProviderInfo::DeviceInfo1::dumpState(int fd) {
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08001385 native_handle_t* handle = native_handle_create(1,0);
1386 handle->data[0] = fd;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001387 const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
1388 if (interface == nullptr) {
1389 return DEAD_OBJECT;
1390 }
1391 hardware::Return<Status> s = interface->dumpState(handle);
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08001392 native_handle_delete(handle);
1393 if (!s.isOk()) {
1394 return INVALID_OPERATION;
1395 }
1396 return mapToStatusT(s);
1397}
1398
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001399CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
Emilian Peev71c73a22017-03-21 16:35:51 +00001400 const metadata_vendor_id_t tagId, const std::string &id,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001401 uint16_t minorVersion,
1402 const CameraResourceCost& resourceCost,
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001403 sp<ProviderInfo> parentProvider,
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001404 const std::vector<std::string>& publicCameraIds,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001405 sp<InterfaceT> interface) :
Emilian Peev71c73a22017-03-21 16:35:51 +00001406 DeviceInfo(name, tagId, id, hardware::hidl_version{3, minorVersion},
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001407 publicCameraIds, resourceCost, parentProvider) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001408 // Get camera characteristics and initialize flash unit availability
1409 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001410 hardware::Return<void> ret;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001411 ret = interface->getCameraCharacteristics([&status, this](Status s,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001412 device::V3_2::CameraMetadata metadata) {
1413 status = s;
1414 if (s == Status::OK) {
1415 camera_metadata_t *buffer =
1416 reinterpret_cast<camera_metadata_t*>(metadata.data());
Yin-Chia Yeh238ef5f2017-04-18 15:01:15 -07001417 size_t expectedSize = metadata.size();
1418 int res = validate_camera_metadata_structure(buffer, &expectedSize);
1419 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
1420 set_camera_metadata_vendor_id(buffer, mProviderTagid);
1421 mCameraCharacteristics = buffer;
1422 } else {
1423 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
1424 status = Status::INTERNAL_ERROR;
1425 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001426 }
1427 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001428 if (!ret.isOk()) {
1429 ALOGE("%s: Transaction error getting camera characteristics for device %s"
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001430 " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07001431 ret.description().c_str());
1432 return;
1433 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001434 if (status != Status::OK) {
1435 ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001436 __FUNCTION__, id.c_str(), CameraProviderManager::statusToString(status), status);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001437 return;
1438 }
Shuzhen Wang268a1362018-10-16 16:32:59 -07001439 status_t res = fixupMonochromeTags();
1440 if (OK != res) {
1441 ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
1442 __FUNCTION__, strerror(-res), res);
1443 return;
1444 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001445 camera_metadata_entry flashAvailable =
1446 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
1447 if (flashAvailable.count == 1 &&
1448 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
1449 mHasFlashUnit = true;
1450 } else {
1451 mHasFlashUnit = false;
1452 }
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001453
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001454 queryPhysicalCameraIds();
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001455 // Get physical camera characteristics if applicable
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001456 auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001457 if (!castResult.isOk()) {
1458 ALOGV("%s: Unable to convert ICameraDevice instance to version 3.5", __FUNCTION__);
1459 return;
1460 }
Peter Kalauskasb7bd4382018-11-15 17:19:48 -08001461 sp<device::V3_5::ICameraDevice> interface_3_5 = castResult;
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001462 if (interface_3_5 == nullptr) {
1463 ALOGE("%s: Converted ICameraDevice instance to nullptr", __FUNCTION__);
1464 return;
1465 }
1466
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001467 if (mIsLogicalCamera) {
1468 for (auto& id : mPhysicalIds) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001469 if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
1470 mPublicCameraIds.end()) {
1471 continue;
1472 }
1473
1474 hardware::hidl_string hidlId(id);
1475 ret = interface_3_5->getPhysicalCameraCharacteristics(hidlId,
1476 [&status, &id, this](Status s, device::V3_2::CameraMetadata metadata) {
1477 status = s;
1478 if (s == Status::OK) {
1479 camera_metadata_t *buffer =
1480 reinterpret_cast<camera_metadata_t*>(metadata.data());
1481 size_t expectedSize = metadata.size();
1482 int res = validate_camera_metadata_structure(buffer, &expectedSize);
1483 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
1484 set_camera_metadata_vendor_id(buffer, mProviderTagid);
1485 mPhysicalCameraCharacteristics[id] = buffer;
1486 } else {
1487 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
1488 status = Status::INTERNAL_ERROR;
1489 }
1490 }
1491 });
1492
1493 if (!ret.isOk()) {
1494 ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001495 __FUNCTION__, id.c_str(), id.c_str(), ret.description().c_str());
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001496 return;
1497 }
1498 if (status != Status::OK) {
1499 ALOGE("%s: Unable to get physical camera %s characteristics for device %s: %s (%d)",
1500 __FUNCTION__, id.c_str(), mId.c_str(),
1501 CameraProviderManager::statusToString(status), status);
1502 return;
1503 }
1504 }
1505 }
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001506
1507 if (!kEnableLazyHal) {
1508 // Save HAL reference indefinitely
1509 mSavedInterface = interface;
1510 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001511}
1512
1513CameraProviderManager::ProviderInfo::DeviceInfo3::~DeviceInfo3() {}
1514
1515status_t CameraProviderManager::ProviderInfo::DeviceInfo3::setTorchMode(bool enabled) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001516 return setTorchModeForDevice<InterfaceT>(enabled);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001517}
1518
1519status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
1520 hardware::CameraInfo *info) const {
1521 if (info == nullptr) return BAD_VALUE;
1522
1523 camera_metadata_ro_entry facing =
1524 mCameraCharacteristics.find(ANDROID_LENS_FACING);
1525 if (facing.count == 1) {
1526 switch (facing.data.u8[0]) {
1527 case ANDROID_LENS_FACING_BACK:
1528 info->facing = hardware::CAMERA_FACING_BACK;
1529 break;
1530 case ANDROID_LENS_FACING_EXTERNAL:
1531 // Map external to front for legacy API
1532 case ANDROID_LENS_FACING_FRONT:
1533 info->facing = hardware::CAMERA_FACING_FRONT;
1534 break;
1535 }
1536 } else {
1537 ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
1538 return NAME_NOT_FOUND;
1539 }
1540
1541 camera_metadata_ro_entry orientation =
1542 mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
1543 if (orientation.count == 1) {
1544 info->orientation = orientation.data.i32[0];
1545 } else {
1546 ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
1547 return NAME_NOT_FOUND;
1548 }
1549
1550 return OK;
1551}
Emilian Peevf53f66e2017-04-11 14:29:43 +01001552bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const {
1553 bool isBackwardCompatible = false;
1554 camera_metadata_ro_entry_t caps = mCameraCharacteristics.find(
1555 ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1556 for (size_t i = 0; i < caps.count; i++) {
1557 if (caps.data.u8[i] ==
1558 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
1559 isBackwardCompatible = true;
1560 break;
1561 }
1562 }
1563
1564 return isBackwardCompatible;
1565}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001566
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001567status_t CameraProviderManager::ProviderInfo::DeviceInfo3::dumpState(int fd) {
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08001568 native_handle_t* handle = native_handle_create(1,0);
1569 handle->data[0] = fd;
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001570 const sp<InterfaceT> interface = startDeviceInterface<InterfaceT>();
1571 if (interface == nullptr) {
1572 return DEAD_OBJECT;
1573 }
1574 auto ret = interface->dumpState(handle);
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08001575 native_handle_delete(handle);
1576 if (!ret.isOk()) {
1577 return INVALID_OPERATION;
1578 }
1579 return OK;
1580}
1581
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001582status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
1583 CameraMetadata *characteristics) const {
1584 if (characteristics == nullptr) return BAD_VALUE;
1585
1586 *characteristics = mCameraCharacteristics;
1587 return OK;
1588}
1589
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001590status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getPhysicalCameraCharacteristics(
1591 const std::string& physicalCameraId, CameraMetadata *characteristics) const {
1592 if (characteristics == nullptr) return BAD_VALUE;
1593 if (mPhysicalCameraCharacteristics.find(physicalCameraId) ==
1594 mPhysicalCameraCharacteristics.end()) {
1595 return NAME_NOT_FOUND;
1596 }
1597
1598 *characteristics = mPhysicalCameraCharacteristics.at(physicalCameraId);
1599 return OK;
1600}
1601
Emilian Peev35ae8262018-11-08 13:11:32 +00001602status_t CameraProviderManager::ProviderInfo::DeviceInfo3::isSessionConfigurationSupported(
1603 const hardware::camera::device::V3_4::StreamConfiguration &configuration,
Peter Kalauskasa29c1352018-10-10 12:05:42 -07001604 bool *status /*out*/) {
1605
1606 const sp<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT> interface =
1607 this->startDeviceInterface<CameraProviderManager::ProviderInfo::DeviceInfo3::InterfaceT>();
1608 if (interface == nullptr) {
1609 return DEAD_OBJECT;
1610 }
1611 auto castResult = device::V3_5::ICameraDevice::castFrom(interface);
Emilian Peev35ae8262018-11-08 13:11:32 +00001612 sp<hardware::camera::device::V3_5::ICameraDevice> interface_3_5 = castResult;
1613 if (interface_3_5 == nullptr) {
1614 return INVALID_OPERATION;
1615 }
1616
1617 status_t res;
1618 Status callStatus;
1619 auto ret = interface_3_5->isStreamCombinationSupported(configuration,
1620 [&callStatus, &status] (Status s, bool combStatus) {
1621 callStatus = s;
1622 *status = combStatus;
1623 });
1624 if (ret.isOk()) {
1625 switch (callStatus) {
1626 case Status::OK:
1627 // Expected case, do nothing.
1628 res = OK;
1629 break;
1630 case Status::METHOD_NOT_SUPPORTED:
1631 res = INVALID_OPERATION;
1632 break;
1633 default:
1634 ALOGE("%s: Session configuration query failed: %d", __FUNCTION__, callStatus);
1635 res = UNKNOWN_ERROR;
1636 }
1637 } else {
1638 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.description().c_str());
1639 res = UNKNOWN_ERROR;
1640 }
1641
1642 return res;
1643}
1644
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001645status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
1646 std::string *type, uint32_t *id) {
1647 // Format must be "<type>/<id>"
1648#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. " \
1649 "Should match '<type>/<id>' - "
1650
1651 if (!type || !id) return INVALID_OPERATION;
1652
1653 std::string::size_type slashIdx = name.find('/');
1654 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
1655 ALOGE(ERROR_MSG_PREFIX
1656 "does not have / separator between type and id",
1657 __FUNCTION__, name.c_str());
1658 return BAD_VALUE;
1659 }
1660
1661 std::string typeVal = name.substr(0, slashIdx);
1662
1663 char *endPtr;
1664 errno = 0;
1665 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
1666 if (errno != 0) {
1667 ALOGE(ERROR_MSG_PREFIX
1668 "cannot parse provider id as an integer: %s (%d)",
1669 __FUNCTION__, name.c_str(), strerror(errno), errno);
1670 return BAD_VALUE;
1671 }
1672 if (endPtr != name.c_str() + name.size()) {
1673 ALOGE(ERROR_MSG_PREFIX
1674 "provider id has unexpected length",
1675 __FUNCTION__, name.c_str());
1676 return BAD_VALUE;
1677 }
1678 if (idVal < 0) {
1679 ALOGE(ERROR_MSG_PREFIX
1680 "id is negative: %ld",
1681 __FUNCTION__, name.c_str(), idVal);
1682 return BAD_VALUE;
1683 }
1684
1685#undef ERROR_MSG_PREFIX
1686
1687 *type = typeVal;
1688 *id = static_cast<uint32_t>(idVal);
1689
1690 return OK;
1691}
1692
Emilian Peev71c73a22017-03-21 16:35:51 +00001693metadata_vendor_id_t CameraProviderManager::ProviderInfo::generateVendorTagId(
1694 const std::string &name) {
1695 metadata_vendor_id_t ret = std::hash<std::string> {} (name);
1696 // CAMERA_METADATA_INVALID_VENDOR_ID is not a valid hash value
1697 if (CAMERA_METADATA_INVALID_VENDOR_ID == ret) {
1698 ret = 0;
1699 }
1700
1701 return ret;
1702}
1703
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001704status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
1705 uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
1706
1707 // Format must be "device@<major>.<minor>/<type>/<id>"
1708
1709#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
1710 "Should match 'device@<major>.<minor>/<type>/<id>' - "
1711
1712 if (!major || !minor || !type || !id) return INVALID_OPERATION;
1713
1714 // Verify starting prefix
1715 const char expectedPrefix[] = "device@";
1716
1717 if (name.find(expectedPrefix) != 0) {
1718 ALOGE(ERROR_MSG_PREFIX
1719 "does not start with '%s'",
1720 __FUNCTION__, name.c_str(), expectedPrefix);
1721 return BAD_VALUE;
1722 }
1723
1724 // Extract major/minor versions
1725 constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
1726 std::string::size_type dotIdx = name.find('.', atIdx);
1727 if (dotIdx == std::string::npos) {
1728 ALOGE(ERROR_MSG_PREFIX
1729 "does not have @<major>. version section",
1730 __FUNCTION__, name.c_str());
1731 return BAD_VALUE;
1732 }
1733 std::string::size_type typeSlashIdx = name.find('/', dotIdx);
1734 if (typeSlashIdx == std::string::npos) {
1735 ALOGE(ERROR_MSG_PREFIX
1736 "does not have .<minor>/ version section",
1737 __FUNCTION__, name.c_str());
1738 return BAD_VALUE;
1739 }
1740
1741 char *endPtr;
1742 errno = 0;
1743 long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
1744 if (errno != 0) {
1745 ALOGE(ERROR_MSG_PREFIX
1746 "cannot parse major version: %s (%d)",
1747 __FUNCTION__, name.c_str(), strerror(errno), errno);
1748 return BAD_VALUE;
1749 }
1750 if (endPtr != name.c_str() + dotIdx) {
1751 ALOGE(ERROR_MSG_PREFIX
1752 "major version has unexpected length",
1753 __FUNCTION__, name.c_str());
1754 return BAD_VALUE;
1755 }
1756 long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
1757 if (errno != 0) {
1758 ALOGE(ERROR_MSG_PREFIX
1759 "cannot parse minor version: %s (%d)",
1760 __FUNCTION__, name.c_str(), strerror(errno), errno);
1761 return BAD_VALUE;
1762 }
1763 if (endPtr != name.c_str() + typeSlashIdx) {
1764 ALOGE(ERROR_MSG_PREFIX
1765 "minor version has unexpected length",
1766 __FUNCTION__, name.c_str());
1767 return BAD_VALUE;
1768 }
1769 if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
1770 ALOGE(ERROR_MSG_PREFIX
1771 "major/minor version is out of range of uint16_t: %ld.%ld",
1772 __FUNCTION__, name.c_str(), majorVal, minorVal);
1773 return BAD_VALUE;
1774 }
1775
1776 // Extract type and id
1777
1778 std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
1779 if (instanceSlashIdx == std::string::npos) {
1780 ALOGE(ERROR_MSG_PREFIX
1781 "does not have /<type>/ component",
1782 __FUNCTION__, name.c_str());
1783 return BAD_VALUE;
1784 }
1785 std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
1786
1787 if (instanceSlashIdx == name.size() - 1) {
1788 ALOGE(ERROR_MSG_PREFIX
1789 "does not have an /<id> component",
1790 __FUNCTION__, name.c_str());
1791 return BAD_VALUE;
1792 }
1793 std::string idVal = name.substr(instanceSlashIdx + 1);
1794
1795#undef ERROR_MSG_PREFIX
1796
1797 *major = static_cast<uint16_t>(majorVal);
1798 *minor = static_cast<uint16_t>(minorVal);
1799 *type = typeVal;
1800 *id = idVal;
1801
1802 return OK;
1803}
1804
1805
1806
1807CameraProviderManager::ProviderInfo::~ProviderInfo() {
1808 // Destruction of ProviderInfo is only supposed to happen when the respective
1809 // CameraProvider interface dies, so do not unregister callbacks.
1810
1811}
1812
1813status_t CameraProviderManager::mapToStatusT(const Status& s) {
1814 switch(s) {
1815 case Status::OK:
1816 return OK;
1817 case Status::ILLEGAL_ARGUMENT:
1818 return BAD_VALUE;
1819 case Status::CAMERA_IN_USE:
1820 return -EBUSY;
1821 case Status::MAX_CAMERAS_IN_USE:
1822 return -EUSERS;
1823 case Status::METHOD_NOT_SUPPORTED:
1824 return UNKNOWN_TRANSACTION;
1825 case Status::OPERATION_NOT_SUPPORTED:
1826 return INVALID_OPERATION;
1827 case Status::CAMERA_DISCONNECTED:
1828 return DEAD_OBJECT;
1829 case Status::INTERNAL_ERROR:
1830 return INVALID_OPERATION;
1831 }
1832 ALOGW("Unexpected HAL status code %d", s);
1833 return INVALID_OPERATION;
1834}
1835
1836const char* CameraProviderManager::statusToString(const Status& s) {
1837 switch(s) {
1838 case Status::OK:
1839 return "OK";
1840 case Status::ILLEGAL_ARGUMENT:
1841 return "ILLEGAL_ARGUMENT";
1842 case Status::CAMERA_IN_USE:
1843 return "CAMERA_IN_USE";
1844 case Status::MAX_CAMERAS_IN_USE:
1845 return "MAX_CAMERAS_IN_USE";
1846 case Status::METHOD_NOT_SUPPORTED:
1847 return "METHOD_NOT_SUPPORTED";
1848 case Status::OPERATION_NOT_SUPPORTED:
1849 return "OPERATION_NOT_SUPPORTED";
1850 case Status::CAMERA_DISCONNECTED:
1851 return "CAMERA_DISCONNECTED";
1852 case Status::INTERNAL_ERROR:
1853 return "INTERNAL_ERROR";
1854 }
1855 ALOGW("Unexpected HAL status code %d", s);
1856 return "UNKNOWN_ERROR";
1857}
1858
1859const char* CameraProviderManager::deviceStatusToString(const CameraDeviceStatus& s) {
1860 switch(s) {
1861 case CameraDeviceStatus::NOT_PRESENT:
1862 return "NOT_PRESENT";
1863 case CameraDeviceStatus::PRESENT:
1864 return "PRESENT";
1865 case CameraDeviceStatus::ENUMERATING:
1866 return "ENUMERATING";
1867 }
1868 ALOGW("Unexpected HAL device status code %d", s);
1869 return "UNKNOWN_STATUS";
1870}
1871
1872const char* CameraProviderManager::torchStatusToString(const TorchModeStatus& s) {
1873 switch(s) {
1874 case TorchModeStatus::NOT_AVAILABLE:
1875 return "NOT_AVAILABLE";
1876 case TorchModeStatus::AVAILABLE_OFF:
1877 return "AVAILABLE_OFF";
1878 case TorchModeStatus::AVAILABLE_ON:
1879 return "AVAILABLE_ON";
1880 }
1881 ALOGW("Unexpected HAL torch mode status code %d", s);
1882 return "UNKNOWN_STATUS";
1883}
1884
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001885
1886status_t HidlVendorTagDescriptor::createDescriptorFromHidl(
Peter Kalauskasb7bd4382018-11-15 17:19:48 -08001887 const hardware::hidl_vec<common::V1_0::VendorTagSection>& vts,
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001888 /*out*/
1889 sp<VendorTagDescriptor>& descriptor) {
1890
1891 int tagCount = 0;
1892
1893 for (size_t s = 0; s < vts.size(); s++) {
1894 tagCount += vts[s].tags.size();
1895 }
1896
1897 if (tagCount < 0 || tagCount > INT32_MAX) {
1898 ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
1899 return BAD_VALUE;
1900 }
1901
1902 Vector<uint32_t> tagArray;
1903 LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
1904 "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
1905
1906
1907 sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
1908 desc->mTagCount = tagCount;
1909
1910 SortedVector<String8> sections;
1911 KeyedVector<uint32_t, String8> tagToSectionMap;
1912
1913 int idx = 0;
1914 for (size_t s = 0; s < vts.size(); s++) {
Peter Kalauskasb7bd4382018-11-15 17:19:48 -08001915 const common::V1_0::VendorTagSection& section = vts[s];
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001916 const char *sectionName = section.sectionName.c_str();
1917 if (sectionName == NULL) {
1918 ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
1919 return BAD_VALUE;
1920 }
1921 String8 sectionString(sectionName);
1922 sections.add(sectionString);
1923
1924 for (size_t j = 0; j < section.tags.size(); j++) {
1925 uint32_t tag = section.tags[j].tagId;
1926 if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
1927 ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
1928 return BAD_VALUE;
1929 }
1930
1931 tagArray.editItemAt(idx++) = section.tags[j].tagId;
1932
1933 const char *tagName = section.tags[j].tagName.c_str();
1934 if (tagName == NULL) {
1935 ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
1936 return BAD_VALUE;
1937 }
1938 desc->mTagToNameMap.add(tag, String8(tagName));
1939 tagToSectionMap.add(tag, sectionString);
1940
1941 int tagType = (int) section.tags[j].tagType;
1942 if (tagType < 0 || tagType >= NUM_TYPES) {
1943 ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
1944 return BAD_VALUE;
1945 }
1946 desc->mTagToTypeMap.add(tag, tagType);
1947 }
1948 }
1949
1950 desc->mSections = sections;
1951
1952 for (size_t i = 0; i < tagArray.size(); ++i) {
1953 uint32_t tag = tagArray[i];
1954 String8 sectionString = tagToSectionMap.valueFor(tag);
1955
1956 // Set up tag to section index map
1957 ssize_t index = sections.indexOf(sectionString);
1958 LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
1959 desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
1960
1961 // Set up reverse mapping
1962 ssize_t reverseIndex = -1;
1963 if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
1964 KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
1965 reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
1966 }
1967 desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
1968 }
1969
George Burgess IVa0b84962017-08-29 17:46:19 -07001970 descriptor = std::move(desc);
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08001971 return OK;
1972}
1973
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001974status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
1975 CameraMetadata* characteristics) const {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001976 auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {5,0});
1977 if (deviceInfo != nullptr) {
1978 return deviceInfo->getCameraCharacteristics(characteristics);
1979 }
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001980
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07001981 // Find hidden physical camera characteristics
1982 for (auto& provider : mProviders) {
1983 for (auto& deviceInfo : provider->mDevices) {
1984 status_t res = deviceInfo->getPhysicalCameraCharacteristics(id, characteristics);
1985 if (res != NAME_NOT_FOUND) return res;
1986 }
1987 }
1988
1989 return NAME_NOT_FOUND;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001990}
1991
1992void CameraProviderManager::filterLogicalCameraIdsLocked(
1993 std::vector<std::string>& deviceIds) const
1994{
1995 std::unordered_set<std::string> removedIds;
1996
1997 for (auto& deviceId : deviceIds) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001998 auto deviceInfo = findDeviceInfoLocked(deviceId);
1999 if (deviceInfo == nullptr) continue;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07002000
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07002001 if (!deviceInfo->mIsLogicalCamera) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -07002002 continue;
2003 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07002004 // idCombo contains the ids of a logical camera and its physical cameras
2005 std::vector<std::string> idCombo = deviceInfo->mPhysicalIds;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07002006 idCombo.push_back(deviceId);
2007
2008 for (auto& id : deviceIds) {
2009 auto foundId = std::find(idCombo.begin(), idCombo.end(), id);
2010 if (foundId == idCombo.end()) {
2011 continue;
2012 }
2013
2014 idCombo.erase(foundId);
2015 removedIds.insert(idCombo.begin(), idCombo.end());
2016 break;
2017 }
2018 }
2019
2020 deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
2021 [&removedIds](const std::string& s) {return removedIds.find(s) != removedIds.end();}),
2022 deviceIds.end());
2023}
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08002024
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002025} // namespace android