blob: 26864fc0fa98a0907b6705d5032f77d878d07ab2 [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
Emilian Peev434248e2022-10-06 14:58:54 -070017#include "system/graphics-base-v1.0.h"
18#include "system/graphics-base-v1.1.h"
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080019#define LOG_TAG "CameraProviderManager"
20#define ATRACE_TAG ATRACE_TAG_CAMERA
21//#define LOG_NDEBUG 0
22
23#include "CameraProviderManager.h"
24
Jayant Chowdharya04055f2022-01-03 02:07:49 +000025#include <aidl/android/hardware/camera/device/ICameraDevice.h>
Shuzhen Wangf9d2c022018-08-21 12:07:35 -070026
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080027#include <algorithm>
Yin-Chia Yeh65405092017-01-13 15:42:28 -080028#include <chrono>
Emilian Peevcbf174b2019-01-25 14:38:59 -080029#include "common/DepthPhotoProcessor.h"
Jayant Chowdhary0bd38522021-11-05 17:49:27 -070030#include "hidl/HidlProviderInfo.h"
Jayant Chowdharya04055f2022-01-03 02:07:49 +000031#include "aidl/AidlProviderInfo.h"
Emilian Peevcbf174b2019-01-25 14:38:59 -080032#include <dlfcn.h>
Peter Kalauskasa29c1352018-10-10 12:05:42 -070033#include <future>
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -070034#include <inttypes.h>
Jan Sebechlebskya79c9392023-11-17 16:03:25 +010035#include <android_companion_virtualdevice_flags.h>
Jan Sebechlebsky2f66b5e2024-01-16 17:00:26 +010036#include <android_companion_virtualdevice_build_flags.h>
Ravneet Dhanjal7f7ab672024-07-18 22:43:04 +000037#include <android/binder_libbinder.h>
Jayant Chowdharya04055f2022-01-03 02:07:49 +000038#include <android/binder_manager.h>
Yin-Chia Yeh177b0c12019-06-25 10:53:03 -070039#include <android/hidl/manager/1.2/IServiceManager.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080040#include <hidl/ServiceManagement.h>
Jayant Chowdharyd65d9442023-07-11 01:18:06 +000041#include <com_android_internal_camera_flags.h>
Jayant Chowdhary81d81b02024-02-15 19:13:39 +000042#include <com_android_window_flags.h>
Emilian Peev71c73a22017-03-21 16:35:51 +000043#include <functional>
44#include <camera_metadata_hidden.h>
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080045#include <android-base/parseint.h>
Peter Kalauskasa29c1352018-10-10 12:05:42 -070046#include <android-base/logging.h>
47#include <cutils/properties.h>
48#include <hwbinder/IPCThreadState.h>
49#include <utils/Trace.h>
Emilian Peev434248e2022-10-06 14:58:54 -070050#include <ui/PublicFormat.h>
Austin Borger1c1bee02023-06-01 16:51:35 -070051#include <camera/StringUtils.h>
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080052
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080053#include "api2/HeicCompositeStream.h"
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -080054#include "device3/ZoomRatioMapper.h"
Eino-Ville Talvalab7723202024-06-24 17:45:51 -070055#include "utils/Utils.h"
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080056
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080057namespace android {
58
59using namespace ::android::hardware::camera;
Austin Borgerea931242021-12-13 23:10:41 +000060using namespace ::android::camera3;
Jayant Chowdhary0bd38522021-11-05 17:49:27 -070061using android::hardware::camera::common::V1_0::Status;
62using namespace camera3::SessionConfigurationUtils;
Peter Kalauskasa29c1352018-10-10 12:05:42 -070063using std::literals::chrono_literals::operator""s;
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -080064using hardware::camera2::utils::CameraIdAndSessionConfiguration;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080065
Jayant Chowdharyd65d9442023-07-11 01:18:06 +000066namespace flags = com::android::internal::camera::flags;
Jan Sebechlebskya79c9392023-11-17 16:03:25 +010067namespace vd_flags = android::companion::virtualdevice::flags;
Jayant Chowdhary81d81b02024-02-15 19:13:39 +000068namespace wm_flags = com::android::window::flags;
Jayant Chowdharyd65d9442023-07-11 01:18:06 +000069
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080070namespace {
Peter Kalauskasa29c1352018-10-10 12:05:42 -070071const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
Valentin Iftime29e2e152021-08-13 15:17:33 +020072const std::string kExternalProviderName = "external/0";
Vadim Caen7eccd7c2023-10-03 16:26:33 +020073const std::string kVirtualProviderName = "virtual/0";
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080074} // anonymous namespace
75
Emilian Peev538c90e2018-12-17 18:03:19 +000076const float CameraProviderManager::kDepthARTolerance = .1f;
Emilian Peev434248e2022-10-06 14:58:54 -070077const bool CameraProviderManager::kFrameworkJpegRDisabled =
78 property_get_bool("ro.camera.disableJpegR", false);
Emilian Peev538c90e2018-12-17 18:03:19 +000079
Jayant Chowdhary0bd38522021-11-05 17:49:27 -070080CameraProviderManager::HidlServiceInteractionProxyImpl
81CameraProviderManager::sHidlServiceInteractionProxy{};
Vadim Caen7eccd7c2023-10-03 16:26:33 +020082CameraProviderManager::AidlServiceInteractionProxyImpl
83CameraProviderManager::sAidlServiceInteractionProxy{};
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080084
85CameraProviderManager::~CameraProviderManager() {
86}
87
Jayant Chowdharya04055f2022-01-03 02:07:49 +000088const char* FrameworkTorchStatusToString(const TorchModeStatus& s) {
89 switch (s) {
90 case TorchModeStatus::NOT_AVAILABLE:
91 return "NOT_AVAILABLE";
92 case TorchModeStatus::AVAILABLE_OFF:
93 return "AVAILABLE_OFF";
94 case TorchModeStatus::AVAILABLE_ON:
95 return "AVAILABLE_ON";
96 }
Eino-Ville Talvalab7723202024-06-24 17:45:51 -070097 ALOGW("Unexpected HAL torch mode status code %d", eToI(s));
Jayant Chowdharya04055f2022-01-03 02:07:49 +000098 return "UNKNOWN_STATUS";
99}
100
101const char* FrameworkDeviceStatusToString(const CameraDeviceStatus& s) {
102 switch (s) {
103 case CameraDeviceStatus::NOT_PRESENT:
104 return "NOT_PRESENT";
105 case CameraDeviceStatus::PRESENT:
106 return "PRESENT";
107 case CameraDeviceStatus::ENUMERATING:
108 return "ENUMERATING";
109 }
Eino-Ville Talvalab7723202024-06-24 17:45:51 -0700110 ALOGW("Unexpected HAL device status code %d", eToI(s));
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000111 return "UNKNOWN_STATUS";
112}
113
Yin-Chia Yeh177b0c12019-06-25 10:53:03 -0700114hardware::hidl_vec<hardware::hidl_string>
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700115CameraProviderManager::HidlServiceInteractionProxyImpl::listServices() {
Yin-Chia Yeh177b0c12019-06-25 10:53:03 -0700116 hardware::hidl_vec<hardware::hidl_string> ret;
117 auto manager = hardware::defaultServiceManager1_2();
118 if (manager != nullptr) {
119 manager->listManifestByInterface(provider::V2_4::ICameraProvider::descriptor,
120 [&ret](const hardware::hidl_vec<hardware::hidl_string> &registered) {
121 ret = registered;
122 });
123 }
124 return ret;
125}
126
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000127status_t CameraProviderManager::tryToInitAndAddHidlProvidersLocked(
128 HidlServiceInteractionProxy *hidlProxy) {
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700129 mHidlServiceProxy = hidlProxy;
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -0800130 // Registering will trigger notifications for all already-known providers
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700131 bool success = mHidlServiceProxy->registerForNotifications(
Yin-Chia Yeh4c5b1c72017-01-31 13:20:56 -0800132 /* instance name, empty means no filter */ "",
133 this);
134 if (!success) {
135 ALOGE("%s: Unable to register with hardware service manager for notifications "
136 "about camera providers", __FUNCTION__);
137 return INVALID_OPERATION;
Yin-Chia Yeh65405092017-01-13 15:42:28 -0800138 }
Emilian Peev5d7e5152017-02-22 15:37:48 +0000139
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700140 for (const auto& instance : mHidlServiceProxy->listServices()) {
141 this->addHidlProviderLocked(instance);
Yin-Chia Yeh177b0c12019-06-25 10:53:03 -0700142 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000143 return OK;
144}
145
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200146std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>
Avichal Rakesh682788a2024-01-11 18:01:36 -0800147CameraProviderManager::AidlServiceInteractionProxyImpl::getService(
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200148 const std::string& serviceName) {
149 using aidl::android::hardware::camera::provider::ICameraProvider;
150
151 AIBinder* binder = nullptr;
152 if (flags::lazy_aidl_wait_for_service()) {
153 binder = AServiceManager_waitForService(serviceName.c_str());
154 } else {
Ravneet Dhanjal81371f12024-01-04 22:13:03 +0000155 binder = AServiceManager_checkService(serviceName.c_str());
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200156 }
157
158 if (binder == nullptr) {
Avichal Rakesh682788a2024-01-11 18:01:36 -0800159 ALOGE("%s: AIDL Camera provider HAL '%s' is not actually available, despite waiting "
160 "indefinitely?", __FUNCTION__, serviceName.c_str());
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200161 return nullptr;
162 }
163 std::shared_ptr<ICameraProvider> interface =
164 ICameraProvider::fromBinder(ndk::SpAIBinder(binder));
165
166 return interface;
Avichal Rakesh682788a2024-01-11 18:01:36 -0800167}
168
169std::shared_ptr<aidl::android::hardware::camera::provider::ICameraProvider>
170CameraProviderManager::AidlServiceInteractionProxyImpl::tryGetService(
171 const std::string& serviceName) {
172 using aidl::android::hardware::camera::provider::ICameraProvider;
173
174 std::shared_ptr<ICameraProvider> interface = ICameraProvider::fromBinder(
175 ndk::SpAIBinder(AServiceManager_checkService(serviceName.c_str())));
176 if (interface == nullptr) {
177 ALOGD("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
178 serviceName.c_str());
179 return nullptr;
180 }
181
182 return interface;
183}
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200184
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000185static std::string getFullAidlProviderName(const std::string instance) {
186 std::string aidlHalServiceDescriptor =
187 std::string(aidl::android::hardware::camera::provider::ICameraProvider::descriptor);
188 return aidlHalServiceDescriptor + "/" + instance;
189}
190
191status_t CameraProviderManager::tryToAddAidlProvidersLocked() {
192 const char * aidlHalServiceDescriptor =
193 aidl::android::hardware::camera::provider::ICameraProvider::descriptor;
194 auto sm = defaultServiceManager();
195 auto aidlProviders = sm->getDeclaredInstances(
196 String16(aidlHalServiceDescriptor));
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200197
198 if (isVirtualCameraHalEnabled()) {
199 // Virtual Camera provider is not declared in the VINTF manifest so we
200 // manually add it if the binary is present.
201 aidlProviders.push_back(String16(kVirtualProviderName.c_str()));
202 }
203
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000204 for (const auto &aidlInstance : aidlProviders) {
205 std::string aidlServiceName =
Austin Borger1c1bee02023-06-01 16:51:35 -0700206 getFullAidlProviderName(toStdString(aidlInstance));
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000207 auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
208 if (res != OK) {
209 ALOGE("%s Unable to register for notifications with AIDL service manager",
210 __FUNCTION__);
211 return res;
212 }
Greg Kaiserae692fb2022-02-10 07:32:06 -0800213 addAidlProviderLocked(aidlServiceName);
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000214 }
215 return OK;
216}
217
218status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200219 HidlServiceInteractionProxy* hidlProxy, AidlServiceInteractionProxy* aidlProxy) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000220 std::lock_guard<std::mutex> lock(mInterfaceMutex);
221 if (hidlProxy == nullptr) {
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200222 ALOGE("%s: No valid service Hidl interaction proxy provided", __FUNCTION__);
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000223 return BAD_VALUE;
224 }
Vadim Caen7eccd7c2023-10-03 16:26:33 +0200225
226 if (aidlProxy == nullptr) {
227 ALOGE("%s: No valid service Aidl interaction proxy provided", __FUNCTION__);
228 return BAD_VALUE;
229 }
230 mAidlServiceProxy = aidlProxy;
231
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000232 mListener = listener;
233 mDeviceState = 0;
234 auto res = tryToInitAndAddHidlProvidersLocked(hidlProxy);
235 if (res != OK) {
236 // Logging done in called function;
237 return res;
238 }
239 res = tryToAddAidlProvidersLocked();
Eino-Ville Talvala65665362017-02-24 13:07:56 -0800240
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700241 IPCThreadState::self()->flushCommands();
242
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000243 return res;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800244}
245
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700246std::pair<int, int> CameraProviderManager::getCameraCount() const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800247 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700248 int systemCameraCount = 0;
249 int publicCameraCount = 0;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800250 for (auto& provider : mProviders) {
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700251 for (auto &id : provider->mUniqueCameraIds) {
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -0700252 SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
253 if (getSystemCameraKindLocked(id, &deviceKind) != OK) {
254 ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, id.c_str());
255 continue;
256 }
257 switch(deviceKind) {
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700258 case SystemCameraKind::PUBLIC:
259 publicCameraCount++;
260 break;
261 case SystemCameraKind::SYSTEM_ONLY_CAMERA:
262 systemCameraCount++;
263 break;
264 default:
265 break;
266 }
267 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800268 }
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700269 return std::make_pair(systemCameraCount, publicCameraCount);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800270}
271
Shuzhen Wang3d316f32022-10-25 20:33:34 +0000272std::vector<std::string> CameraProviderManager::getCameraDeviceIds(std::unordered_map<
273 std::string, std::set<std::string>>* unavailablePhysicalIds) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800274 std::lock_guard<std::mutex> lock(mInterfaceMutex);
275 std::vector<std::string> deviceIds;
276 for (auto& provider : mProviders) {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700277 for (auto& id : provider->mUniqueCameraIds) {
278 deviceIds.push_back(id);
Shuzhen Wang3d316f32022-10-25 20:33:34 +0000279 if (unavailablePhysicalIds != nullptr &&
280 provider->mUnavailablePhysicalCameras.count(id) > 0) {
281 (*unavailablePhysicalIds)[id] = provider->mUnavailablePhysicalCameras.at(id);
282 }
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700283 }
284 }
285 return deviceIds;
286}
287
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700288void CameraProviderManager::collectDeviceIdsLocked(const std::vector<std::string> deviceIds,
289 std::vector<std::string>& publicDeviceIds,
290 std::vector<std::string>& systemDeviceIds) const {
291 for (auto &deviceId : deviceIds) {
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -0700292 SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
293 if (getSystemCameraKindLocked(deviceId, &deviceKind) != OK) {
294 ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, deviceId.c_str());
295 continue;
296 }
297 if (deviceKind == SystemCameraKind::SYSTEM_ONLY_CAMERA) {
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700298 systemDeviceIds.push_back(deviceId);
299 } else {
300 publicDeviceIds.push_back(deviceId);
301 }
302 }
303}
304
Emilian Peevf53f66e2017-04-11 14:29:43 +0100305std::vector<std::string> CameraProviderManager::getAPI1CompatibleCameraDeviceIds() const {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700306 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700307 std::vector<std::string> publicDeviceIds;
308 std::vector<std::string> systemDeviceIds;
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700309 std::vector<std::string> deviceIds;
310 for (auto& provider : mProviders) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700311 std::vector<std::string> providerDeviceIds = provider->mUniqueAPI1CompatibleCameraIds;
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700312 // Secure cameras should not be exposed through camera 1 api
313 providerDeviceIds.erase(std::remove_if(providerDeviceIds.begin(), providerDeviceIds.end(),
314 [this](const std::string& s) {
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -0700315 SystemCameraKind deviceKind = SystemCameraKind::PUBLIC;
316 if (getSystemCameraKindLocked(s, &deviceKind) != OK) {
317 ALOGE("%s: Invalid camera id %s, skipping", __FUNCTION__, s.c_str());
318 return true;
319 }
320 return deviceKind == SystemCameraKind::HIDDEN_SECURE_CAMERA;}),
321 providerDeviceIds.end());
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700322 // API1 app doesn't handle logical and physical camera devices well. So
Shuzhen Wang38e119b2018-10-01 16:03:53 -0700323 // for each camera facing, only take the first id advertised by HAL in
324 // all [logical, physical1, physical2, ...] id combos, and filter out the rest.
Shuzhen Wange8aceb52018-05-21 12:00:56 -0700325 filterLogicalCameraIdsLocked(providerDeviceIds);
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700326 collectDeviceIdsLocked(providerDeviceIds, publicDeviceIds, systemDeviceIds);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800327 }
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700328 auto sortFunc =
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -0800329 [](const std::string& a, const std::string& b) -> bool {
330 uint32_t aUint = 0, bUint = 0;
331 bool aIsUint = base::ParseUint(a, &aUint);
332 bool bIsUint = base::ParseUint(b, &bUint);
333
334 // Uint device IDs first
335 if (aIsUint && bIsUint) {
336 return aUint < bUint;
337 } else if (aIsUint) {
338 return true;
339 } else if (bIsUint) {
340 return false;
341 }
342 // Simple string compare if both id are not uint
343 return a < b;
Jayant Chowdhary847947d2019-08-30 18:02:59 -0700344 };
345 // We put device ids for system cameras at the end since they will be pared
346 // off for processes not having system camera permissions.
347 std::sort(publicDeviceIds.begin(), publicDeviceIds.end(), sortFunc);
348 std::sort(systemDeviceIds.begin(), systemDeviceIds.end(), sortFunc);
349 deviceIds.insert(deviceIds.end(), publicDeviceIds.begin(), publicDeviceIds.end());
350 deviceIds.insert(deviceIds.end(), systemDeviceIds.begin(), systemDeviceIds.end());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800351 return deviceIds;
352}
353
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000354bool CameraProviderManager::isValidDeviceLocked(const std::string &id, uint16_t majorVersion,
355 IPCTransport transport) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800356 for (auto& provider : mProviders) {
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000357 IPCTransport providerTransport = provider->getIPCTransport();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800358 for (auto& deviceInfo : provider->mDevices) {
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000359 if (deviceInfo->mId == id && deviceInfo->mVersion.get_major() == majorVersion &&
360 transport == providerTransport) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800361 return true;
362 }
363 }
364 }
365 return false;
366}
367
368bool CameraProviderManager::hasFlashUnit(const std::string &id) const {
369 std::lock_guard<std::mutex> lock(mInterfaceMutex);
370
371 auto deviceInfo = findDeviceInfoLocked(id);
372 if (deviceInfo == nullptr) return false;
373
374 return deviceInfo->hasFlashUnit();
375}
376
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800377bool CameraProviderManager::supportNativeZoomRatio(const std::string &id) const {
378 std::lock_guard<std::mutex> lock(mInterfaceMutex);
379
380 auto deviceInfo = findDeviceInfoLocked(id);
381 if (deviceInfo == nullptr) return false;
382
383 return deviceInfo->supportNativeZoomRatio();
384}
385
Emilian Peev15230142023-04-27 20:22:54 +0000386bool CameraProviderManager::isCompositeJpegRDisabled(const std::string &id) const {
Emilian Peeve579d8b2023-02-28 14:16:08 -0800387 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Emilian Peev15230142023-04-27 20:22:54 +0000388 return isCompositeJpegRDisabledLocked(id);
Emilian Peeve579d8b2023-02-28 14:16:08 -0800389}
390
Emilian Peev15230142023-04-27 20:22:54 +0000391bool CameraProviderManager::isCompositeJpegRDisabledLocked(const std::string &id) const {
Emilian Peeve579d8b2023-02-28 14:16:08 -0800392 auto deviceInfo = findDeviceInfoLocked(id);
393 if (deviceInfo == nullptr) return false;
394
Emilian Peev15230142023-04-27 20:22:54 +0000395 return deviceInfo->isCompositeJpegRDisabled();
Emilian Peeve579d8b2023-02-28 14:16:08 -0800396}
397
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800398status_t CameraProviderManager::getResourceCost(const std::string &id,
399 CameraResourceCost* cost) const {
400 std::lock_guard<std::mutex> lock(mInterfaceMutex);
401
402 auto deviceInfo = findDeviceInfoLocked(id);
403 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
404
405 *cost = deviceInfo->mResourceCost;
406 return OK;
407}
408
409status_t CameraProviderManager::getCameraInfo(const std::string &id,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000410 int rotationOverride, int *portraitRotation,
411 hardware::CameraInfo* info) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800412 std::lock_guard<std::mutex> lock(mInterfaceMutex);
413
414 auto deviceInfo = findDeviceInfoLocked(id);
415 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
416
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000417 return deviceInfo->getCameraInfo(rotationOverride, portraitRotation, info);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800418}
419
Emilian Peev35ae8262018-11-08 13:11:32 +0000420status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700421 const SessionConfiguration &configuration, bool overrideForPerfClass,
Shuzhen Wang045be6c2023-10-12 10:01:10 -0700422 bool checkSessionParams, bool *status /*out*/) const {
Emilian Peev35ae8262018-11-08 13:11:32 +0000423 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Emilian Peev35ae8262018-11-08 13:11:32 +0000424 auto deviceInfo = findDeviceInfoLocked(id);
425 if (deviceInfo == nullptr) {
426 return NAME_NOT_FOUND;
427 }
428
Shuzhen Wang141c64a2024-04-03 23:25:14 -0700429 metadataGetter getMetadata = [this](const std::string &id,
430 bool overrideForPerfClass) {
431 CameraMetadata metadata;
432 this->getCameraCharacteristicsLocked(id, overrideForPerfClass,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000433 &metadata,
434 hardware::ICameraService::ROTATION_OVERRIDE_NONE);
Shuzhen Wang141c64a2024-04-03 23:25:14 -0700435 return metadata;
436 };
Shuzhen Wanga79a64d2022-04-24 19:56:30 -0700437 return deviceInfo->isSessionConfigurationSupported(configuration,
Shuzhen Wang141c64a2024-04-03 23:25:14 -0700438 overrideForPerfClass, getMetadata, checkSessionParams, status);
Shuzhen Wang045be6c2023-10-12 10:01:10 -0700439}
440
441status_t CameraProviderManager::createDefaultRequest(const std::string& cameraId,
442 camera_request_template_t templateId,
443 CameraMetadata* metadata) const {
444 ATRACE_CALL();
445 if (templateId <= 0 || templateId >= CAMERA_TEMPLATE_COUNT) {
446 return BAD_VALUE;
447 }
448
449 std::lock_guard<std::mutex> lock(mInterfaceMutex);
450 auto deviceInfo = findDeviceInfoLocked(cameraId);
451 if (deviceInfo == nullptr) {
452 return NAME_NOT_FOUND;
453 }
454
Shuzhen Wang045be6c2023-10-12 10:01:10 -0700455 status_t res = deviceInfo->createDefaultRequest(templateId,
Shuzhen Wang33c84cd2024-01-03 17:45:03 +0000456 metadata);
Shuzhen Wang045be6c2023-10-12 10:01:10 -0700457
458 if (res == BAD_VALUE) {
459 ALOGI("%s: template %d is not supported on this camera device",
460 __FUNCTION__, templateId);
461 return res;
462 } else if (res != OK) {
463 ALOGE("Unable to construct request template %d: %s (%d)",
464 templateId, strerror(-res), res);
465 return res;
466 }
467
Shuzhen Wang045be6c2023-10-12 10:01:10 -0700468 return OK;
Emilian Peev35ae8262018-11-08 13:11:32 +0000469}
470
Avichal Rakesh3c522e22024-02-07 16:40:46 -0800471status_t CameraProviderManager::getSessionCharacteristics(
472 const std::string& id, const SessionConfiguration& configuration, bool overrideForPerfClass,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000473 int rotationOverride, CameraMetadata* sessionCharacteristics /*out*/) const {
Bharatt Kukreja6dddeb72023-11-21 10:06:25 +0000474 if (!flags::feature_combination_query()) {
475 return INVALID_OPERATION;
476 }
Avichal Rakesh3c522e22024-02-07 16:40:46 -0800477
Bharatt Kukreja6dddeb72023-11-21 10:06:25 +0000478 std::lock_guard<std::mutex> lock(mInterfaceMutex);
479 auto deviceInfo = findDeviceInfoLocked(id);
480 if (deviceInfo == nullptr) {
481 return NAME_NOT_FOUND;
482 }
483
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000484 metadataGetter getMetadata = [this, rotationOverride](const std::string& id,
Avichal Rakesh3c522e22024-02-07 16:40:46 -0800485 bool overrideForPerfClass) {
486 CameraMetadata metadata;
487 status_t ret = this->getCameraCharacteristicsLocked(id, overrideForPerfClass, &metadata,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000488 rotationOverride);
Avichal Rakesh3c522e22024-02-07 16:40:46 -0800489 if (ret != OK) {
490 ALOGE("%s: Could not get CameraCharacteristics for device %s", __FUNCTION__,
491 id.c_str());
492 }
493 return metadata;
494 };
495
Bharatt Kukreja6dddeb72023-11-21 10:06:25 +0000496 return deviceInfo->getSessionCharacteristics(configuration,
497 overrideForPerfClass, getMetadata, sessionCharacteristics);
498}
499
Jayant Chowdhary22441f32021-12-26 18:35:41 -0800500status_t CameraProviderManager::getCameraIdIPCTransport(const std::string &id,
501 IPCTransport *providerTransport) const {
502 std::lock_guard<std::mutex> lock(mInterfaceMutex);
503 auto deviceInfo = findDeviceInfoLocked(id);
504 if (deviceInfo == nullptr) {
505 return NAME_NOT_FOUND;
506 }
507 sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
508 if (parentProvider == nullptr) {
509 return DEAD_OBJECT;
510 }
511 *providerTransport = parentProvider->getIPCTransport();
512 return OK;
513}
514
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800515status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
Austin Borger18b30a72022-10-27 12:20:29 -0700516 bool overrideForPerfClass, CameraMetadata* characteristics,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000517 int rotationOverride) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800518 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Austin Borger18b30a72022-10-27 12:20:29 -0700519 return getCameraCharacteristicsLocked(id, overrideForPerfClass, characteristics,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000520 rotationOverride);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800521}
522
523status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000524 hardware::hidl_version *v, IPCTransport *transport) {
525 if (v == nullptr || transport == nullptr) {
526 return BAD_VALUE;
527 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800528 std::lock_guard<std::mutex> lock(mInterfaceMutex);
529
530 hardware::hidl_version maxVersion{0,0};
531 bool found = false;
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000532 IPCTransport providerTransport = IPCTransport::INVALID;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800533 for (auto& provider : mProviders) {
534 for (auto& deviceInfo : provider->mDevices) {
535 if (deviceInfo->mId == id) {
536 if (deviceInfo->mVersion > maxVersion) {
537 maxVersion = deviceInfo->mVersion;
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000538 providerTransport = provider->getIPCTransport();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800539 found = true;
540 }
541 }
542 }
543 }
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000544 if (!found || providerTransport == IPCTransport::INVALID) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800545 return NAME_NOT_FOUND;
546 }
547 *v = maxVersion;
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000548 *transport = providerTransport;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800549 return OK;
550}
551
Rucha Katakwar38284522021-11-10 11:25:21 -0800552status_t CameraProviderManager::getTorchStrengthLevel(const std::string &id,
553 int32_t* torchStrength /*out*/) {
554 std::lock_guard<std::mutex> lock(mInterfaceMutex);
555
556 auto deviceInfo = findDeviceInfoLocked(id);
557 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
558
559 return deviceInfo->getTorchStrengthLevel(torchStrength);
560}
561
562status_t CameraProviderManager::turnOnTorchWithStrengthLevel(const std::string &id,
563 int32_t torchStrength) {
564 std::lock_guard<std::mutex> lock(mInterfaceMutex);
565
566 auto deviceInfo = findDeviceInfoLocked(id);
567 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
568
569 return deviceInfo->turnOnTorchWithStrengthLevel(torchStrength);
570}
571
572bool CameraProviderManager::shouldSkipTorchStrengthUpdate(const std::string &id,
573 int32_t torchStrength) const {
574 std::lock_guard<std::mutex> lock(mInterfaceMutex);
575
576 auto deviceInfo = findDeviceInfoLocked(id);
577 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
578
579 if (deviceInfo->mTorchStrengthLevel == torchStrength) {
580 ALOGV("%s: Skipping torch strength level updates prev_level: %d, new_level: %d",
581 __FUNCTION__, deviceInfo->mTorchStrengthLevel, torchStrength);
582 return true;
583 }
584 return false;
585}
586
587int32_t CameraProviderManager::getTorchDefaultStrengthLevel(const std::string &id) const {
588 std::lock_guard<std::mutex> lock(mInterfaceMutex);
589
590 auto deviceInfo = findDeviceInfoLocked(id);
591 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
592
593 return deviceInfo->mTorchDefaultStrengthLevel;
594}
595
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700596bool CameraProviderManager::supportSetTorchMode(const std::string &id) const {
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700597 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700598 for (auto& provider : mProviders) {
Emilian Peevb070e1d2022-05-24 17:09:31 -0700599 for (auto& deviceInfo : provider->mDevices) {
600 if (deviceInfo->mId == id) {
601 return provider->mSetTorchModeSupported;
602 }
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700603 }
604 }
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700605 return false;
Yin-Chia Yehdc3134e2017-03-23 15:26:59 -0700606}
607
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000608template <class ProviderInfoType, class HalCameraProviderType>
609status_t CameraProviderManager::setTorchModeT(sp<ProviderInfo> &parentProvider,
610 std::shared_ptr<HalCameraProvider> *halCameraProvider) {
611 if (halCameraProvider == nullptr) {
612 return BAD_VALUE;
613 }
614 ProviderInfoType *idlProviderInfo = static_cast<ProviderInfoType *>(parentProvider.get());
615 auto idlInterface = idlProviderInfo->startProviderInterface();
616 if (idlInterface == nullptr) {
617 return DEAD_OBJECT;
618 }
619 *halCameraProvider =
620 std::make_shared<HalCameraProviderType>(idlInterface, idlInterface->descriptor);
621 return OK;
622}
623
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800624status_t CameraProviderManager::setTorchMode(const std::string &id, bool enabled) {
625 std::lock_guard<std::mutex> lock(mInterfaceMutex);
626
627 auto deviceInfo = findDeviceInfoLocked(id);
628 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
629
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700630 // Pass the camera ID to start interface so that it will save it to the map of ICameraProviders
631 // that are currently in use.
Shuzhen Wang79680432020-03-05 11:53:46 -0800632 sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
633 if (parentProvider == nullptr) {
634 return DEAD_OBJECT;
635 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700636 std::shared_ptr<HalCameraProvider> halCameraProvider = nullptr;
637 IPCTransport providerTransport = parentProvider->getIPCTransport();
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000638 status_t res = OK;
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700639 if (providerTransport == IPCTransport::HIDL) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000640 res = setTorchModeT<HidlProviderInfo, HidlHalCameraProvider>(parentProvider,
641 &halCameraProvider);
642 if (res != OK) {
643 return res;
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700644 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700645 } else if (providerTransport == IPCTransport::AIDL) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000646 res = setTorchModeT<AidlProviderInfo, AidlHalCameraProvider>(parentProvider,
647 &halCameraProvider);
648 if (res != OK) {
649 return res;
650 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700651 } else {
652 ALOGE("%s Invalid provider transport", __FUNCTION__);
653 return INVALID_OPERATION;
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700654 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700655 saveRef(DeviceMode::TORCH, deviceInfo->mId, halCameraProvider);
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700656
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800657 return deviceInfo->setTorchMode(enabled);
658}
659
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800660status_t CameraProviderManager::setUpVendorTags() {
Emilian Peev71c73a22017-03-21 16:35:51 +0000661 sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
662
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800663 for (auto& provider : mProviders) {
Peter Kalauskas1b3c9072018-11-07 12:41:53 -0800664 tagCache->addVendorDescriptor(provider->mProviderTagid, provider->mVendorTagDescriptor);
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800665 }
Emilian Peev71c73a22017-03-21 16:35:51 +0000666
667 VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
668
Yin-Chia Yeh067428c2017-01-13 15:19:24 -0800669 return OK;
670}
671
Valentin Iftime29e2e152021-08-13 15:17:33 +0200672sp<CameraProviderManager::ProviderInfo> CameraProviderManager::startExternalLazyProvider() const {
673 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
674 std::lock_guard<std::mutex> lock(mInterfaceMutex);
675
676 for (const auto& providerInfo : mProviders) {
677 if (providerInfo->isExternalLazyHAL()) {
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700678 if (!providerInfo->successfullyStartedProviderInterface()) {
Valentin Iftime29e2e152021-08-13 15:17:33 +0200679 return nullptr;
680 } else {
681 return providerInfo;
682 }
683 }
684 }
685 return nullptr;
686}
687
688status_t CameraProviderManager::notifyUsbDeviceEvent(int32_t eventId,
689 const std::string& usbDeviceId) {
690 if (!kEnableLazyHal) {
691 return OK;
692 }
693
694 ALOGV("notifySystemEvent: %d usbDeviceId : %s", eventId, usbDeviceId.c_str());
695
696 if (eventId == android::hardware::ICameraService::EVENT_USB_DEVICE_ATTACHED) {
697 sp<ProviderInfo> externalProvider = startExternalLazyProvider();
698 if (externalProvider != nullptr) {
699 auto usbDevices = mExternalUsbDevicesForProvider.first;
700 usbDevices.push_back(usbDeviceId);
701 mExternalUsbDevicesForProvider = {usbDevices, externalProvider};
702 }
703 } else if (eventId
704 == android::hardware::ICameraService::EVENT_USB_DEVICE_DETACHED) {
705 usbDeviceDetached(usbDeviceId);
706 }
707
708 return OK;
709}
710
711status_t CameraProviderManager::usbDeviceDetached(const std::string &usbDeviceId) {
712 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
713 std::lock_guard<std::mutex> interfaceLock(mInterfaceMutex);
714
715 auto usbDevices = mExternalUsbDevicesForProvider.first;
716 auto foundId = std::find(usbDevices.begin(), usbDevices.end(), usbDeviceId);
717 if (foundId != usbDevices.end()) {
718 sp<ProviderInfo> providerInfo = mExternalUsbDevicesForProvider.second;
719 if (providerInfo == nullptr) {
720 ALOGE("%s No valid external provider for USB device: %s",
721 __FUNCTION__,
722 usbDeviceId.c_str());
723 mExternalUsbDevicesForProvider = {std::vector<std::string>(), nullptr};
724 return DEAD_OBJECT;
725 } else {
726 mInterfaceMutex.unlock();
727 providerInfo->removeAllDevices();
728 mInterfaceMutex.lock();
729 mExternalUsbDevicesForProvider = {std::vector<std::string>(), nullptr};
730 }
731 } else {
732 return DEAD_OBJECT;
733 }
734 return OK;
735}
736
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700737status_t CameraProviderManager::notifyDeviceStateChange(int64_t newState) {
Eino-Ville Talvala63f36112018-12-06 14:57:03 -0800738 std::lock_guard<std::mutex> lock(mInterfaceMutex);
739 mDeviceState = newState;
740 status_t res = OK;
Shuzhen Wang2e9d8fa2022-05-27 20:25:36 +0000741 // Make a copy of mProviders because we unlock mInterfaceMutex temporarily
742 // within the loop. It's possible that during the time mInterfaceMutex is
743 // unlocked, mProviders has changed.
744 auto providers = mProviders;
745 for (auto& provider : providers) {
Eino-Ville Talvala63f36112018-12-06 14:57:03 -0800746 ALOGV("%s: Notifying %s for new state 0x%" PRIx64,
747 __FUNCTION__, provider->mProviderName.c_str(), newState);
Emilian Peev7fe6c422021-09-08 13:43:20 -0700748 // b/199240726 Camera providers can for example try to add/remove
749 // camera devices as part of the state change notification. Holding
750 // 'mInterfaceMutex' while calling 'notifyDeviceStateChange' can
751 // result in a recursive deadlock.
752 mInterfaceMutex.unlock();
Eino-Ville Talvala63f36112018-12-06 14:57:03 -0800753 status_t singleRes = provider->notifyDeviceStateChange(mDeviceState);
Emilian Peev7fe6c422021-09-08 13:43:20 -0700754 mInterfaceMutex.lock();
Eino-Ville Talvala63f36112018-12-06 14:57:03 -0800755 if (singleRes != OK) {
756 ALOGE("%s: Unable to notify provider %s about device state change",
757 __FUNCTION__,
758 provider->mProviderName.c_str());
759 res = singleRes;
760 // continue to do the rest of the providers instead of returning now
761 }
Emilian Peevb50402e2021-09-24 17:41:57 -0700762 provider->notifyDeviceInfoStateChangeLocked(mDeviceState);
Eino-Ville Talvala63f36112018-12-06 14:57:03 -0800763 }
764 return res;
765}
766
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000767status_t CameraProviderManager::openAidlSession(const std::string &id,
768 const std::shared_ptr<
769 aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
770 /*out*/
771 std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> *session) {
772
773 std::lock_guard<std::mutex> lock(mInterfaceMutex);
774
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000775 auto deviceInfo = findDeviceInfoLocked(id);
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000776 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
777
778 auto *aidlDeviceInfo3 = static_cast<AidlProviderInfo::AidlDeviceInfo3*>(deviceInfo);
779 sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
780 if (parentProvider == nullptr) {
781 return DEAD_OBJECT;
782 }
783 auto provider =
784 static_cast<AidlProviderInfo *>(parentProvider.get())->startProviderInterface();
785 if (provider == nullptr) {
786 return DEAD_OBJECT;
787 }
788 std::shared_ptr<HalCameraProvider> halCameraProvider =
789 std::make_shared<AidlHalCameraProvider>(provider, provider->descriptor);
790 saveRef(DeviceMode::CAMERA, id, halCameraProvider);
791
792 auto interface = aidlDeviceInfo3->startDeviceInterface();
793 if (interface == nullptr) {
794 removeRef(DeviceMode::CAMERA, id);
795 return DEAD_OBJECT;
796 }
797
798 auto ret = interface->open(callback, session);
799 if (!ret.isOk()) {
800 removeRef(DeviceMode::CAMERA, id);
801 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
802 __FUNCTION__, id.c_str(), ret.getMessage());
Jayant Chowdharycc3e12c2022-03-10 01:43:41 +0000803 return AidlProviderInfo::mapToStatusT(ret);
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000804 }
805 return OK;
806}
807
Jayant Chowdhary35642f22022-01-08 00:39:39 +0000808status_t CameraProviderManager::openAidlInjectionSession(const std::string &id,
809 const std::shared_ptr<
810 aidl::android::hardware::camera::device::ICameraDeviceCallback>& callback,
811 /*out*/
812 std::shared_ptr<
813 aidl::android::hardware::camera::device::ICameraInjectionSession> *session) {
814
815 std::lock_guard<std::mutex> lock(mInterfaceMutex);
816
817 auto deviceInfo = findDeviceInfoLocked(id);
818 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
819
820 auto *aidlDeviceInfo3 = static_cast<AidlProviderInfo::AidlDeviceInfo3*>(deviceInfo);
821 sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
822 if (parentProvider == nullptr) {
823 return DEAD_OBJECT;
824 }
825 auto provider =
826 static_cast<AidlProviderInfo *>(parentProvider.get())->startProviderInterface();
827 if (provider == nullptr) {
828 return DEAD_OBJECT;
829 }
830 std::shared_ptr<HalCameraProvider> halCameraProvider =
831 std::make_shared<AidlHalCameraProvider>(provider, provider->descriptor);
832 saveRef(DeviceMode::CAMERA, id, halCameraProvider);
833
834 auto interface = aidlDeviceInfo3->startDeviceInterface();
835 if (interface == nullptr) {
836 return DEAD_OBJECT;
837 }
838
839 auto ret = interface->openInjectionSession(callback, session);
840 if (!ret.isOk()) {
841 removeRef(DeviceMode::CAMERA, id);
842 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
843 __FUNCTION__, id.c_str(), ret.getMessage());
844 return DEAD_OBJECT;
845 }
846 return OK;
847}
848
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700849status_t CameraProviderManager::openHidlSession(const std::string &id,
Peter Kalauskasb7bd4382018-11-15 17:19:48 -0800850 const sp<device::V3_2::ICameraDeviceCallback>& callback,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800851 /*out*/
Peter Kalauskasb7bd4382018-11-15 17:19:48 -0800852 sp<device::V3_2::ICameraDeviceSession> *session) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800853
854 std::lock_guard<std::mutex> lock(mInterfaceMutex);
855
Jayant Chowdharyffc5d682022-05-12 18:34:34 +0000856 auto deviceInfo = findDeviceInfoLocked(id);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800857 if (deviceInfo == nullptr) return NAME_NOT_FOUND;
858
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700859 auto *hidlDeviceInfo3 = static_cast<HidlProviderInfo::HidlDeviceInfo3*>(deviceInfo);
Shuzhen Wang79680432020-03-05 11:53:46 -0800860 sp<ProviderInfo> parentProvider = deviceInfo->mParentProvider.promote();
861 if (parentProvider == nullptr) {
862 return DEAD_OBJECT;
863 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700864 const sp<provider::V2_4::ICameraProvider> provider =
865 static_cast<HidlProviderInfo *>(parentProvider.get())->startProviderInterface();
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700866 if (provider == nullptr) {
867 return DEAD_OBJECT;
868 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700869 std::shared_ptr<HalCameraProvider> halCameraProvider =
870 std::make_shared<HidlHalCameraProvider>(provider, provider->descriptor);
871 saveRef(DeviceMode::CAMERA, id, halCameraProvider);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800872
873 Status status;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700874 hardware::Return<void> ret;
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700875 auto interface = hidlDeviceInfo3->startDeviceInterface();
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700876 if (interface == nullptr) {
877 return DEAD_OBJECT;
878 }
879
880 ret = interface->open(callback, [&status, &session]
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800881 (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
882 status = s;
883 if (status == Status::OK) {
884 *session = cameraSession;
885 }
886 });
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700887 if (!ret.isOk()) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700888 removeRef(DeviceMode::CAMERA, id);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -0700889 ALOGE("%s: Transaction error opening a session for camera device %s: %s",
890 __FUNCTION__, id.c_str(), ret.description().c_str());
891 return DEAD_OBJECT;
892 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700893 return HidlProviderInfo::mapToStatusT(status);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800894}
895
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700896void CameraProviderManager::saveRef(DeviceMode usageType, const std::string &cameraId,
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700897 std::shared_ptr<HalCameraProvider> provider) {
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700898 if (!kEnableLazyHal) {
899 return;
900 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700901 ALOGV("Saving camera provider %s for camera device %s", provider->mDescriptor.c_str(),
902 cameraId.c_str());
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700903 std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700904 std::unordered_map<std::string, std::shared_ptr<HalCameraProvider>> *primaryMap, *alternateMap;
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700905 if (usageType == DeviceMode::TORCH) {
906 primaryMap = &mTorchProviderByCameraId;
907 alternateMap = &mCameraProviderByCameraId;
908 } else {
909 primaryMap = &mCameraProviderByCameraId;
910 alternateMap = &mTorchProviderByCameraId;
911 }
Austin Borger1c1bee02023-06-01 16:51:35 -0700912
913 (*primaryMap)[cameraId] = provider;
914 auto search = alternateMap->find(cameraId);
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700915 if (search != alternateMap->end()) {
916 ALOGW("%s: Camera device %s is using both torch mode and camera mode simultaneously. "
Austin Borger1c1bee02023-06-01 16:51:35 -0700917 "That should not be possible", __FUNCTION__, cameraId.c_str());
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700918 }
Austin Borger1c1bee02023-06-01 16:51:35 -0700919 ALOGV("%s: Camera device %s connected", __FUNCTION__, cameraId.c_str());
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700920}
921
922void CameraProviderManager::removeRef(DeviceMode usageType, const std::string &cameraId) {
923 if (!kEnableLazyHal) {
924 return;
925 }
Eino-Ville Talvala63f36112018-12-06 14:57:03 -0800926 ALOGV("Removing camera device %s", cameraId.c_str());
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700927 std::unordered_map<std::string, std::shared_ptr<HalCameraProvider>> *providerMap;
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700928 if (usageType == DeviceMode::TORCH) {
929 providerMap = &mTorchProviderByCameraId;
930 } else {
931 providerMap = &mCameraProviderByCameraId;
932 }
933 std::lock_guard<std::mutex> lock(mProviderInterfaceMapLock);
Austin Borger1c1bee02023-06-01 16:51:35 -0700934 auto search = providerMap->find(cameraId);
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700935 if (search != providerMap->end()) {
Peter Kalauskas26af1a52019-01-25 06:57:01 -0800936 // Drop the reference to this ICameraProvider. This is safe to do immediately (without an
937 // added delay) because hwservicemanager guarantees to hold the reference for at least five
938 // more seconds. We depend on this behavior so that if the provider is unreferenced and
939 // then referenced again quickly, we do not let the HAL exit and then need to immediately
940 // restart it. An example when this could happen is switching from a front-facing to a
941 // rear-facing camera. If the HAL were to exit during the camera switch, the camera could
942 // appear janky to the user.
Austin Borger1c1bee02023-06-01 16:51:35 -0700943 providerMap->erase(cameraId);
Peter Kalauskas26af1a52019-01-25 06:57:01 -0800944 IPCThreadState::self()->flushCommands();
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700945 } else {
946 ALOGE("%s: Asked to remove reference for camera %s, but no reference to it was found. This "
947 "could mean removeRef was called twice for the same camera ID.", __FUNCTION__,
948 cameraId.c_str());
949 }
950}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800951
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000952// We ignore sp<IBinder> param here since we need std::shared_ptr<...> which
953// will be retrieved through the ndk api through addAidlProviderLocked ->
954// tryToInitializeAidlProvider.
955void CameraProviderManager::onServiceRegistration(const String16 &name, const sp<IBinder>&) {
956 status_t res = OK;
957 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
958 {
959 std::lock_guard<std::mutex> lock(mInterfaceMutex);
960
Austin Borger1c1bee02023-06-01 16:51:35 -0700961 res = addAidlProviderLocked(toStdString(name));
Jayant Chowdharya04055f2022-01-03 02:07:49 +0000962 }
963
964 sp<StatusListener> listener = getStatusListener();
965 if (nullptr != listener.get() && res == OK) {
966 listener->onNewProviderRegistered();
967 }
968
969 IPCThreadState::self()->flushCommands();
970}
971
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800972hardware::Return<void> CameraProviderManager::onRegistration(
973 const hardware::hidl_string& /*fqName*/,
974 const hardware::hidl_string& name,
Emilian Peevc93cac22020-08-17 16:00:10 -0700975 bool preexisting) {
Shuzhen Wangb38b53f2021-07-15 12:46:09 -0700976 status_t res = OK;
Shuzhen Wang6ba8eb22018-07-08 13:10:44 -0700977 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
Emilian Peevaee727d2017-05-04 16:35:48 +0100978 {
979 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800980
Jayant Chowdhary0bd38522021-11-05 17:49:27 -0700981 res = addHidlProviderLocked(name, preexisting);
Emilian Peevaee727d2017-05-04 16:35:48 +0100982 }
983
984 sp<StatusListener> listener = getStatusListener();
Shuzhen Wangb38b53f2021-07-15 12:46:09 -0700985 if (nullptr != listener.get() && res == OK) {
Emilian Peevaee727d2017-05-04 16:35:48 +0100986 listener->onNewProviderRegistered();
987 }
988
Peter Kalauskasa29c1352018-10-10 12:05:42 -0700989 IPCThreadState::self()->flushCommands();
990
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800991 return hardware::Return<void>();
992}
993
994status_t CameraProviderManager::dump(int fd, const Vector<String16>& args) {
995 std::lock_guard<std::mutex> lock(mInterfaceMutex);
996
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800997 for (auto& provider : mProviders) {
998 provider->dump(fd, args);
999 }
1000 return OK;
1001}
1002
Jayant Chowdharya04055f2022-01-03 02:07:49 +00001003void CameraProviderManager::ProviderInfo::initializeProviderInfoCommon(
1004 const std::vector<std::string> &devices) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +00001005 for (auto& device : devices) {
1006 std::string id;
1007 status_t res = addDevice(device, CameraDeviceStatus::PRESENT, &id);
1008 if (res != OK) {
1009 ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
1010 __FUNCTION__, device.c_str(), strerror(-res), res);
1011 continue;
1012 }
1013 }
1014
1015 ALOGI("Camera provider %s ready with %zu camera devices",
1016 mProviderName.c_str(), mDevices.size());
1017
1018 // Process cached status callbacks
Jayant Chowdharya04055f2022-01-03 02:07:49 +00001019 {
1020 std::lock_guard<std::mutex> lock(mInitLock);
1021
1022 for (auto& statusInfo : mCachedStatus) {
1023 std::string id, physicalId;
Jayant Chowdharya04055f2022-01-03 02:07:49 +00001024 if (statusInfo.isPhysicalCameraStatus) {
Shuzhen Wang3d316f32022-10-25 20:33:34 +00001025 physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
Jayant Chowdharya04055f2022-01-03 02:07:49 +00001026 statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
1027 } else {
Shuzhen Wang3d316f32022-10-25 20:33:34 +00001028 cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00001029 }
1030 }
1031 mCachedStatus.clear();
1032
1033 mInitialized = true;
1034 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +00001035}
1036
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001037CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00001038 const std::string& id) const {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001039 for (auto& provider : mProviders) {
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00001040 using hardware::hidl_version;
1041 IPCTransport transport = provider->getIPCTransport();
1042 // AIDL min version starts at major: 1 minor: 1
1043 hidl_version minVersion =
1044 (transport == IPCTransport::HIDL) ? hidl_version{3, 2} : hidl_version{1, 1} ;
1045 hidl_version maxVersion =
1046 (transport == IPCTransport::HIDL) ? hidl_version{3, 7} : hidl_version{1000, 0};
1047
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001048 for (auto& deviceInfo : provider->mDevices) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001049 if (deviceInfo->mId == id &&
1050 minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001051 return deviceInfo.get();
1052 }
1053 }
1054 }
1055 return nullptr;
1056}
1057
Emilian Peev71c73a22017-03-21 16:35:51 +00001058metadata_vendor_id_t CameraProviderManager::getProviderTagIdLocked(
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00001059 const std::string& id) const {
Emilian Peev71c73a22017-03-21 16:35:51 +00001060 metadata_vendor_id_t ret = CAMERA_METADATA_INVALID_VENDOR_ID;
1061
1062 std::lock_guard<std::mutex> lock(mInterfaceMutex);
1063 for (auto& provider : mProviders) {
1064 for (auto& deviceInfo : provider->mDevices) {
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00001065 if (deviceInfo->mId == id) {
Emilian Peev71c73a22017-03-21 16:35:51 +00001066 return provider->mProviderTagid;
1067 }
1068 }
1069 }
1070
1071 return ret;
1072}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001073
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001074void CameraProviderManager::ProviderInfo::DeviceInfo3::queryPhysicalCameraIds() {
1075 camera_metadata_entry_t entryCap;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001076
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001077 entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001078 for (size_t i = 0; i < entryCap.count; ++i) {
1079 uint8_t capability = entryCap.data.u8[i];
1080 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001081 mIsLogicalCamera = true;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001082 break;
1083 }
1084 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001085 if (!mIsLogicalCamera) {
1086 return;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001087 }
1088
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001089 camera_metadata_entry_t entryIds = mCameraCharacteristics.find(
1090 ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS);
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001091 const uint8_t* ids = entryIds.data.u8;
1092 size_t start = 0;
1093 for (size_t i = 0; i < entryIds.count; ++i) {
1094 if (ids[i] == '\0') {
1095 if (start != i) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001096 mPhysicalIds.push_back((const char*)ids+start);
Shuzhen Wange8aceb52018-05-21 12:00:56 -07001097 }
1098 start = i+1;
1099 }
1100 }
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07001101}
1102
Jayant Chowdhary5216b212019-07-17 09:26:23 -07001103SystemCameraKind CameraProviderManager::ProviderInfo::DeviceInfo3::getSystemCameraKind() {
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08001104 camera_metadata_entry_t entryCap;
1105 entryCap = mCameraCharacteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
Jayant Chowdhary5216b212019-07-17 09:26:23 -07001106 if (entryCap.count == 1 &&
1107 entryCap.data.u8[0] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA) {
1108 return SystemCameraKind::HIDDEN_SECURE_CAMERA;
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08001109 }
Jayant Chowdhary5216b212019-07-17 09:26:23 -07001110
1111 // Go through the capabilities and check if it has
1112 // ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA
1113 for (size_t i = 0; i < entryCap.count; ++i) {
1114 uint8_t capability = entryCap.data.u8[i];
1115 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SYSTEM_CAMERA) {
1116 return SystemCameraKind::SYSTEM_ONLY_CAMERA;
1117 }
1118 }
1119 return SystemCameraKind::PUBLIC;
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08001120}
1121
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001122void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedSizes(
1123 const CameraMetadata& ch, uint32_t tag, android_pixel_format_t format,
1124 std::vector<std::tuple<size_t, size_t>> *sizes/*out*/) {
1125 if (sizes == nullptr) {
1126 return;
1127 }
1128
1129 auto scalerDims = ch.find(tag);
1130 if (scalerDims.count > 0) {
1131 // Scaler entry contains 4 elements (format, width, height, type)
1132 for (size_t i = 0; i < scalerDims.count; i += 4) {
1133 if ((scalerDims.data.i32[i] == format) &&
1134 (scalerDims.data.i32[i+3] ==
1135 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
1136 sizes->push_back(std::make_tuple(scalerDims.data.i32[i+1],
1137 scalerDims.data.i32[i+2]));
1138 }
1139 }
1140 }
1141}
1142
1143void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedDurations(
1144 const CameraMetadata& ch, uint32_t tag, android_pixel_format_t format,
1145 const std::vector<std::tuple<size_t, size_t>>& sizes,
1146 std::vector<int64_t> *durations/*out*/) {
1147 if (durations == nullptr) {
1148 return;
1149 }
1150
1151 auto availableDurations = ch.find(tag);
1152 if (availableDurations.count > 0) {
1153 // Duration entry contains 4 elements (format, width, height, duration)
Euisang Limff49bdb2023-02-13 19:54:53 +09001154 for (const auto& size : sizes) {
1155 int64_t width = std::get<0>(size);
1156 int64_t height = std::get<1>(size);
1157 for (size_t i = 0; i < availableDurations.count; i += 4) {
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001158 if ((availableDurations.data.i64[i] == format) &&
1159 (availableDurations.data.i64[i+1] == width) &&
1160 (availableDurations.data.i64[i+2] == height)) {
1161 durations->push_back(availableDurations.data.i64[i+3]);
Euisang Limff49bdb2023-02-13 19:54:53 +09001162 break;
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001163 }
1164 }
1165 }
1166 }
1167}
Euisang Limff49bdb2023-02-13 19:54:53 +09001168
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001169void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedDynamicDepthDurations(
1170 const std::vector<int64_t>& depthDurations, const std::vector<int64_t>& blobDurations,
1171 std::vector<int64_t> *dynamicDepthDurations /*out*/) {
1172 if ((dynamicDepthDurations == nullptr) || (depthDurations.size() != blobDurations.size())) {
1173 return;
1174 }
1175
1176 // Unfortunately there is no direct way to calculate the dynamic depth stream duration.
1177 // Processing time on camera service side can vary greatly depending on multiple
1178 // variables which are not under our control. Make a guesstimate by taking the maximum
1179 // corresponding duration value from depth and blob.
1180 auto depthDuration = depthDurations.begin();
1181 auto blobDuration = blobDurations.begin();
1182 dynamicDepthDurations->reserve(depthDurations.size());
1183 while ((depthDuration != depthDurations.end()) && (blobDuration != blobDurations.end())) {
1184 dynamicDepthDurations->push_back(std::max(*depthDuration, *blobDuration));
1185 depthDuration++; blobDuration++;
1186 }
1187}
1188
1189void CameraProviderManager::ProviderInfo::DeviceInfo3::getSupportedDynamicDepthSizes(
1190 const std::vector<std::tuple<size_t, size_t>>& blobSizes,
1191 const std::vector<std::tuple<size_t, size_t>>& depthSizes,
1192 std::vector<std::tuple<size_t, size_t>> *dynamicDepthSizes /*out*/,
1193 std::vector<std::tuple<size_t, size_t>> *internalDepthSizes /*out*/) {
1194 if (dynamicDepthSizes == nullptr || internalDepthSizes == nullptr) {
1195 return;
1196 }
1197
1198 // The dynamic depth spec. does not mention how close the AR ratio should be.
1199 // Try using something appropriate.
Emilian Peev538c90e2018-12-17 18:03:19 +00001200 float ARTolerance = kDepthARTolerance;
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001201
1202 for (const auto& blobSize : blobSizes) {
1203 float jpegAR = static_cast<float> (std::get<0>(blobSize)) /
1204 static_cast<float>(std::get<1>(blobSize));
1205 bool found = false;
1206 for (const auto& depthSize : depthSizes) {
1207 if (depthSize == blobSize) {
1208 internalDepthSizes->push_back(depthSize);
1209 found = true;
1210 break;
1211 } else {
1212 float depthAR = static_cast<float> (std::get<0>(depthSize)) /
1213 static_cast<float>(std::get<1>(depthSize));
1214 if (std::fabs(jpegAR - depthAR) <= ARTolerance) {
1215 internalDepthSizes->push_back(depthSize);
1216 found = true;
1217 break;
1218 }
1219 }
1220 }
1221
1222 if (found) {
1223 dynamicDepthSizes->push_back(blobSize);
1224 }
1225 }
1226}
1227
Emilian Peev434248e2022-10-06 14:58:54 -07001228bool CameraProviderManager::isConcurrentDynamicRangeCaptureSupported(
1229 const CameraMetadata& deviceInfo, int64_t profile, int64_t concurrentProfile) {
1230 auto entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1231 if (entry.count == 0) {
1232 return false;
1233 }
1234
1235 const auto it = std::find(entry.data.u8, entry.data.u8 + entry.count,
1236 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT);
1237 if (it == entry.data.u8 + entry.count) {
1238 return false;
1239 }
1240
1241 entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
1242 if (entry.count == 0 || ((entry.count % 3) != 0)) {
1243 return false;
1244 }
1245
1246 for (size_t i = 0; i < entry.count; i += 3) {
1247 if (entry.data.i64[i] == profile) {
Emilian Peev6a66d992023-04-19 18:12:01 -07001248 if ((entry.data.i64[i+1] == 0) || (entry.data.i64[i+1] & concurrentProfile)) {
Emilian Peev434248e2022-10-06 14:58:54 -07001249 return true;
1250 }
1251 }
1252 }
1253
1254 return false;
1255}
1256
1257status_t CameraProviderManager::ProviderInfo::DeviceInfo3::deriveJpegRTags(bool maxResolution) {
Emilian Peev15230142023-04-27 20:22:54 +00001258 if (kFrameworkJpegRDisabled || mCompositeJpegRDisabled) {
Emilian Peev434248e2022-10-06 14:58:54 -07001259 return OK;
1260 }
1261
1262 const int32_t scalerSizesTag =
1263 SessionConfigurationUtils::getAppropriateModeTag(
1264 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
Emilian Peevbf1565b2023-06-06 13:36:58 -07001265 const int32_t scalerMinFrameDurationsTag = SessionConfigurationUtils::getAppropriateModeTag(
1266 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, maxResolution);
Emilian Peev434248e2022-10-06 14:58:54 -07001267 const int32_t scalerStallDurationsTag =
1268 SessionConfigurationUtils::getAppropriateModeTag(
1269 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, maxResolution);
1270
1271 const int32_t jpegRSizesTag =
1272 SessionConfigurationUtils::getAppropriateModeTag(
1273 ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS, maxResolution);
1274 const int32_t jpegRStallDurationsTag =
1275 SessionConfigurationUtils::getAppropriateModeTag(
1276 ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS, maxResolution);
1277 const int32_t jpegRMinFrameDurationsTag =
1278 SessionConfigurationUtils::getAppropriateModeTag(
1279 ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS, maxResolution);
1280
1281 auto& c = mCameraCharacteristics;
1282 std::vector<int32_t> supportedChTags;
1283 auto chTags = c.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
1284 if (chTags.count == 0) {
1285 ALOGE("%s: No supported camera characteristics keys!", __FUNCTION__);
1286 return BAD_VALUE;
1287 }
1288
Euisang Limff49bdb2023-02-13 19:54:53 +09001289 std::vector<std::tuple<size_t, size_t>> supportedP010Sizes, supportedBlobSizes;
Emilian Peev434248e2022-10-06 14:58:54 -07001290 auto capabilities = c.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1291 if (capabilities.count == 0) {
1292 ALOGE("%s: Supported camera capabilities is empty!", __FUNCTION__);
1293 return BAD_VALUE;
1294 }
1295
1296 auto end = capabilities.data.u8 + capabilities.count;
1297 bool isTenBitOutputSupported = std::find(capabilities.data.u8, end,
1298 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT) != end;
1299 if (!isTenBitOutputSupported) {
1300 // No 10-bit support, nothing more to do.
1301 return OK;
1302 }
1303
Emilian Peev15230142023-04-27 20:22:54 +00001304 if (!isConcurrentDynamicRangeCaptureSupported(c,
1305 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10,
1306 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) &&
1307 !property_get_bool("ro.camera.enableCompositeAPI0JpegR", false)) {
1308 // API0, P010 only Jpeg/R support is meant to be used only as a reference due to possible
1309 // impact on quality and performance.
1310 // This data path will be turned off by default and individual device builds must enable
1311 // 'ro.camera.enableCompositeAPI0JpegR' in order to experiment using it.
1312 mCompositeJpegRDisabled = true;
1313 return OK;
1314 }
1315
Emilian Peev434248e2022-10-06 14:58:54 -07001316 getSupportedSizes(c, scalerSizesTag,
1317 static_cast<android_pixel_format_t>(HAL_PIXEL_FORMAT_BLOB), &supportedBlobSizes);
1318 getSupportedSizes(c, scalerSizesTag,
1319 static_cast<android_pixel_format_t>(HAL_PIXEL_FORMAT_YCBCR_P010), &supportedP010Sizes);
1320 auto it = supportedP010Sizes.begin();
1321 while (it != supportedP010Sizes.end()) {
Emilian Peevbbfff9c2023-02-02 14:01:14 -08001322 if (std::find(supportedBlobSizes.begin(), supportedBlobSizes.end(), *it) ==
1323 supportedBlobSizes.end()) {
Emilian Peev434248e2022-10-06 14:58:54 -07001324 it = supportedP010Sizes.erase(it);
1325 } else {
1326 it++;
1327 }
1328 }
1329 if (supportedP010Sizes.empty()) {
1330 // Nothing to do in this case.
1331 return OK;
1332 }
1333
1334 std::vector<int32_t> jpegREntries;
1335 for (const auto& it : supportedP010Sizes) {
1336 int32_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(it)),
1337 static_cast<int32_t> (std::get<1>(it)),
1338 ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_OUTPUT };
1339 jpegREntries.insert(jpegREntries.end(), entry, entry + 4);
1340 }
1341
1342 std::vector<int64_t> blobMinDurations, blobStallDurations;
1343 std::vector<int64_t> jpegRMinDurations, jpegRStallDurations;
1344
1345 // We use the jpeg stall and min frame durations to approximate the respective jpeg/r
1346 // durations.
1347 getSupportedDurations(c, scalerMinFrameDurationsTag, HAL_PIXEL_FORMAT_BLOB,
1348 supportedP010Sizes, &blobMinDurations);
1349 getSupportedDurations(c, scalerStallDurationsTag, HAL_PIXEL_FORMAT_BLOB,
1350 supportedP010Sizes, &blobStallDurations);
1351 if (blobStallDurations.empty() || blobMinDurations.empty() ||
Euisang Limff49bdb2023-02-13 19:54:53 +09001352 supportedP010Sizes.size() != blobMinDurations.size() ||
1353 blobMinDurations.size() != blobStallDurations.size()) {
1354 ALOGE("%s: Unexpected number of available blob durations! %zu vs. %zu with "
1355 "supportedP010Sizes size: %zu", __FUNCTION__, blobMinDurations.size(),
1356 blobStallDurations.size(), supportedP010Sizes.size());
Emilian Peev434248e2022-10-06 14:58:54 -07001357 return BAD_VALUE;
1358 }
1359
1360 auto itDuration = blobMinDurations.begin();
1361 auto itSize = supportedP010Sizes.begin();
1362 while (itDuration != blobMinDurations.end()) {
1363 int64_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(*itSize)),
1364 static_cast<int32_t> (std::get<1>(*itSize)), *itDuration};
1365 jpegRMinDurations.insert(jpegRMinDurations.end(), entry, entry + 4);
1366 itDuration++; itSize++;
1367 }
1368
1369 itDuration = blobStallDurations.begin();
1370 itSize = supportedP010Sizes.begin();
1371 while (itDuration != blobStallDurations.end()) {
1372 int64_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(*itSize)),
1373 static_cast<int32_t> (std::get<1>(*itSize)), *itDuration};
1374 jpegRStallDurations.insert(jpegRStallDurations.end(), entry, entry + 4);
1375 itDuration++; itSize++;
1376 }
1377
1378 supportedChTags.reserve(chTags.count + 3);
1379 supportedChTags.insert(supportedChTags.end(), chTags.data.i32,
1380 chTags.data.i32 + chTags.count);
1381 supportedChTags.push_back(jpegRSizesTag);
1382 supportedChTags.push_back(jpegRMinFrameDurationsTag);
1383 supportedChTags.push_back(jpegRStallDurationsTag);
1384 c.update(jpegRSizesTag, jpegREntries.data(), jpegREntries.size());
1385 c.update(jpegRMinFrameDurationsTag, jpegRMinDurations.data(), jpegRMinDurations.size());
1386 c.update(jpegRStallDurationsTag, jpegRStallDurations.data(), jpegRStallDurations.size());
1387 c.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, supportedChTags.data(),
1388 supportedChTags.size());
1389
1390 auto colorSpaces = c.find(ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP);
1391 if (colorSpaces.count > 0 && !maxResolution) {
1392 bool displayP3Support = false;
1393 int64_t dynamicRange = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
1394 for (size_t i = 0; i < colorSpaces.count; i += 3) {
1395 auto colorSpace = colorSpaces.data.i64[i];
1396 auto format = colorSpaces.data.i64[i+1];
1397 bool formatMatch = (format == static_cast<int64_t>(PublicFormat::JPEG)) ||
1398 (format == static_cast<int64_t>(PublicFormat::UNKNOWN));
1399 bool colorSpaceMatch =
1400 colorSpace == ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3;
1401 if (formatMatch && colorSpaceMatch) {
1402 displayP3Support = true;
1403 }
1404
1405 // Jpeg/R will support the same dynamic range profiles as P010
1406 if (format == static_cast<int64_t>(PublicFormat::YCBCR_P010)) {
1407 dynamicRange |= colorSpaces.data.i64[i+2];
1408 }
1409 }
1410 if (displayP3Support) {
1411 std::vector<int64_t> supportedColorSpaces;
1412 // Jpeg/R must support the default system as well ase display P3 color space
1413 supportedColorSpaces.reserve(colorSpaces.count + 3*2);
1414 supportedColorSpaces.insert(supportedColorSpaces.end(), colorSpaces.data.i64,
1415 colorSpaces.data.i64 + colorSpaces.count);
1416
1417 supportedColorSpaces.push_back(static_cast<int64_t>(
1418 ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB));
1419 supportedColorSpaces.push_back(static_cast<int64_t>(PublicFormat::JPEG_R));
1420 supportedColorSpaces.push_back(dynamicRange);
1421
1422 supportedColorSpaces.push_back(static_cast<int64_t>(
1423 ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3));
1424 supportedColorSpaces.push_back(static_cast<int64_t>(PublicFormat::JPEG_R));
1425 supportedColorSpaces.push_back(dynamicRange);
1426 c.update(ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP,
1427 supportedColorSpaces.data(), supportedColorSpaces.size());
1428 }
1429 }
1430
1431 return OK;
1432}
1433
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001434status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addDynamicDepthTags(
1435 bool maxResolution) {
1436 const int32_t depthExclTag = ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE;
1437
1438 const int32_t scalerSizesTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001439 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001440 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
1441 const int32_t scalerMinFrameDurationsTag =
1442 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
1443 const int32_t scalerStallDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001444 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001445 ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, maxResolution);
1446
1447 const int32_t depthSizesTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001448 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001449 ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, maxResolution);
1450 const int32_t depthStallDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001451 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001452 ANDROID_DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS, maxResolution);
1453 const int32_t depthMinFrameDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001454 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001455 ANDROID_DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS, maxResolution);
1456
1457 const int32_t dynamicDepthSizesTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001458 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001459 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STREAM_CONFIGURATIONS, maxResolution);
1460 const int32_t dynamicDepthStallDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001461 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001462 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_STALL_DURATIONS, maxResolution);
1463 const int32_t dynamicDepthMinFrameDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001464 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001465 ANDROID_DEPTH_AVAILABLE_DYNAMIC_DEPTH_MIN_FRAME_DURATIONS, maxResolution);
1466
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001467 auto& c = mCameraCharacteristics;
1468 std::vector<std::tuple<size_t, size_t>> supportedBlobSizes, supportedDepthSizes,
1469 supportedDynamicDepthSizes, internalDepthSizes;
1470 auto chTags = c.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
1471 if (chTags.count == 0) {
1472 ALOGE("%s: Supported camera characteristics is empty!", __FUNCTION__);
1473 return BAD_VALUE;
1474 }
1475
1476 bool isDepthExclusivePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
1477 depthExclTag) != (chTags.data.i32 + chTags.count);
1478 bool isDepthSizePresent = std::find(chTags.data.i32, chTags.data.i32 + chTags.count,
Emilian Peeva1185162019-01-30 16:41:43 -08001479 depthSizesTag) != (chTags.data.i32 + chTags.count);
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001480 if (!(isDepthExclusivePresent && isDepthSizePresent)) {
1481 // No depth support, nothing more to do.
1482 return OK;
1483 }
1484
1485 auto depthExclusiveEntry = c.find(depthExclTag);
1486 if (depthExclusiveEntry.count > 0) {
1487 if (depthExclusiveEntry.data.u8[0] != ANDROID_DEPTH_DEPTH_IS_EXCLUSIVE_FALSE) {
1488 // Depth support is exclusive, nothing more to do.
1489 return OK;
1490 }
1491 } else {
1492 ALOGE("%s: Advertised depth exclusive tag but value is not present!", __FUNCTION__);
1493 return BAD_VALUE;
1494 }
1495
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001496 getSupportedSizes(c, scalerSizesTag, HAL_PIXEL_FORMAT_BLOB,
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001497 &supportedBlobSizes);
1498 getSupportedSizes(c, depthSizesTag, HAL_PIXEL_FORMAT_Y16, &supportedDepthSizes);
1499 if (supportedBlobSizes.empty() || supportedDepthSizes.empty()) {
1500 // Nothing to do in this case.
1501 return OK;
1502 }
1503
1504 getSupportedDynamicDepthSizes(supportedBlobSizes, supportedDepthSizes,
1505 &supportedDynamicDepthSizes, &internalDepthSizes);
1506 if (supportedDynamicDepthSizes.empty()) {
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001507 // Nothing more to do.
1508 return OK;
1509 }
1510
1511 std::vector<int32_t> dynamicDepthEntries;
1512 for (const auto& it : supportedDynamicDepthSizes) {
1513 int32_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(it)),
1514 static_cast<int32_t> (std::get<1>(it)),
1515 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT };
1516 dynamicDepthEntries.insert(dynamicDepthEntries.end(), entry, entry + 4);
1517 }
1518
1519 std::vector<int64_t> depthMinDurations, depthStallDurations;
1520 std::vector<int64_t> blobMinDurations, blobStallDurations;
1521 std::vector<int64_t> dynamicDepthMinDurations, dynamicDepthStallDurations;
1522
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001523 getSupportedDurations(c, depthMinFrameDurationsTag, HAL_PIXEL_FORMAT_Y16, internalDepthSizes,
1524 &depthMinDurations);
1525 getSupportedDurations(c, scalerMinFrameDurationsTag, HAL_PIXEL_FORMAT_BLOB,
1526 supportedDynamicDepthSizes, &blobMinDurations);
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001527 if (blobMinDurations.empty() || depthMinDurations.empty() ||
1528 (depthMinDurations.size() != blobMinDurations.size())) {
1529 ALOGE("%s: Unexpected number of available depth min durations! %zu vs. %zu",
1530 __FUNCTION__, depthMinDurations.size(), blobMinDurations.size());
1531 return BAD_VALUE;
1532 }
1533
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001534 getSupportedDurations(c, depthStallDurationsTag, HAL_PIXEL_FORMAT_Y16, internalDepthSizes,
1535 &depthStallDurations);
1536 getSupportedDurations(c, scalerStallDurationsTag, HAL_PIXEL_FORMAT_BLOB,
1537 supportedDynamicDepthSizes, &blobStallDurations);
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001538 if (blobStallDurations.empty() || depthStallDurations.empty() ||
1539 (depthStallDurations.size() != blobStallDurations.size())) {
1540 ALOGE("%s: Unexpected number of available depth stall durations! %zu vs. %zu",
1541 __FUNCTION__, depthStallDurations.size(), blobStallDurations.size());
1542 return BAD_VALUE;
1543 }
1544
1545 getSupportedDynamicDepthDurations(depthMinDurations, blobMinDurations,
1546 &dynamicDepthMinDurations);
1547 getSupportedDynamicDepthDurations(depthStallDurations, blobStallDurations,
1548 &dynamicDepthStallDurations);
1549 if (dynamicDepthMinDurations.empty() || dynamicDepthStallDurations.empty() ||
1550 (dynamicDepthMinDurations.size() != dynamicDepthStallDurations.size())) {
1551 ALOGE("%s: Unexpected number of dynamic depth stall/min durations! %zu vs. %zu",
1552 __FUNCTION__, dynamicDepthMinDurations.size(), dynamicDepthStallDurations.size());
1553 return BAD_VALUE;
1554 }
1555
1556 std::vector<int64_t> dynamicDepthMinDurationEntries;
1557 auto itDuration = dynamicDepthMinDurations.begin();
1558 auto itSize = supportedDynamicDepthSizes.begin();
1559 while (itDuration != dynamicDepthMinDurations.end()) {
1560 int64_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(*itSize)),
1561 static_cast<int32_t> (std::get<1>(*itSize)), *itDuration};
1562 dynamicDepthMinDurationEntries.insert(dynamicDepthMinDurationEntries.end(), entry,
1563 entry + 4);
1564 itDuration++; itSize++;
1565 }
1566
1567 std::vector<int64_t> dynamicDepthStallDurationEntries;
1568 itDuration = dynamicDepthStallDurations.begin();
1569 itSize = supportedDynamicDepthSizes.begin();
1570 while (itDuration != dynamicDepthStallDurations.end()) {
1571 int64_t entry[4] = {HAL_PIXEL_FORMAT_BLOB, static_cast<int32_t> (std::get<0>(*itSize)),
1572 static_cast<int32_t> (std::get<1>(*itSize)), *itDuration};
1573 dynamicDepthStallDurationEntries.insert(dynamicDepthStallDurationEntries.end(), entry,
1574 entry + 4);
1575 itDuration++; itSize++;
1576 }
1577
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001578 std::vector<int32_t> supportedChTags;
1579 supportedChTags.reserve(chTags.count + 3);
1580 supportedChTags.insert(supportedChTags.end(), chTags.data.i32,
1581 chTags.data.i32 + chTags.count);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001582 supportedChTags.push_back(dynamicDepthSizesTag);
1583 supportedChTags.push_back(dynamicDepthMinFrameDurationsTag);
1584 supportedChTags.push_back(dynamicDepthStallDurationsTag);
1585 c.update(dynamicDepthSizesTag, dynamicDepthEntries.data(), dynamicDepthEntries.size());
1586 c.update(dynamicDepthMinFrameDurationsTag, dynamicDepthMinDurationEntries.data(),
1587 dynamicDepthMinDurationEntries.size());
1588 c.update(dynamicDepthStallDurationsTag, dynamicDepthStallDurationEntries.data(),
1589 dynamicDepthStallDurationEntries.size());
Emilian Peev4c6d2b52019-01-04 17:13:56 +00001590 c.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, supportedChTags.data(),
1591 supportedChTags.size());
1592
1593 return OK;
1594}
1595
Rucha Katakwar31fbf3a2022-05-02 13:23:56 -07001596status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupTorchStrengthTags() {
1597 status_t res = OK;
1598 auto& c = mCameraCharacteristics;
1599 auto flashInfoStrengthDefaultLevelEntry = c.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
1600 if (flashInfoStrengthDefaultLevelEntry.count == 0) {
1601 int32_t flashInfoStrengthDefaultLevel = 1;
1602 res = c.update(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL,
1603 &flashInfoStrengthDefaultLevel, 1);
1604 if (res != OK) {
1605 ALOGE("%s: Failed to update ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL: %s (%d)",
1606 __FUNCTION__,strerror(-res), res);
1607 return res;
1608 }
1609 }
1610 auto flashInfoStrengthMaximumLevelEntry = c.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
1611 if (flashInfoStrengthMaximumLevelEntry.count == 0) {
1612 int32_t flashInfoStrengthMaximumLevel = 1;
1613 res = c.update(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL,
1614 &flashInfoStrengthMaximumLevel, 1);
1615 if (res != OK) {
1616 ALOGE("%s: Failed to update ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL: %s (%d)",
1617 __FUNCTION__,strerror(-res), res);
1618 return res;
1619 }
1620 }
1621 return res;
1622}
1623
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001624
1625status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupManualFlashStrengthControlTags(
1626 CameraMetadata& ch) {
Rucha Katakward0dc8032023-09-26 15:39:31 -07001627 status_t res = OK;
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001628 auto flashSingleStrengthMaxLevelEntry = ch.find(ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL);
Rucha Katakward0dc8032023-09-26 15:39:31 -07001629 if (flashSingleStrengthMaxLevelEntry.count == 0) {
1630 int32_t flashSingleStrengthMaxLevel = 1;
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001631 res = ch.update(ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL,
Rucha Katakward0dc8032023-09-26 15:39:31 -07001632 &flashSingleStrengthMaxLevel, 1);
1633 if (res != OK) {
1634 ALOGE("%s: Failed to update ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL: %s (%d)",
1635 __FUNCTION__,strerror(-res), res);
1636 return res;
1637 }
1638 }
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001639 auto flashSingleStrengthDefaultLevelEntry = ch.find(
1640 ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL);
Rucha Katakward0dc8032023-09-26 15:39:31 -07001641 if (flashSingleStrengthDefaultLevelEntry.count == 0) {
1642 int32_t flashSingleStrengthDefaultLevel = 1;
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001643 res = ch.update(ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL,
Rucha Katakward0dc8032023-09-26 15:39:31 -07001644 &flashSingleStrengthDefaultLevel, 1);
1645 if (res != OK) {
1646 ALOGE("%s: Failed to update ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL: %s (%d)",
1647 __FUNCTION__,strerror(-res), res);
1648 return res;
1649 }
1650 }
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001651 auto flashTorchStrengthMaxLevelEntry = ch.find(ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL);
Rucha Katakward0dc8032023-09-26 15:39:31 -07001652 if (flashTorchStrengthMaxLevelEntry.count == 0) {
1653 int32_t flashTorchStrengthMaxLevel = 1;
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001654 res = ch.update(ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL,
Rucha Katakward0dc8032023-09-26 15:39:31 -07001655 &flashTorchStrengthMaxLevel, 1);
1656 if (res != OK) {
1657 ALOGE("%s: Failed to update ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL: %s (%d)",
1658 __FUNCTION__,strerror(-res), res);
1659 return res;
1660 }
1661 }
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001662 auto flashTorchStrengthDefaultLevelEntry = ch.find(ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL);
Rucha Katakward0dc8032023-09-26 15:39:31 -07001663 if (flashTorchStrengthDefaultLevelEntry.count == 0) {
1664 int32_t flashTorchStrengthDefaultLevel = 1;
Rucha Katakware4d3e1f2023-11-06 13:46:45 -08001665 res = ch.update(ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL,
Rucha Katakward0dc8032023-09-26 15:39:31 -07001666 &flashTorchStrengthDefaultLevel, 1);
1667 if (res != OK) {
1668 ALOGE("%s: Failed to update ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL: %s (%d)",
1669 __FUNCTION__,strerror(-res), res);
1670 return res;
1671 }
1672 }
1673 return res;
1674}
1675
Shuzhen Wang268a1362018-10-16 16:32:59 -07001676status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fixupMonochromeTags() {
1677 status_t res = OK;
1678 auto& c = mCameraCharacteristics;
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00001679 sp<ProviderInfo> parentProvider = mParentProvider.promote();
1680 if (parentProvider == nullptr) {
1681 return DEAD_OBJECT;
1682 }
1683 IPCTransport ipcTransport = parentProvider->getIPCTransport();
Shuzhen Wang268a1362018-10-16 16:32:59 -07001684 // Override static metadata for MONOCHROME camera with older device version
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00001685 if (ipcTransport == IPCTransport::HIDL &&
1686 (mVersion.get_major() == 3 && mVersion.get_minor() < 5)) {
Shuzhen Wang268a1362018-10-16 16:32:59 -07001687 camera_metadata_entry cap = c.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
1688 for (size_t i = 0; i < cap.count; i++) {
1689 if (cap.data.u8[i] == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
1690 // ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
1691 uint8_t cfa = ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO;
1692 res = c.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, &cfa, 1);
1693 if (res != OK) {
1694 ALOGE("%s: Failed to update COLOR_FILTER_ARRANGEMENT: %s (%d)",
1695 __FUNCTION__, strerror(-res), res);
1696 return res;
1697 }
1698
1699 // ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
1700 const std::vector<uint32_t> sKeys = {
1701 ANDROID_SENSOR_REFERENCE_ILLUMINANT1,
1702 ANDROID_SENSOR_REFERENCE_ILLUMINANT2,
1703 ANDROID_SENSOR_CALIBRATION_TRANSFORM1,
1704 ANDROID_SENSOR_CALIBRATION_TRANSFORM2,
1705 ANDROID_SENSOR_COLOR_TRANSFORM1,
1706 ANDROID_SENSOR_COLOR_TRANSFORM2,
1707 ANDROID_SENSOR_FORWARD_MATRIX1,
1708 ANDROID_SENSOR_FORWARD_MATRIX2,
1709 };
1710 res = removeAvailableKeys(c, sKeys,
1711 ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
1712 if (res != OK) {
1713 ALOGE("%s: Failed to update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s (%d)",
1714 __FUNCTION__, strerror(-res), res);
1715 return res;
1716 }
1717
1718 // ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS
1719 const std::vector<uint32_t> reqKeys = {
1720 ANDROID_COLOR_CORRECTION_MODE,
1721 ANDROID_COLOR_CORRECTION_TRANSFORM,
1722 ANDROID_COLOR_CORRECTION_GAINS,
1723 };
1724 res = removeAvailableKeys(c, reqKeys, ANDROID_REQUEST_AVAILABLE_REQUEST_KEYS);
1725 if (res != OK) {
1726 ALOGE("%s: Failed to update REQUEST_AVAILABLE_REQUEST_KEYS: %s (%d)",
1727 __FUNCTION__, strerror(-res), res);
1728 return res;
1729 }
1730
1731 // ANDROID_REQUEST_AVAILABLE_RESULT_KEYS
1732 const std::vector<uint32_t> resKeys = {
1733 ANDROID_SENSOR_GREEN_SPLIT,
1734 ANDROID_SENSOR_NEUTRAL_COLOR_POINT,
1735 ANDROID_COLOR_CORRECTION_MODE,
1736 ANDROID_COLOR_CORRECTION_TRANSFORM,
1737 ANDROID_COLOR_CORRECTION_GAINS,
1738 };
1739 res = removeAvailableKeys(c, resKeys, ANDROID_REQUEST_AVAILABLE_RESULT_KEYS);
1740 if (res != OK) {
1741 ALOGE("%s: Failed to update REQUEST_AVAILABLE_RESULT_KEYS: %s (%d)",
1742 __FUNCTION__, strerror(-res), res);
1743 return res;
1744 }
1745
1746 // ANDROID_SENSOR_BLACK_LEVEL_PATTERN
1747 camera_metadata_entry blEntry = c.find(ANDROID_SENSOR_BLACK_LEVEL_PATTERN);
1748 for (size_t j = 1; j < blEntry.count; j++) {
1749 blEntry.data.i32[j] = blEntry.data.i32[0];
1750 }
1751 }
1752 }
1753 }
1754 return res;
1755}
1756
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001757status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addRotateCropTags() {
1758 status_t res = OK;
1759 auto& c = mCameraCharacteristics;
1760
1761 auto availableRotateCropEntry = c.find(ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES);
1762 if (availableRotateCropEntry.count == 0) {
1763 uint8_t defaultAvailableRotateCropEntry = ANDROID_SCALER_ROTATE_AND_CROP_NONE;
1764 res = c.update(ANDROID_SCALER_AVAILABLE_ROTATE_AND_CROP_MODES,
1765 &defaultAvailableRotateCropEntry, 1);
1766 }
1767 return res;
1768}
1769
Bharatt Kukrejad33fe9f2022-11-23 21:52:52 +00001770status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addAutoframingTags() {
1771 status_t res = OK;
1772 auto& c = mCameraCharacteristics;
1773
1774 auto availableAutoframingEntry = c.find(ANDROID_CONTROL_AUTOFRAMING_AVAILABLE);
1775 if (availableAutoframingEntry.count == 0) {
1776 uint8_t defaultAutoframingEntry = ANDROID_CONTROL_AUTOFRAMING_AVAILABLE_FALSE;
1777 res = c.update(ANDROID_CONTROL_AUTOFRAMING_AVAILABLE,
1778 &defaultAutoframingEntry, 1);
1779 }
1780 return res;
1781}
1782
Shuzhen Wang9bf8a6f2020-05-01 09:49:04 -07001783status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addPreCorrectionActiveArraySize() {
1784 status_t res = OK;
1785 auto& c = mCameraCharacteristics;
1786
1787 auto activeArraySize = c.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
1788 auto preCorrectionActiveArraySize = c.find(
1789 ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
1790 if (activeArraySize.count == 4 && preCorrectionActiveArraySize.count == 0) {
1791 std::vector<int32_t> preCorrectionArray(
1792 activeArraySize.data.i32, activeArraySize.data.i32+4);
1793 res = c.update(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE,
1794 preCorrectionArray.data(), 4);
1795 if (res != OK) {
1796 ALOGE("%s: Failed to add ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE: %s(%d)",
1797 __FUNCTION__, strerror(-res), res);
1798 return res;
1799 }
1800 } else {
1801 return res;
1802 }
1803
1804 auto charTags = c.find(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS);
1805 bool hasPreCorrectionActiveArraySize = std::find(charTags.data.i32,
1806 charTags.data.i32 + charTags.count,
1807 ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE) !=
1808 (charTags.data.i32 + charTags.count);
1809 if (!hasPreCorrectionActiveArraySize) {
1810 std::vector<int32_t> supportedCharTags;
1811 supportedCharTags.reserve(charTags.count + 1);
1812 supportedCharTags.insert(supportedCharTags.end(), charTags.data.i32,
1813 charTags.data.i32 + charTags.count);
1814 supportedCharTags.push_back(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
1815
1816 res = c.update(ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS, supportedCharTags.data(),
1817 supportedCharTags.size());
1818 if (res != OK) {
1819 ALOGE("%s: Failed to update ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS: %s(%d)",
1820 __FUNCTION__, strerror(-res), res);
1821 return res;
1822 }
1823 }
1824
1825 return res;
1826}
1827
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00001828status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addReadoutTimestampTag(
1829 bool readoutTimestampSupported) {
Shuzhen Wangffc4c012022-04-20 15:55:46 -07001830 status_t res = OK;
1831 auto& c = mCameraCharacteristics;
1832
1833 auto entry = c.find(ANDROID_SENSOR_READOUT_TIMESTAMP);
Avichal Rakeshd6b51642023-12-13 12:50:35 -08001834 if (entry.count == 0) {
1835 uint8_t defaultReadoutTimestamp = readoutTimestampSupported ?
1836 ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE :
1837 ANDROID_SENSOR_READOUT_TIMESTAMP_NOT_SUPPORTED;
1838 res = c.update(ANDROID_SENSOR_READOUT_TIMESTAMP, &defaultReadoutTimestamp, 1);
Shuzhen Wangffc4c012022-04-20 15:55:46 -07001839 }
1840
Shuzhen Wangffc4c012022-04-20 15:55:46 -07001841 return res;
1842}
1843
Shuzhen Wang045be6c2023-10-12 10:01:10 -07001844status_t CameraProviderManager::ProviderInfo::DeviceInfo3::addSessionConfigQueryVersionTag() {
1845 sp<ProviderInfo> parentProvider = mParentProvider.promote();
1846 if (parentProvider == nullptr) {
1847 return DEAD_OBJECT;
1848 }
1849
1850 int versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_UPSIDE_DOWN_CAKE;
1851 IPCTransport ipcTransport = parentProvider->getIPCTransport();
1852 int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
1853 if (ipcTransport == IPCTransport::AIDL
1854 && deviceVersion >= CAMERA_DEVICE_API_VERSION_1_3) {
1855 versionCode = ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION_VANILLA_ICE_CREAM;
1856 }
1857
1858 auto& c = mCameraCharacteristics;
1859 status_t res = c.update(ANDROID_INFO_SESSION_CONFIGURATION_QUERY_VERSION, &versionCode, 1);
Avichal Rakesh4baf7262024-03-20 19:16:04 -07001860 mSessionConfigQueryVersion = versionCode;
Shuzhen Wang045be6c2023-10-12 10:01:10 -07001861 return res;
1862}
1863
Shuzhen Wang268a1362018-10-16 16:32:59 -07001864status_t CameraProviderManager::ProviderInfo::DeviceInfo3::removeAvailableKeys(
1865 CameraMetadata& c, const std::vector<uint32_t>& keys, uint32_t keyTag) {
1866 status_t res = OK;
1867
1868 camera_metadata_entry keysEntry = c.find(keyTag);
1869 if (keysEntry.count == 0) {
1870 ALOGE("%s: Failed to find tag %u: %s (%d)", __FUNCTION__, keyTag, strerror(-res), res);
1871 return res;
1872 }
1873 std::vector<int32_t> vKeys;
1874 vKeys.reserve(keysEntry.count);
1875 for (size_t i = 0; i < keysEntry.count; i++) {
1876 if (std::find(keys.begin(), keys.end(), keysEntry.data.i32[i]) == keys.end()) {
1877 vKeys.push_back(keysEntry.data.i32[i]);
1878 }
1879 }
1880 res = c.update(keyTag, vKeys.data(), vKeys.size());
1881 return res;
1882}
1883
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001884status_t CameraProviderManager::ProviderInfo::DeviceInfo3::fillHeicStreamCombinations(
1885 std::vector<int32_t>* outputs,
1886 std::vector<int64_t>* durations,
1887 std::vector<int64_t>* stallDurations,
1888 const camera_metadata_entry& halStreamConfigs,
1889 const camera_metadata_entry& halStreamDurations) {
1890 if (outputs == nullptr || durations == nullptr || stallDurations == nullptr) {
1891 return BAD_VALUE;
1892 }
1893
1894 static bool supportInMemoryTempFile =
1895 camera3::HeicCompositeStream::isInMemoryTempFileSupported();
1896 if (!supportInMemoryTempFile) {
1897 ALOGI("%s: No HEIC support due to absence of in memory temp file support",
1898 __FUNCTION__);
1899 return OK;
1900 }
1901
1902 for (size_t i = 0; i < halStreamConfigs.count; i += 4) {
1903 int32_t format = halStreamConfigs.data.i32[i];
1904 // Only IMPLEMENTATION_DEFINED and YUV_888 can be used to generate HEIC
1905 // image.
1906 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
1907 format != HAL_PIXEL_FORMAT_YCBCR_420_888) {
1908 continue;
1909 }
1910
1911 bool sizeAvail = false;
1912 for (size_t j = 0; j < outputs->size(); j+= 4) {
1913 if ((*outputs)[j+1] == halStreamConfigs.data.i32[i+1] &&
1914 (*outputs)[j+2] == halStreamConfigs.data.i32[i+2]) {
1915 sizeAvail = true;
1916 break;
1917 }
1918 }
1919 if (sizeAvail) continue;
1920
1921 int64_t stall = 0;
Susmitha Gummallafca67142020-03-05 14:58:30 -08001922 bool useHeic = false;
1923 bool useGrid = false;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001924 if (camera3::HeicCompositeStream::isSizeSupportedByHeifEncoder(
1925 halStreamConfigs.data.i32[i+1], halStreamConfigs.data.i32[i+2],
1926 &useHeic, &useGrid, &stall)) {
1927 if (useGrid != (format == HAL_PIXEL_FORMAT_YCBCR_420_888)) {
1928 continue;
1929 }
1930
1931 // HEIC configuration
1932 int32_t config[] = {HAL_PIXEL_FORMAT_BLOB, halStreamConfigs.data.i32[i+1],
1933 halStreamConfigs.data.i32[i+2], 0 /*isInput*/};
1934 outputs->insert(outputs->end(), config, config + 4);
1935
1936 // HEIC minFrameDuration
1937 for (size_t j = 0; j < halStreamDurations.count; j += 4) {
1938 if (halStreamDurations.data.i64[j] == format &&
1939 halStreamDurations.data.i64[j+1] == halStreamConfigs.data.i32[i+1] &&
1940 halStreamDurations.data.i64[j+2] == halStreamConfigs.data.i32[i+2]) {
1941 int64_t duration[] = {HAL_PIXEL_FORMAT_BLOB, halStreamConfigs.data.i32[i+1],
1942 halStreamConfigs.data.i32[i+2], halStreamDurations.data.i64[j+3]};
1943 durations->insert(durations->end(), duration, duration+4);
1944 break;
1945 }
1946 }
1947
1948 // HEIC stallDuration
1949 int64_t stallDuration[] = {HAL_PIXEL_FORMAT_BLOB, halStreamConfigs.data.i32[i+1],
1950 halStreamConfigs.data.i32[i+2], stall};
1951 stallDurations->insert(stallDurations->end(), stallDuration, stallDuration+4);
1952 }
1953 }
1954 return OK;
1955}
1956
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001957status_t CameraProviderManager::ProviderInfo::DeviceInfo3::deriveHeicTags(bool maxResolution) {
1958 int32_t scalerStreamSizesTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001959 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001960 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
1961 int32_t scalerMinFrameDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001962 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001963 ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, maxResolution);
1964
1965 int32_t heicStreamSizesTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001966 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001967 ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, maxResolution);
1968 int32_t heicMinFrameDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001969 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001970 ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS, maxResolution);
1971 int32_t heicStallDurationsTag =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001972 SessionConfigurationUtils::getAppropriateModeTag(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001973 ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS, maxResolution);
1974
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001975 auto& c = mCameraCharacteristics;
1976
1977 camera_metadata_entry halHeicSupport = c.find(ANDROID_HEIC_INFO_SUPPORTED);
1978 if (halHeicSupport.count > 1) {
1979 ALOGE("%s: Invalid entry count %zu for ANDROID_HEIC_INFO_SUPPORTED",
1980 __FUNCTION__, halHeicSupport.count);
1981 return BAD_VALUE;
1982 } else if (halHeicSupport.count == 0 ||
1983 halHeicSupport.data.u8[0] == ANDROID_HEIC_INFO_SUPPORTED_FALSE) {
1984 // Camera HAL doesn't support mandatory stream combinations for HEIC.
1985 return OK;
1986 }
1987
1988 camera_metadata_entry maxJpegAppsSegments =
1989 c.find(ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT);
1990 if (maxJpegAppsSegments.count != 1 || maxJpegAppsSegments.data.u8[0] == 0 ||
1991 maxJpegAppsSegments.data.u8[0] > 16) {
1992 ALOGE("%s: ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT must be within [1, 16]",
1993 __FUNCTION__);
1994 return BAD_VALUE;
1995 }
1996
1997 // Populate HEIC output configurations and its related min frame duration
1998 // and stall duration.
1999 std::vector<int32_t> heicOutputs;
2000 std::vector<int64_t> heicDurations;
2001 std::vector<int64_t> heicStallDurations;
2002
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08002003 camera_metadata_entry halStreamConfigs = c.find(scalerStreamSizesTag);
2004 camera_metadata_entry minFrameDurations = c.find(scalerMinFrameDurationsTag);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08002005
2006 status_t res = fillHeicStreamCombinations(&heicOutputs, &heicDurations, &heicStallDurations,
2007 halStreamConfigs, minFrameDurations);
2008 if (res != OK) {
2009 ALOGE("%s: Failed to fill HEIC stream combinations: %s (%d)", __FUNCTION__,
2010 strerror(-res), res);
2011 return res;
2012 }
2013
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08002014 c.update(heicStreamSizesTag, heicOutputs.data(), heicOutputs.size());
2015 c.update(heicMinFrameDurationsTag, heicDurations.data(), heicDurations.size());
2016 c.update(heicStallDurationsTag, heicStallDurations.data(), heicStallDurations.size());
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08002017
2018 return OK;
2019}
2020
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08002021bool CameraProviderManager::isLogicalCameraLocked(const std::string& id,
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07002022 std::vector<std::string>* physicalCameraIds) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07002023 auto deviceInfo = findDeviceInfoLocked(id);
2024 if (deviceInfo == nullptr) return false;
2025
2026 if (deviceInfo->mIsLogicalCamera && physicalCameraIds != nullptr) {
2027 *physicalCameraIds = deviceInfo->mPhysicalIds;
2028 }
2029 return deviceInfo->mIsLogicalCamera;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07002030}
2031
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08002032bool CameraProviderManager::isLogicalCamera(const std::string& id,
2033 std::vector<std::string>* physicalCameraIds) {
2034 std::lock_guard<std::mutex> lock(mInterfaceMutex);
2035 return isLogicalCameraLocked(id, physicalCameraIds);
2036}
2037
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002038status_t CameraProviderManager::getSystemCameraKind(const std::string& id,
2039 SystemCameraKind *kind) const {
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08002040 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002041 return getSystemCameraKindLocked(id, kind);
Jayant Chowdhary847947d2019-08-30 18:02:59 -07002042}
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08002043
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002044status_t CameraProviderManager::getSystemCameraKindLocked(const std::string& id,
2045 SystemCameraKind *kind) const {
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08002046 auto deviceInfo = findDeviceInfoLocked(id);
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002047 if (deviceInfo != nullptr) {
2048 *kind = deviceInfo->mSystemCameraKind;
2049 return OK;
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08002050 }
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002051 // If this is a hidden physical camera, we should return what kind of
2052 // camera the enclosing logical camera is.
2053 auto isHiddenAndParent = isHiddenPhysicalCameraInternal(id);
2054 if (isHiddenAndParent.first) {
2055 LOG_ALWAYS_FATAL_IF(id == isHiddenAndParent.second->mId,
2056 "%s: hidden physical camera id %s and enclosing logical camera id %s are the same",
2057 __FUNCTION__, id.c_str(), isHiddenAndParent.second->mId.c_str());
2058 return getSystemCameraKindLocked(isHiddenAndParent.second->mId, kind);
2059 }
2060 // Neither a hidden physical camera nor a logical camera
2061 return NAME_NOT_FOUND;
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08002062}
2063
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002064bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) const {
Emilian Peev7fe6c422021-09-08 13:43:20 -07002065 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002066 return isHiddenPhysicalCameraInternal(cameraId).first;
2067}
2068
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002069status_t CameraProviderManager::filterSmallJpegSizes(const std::string& cameraId) {
Emilian Peev7fe6c422021-09-08 13:43:20 -07002070 std::lock_guard<std::mutex> lock(mInterfaceMutex);
Shuzhen Wang89db2992021-05-20 13:09:48 -07002071 for (auto& provider : mProviders) {
2072 for (auto& deviceInfo : provider->mDevices) {
2073 if (deviceInfo->mId == cameraId) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002074 return deviceInfo->filterSmallJpegSizes();
Shuzhen Wang89db2992021-05-20 13:09:48 -07002075 }
2076 }
2077 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002078 return NAME_NOT_FOUND;
Shuzhen Wang89db2992021-05-20 13:09:48 -07002079}
2080
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002081std::pair<bool, CameraProviderManager::ProviderInfo::DeviceInfo *>
2082CameraProviderManager::isHiddenPhysicalCameraInternal(const std::string& cameraId) const {
2083 auto falseRet = std::make_pair(false, nullptr);
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002084 for (auto& provider : mProviders) {
2085 for (auto& deviceInfo : provider->mDevices) {
2086 if (deviceInfo->mId == cameraId) {
2087 // cameraId is found in public camera IDs advertised by the
2088 // provider.
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002089 return falseRet;
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002090 }
2091 }
2092 }
2093
2094 for (auto& provider : mProviders) {
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00002095 IPCTransport transport = provider->getIPCTransport();
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002096 for (auto& deviceInfo : provider->mDevices) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002097 std::vector<std::string> physicalIds;
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07002098 if (deviceInfo->mIsLogicalCamera) {
2099 if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
2100 cameraId) != deviceInfo->mPhysicalIds.end()) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002101 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
2102 deviceInfo->mVersion.get_major(), deviceInfo->mVersion.get_minor());
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00002103 if (transport == IPCTransport::HIDL &&
2104 deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002105 ALOGE("%s: Wrong deviceVersion %x for hiddenPhysicalCameraId %s",
2106 __FUNCTION__, deviceVersion, cameraId.c_str());
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002107 return falseRet;
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002108 } else {
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002109 return std::make_pair(true, deviceInfo.get());
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002110 }
2111 }
2112 }
2113 }
2114 }
2115
Jayant Chowdhary33e8ef82019-09-27 09:20:42 -07002116 return falseRet;
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002117}
2118
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002119status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
2120 const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
2121 using aidl::android::hardware::camera::provider::ICameraProvider;
Jayant Chowdharyd65d9442023-07-11 01:18:06 +00002122
Avichal Rakesh682788a2024-01-11 18:01:36 -08002123 std::shared_ptr<ICameraProvider> interface;
2124 if (flags::delay_lazy_hal_instantiation()) {
2125 // Only get remote instance if already running. Lazy Providers will be
2126 // woken up later.
2127 interface = mAidlServiceProxy->tryGetService(providerName);
2128 } else {
2129 interface = mAidlServiceProxy->getService(providerName);
2130 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002131
2132 if (interface == nullptr) {
2133 ALOGW("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
2134 providerName.c_str());
2135 return BAD_VALUE;
2136 }
2137
2138 AidlProviderInfo *aidlProviderInfo = static_cast<AidlProviderInfo *>(providerInfo.get());
Ravneet Dhanjal7f7ab672024-07-18 22:43:04 +00002139 status_t res = aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);
2140
2141 if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
2142 pid_t pid = 0;
2143
2144 if (AIBinder_toPlatformBinder(interface->asBinder().get())->getDebugPid(&pid) == OK
2145 && res == OK) {
2146 std::lock_guard<std::mutex> lock(mProviderPidMapLock);
2147 mProviderPidMap[providerInfo->mProviderInstance] = pid;
2148 }
2149 }
2150
2151 return res;
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002152}
2153
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002154status_t CameraProviderManager::tryToInitializeHidlProviderLocked(
Emilian Peevc93cac22020-08-17 16:00:10 -07002155 const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002156 sp<provider::V2_4::ICameraProvider> interface;
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002157 interface = mHidlServiceProxy->tryGetService(providerName);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002158
2159 if (interface == nullptr) {
Shuzhen Wang77d04192021-04-02 12:33:54 -07002160 // The interface may not be started yet. In that case, this is not a
2161 // fatal error.
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002162 ALOGW("%s: HIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
Emilian Peevc93cac22020-08-17 16:00:10 -07002163 providerName.c_str());
Yin-Chia Yeh177b0c12019-06-25 10:53:03 -07002164 return BAD_VALUE;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002165 }
2166
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002167 HidlProviderInfo *hidlProviderInfo = static_cast<HidlProviderInfo *>(providerInfo.get());
Ravneet Dhanjal7f7ab672024-07-18 22:43:04 +00002168 status_t res = hidlProviderInfo->initializeHidlProvider(interface, mDeviceState);
2169
2170 if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
2171 pid_t pid = 0;
2172
2173 auto ret = interface->getDebugInfo([&pid](
2174 const ::android::hidl::base::V1_0::DebugInfo& info) {
2175 pid = info.pid;
2176 });
2177
2178 if (ret.isOk() && res == OK) {
2179 std::lock_guard<std::mutex> lock(mProviderPidMapLock);
2180 mProviderPidMap[providerInfo->mProviderInstance] = pid;
2181 }
2182 }
2183
2184 return res;
Emilian Peevc93cac22020-08-17 16:00:10 -07002185}
2186
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002187status_t CameraProviderManager::addAidlProviderLocked(const std::string& newProvider) {
2188 // Several camera provider instances can be temporarily present.
2189 // Defer initialization of a new instance until the older instance is properly removed.
2190 auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
2191 bool providerPresent = false;
2192 bool preexisting =
2193 (mAidlProviderWithBinders.find(newProvider) != mAidlProviderWithBinders.end());
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002194 using aidl::android::hardware::camera::provider::ICameraProvider;
Jayant Chowdharyd65d9442023-07-11 01:18:06 +00002195 std::string providerNameUsed =
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002196 newProvider.substr(std::string(ICameraProvider::descriptor).size() + 1);
Jayant Chowdharyd65d9442023-07-11 01:18:06 +00002197 if (flags::lazy_aidl_wait_for_service()) {
2198 // 'newProvider' has the fully qualified name of the provider service in case of AIDL.
2199 // ProviderInfo::mProviderName also has the fully qualified name - so we just compare them
2200 // here.
2201 providerNameUsed = newProvider;
2202 }
2203
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002204 for (const auto& providerInfo : mProviders) {
Jayant Chowdharyd65d9442023-07-11 01:18:06 +00002205 if (providerInfo->mProviderName == providerNameUsed) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002206 ALOGW("%s: Camera provider HAL with name '%s' already registered",
2207 __FUNCTION__, newProvider.c_str());
2208 // Do not add new instances for lazy HAL external provider or aidl
2209 // binders previously seen.
2210 if (preexisting || providerInfo->isExternalLazyHAL()) {
2211 return ALREADY_EXISTS;
2212 } else {
2213 ALOGW("%s: The new provider instance will get initialized immediately after the"
2214 " currently present instance is removed!", __FUNCTION__);
2215 providerPresent = true;
2216 break;
2217 }
2218 }
2219 }
2220
2221 sp<AidlProviderInfo> providerInfo =
Jayant Chowdharyd65d9442023-07-11 01:18:06 +00002222 new AidlProviderInfo(providerNameUsed, providerInstance, this);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002223
2224 if (!providerPresent) {
2225 status_t res = tryToInitializeAidlProviderLocked(newProvider, providerInfo);
2226 if (res != OK) {
2227 return res;
2228 }
2229 mAidlProviderWithBinders.emplace(newProvider);
2230 }
2231
2232 mProviders.push_back(providerInfo);
2233 mProviderInstanceId++;
2234
2235 return OK;
2236}
2237
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002238status_t CameraProviderManager::addHidlProviderLocked(const std::string& newProvider,
Emilian Peevc93cac22020-08-17 16:00:10 -07002239 bool preexisting) {
2240 // Several camera provider instances can be temporarily present.
2241 // Defer initialization of a new instance until the older instance is properly removed.
2242 auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
2243 bool providerPresent = false;
2244 for (const auto& providerInfo : mProviders) {
2245 if (providerInfo->mProviderName == newProvider) {
2246 ALOGW("%s: Camera provider HAL with name '%s' already registered",
2247 __FUNCTION__, newProvider.c_str());
Valentin Iftime29e2e152021-08-13 15:17:33 +02002248 // Do not add new instances for lazy HAL external provider
2249 if (preexisting || providerInfo->isExternalLazyHAL()) {
Emilian Peevc93cac22020-08-17 16:00:10 -07002250 return ALREADY_EXISTS;
Valentin Iftime29e2e152021-08-13 15:17:33 +02002251 } else {
Emilian Peevc93cac22020-08-17 16:00:10 -07002252 ALOGW("%s: The new provider instance will get initialized immediately after the"
2253 " currently present instance is removed!", __FUNCTION__);
2254 providerPresent = true;
2255 break;
2256 }
2257 }
2258 }
2259
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002260 sp<HidlProviderInfo> providerInfo = new HidlProviderInfo(newProvider, providerInstance, this);
Emilian Peevc93cac22020-08-17 16:00:10 -07002261 if (!providerPresent) {
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002262 status_t res = tryToInitializeHidlProviderLocked(newProvider, providerInfo);
Emilian Peevc93cac22020-08-17 16:00:10 -07002263 if (res != OK) {
2264 return res;
2265 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002266 }
2267
2268 mProviders.push_back(providerInfo);
Emilian Peevc93cac22020-08-17 16:00:10 -07002269 mProviderInstanceId++;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002270
2271 return OK;
2272}
2273
2274status_t CameraProviderManager::removeProvider(const std::string& provider) {
Shuzhen Wang6ba8eb22018-07-08 13:10:44 -07002275 std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002276 std::unique_lock<std::mutex> lock(mInterfaceMutex);
Austin Borger1c1bee02023-06-01 16:51:35 -07002277 std::vector<std::string> removedDeviceIds;
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002278 status_t res = NAME_NOT_FOUND;
Emilian Peevc93cac22020-08-17 16:00:10 -07002279 std::string removedProviderName;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002280 for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
Emilian Peevc93cac22020-08-17 16:00:10 -07002281 if ((*it)->mProviderInstance == provider) {
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002282 removedDeviceIds.reserve((*it)->mDevices.size());
2283 for (auto& deviceInfo : (*it)->mDevices) {
Austin Borger1c1bee02023-06-01 16:51:35 -07002284 removedDeviceIds.push_back(deviceInfo->mId);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002285 }
Emilian Peevc93cac22020-08-17 16:00:10 -07002286 removedProviderName = (*it)->mProviderName;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002287 mProviders.erase(it);
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002288 res = OK;
2289 break;
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002290 }
2291 }
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002292 if (res != OK) {
2293 ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
2294 provider.c_str());
2295 } else {
Ravneet Dhanjal7f7ab672024-07-18 22:43:04 +00002296 if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
2297 {
2298 std::lock_guard<std::mutex> pidLock(mProviderPidMapLock);
2299 mProviderPidMap.erase(provider);
2300 }
2301 }
2302
Emilian Peevc93cac22020-08-17 16:00:10 -07002303 // Check if there are any newer camera instances from the same provider and try to
2304 // initialize.
2305 for (const auto& providerInfo : mProviders) {
2306 if (providerInfo->mProviderName == removedProviderName) {
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002307 IPCTransport providerTransport = providerInfo->getIPCTransport();
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002308 std::string removedAidlProviderName = getFullAidlProviderName(removedProviderName);
Jayant Chowdharyd65d9442023-07-11 01:18:06 +00002309 if (flags::lazy_aidl_wait_for_service()) {
2310 removedAidlProviderName = removedProviderName;
2311 }
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002312 switch(providerTransport) {
2313 case IPCTransport::HIDL:
2314 return tryToInitializeHidlProviderLocked(removedProviderName, providerInfo);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002315 case IPCTransport::AIDL:
2316 return tryToInitializeAidlProviderLocked(removedAidlProviderName,
2317 providerInfo);
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002318 default:
Eino-Ville Talvalab7723202024-06-24 17:45:51 -07002319 ALOGE("%s Unsupported Transport %d", __FUNCTION__, eToI(providerTransport));
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002320 }
Emilian Peevc93cac22020-08-17 16:00:10 -07002321 }
2322 }
2323
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002324 // Inform camera service of loss of presence for all the devices from this provider,
2325 // without lock held for reentrancy
2326 sp<StatusListener> listener = getStatusListener();
2327 if (listener != nullptr) {
2328 lock.unlock();
2329 for (auto& id : removedDeviceIds) {
2330 listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
2331 }
Emilian Peevc93cac22020-08-17 16:00:10 -07002332 lock.lock();
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002333 }
Emilian Peevc93cac22020-08-17 16:00:10 -07002334
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002335 }
2336 return res;
2337}
2338
2339sp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListener() const {
2340 return mListener.promote();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002341}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002342/**** Methods for ProviderInfo ****/
2343
2344
2345CameraProviderManager::ProviderInfo::ProviderInfo(
2346 const std::string &providerName,
Emilian Peevc93cac22020-08-17 16:00:10 -07002347 const std::string &providerInstance,
Jing Mikec7f9b132023-03-12 11:12:04 +08002348 [[maybe_unused]] CameraProviderManager *manager) :
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002349 mProviderName(providerName),
Emilian Peevc93cac22020-08-17 16:00:10 -07002350 mProviderInstance(providerInstance),
Emilian Peev71c73a22017-03-21 16:35:51 +00002351 mProviderTagid(generateVendorTagId(providerName)),
Emilian Peevcdb74a62017-05-11 20:29:52 +01002352 mUniqueDeviceCount(0),
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002353 mManager(manager) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002354}
2355
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002356const std::string& CameraProviderManager::ProviderInfo::getType() const {
2357 return mType;
2358}
2359
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002360status_t CameraProviderManager::ProviderInfo::addDevice(
2361 const std::string& name, CameraDeviceStatus initialStatus,
2362 /*out*/ std::string* parsedId) {
2363
2364 ALOGI("Enumerating new camera device: %s", name.c_str());
2365
2366 uint16_t major, minor;
2367 std::string type, id;
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00002368 IPCTransport transport = getIPCTransport();
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002369
2370 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
2371 if (res != OK) {
2372 return res;
2373 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002374
2375 if (type != mType) {
2376 ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
2377 type.c_str(), mType.c_str());
2378 return BAD_VALUE;
2379 }
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00002380 if (mManager->isValidDeviceLocked(id, major, transport)) {
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002381 ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
2382 name.c_str(), id.c_str(), major);
2383 return BAD_VALUE;
2384 }
2385
2386 std::unique_ptr<DeviceInfo> deviceInfo;
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00002387 switch (transport) {
2388 case IPCTransport::HIDL:
2389 switch (major) {
2390 case 3:
2391 break;
2392 default:
2393 ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:",
2394 __FUNCTION__, name.c_str(), major);
2395 return BAD_VALUE;
2396 }
2397 break;
2398 case IPCTransport::AIDL:
2399 if (major != 1) {
2400 ALOGE("%s: Device %s: Unsupported AIDL device HAL major version %d:", __FUNCTION__,
2401 name.c_str(), major);
2402 return BAD_VALUE;
2403 }
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002404 break;
2405 default:
Eino-Ville Talvalab7723202024-06-24 17:45:51 -07002406 ALOGE("%s Invalid transport %d", __FUNCTION__, eToI(transport));
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002407 return BAD_VALUE;
2408 }
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00002409
2410 deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002411 if (deviceInfo == nullptr) return BAD_VALUE;
2412 deviceInfo->notifyDeviceStateChange(getDeviceState());
2413 deviceInfo->mStatus = initialStatus;
2414 bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
2415
2416 mDevices.push_back(std::move(deviceInfo));
2417
2418 mUniqueCameraIds.insert(id);
2419 if (isAPI1Compatible) {
2420 // addDevice can be called more than once for the same camera id if HAL
2421 // supports openLegacy.
2422 if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
2423 id) == mUniqueAPI1CompatibleCameraIds.end()) {
2424 mUniqueAPI1CompatibleCameraIds.push_back(id);
2425 }
2426 }
2427
2428 if (parsedId != nullptr) {
2429 *parsedId = id;
2430 }
2431 return OK;
2432}
2433
Austin Borger1c1bee02023-06-01 16:51:35 -07002434void CameraProviderManager::ProviderInfo::removeDevice(const std::string &id) {
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +01002435 for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
2436 if ((*it)->mId == id) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08002437 mUniqueCameraIds.erase(id);
Shuzhen Wang3d316f32022-10-25 20:33:34 +00002438 mUnavailablePhysicalCameras.erase(id);
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08002439 if ((*it)->isAPI1Compatible()) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -07002440 mUniqueAPI1CompatibleCameraIds.erase(std::remove(
Valentin Iftime29e2e152021-08-13 15:17:33 +02002441 mUniqueAPI1CompatibleCameraIds.begin(),
2442 mUniqueAPI1CompatibleCameraIds.end(), id));
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -08002443 }
Valentin Iftime29e2e152021-08-13 15:17:33 +02002444
2445 // Remove reference to camera provider to avoid pointer leak when
2446 // unplugging external camera while in use with lazy HALs
2447 mManager->removeRef(DeviceMode::CAMERA, id);
2448 mManager->removeRef(DeviceMode::TORCH, id);
2449
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +01002450 mDevices.erase(it);
2451 break;
2452 }
2453 }
2454}
2455
Valentin Iftime29e2e152021-08-13 15:17:33 +02002456void CameraProviderManager::ProviderInfo::removeAllDevices() {
2457 std::lock_guard<std::mutex> lock(mLock);
2458
2459 auto itDevices = mDevices.begin();
2460 while (itDevices != mDevices.end()) {
2461 std::string id = (*itDevices)->mId;
2462 std::string deviceName = (*itDevices)->mName;
2463 removeDevice(id);
2464 // device was removed, reset iterator
2465 itDevices = mDevices.begin();
2466
2467 //notify CameraService of status change
2468 sp<StatusListener> listener = mManager->getStatusListener();
2469 if (listener != nullptr) {
2470 mLock.unlock();
2471 ALOGV("%s: notify device not_present: %s",
2472 __FUNCTION__,
2473 deviceName.c_str());
Austin Borger1c1bee02023-06-01 16:51:35 -07002474 listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
Valentin Iftime29e2e152021-08-13 15:17:33 +02002475 mLock.lock();
2476 }
2477 }
2478}
2479
2480bool CameraProviderManager::ProviderInfo::isExternalLazyHAL() const {
Jayant Chowdharyd65d9442023-07-11 01:18:06 +00002481 std::string providerName = mProviderName;
2482 if (flags::lazy_aidl_wait_for_service() && getIPCTransport() == IPCTransport::AIDL) {
2483 using aidl::android::hardware::camera::provider::ICameraProvider;
2484 providerName =
2485 mProviderName.substr(std::string(ICameraProvider::descriptor).size() + 1);
2486 }
2487 return kEnableLazyHal && (providerName == kExternalProviderName);
Valentin Iftime29e2e152021-08-13 15:17:33 +02002488}
2489
Ravneet Dhanjal7f7ab672024-07-18 22:43:04 +00002490std::set<pid_t> CameraProviderManager::getProviderPids() {
2491 std::set<pid_t> pids;
2492
2493 if (flags::enable_hal_abort_from_cameraservicewatchdog()) {
2494 std::lock_guard<std::mutex> lock(mProviderPidMapLock);
2495
2496 std::transform(mProviderPidMap.begin(), mProviderPidMap.end(),
2497 std::inserter(pids, pids.begin()),
2498 [](std::pair<const std::string, pid_t>& entry) { return entry.second; });
2499 }
2500
2501 return pids;
2502}
2503
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002504status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
Eino-Ville Talvala63f36112018-12-06 14:57:03 -08002505 dprintf(fd, "== Camera Provider HAL %s (v2.%d, %s) static info: %zu devices: ==\n",
Emilian Peevc93cac22020-08-17 16:00:10 -07002506 mProviderInstance.c_str(),
Eino-Ville Talvala63f36112018-12-06 14:57:03 -08002507 mMinorVersion,
2508 mIsRemote ? "remote" : "passthrough",
Eino-Ville Talvala8d942f92017-03-13 10:09:51 -07002509 mDevices.size());
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002510
2511 for (auto& device : mDevices) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002512 dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
2513 device->mVersion.get_major(), device->mVersion.get_minor());
2514 dprintf(fd, " Resource cost: %d\n", device->mResourceCost.resourceCost);
2515 if (device->mResourceCost.conflictingDevices.size() == 0) {
2516 dprintf(fd, " Conflicting devices: None\n");
2517 } else {
2518 dprintf(fd, " Conflicting devices:\n");
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002519 for (size_t i = 0; i < device->mResourceCost.conflictingDevices.size(); i++) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002520 dprintf(fd, " %s\n",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002521 device->mResourceCost.conflictingDevices[i].c_str());
2522 }
2523 }
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002524 dprintf(fd, " API1 info:\n");
2525 dprintf(fd, " Has a flash unit: %s\n",
2526 device->hasFlashUnit() ? "true" : "false");
2527 hardware::CameraInfo info;
Austin Borger18b30a72022-10-27 12:20:29 -07002528 int portraitRotation;
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002529 status_t res = device->getCameraInfo(
2530 /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
2531 &portraitRotation, &info);
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002532 if (res != OK) {
2533 dprintf(fd, " <Error reading camera info: %s (%d)>\n",
2534 strerror(-res), res);
2535 } else {
2536 dprintf(fd, " Facing: %s\n",
2537 info.facing == hardware::CAMERA_FACING_BACK ? "Back" : "Front");
2538 dprintf(fd, " Orientation: %d\n", info.orientation);
2539 }
2540 CameraMetadata info2;
Austin Borger18b30a72022-10-27 12:20:29 -07002541 res = device->getCameraCharacteristics(true /*overrideForPerfClass*/, &info2,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002542 hardware::ICameraService::ROTATION_OVERRIDE_NONE);
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08002543 if (res == INVALID_OPERATION) {
2544 dprintf(fd, " API2 not directly supported\n");
2545 } else if (res != OK) {
2546 dprintf(fd, " <Error reading camera characteristics: %s (%d)>\n",
2547 strerror(-res), res);
2548 } else {
2549 dprintf(fd, " API2 camera characteristics:\n");
2550 info2.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
2551 }
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08002552
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002553 // Dump characteristics of non-standalone physical camera
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07002554 if (device->mIsLogicalCamera) {
2555 for (auto& id : device->mPhysicalIds) {
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002556 // Skip if physical id is an independent camera
2557 if (std::find(mProviderPublicCameraIds.begin(), mProviderPublicCameraIds.end(), id)
2558 != mProviderPublicCameraIds.end()) {
2559 continue;
2560 }
2561
2562 CameraMetadata physicalInfo;
2563 status_t status = device->getPhysicalCameraCharacteristics(id, &physicalInfo);
2564 if (status == OK) {
2565 dprintf(fd, " Physical camera %s characteristics:\n", id.c_str());
2566 physicalInfo.dump(fd, /*verbosity*/ 2, /*indentation*/ 4);
2567 }
2568 }
2569 }
2570
Yin-Chia Yeh487785a2018-01-02 12:06:57 -08002571 dprintf(fd, "== Camera HAL device %s (v%d.%d) dumpState: ==\n", device->mName.c_str(),
2572 device->mVersion.get_major(), device->mVersion.get_minor());
2573 res = device->dumpState(fd);
2574 if (res != OK) {
2575 dprintf(fd, " <Error dumping device %s state: %s (%d)>\n",
2576 device->mName.c_str(), strerror(-res), res);
2577 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002578 }
2579 return OK;
2580}
2581
Jayant Chowdharycbe770a2020-02-14 11:14:46 -08002582std::vector<std::unordered_set<std::string>>
2583CameraProviderManager::ProviderInfo::getConcurrentCameraIdCombinations() {
2584 std::lock_guard<std::mutex> lock(mLock);
2585 return mConcurrentCameraIdCombinations;
2586}
2587
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002588void CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeInternal(
2589 const std::string& cameraDeviceName, CameraDeviceStatus newStatus) {
2590 sp<StatusListener> listener;
2591 std::string id;
2592 std::lock_guard<std::mutex> lock(mInitLock);
2593 CameraDeviceStatus internalNewStatus = newStatus;
2594 if (!mInitialized) {
2595 mCachedStatus.emplace_back(false /*isPhysicalCameraStatus*/,
Austin Borger1c1bee02023-06-01 16:51:35 -07002596 cameraDeviceName, std::string(), internalNewStatus);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002597 return;
2598 }
2599
2600 {
2601 std::lock_guard<std::mutex> lock(mLock);
2602 if (OK != cameraDeviceStatusChangeLocked(&id, cameraDeviceName, newStatus)) {
2603 return;
2604 }
2605 listener = mManager->getStatusListener();
2606 }
2607
2608 // Call without lock held to allow reentrancy into provider manager
2609 if (listener != nullptr) {
Austin Borger1c1bee02023-06-01 16:51:35 -07002610 listener->onDeviceStatusChanged(id, internalNewStatus);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002611 }
2612}
2613
2614status_t CameraProviderManager::ProviderInfo::cameraDeviceStatusChangeLocked(
2615 std::string* id, const std::string& cameraDeviceName,
2616 CameraDeviceStatus newStatus) {
2617 bool known = false;
2618 std::string cameraId;
2619 for (auto& deviceInfo : mDevices) {
2620 if (deviceInfo->mName == cameraDeviceName) {
2621 Mutex::Autolock l(deviceInfo->mDeviceAvailableLock);
2622 ALOGI("Camera device %s status is now %s, was %s", cameraDeviceName.c_str(),
2623 FrameworkDeviceStatusToString(newStatus),
2624 FrameworkDeviceStatusToString(deviceInfo->mStatus));
2625 deviceInfo->mStatus = newStatus;
2626 // TODO: Handle device removal (NOT_PRESENT)
2627 cameraId = deviceInfo->mId;
2628 known = true;
2629 deviceInfo->mIsDeviceAvailable =
2630 (newStatus == CameraDeviceStatus::PRESENT);
2631 deviceInfo->mDeviceAvailableSignal.signal();
2632 break;
2633 }
2634 }
2635 // Previously unseen device; status must not be NOT_PRESENT
2636 if (!known) {
2637 if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
2638 ALOGW("Camera provider %s says an unknown camera device %s is not present. Curious.",
2639 mProviderName.c_str(), cameraDeviceName.c_str());
2640 return BAD_VALUE;
2641 }
2642 addDevice(cameraDeviceName, newStatus, &cameraId);
2643 } else if (newStatus == CameraDeviceStatus::NOT_PRESENT) {
2644 removeDevice(cameraId);
2645 } else if (isExternalLazyHAL()) {
2646 // Do not notify CameraService for PRESENT->PRESENT (lazy HAL restart)
2647 // because NOT_AVAILABLE is set on CameraService::connect and a PRESENT
2648 // notif. would overwrite it
2649 return BAD_VALUE;
2650 }
2651
2652 if (reCacheConcurrentStreamingCameraIdsLocked() != OK) {
2653 ALOGE("%s: CameraProvider %s could not re-cache concurrent streaming camera id list ",
2654 __FUNCTION__, mProviderName.c_str());
2655 }
2656 *id = cameraId;
2657 return OK;
2658}
2659
2660void CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeInternal(
2661 const std::string& cameraDeviceName,
2662 const std::string& physicalCameraDeviceName,
2663 CameraDeviceStatus newStatus) {
2664 sp<StatusListener> listener;
2665 std::string id;
2666 std::string physicalId;
2667 std::lock_guard<std::mutex> lock(mInitLock);
2668 if (!mInitialized) {
2669 mCachedStatus.emplace_back(true /*isPhysicalCameraStatus*/, cameraDeviceName,
2670 physicalCameraDeviceName, newStatus);
2671 return;
2672 }
2673
2674 {
2675 std::lock_guard<std::mutex> lock(mLock);
2676
2677 if (OK != physicalCameraDeviceStatusChangeLocked(&id, &physicalId, cameraDeviceName,
2678 physicalCameraDeviceName, newStatus)) {
2679 return;
2680 }
2681
2682 listener = mManager->getStatusListener();
2683 }
2684 // Call without lock held to allow reentrancy into provider manager
2685 if (listener != nullptr) {
Austin Borger1c1bee02023-06-01 16:51:35 -07002686 listener->onDeviceStatusChanged(id, physicalId, newStatus);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002687 }
2688 return;
2689}
2690
2691status_t CameraProviderManager::ProviderInfo::physicalCameraDeviceStatusChangeLocked(
2692 std::string* id, std::string* physicalId,
2693 const std::string& cameraDeviceName,
2694 const std::string& physicalCameraDeviceName,
2695 CameraDeviceStatus newStatus) {
2696 bool known = false;
2697 std::string cameraId;
2698 for (auto& deviceInfo : mDevices) {
2699 if (deviceInfo->mName == cameraDeviceName) {
2700 cameraId = deviceInfo->mId;
2701 if (!deviceInfo->mIsLogicalCamera) {
2702 ALOGE("%s: Invalid combination of camera id %s, physical id %s",
2703 __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
2704 return BAD_VALUE;
2705 }
2706 if (std::find(deviceInfo->mPhysicalIds.begin(), deviceInfo->mPhysicalIds.end(),
2707 physicalCameraDeviceName) == deviceInfo->mPhysicalIds.end()) {
2708 ALOGE("%s: Invalid combination of camera id %s, physical id %s",
2709 __FUNCTION__, cameraId.c_str(), physicalCameraDeviceName.c_str());
2710 return BAD_VALUE;
2711 }
2712 ALOGI("Camera device %s physical device %s status is now %s",
2713 cameraDeviceName.c_str(), physicalCameraDeviceName.c_str(),
2714 FrameworkDeviceStatusToString(newStatus));
2715 known = true;
2716 break;
2717 }
2718 }
2719 // Previously unseen device; status must not be NOT_PRESENT
2720 if (!known) {
2721 ALOGW("Camera provider %s says an unknown camera device %s-%s is not present. Curious.",
2722 mProviderName.c_str(), cameraDeviceName.c_str(),
2723 physicalCameraDeviceName.c_str());
2724 return BAD_VALUE;
2725 }
2726
Shuzhen Wang3d316f32022-10-25 20:33:34 +00002727 if (mUnavailablePhysicalCameras.count(cameraId) == 0) {
2728 mUnavailablePhysicalCameras.emplace(cameraId, std::set<std::string>{});
2729 }
2730 if (newStatus != CameraDeviceStatus::PRESENT) {
2731 mUnavailablePhysicalCameras[cameraId].insert(physicalCameraDeviceName);
2732 } else {
2733 mUnavailablePhysicalCameras[cameraId].erase(physicalCameraDeviceName);
2734 }
2735
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002736 *id = cameraId;
Austin Borger1c1bee02023-06-01 16:51:35 -07002737 *physicalId = physicalCameraDeviceName;
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002738 return OK;
2739}
2740
2741void CameraProviderManager::ProviderInfo::torchModeStatusChangeInternal(
2742 const std::string& cameraDeviceName,
2743 TorchModeStatus newStatus) {
2744 sp<StatusListener> listener;
2745 SystemCameraKind systemCameraKind = SystemCameraKind::PUBLIC;
2746 std::string id;
2747 bool known = false;
2748 {
2749 // Hold mLock for accessing mDevices
2750 std::lock_guard<std::mutex> lock(mLock);
2751 for (auto& deviceInfo : mDevices) {
2752 if (deviceInfo->mName == cameraDeviceName) {
2753 ALOGI("Camera device %s torch status is now %s", cameraDeviceName.c_str(),
2754 FrameworkTorchStatusToString(newStatus));
2755 id = deviceInfo->mId;
2756 known = true;
2757 systemCameraKind = deviceInfo->mSystemCameraKind;
2758 if (TorchModeStatus::AVAILABLE_ON != newStatus) {
2759 mManager->removeRef(CameraProviderManager::DeviceMode::TORCH, id);
2760 }
2761 break;
2762 }
2763 }
2764 if (!known) {
2765 ALOGW("Camera provider %s says an unknown camera %s now has torch status %d. Curious.",
Eino-Ville Talvalab7723202024-06-24 17:45:51 -07002766 mProviderName.c_str(), cameraDeviceName.c_str(), eToI(newStatus));
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002767 return;
2768 }
2769 // no lock needed since listener is set up only once during
2770 // CameraProviderManager initialization and then never changed till it is
2771 // destructed.
2772 listener = mManager->getStatusListener();
2773 }
2774 // Call without lock held to allow reentrancy into provider manager
2775 // The problem with holding mLock here is that we
2776 // might be limiting re-entrancy : CameraService::onTorchStatusChanged calls
2777 // back into CameraProviderManager which might try to hold mLock again (eg:
2778 // findDeviceInfo, which should be holding mLock while iterating through
2779 // each provider's devices).
2780 if (listener != nullptr) {
Austin Borger1c1bee02023-06-01 16:51:35 -07002781 listener->onTorchStatusChanged(id, newStatus, systemCameraKind);
Jayant Chowdharya04055f2022-01-03 02:07:49 +00002782 }
2783 return;
2784}
2785
Emilian Peevb50402e2021-09-24 17:41:57 -07002786void CameraProviderManager::ProviderInfo::notifyDeviceInfoStateChangeLocked(
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002787 int64_t newDeviceState) {
Emilian Peevb50402e2021-09-24 17:41:57 -07002788 std::lock_guard<std::mutex> lock(mLock);
2789 for (auto it = mDevices.begin(); it != mDevices.end(); it++) {
2790 (*it)->notifyDeviceStateChange(newDeviceState);
2791 }
2792}
2793
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002794CameraProviderManager::ProviderInfo::DeviceInfo3::DeviceInfo3(const std::string& name,
Emilian Peev71c73a22017-03-21 16:35:51 +00002795 const metadata_vendor_id_t tagId, const std::string &id,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002796 uint16_t minorVersion,
2797 const CameraResourceCost& resourceCost,
Peter Kalauskasa29c1352018-10-10 12:05:42 -07002798 sp<ProviderInfo> parentProvider,
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002799 const std::vector<std::string>& publicCameraIds) :
Jayant Chowdhary16af6ce2023-05-04 10:36:31 -07002800 DeviceInfo(name, tagId, id,
2801 hardware::hidl_version{
2802 static_cast<uint16_t >(
2803 parentProvider->getIPCTransport() == IPCTransport::HIDL ? 3 : 1),
2804 minorVersion},
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002805 publicCameraIds, resourceCost, parentProvider) { }
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -08002806
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07002807void CameraProviderManager::ProviderInfo::DeviceInfo3::notifyDeviceStateChange(int64_t newState) {
Emilian Peevb50402e2021-09-24 17:41:57 -07002808 if (!mDeviceStateOrientationMap.empty() &&
2809 (mDeviceStateOrientationMap.find(newState) != mDeviceStateOrientationMap.end())) {
2810 mCameraCharacteristics.update(ANDROID_SENSOR_ORIENTATION,
2811 &mDeviceStateOrientationMap[newState], 1);
Emilian Peevfa453762023-04-28 15:12:09 -07002812 if (mCameraCharNoPCOverride.get() != nullptr) {
2813 mCameraCharNoPCOverride->update(ANDROID_SENSOR_ORIENTATION,
2814 &mDeviceStateOrientationMap[newState], 1);
2815 }
Emilian Peevb50402e2021-09-24 17:41:57 -07002816 }
2817}
2818
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002819status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002820 int rotationOverride, int *portraitRotation,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002821 hardware::CameraInfo *info) const {
2822 if (info == nullptr) return BAD_VALUE;
2823
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002824 bool freeform_compat_enabled = wm_flags::camera_compat_for_freeform();
2825 if (!freeform_compat_enabled &&
2826 rotationOverride > hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT) {
2827 ALOGW("Camera compat freeform flag disabled but rotation override is %d", rotationOverride);
2828 }
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002829 camera_metadata_ro_entry facing =
2830 mCameraCharacteristics.find(ANDROID_LENS_FACING);
2831 if (facing.count == 1) {
2832 switch (facing.data.u8[0]) {
2833 case ANDROID_LENS_FACING_BACK:
2834 info->facing = hardware::CAMERA_FACING_BACK;
2835 break;
2836 case ANDROID_LENS_FACING_EXTERNAL:
2837 // Map external to front for legacy API
2838 case ANDROID_LENS_FACING_FRONT:
2839 info->facing = hardware::CAMERA_FACING_FRONT;
2840 break;
2841 }
2842 } else {
2843 ALOGE("%s: Unable to find android.lens.facing static metadata", __FUNCTION__);
2844 return NAME_NOT_FOUND;
2845 }
2846
2847 camera_metadata_ro_entry orientation =
2848 mCameraCharacteristics.find(ANDROID_SENSOR_ORIENTATION);
2849 if (orientation.count == 1) {
2850 info->orientation = orientation.data.i32[0];
2851 } else {
2852 ALOGE("%s: Unable to find android.sensor.orientation static metadata", __FUNCTION__);
2853 return NAME_NOT_FOUND;
2854 }
2855
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002856 if (rotationOverride == hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT
2857 && (info->orientation == 0 || info->orientation == 180)) {
Austin Borger18b30a72022-10-27 12:20:29 -07002858 *portraitRotation = 90;
2859 if (info->facing == hardware::CAMERA_FACING_FRONT) {
2860 info->orientation = (360 + info->orientation - 90) % 360;
2861 } else {
2862 info->orientation = (360 + info->orientation + 90) % 360;
2863 }
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002864 } else if (freeform_compat_enabled &&
2865 rotationOverride == hardware::ICameraService::ROTATION_OVERRIDE_ROTATION_ONLY
2866 && (info->orientation == 90 || info->orientation == 270)) {
2867 *portraitRotation = info->facing == hardware::CAMERA_FACING_BACK ? 90 : 270;
Austin Borger18b30a72022-10-27 12:20:29 -07002868 } else {
2869 *portraitRotation = 0;
2870 }
2871
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002872 return OK;
2873}
Emilian Peevf53f66e2017-04-11 14:29:43 +01002874bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const {
Shuzhen Wang7a7e6342019-05-31 16:28:21 -07002875 // Do not advertise NIR cameras to API1 camera app.
2876 camera_metadata_ro_entry cfa = mCameraCharacteristics.find(
2877 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
2878 if (cfa.count == 1 && cfa.data.u8[0] == ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR) {
2879 return false;
2880 }
2881
Emilian Peevf53f66e2017-04-11 14:29:43 +01002882 bool isBackwardCompatible = false;
2883 camera_metadata_ro_entry_t caps = mCameraCharacteristics.find(
2884 ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
2885 for (size_t i = 0; i < caps.count; i++) {
2886 if (caps.data.u8[i] ==
2887 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) {
2888 isBackwardCompatible = true;
2889 break;
2890 }
2891 }
2892
2893 return isBackwardCompatible;
2894}
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002895
2896status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002897 bool overrideForPerfClass, CameraMetadata *characteristics,
2898 int rotationOverride) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002899 if (characteristics == nullptr) return BAD_VALUE;
2900
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002901 if (!overrideForPerfClass && mCameraCharNoPCOverride != nullptr) {
2902 *characteristics = *mCameraCharNoPCOverride;
2903 } else {
2904 *characteristics = mCameraCharacteristics;
2905 }
2906
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00002907 if (rotationOverride == hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT) {
Austin Borger18b30a72022-10-27 12:20:29 -07002908 const auto &lensFacingEntry = characteristics->find(ANDROID_LENS_FACING);
2909 const auto &sensorOrientationEntry = characteristics->find(ANDROID_SENSOR_ORIENTATION);
Austin Borger925abed2023-01-09 12:29:10 -08002910 uint8_t lensFacing = lensFacingEntry.data.u8[0];
Austin Borger18b30a72022-10-27 12:20:29 -07002911 if (lensFacingEntry.count > 0 && sensorOrientationEntry.count > 0) {
Austin Borger18b30a72022-10-27 12:20:29 -07002912 int32_t sensorOrientation = sensorOrientationEntry.data.i32[0];
2913 int32_t newSensorOrientation = sensorOrientation;
2914
2915 if (sensorOrientation == 0 || sensorOrientation == 180) {
2916 if (lensFacing == ANDROID_LENS_FACING_FRONT) {
2917 newSensorOrientation = (360 + sensorOrientation - 90) % 360;
2918 } else if (lensFacing == ANDROID_LENS_FACING_BACK) {
2919 newSensorOrientation = (360 + sensorOrientation + 90) % 360;
2920 }
2921 }
2922
2923 if (newSensorOrientation != sensorOrientation) {
2924 ALOGV("%s: Update ANDROID_SENSOR_ORIENTATION for lens facing %d "
2925 "from %d to %d", __FUNCTION__, lensFacing, sensorOrientation,
2926 newSensorOrientation);
2927 characteristics->update(ANDROID_SENSOR_ORIENTATION, &newSensorOrientation, 1);
2928 }
2929 }
2930
2931 if (characteristics->exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
Austin Borger925abed2023-01-09 12:29:10 -08002932 ALOGV("%s: Erasing ANDROID_INFO_DEVICE_STATE_ORIENTATIONS for lens facing %d",
2933 __FUNCTION__, lensFacing);
Austin Borger18b30a72022-10-27 12:20:29 -07002934 characteristics->erase(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
2935 }
2936 }
2937
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002938 return OK;
2939}
2940
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07002941status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getPhysicalCameraCharacteristics(
2942 const std::string& physicalCameraId, CameraMetadata *characteristics) const {
2943 if (characteristics == nullptr) return BAD_VALUE;
2944 if (mPhysicalCameraCharacteristics.find(physicalCameraId) ==
2945 mPhysicalCameraCharacteristics.end()) {
2946 return NAME_NOT_FOUND;
2947 }
2948
2949 *characteristics = mPhysicalCameraCharacteristics.at(physicalCameraId);
2950 return OK;
2951}
2952
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002953status_t CameraProviderManager::ProviderInfo::DeviceInfo3::filterSmallJpegSizes() {
2954 int32_t thresholdW = SessionConfigurationUtils::PERF_CLASS_JPEG_THRESH_W;
2955 int32_t thresholdH = SessionConfigurationUtils::PERF_CLASS_JPEG_THRESH_H;
2956
2957 if (mCameraCharNoPCOverride != nullptr) return OK;
2958
2959 mCameraCharNoPCOverride = std::make_unique<CameraMetadata>(mCameraCharacteristics);
Shuzhen Wang89db2992021-05-20 13:09:48 -07002960
2961 // Remove small JPEG sizes from available stream configurations
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002962 size_t largeJpegCount = 0;
Shuzhen Wang89db2992021-05-20 13:09:48 -07002963 std::vector<int32_t> newStreamConfigs;
2964 camera_metadata_entry streamConfigs =
2965 mCameraCharacteristics.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
2966 for (size_t i = 0; i < streamConfigs.count; i += 4) {
2967 if ((streamConfigs.data.i32[i] == HAL_PIXEL_FORMAT_BLOB) && (streamConfigs.data.i32[i+3] ==
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002968 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT)) {
Shuzhen Wang10f99212023-02-02 18:55:31 -08002969 if (streamConfigs.data.i32[i+1] * streamConfigs.data.i32[i+2] <
2970 thresholdW * thresholdH) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002971 continue;
2972 } else {
2973 largeJpegCount ++;
2974 }
Shuzhen Wang89db2992021-05-20 13:09:48 -07002975 }
2976 newStreamConfigs.insert(newStreamConfigs.end(), streamConfigs.data.i32 + i,
2977 streamConfigs.data.i32 + i + 4);
2978 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002979 if (newStreamConfigs.size() == 0 || largeJpegCount == 0) {
2980 return BAD_VALUE;
Shuzhen Wang89db2992021-05-20 13:09:48 -07002981 }
2982
2983 // Remove small JPEG sizes from available min frame durations
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002984 largeJpegCount = 0;
Shuzhen Wang89db2992021-05-20 13:09:48 -07002985 std::vector<int64_t> newMinDurations;
2986 camera_metadata_entry minDurations =
2987 mCameraCharacteristics.find(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS);
2988 for (size_t i = 0; i < minDurations.count; i += 4) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002989 if (minDurations.data.i64[i] == HAL_PIXEL_FORMAT_BLOB) {
Shuzhen Wang10f99212023-02-02 18:55:31 -08002990 if ((int32_t)minDurations.data.i64[i+1] * (int32_t)minDurations.data.i64[i+2] <
2991 thresholdW * thresholdH) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002992 continue;
2993 } else {
2994 largeJpegCount++;
2995 }
Shuzhen Wang89db2992021-05-20 13:09:48 -07002996 }
2997 newMinDurations.insert(newMinDurations.end(), minDurations.data.i64 + i,
2998 minDurations.data.i64 + i + 4);
2999 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003000 if (newMinDurations.size() == 0 || largeJpegCount == 0) {
3001 return BAD_VALUE;
Shuzhen Wang89db2992021-05-20 13:09:48 -07003002 }
3003
3004 // Remove small JPEG sizes from available stall durations
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003005 largeJpegCount = 0;
Shuzhen Wang89db2992021-05-20 13:09:48 -07003006 std::vector<int64_t> newStallDurations;
3007 camera_metadata_entry stallDurations =
3008 mCameraCharacteristics.find(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS);
3009 for (size_t i = 0; i < stallDurations.count; i += 4) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003010 if (stallDurations.data.i64[i] == HAL_PIXEL_FORMAT_BLOB) {
Shuzhen Wang10f99212023-02-02 18:55:31 -08003011 if ((int32_t)stallDurations.data.i64[i+1] * (int32_t)stallDurations.data.i64[i+2] <
3012 thresholdW * thresholdH) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003013 continue;
3014 } else {
3015 largeJpegCount++;
3016 }
Shuzhen Wang89db2992021-05-20 13:09:48 -07003017 }
3018 newStallDurations.insert(newStallDurations.end(), stallDurations.data.i64 + i,
3019 stallDurations.data.i64 + i + 4);
3020 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003021 if (newStallDurations.size() == 0 || largeJpegCount == 0) {
3022 return BAD_VALUE;
Shuzhen Wang89db2992021-05-20 13:09:48 -07003023 }
3024
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003025 mCameraCharacteristics.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
3026 newStreamConfigs.data(), newStreamConfigs.size());
3027 mCameraCharacteristics.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
3028 newMinDurations.data(), newMinDurations.size());
3029 mCameraCharacteristics.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS,
3030 newStallDurations.data(), newStallDurations.size());
3031
Shuzhen Wang89db2992021-05-20 13:09:48 -07003032 // Re-generate metadata tags that have dependencies on BLOB sizes
3033 auto res = addDynamicDepthTags();
3034 if (OK != res) {
3035 ALOGE("%s: Failed to append dynamic depth tags: %s (%d)", __FUNCTION__,
3036 strerror(-res), res);
Shuzhen Wang2ebb8392021-06-21 23:31:10 -07003037 // Allow filtering of small JPEG sizes to succeed even if dynamic depth
3038 // tags fail to generate.
Shuzhen Wang89db2992021-05-20 13:09:48 -07003039 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003040
3041 return OK;
Shuzhen Wang89db2992021-05-20 13:09:48 -07003042}
3043
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08003044status_t CameraProviderManager::ProviderInfo::parseProviderName(const std::string& name,
3045 std::string *type, uint32_t *id) {
3046 // Format must be "<type>/<id>"
3047#define ERROR_MSG_PREFIX "%s: Invalid provider name '%s'. " \
3048 "Should match '<type>/<id>' - "
3049
3050 if (!type || !id) return INVALID_OPERATION;
3051
3052 std::string::size_type slashIdx = name.find('/');
3053 if (slashIdx == std::string::npos || slashIdx == name.size() - 1) {
3054 ALOGE(ERROR_MSG_PREFIX
3055 "does not have / separator between type and id",
3056 __FUNCTION__, name.c_str());
3057 return BAD_VALUE;
3058 }
3059
3060 std::string typeVal = name.substr(0, slashIdx);
3061
3062 char *endPtr;
3063 errno = 0;
3064 long idVal = strtol(name.c_str() + slashIdx + 1, &endPtr, 10);
3065 if (errno != 0) {
3066 ALOGE(ERROR_MSG_PREFIX
3067 "cannot parse provider id as an integer: %s (%d)",
3068 __FUNCTION__, name.c_str(), strerror(errno), errno);
3069 return BAD_VALUE;
3070 }
3071 if (endPtr != name.c_str() + name.size()) {
3072 ALOGE(ERROR_MSG_PREFIX
3073 "provider id has unexpected length",
3074 __FUNCTION__, name.c_str());
3075 return BAD_VALUE;
3076 }
3077 if (idVal < 0) {
3078 ALOGE(ERROR_MSG_PREFIX
3079 "id is negative: %ld",
3080 __FUNCTION__, name.c_str(), idVal);
3081 return BAD_VALUE;
3082 }
3083
3084#undef ERROR_MSG_PREFIX
3085
3086 *type = typeVal;
3087 *id = static_cast<uint32_t>(idVal);
3088
3089 return OK;
3090}
3091
Emilian Peev71c73a22017-03-21 16:35:51 +00003092metadata_vendor_id_t CameraProviderManager::ProviderInfo::generateVendorTagId(
3093 const std::string &name) {
3094 metadata_vendor_id_t ret = std::hash<std::string> {} (name);
3095 // CAMERA_METADATA_INVALID_VENDOR_ID is not a valid hash value
3096 if (CAMERA_METADATA_INVALID_VENDOR_ID == ret) {
3097 ret = 0;
3098 }
3099
3100 return ret;
3101}
3102
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08003103status_t CameraProviderManager::ProviderInfo::parseDeviceName(const std::string& name,
3104 uint16_t *major, uint16_t *minor, std::string *type, std::string *id) {
3105
3106 // Format must be "device@<major>.<minor>/<type>/<id>"
3107
3108#define ERROR_MSG_PREFIX "%s: Invalid device name '%s'. " \
3109 "Should match 'device@<major>.<minor>/<type>/<id>' - "
3110
3111 if (!major || !minor || !type || !id) return INVALID_OPERATION;
3112
3113 // Verify starting prefix
3114 const char expectedPrefix[] = "device@";
3115
3116 if (name.find(expectedPrefix) != 0) {
3117 ALOGE(ERROR_MSG_PREFIX
3118 "does not start with '%s'",
3119 __FUNCTION__, name.c_str(), expectedPrefix);
3120 return BAD_VALUE;
3121 }
3122
3123 // Extract major/minor versions
3124 constexpr std::string::size_type atIdx = sizeof(expectedPrefix) - 2;
3125 std::string::size_type dotIdx = name.find('.', atIdx);
3126 if (dotIdx == std::string::npos) {
3127 ALOGE(ERROR_MSG_PREFIX
3128 "does not have @<major>. version section",
3129 __FUNCTION__, name.c_str());
3130 return BAD_VALUE;
3131 }
3132 std::string::size_type typeSlashIdx = name.find('/', dotIdx);
3133 if (typeSlashIdx == std::string::npos) {
3134 ALOGE(ERROR_MSG_PREFIX
3135 "does not have .<minor>/ version section",
3136 __FUNCTION__, name.c_str());
3137 return BAD_VALUE;
3138 }
3139
3140 char *endPtr;
3141 errno = 0;
3142 long majorVal = strtol(name.c_str() + atIdx + 1, &endPtr, 10);
3143 if (errno != 0) {
3144 ALOGE(ERROR_MSG_PREFIX
3145 "cannot parse major version: %s (%d)",
3146 __FUNCTION__, name.c_str(), strerror(errno), errno);
3147 return BAD_VALUE;
3148 }
3149 if (endPtr != name.c_str() + dotIdx) {
3150 ALOGE(ERROR_MSG_PREFIX
3151 "major version has unexpected length",
3152 __FUNCTION__, name.c_str());
3153 return BAD_VALUE;
3154 }
3155 long minorVal = strtol(name.c_str() + dotIdx + 1, &endPtr, 10);
3156 if (errno != 0) {
3157 ALOGE(ERROR_MSG_PREFIX
3158 "cannot parse minor version: %s (%d)",
3159 __FUNCTION__, name.c_str(), strerror(errno), errno);
3160 return BAD_VALUE;
3161 }
3162 if (endPtr != name.c_str() + typeSlashIdx) {
3163 ALOGE(ERROR_MSG_PREFIX
3164 "minor version has unexpected length",
3165 __FUNCTION__, name.c_str());
3166 return BAD_VALUE;
3167 }
3168 if (majorVal < 0 || majorVal > UINT16_MAX || minorVal < 0 || minorVal > UINT16_MAX) {
3169 ALOGE(ERROR_MSG_PREFIX
3170 "major/minor version is out of range of uint16_t: %ld.%ld",
3171 __FUNCTION__, name.c_str(), majorVal, minorVal);
3172 return BAD_VALUE;
3173 }
3174
3175 // Extract type and id
3176
3177 std::string::size_type instanceSlashIdx = name.find('/', typeSlashIdx + 1);
3178 if (instanceSlashIdx == std::string::npos) {
3179 ALOGE(ERROR_MSG_PREFIX
3180 "does not have /<type>/ component",
3181 __FUNCTION__, name.c_str());
3182 return BAD_VALUE;
3183 }
3184 std::string typeVal = name.substr(typeSlashIdx + 1, instanceSlashIdx - typeSlashIdx - 1);
3185
3186 if (instanceSlashIdx == name.size() - 1) {
3187 ALOGE(ERROR_MSG_PREFIX
3188 "does not have an /<id> component",
3189 __FUNCTION__, name.c_str());
3190 return BAD_VALUE;
3191 }
3192 std::string idVal = name.substr(instanceSlashIdx + 1);
3193
3194#undef ERROR_MSG_PREFIX
3195
3196 *major = static_cast<uint16_t>(majorVal);
3197 *minor = static_cast<uint16_t>(minorVal);
3198 *type = typeVal;
3199 *id = idVal;
3200
3201 return OK;
3202}
3203
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08003204CameraProviderManager::ProviderInfo::~ProviderInfo() {
3205 // Destruction of ProviderInfo is only supposed to happen when the respective
3206 // CameraProvider interface dies, so do not unregister callbacks.
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08003207}
3208
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08003209// Expects to have mInterfaceMutex locked
3210std::vector<std::unordered_set<std::string>>
Jayant Chowdharycad23c22020-03-10 15:04:59 -07003211CameraProviderManager::getConcurrentCameraIds() const {
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08003212 std::vector<std::unordered_set<std::string>> deviceIdCombinations;
3213 std::lock_guard<std::mutex> lock(mInterfaceMutex);
3214 for (auto &provider : mProviders) {
Jayant Chowdharycbe770a2020-02-14 11:14:46 -08003215 for (auto &combinations : provider->getConcurrentCameraIdCombinations()) {
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08003216 deviceIdCombinations.push_back(combinations);
3217 }
3218 }
3219 return deviceIdCombinations;
3220}
3221
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08003222// Checks if the containing vector of sets has any set that contains all of the
3223// camera ids in cameraIdsAndSessionConfigs.
3224static bool checkIfSetContainsAll(
3225 const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
3226 const std::vector<std::unordered_set<std::string>> &containingSets) {
3227 for (auto &containingSet : containingSets) {
3228 bool didHaveAll = true;
3229 for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
3230 if (containingSet.find(cameraIdAndSessionConfig.mCameraId) == containingSet.end()) {
3231 // a camera id doesn't belong to this set, keep looking in other
3232 // sets
3233 didHaveAll = false;
3234 break;
3235 }
3236 }
3237 if (didHaveAll) {
3238 // found a set that has all camera ids, lets return;
3239 return true;
3240 }
3241 }
3242 return false;
3243}
3244
3245status_t CameraProviderManager::isConcurrentSessionConfigurationSupported(
3246 const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07003247 const std::set<std::string>& perfClassPrimaryCameraIds,
3248 int targetSdkVersion, bool *isSupported) {
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08003249 std::lock_guard<std::mutex> lock(mInterfaceMutex);
3250 // Check if all the devices are a subset of devices advertised by the
3251 // same provider through getConcurrentStreamingCameraIds()
3252 // TODO: we should also do a findDeviceInfoLocked here ?
3253 for (auto &provider : mProviders) {
3254 if (checkIfSetContainsAll(cameraIdsAndSessionConfigs,
Jayant Chowdharycbe770a2020-02-14 11:14:46 -08003255 provider->getConcurrentCameraIdCombinations())) {
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08003256 return provider->isConcurrentSessionConfigurationSupported(
Jayant Chowdhary0bd38522021-11-05 17:49:27 -07003257 cameraIdsAndSessionConfigs, perfClassPrimaryCameraIds, targetSdkVersion,
3258 isSupported);
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -08003259 }
3260 }
3261 *isSupported = false;
3262 //The set of camera devices were not found
3263 return INVALID_OPERATION;
3264}
3265
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003266status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
Austin Borger18b30a72022-10-27 12:20:29 -07003267 bool overrideForPerfClass, CameraMetadata* characteristics,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00003268 int rotationOverride) const {
Jayant Chowdharyffc5d682022-05-12 18:34:34 +00003269 auto deviceInfo = findDeviceInfoLocked(id);
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07003270 if (deviceInfo != nullptr) {
Austin Borger18b30a72022-10-27 12:20:29 -07003271 return deviceInfo->getCameraCharacteristics(overrideForPerfClass, characteristics,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00003272 rotationOverride);
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07003273 }
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003274
Shuzhen Wangf9d2c022018-08-21 12:07:35 -07003275 // Find hidden physical camera characteristics
3276 for (auto& provider : mProviders) {
3277 for (auto& deviceInfo : provider->mDevices) {
3278 status_t res = deviceInfo->getPhysicalCameraCharacteristics(id, characteristics);
3279 if (res != NAME_NOT_FOUND) return res;
3280 }
3281 }
3282
3283 return NAME_NOT_FOUND;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003284}
3285
3286void CameraProviderManager::filterLogicalCameraIdsLocked(
3287 std::vector<std::string>& deviceIds) const
3288{
Shuzhen Wang38e119b2018-10-01 16:03:53 -07003289 // Map between camera facing and camera IDs related to logical camera.
3290 std::map<int, std::unordered_set<std::string>> idCombos;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003291
Shuzhen Wang38e119b2018-10-01 16:03:53 -07003292 // Collect all logical and its underlying physical camera IDs for each
3293 // facing.
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003294 for (auto& deviceId : deviceIds) {
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07003295 auto deviceInfo = findDeviceInfoLocked(deviceId);
3296 if (deviceInfo == nullptr) continue;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003297
Shuzhen Wang03d8cc12018-09-12 14:17:09 -07003298 if (!deviceInfo->mIsLogicalCamera) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003299 continue;
3300 }
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003301
Shuzhen Wang38e119b2018-10-01 16:03:53 -07003302 // combo contains the ids of a logical camera and its physical cameras
3303 std::vector<std::string> combo = deviceInfo->mPhysicalIds;
3304 combo.push_back(deviceId);
3305
3306 hardware::CameraInfo info;
Austin Borger18b30a72022-10-27 12:20:29 -07003307 int portraitRotation;
Jayant Chowdhary81d81b02024-02-15 19:13:39 +00003308 status_t res = deviceInfo->getCameraInfo(
3309 /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
3310 &portraitRotation, &info);
Shuzhen Wang38e119b2018-10-01 16:03:53 -07003311 if (res != OK) {
3312 ALOGE("%s: Error reading camera info: %s (%d)", __FUNCTION__, strerror(-res), res);
3313 continue;
3314 }
3315 idCombos[info.facing].insert(combo.begin(), combo.end());
3316 }
3317
3318 // Only expose one camera ID per facing for all logical and underlying
3319 // physical camera IDs.
3320 for (auto& r : idCombos) {
3321 auto& removedIds = r.second;
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003322 for (auto& id : deviceIds) {
Shuzhen Wang38e119b2018-10-01 16:03:53 -07003323 auto foundId = std::find(removedIds.begin(), removedIds.end(), id);
3324 if (foundId == removedIds.end()) {
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003325 continue;
3326 }
3327
Shuzhen Wang38e119b2018-10-01 16:03:53 -07003328 removedIds.erase(foundId);
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003329 break;
3330 }
Shuzhen Wang38e119b2018-10-01 16:03:53 -07003331 deviceIds.erase(std::remove_if(deviceIds.begin(), deviceIds.end(),
3332 [&removedIds](const std::string& s) {
3333 return removedIds.find(s) != removedIds.end();}),
3334 deviceIds.end());
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003335 }
Shuzhen Wange8aceb52018-05-21 12:00:56 -07003336}
Yin-Chia Yeh067428c2017-01-13 15:19:24 -08003337
Vadim Caen7eccd7c2023-10-03 16:26:33 +02003338bool CameraProviderManager::isVirtualCameraHalEnabled() {
Jan Sebechlebsky2f66b5e2024-01-16 17:00:26 +01003339 return vd_flags::virtual_camera_service_discovery() &&
3340 vd_flags::virtual_camera_service_build_flag();
Vadim Caen7eccd7c2023-10-03 16:26:33 +02003341}
3342
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08003343} // namespace android