blob: 5dddd29c74bd7b6d3ef4f74f3032c1f1a5c8543c [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ACameraManager"
19
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080020#include "ACameraManager.h"
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020021#include <android_companion_virtualdevice_flags.h>
Jayant Chowdharyf5b9cc62020-09-08 16:25:17 -070022#include <camera/CameraUtils.h>
Austin Borger0fb3ad92023-06-01 16:51:35 -070023#include <camera/StringUtils.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080024#include <camera/VendorTagDescriptor.h>
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020025#include <cutils/properties.h>
26#include <stdlib.h>
27#include <utils/Vector.h>
28#include <memory>
29#include "ACameraDevice.h"
30#include "ACameraMetadata.h"
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070031#include <com_android_internal_camera_flags.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080032
Jayant Chowdhary6df26072018-11-06 23:55:12 -080033using namespace android::acam;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020034namespace vd_flags = android::companion::virtualdevice::flags;
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -070035namespace flags = com::android::internal::camera::flags;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080036
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080037namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080038namespace acam {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020039namespace {
Biswarup Pal37a75182024-01-16 15:53:35 +000040
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020041using ::android::binder::Status;
42using ::android::companion::virtualnative::IVirtualDeviceManagerNative;
43
44// Return binder connection to VirtualDeviceManager.
45//
46// Subsequent calls return the same cached instance.
47sp<IVirtualDeviceManagerNative> getVirtualDeviceManager() {
48 auto connectToVirtualDeviceManagerNative = []() {
49 sp<IBinder> binder =
50 defaultServiceManager()->checkService(String16("virtualdevice_native"));
51 if (binder == nullptr) {
52 ALOGW("%s: Cannot get virtualdevice_native service", __func__);
53 return interface_cast<IVirtualDeviceManagerNative>(nullptr);
54 }
55 return interface_cast<IVirtualDeviceManagerNative>(binder);
56 };
57
58 static sp<IVirtualDeviceManagerNative> vdm = connectToVirtualDeviceManagerNative();
59 return vdm;
60}
61
62// Returns device id calling process is running on.
63// If the process cannot be attributed to single virtual device id, returns default device id.
64int getCurrentDeviceId() {
65 if (!vd_flags::camera_device_awareness()) {
66 return kDefaultDeviceId;
67 }
68
69 auto vdm = getVirtualDeviceManager();
70 if (vdm == nullptr) {
71 return kDefaultDeviceId;
72 }
73
74 const uid_t myUid = getuid();
75 std::vector<int> deviceIds;
76 Status status = vdm->getDeviceIdsForUid(myUid, &deviceIds);
77 if (!status.isOk() || deviceIds.empty()) {
78 ALOGE("%s: Failed to call getDeviceIdsForUid to determine device id for uid %d: %s",
79 __func__, myUid, status.toString8().c_str());
80 return kDefaultDeviceId;
81 }
82
83 // If the UID is associated with multiple virtual devices, use the default device's
84 // camera as we cannot disambiguate here. This effectively means that the app has
85 // activities on different devices at the same time.
86 if (deviceIds.size() != 1) {
87 return kDefaultDeviceId;
88 }
89 return deviceIds[0];
90}
91
92// Returns device policy for POLICY_TYPE_CAMERA corresponding to deviceId.
93DevicePolicy getDevicePolicyForDeviceId(const int deviceId) {
94 if (!vd_flags::camera_device_awareness() || deviceId == kDefaultDeviceId) {
95 return DevicePolicy::DEVICE_POLICY_DEFAULT;
96 }
97
98 auto vdm = getVirtualDeviceManager();
99 if (vdm == nullptr) {
100 return DevicePolicy::DEVICE_POLICY_DEFAULT;
101 }
102
103 int policy = IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT;
104 Status status = vdm->getDevicePolicy(deviceId, IVirtualDeviceManagerNative::POLICY_TYPE_CAMERA,
105 &policy);
106 if (!status.isOk()) {
107 ALOGE("%s: Failed to call getDevicePolicy to determine camera policy for device id %d: %s",
108 __func__, deviceId, status.toString8().c_str());
109 return DevicePolicy::DEVICE_POLICY_DEFAULT;
110 }
111 return static_cast<DevicePolicy>(policy);
112}
113
114// Returns true if camera owned by device cameraDeviceId can be accessed within deviceContext.
115bool isCameraAccessible(const DeviceContext deviceContext, const int cameraDeviceId) {
116 if (!vd_flags::camera_device_awareness() ||
117 deviceContext.policy == DevicePolicy::DEVICE_POLICY_DEFAULT) {
118 return cameraDeviceId == kDefaultDeviceId;
119 }
120 return deviceContext.deviceId == cameraDeviceId;
121}
122
123} // namespace
Biswarup Pal37a75182024-01-16 15:53:35 +0000124
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800125// Static member definitions
126const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
Shuzhen Wang43858162020-01-10 13:42:15 -0800127const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800128const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
129const char* CameraManagerGlobal::kContextKey = "CallbackContext";
Shuzhen Wang7e540682020-04-10 13:30:25 -0700130const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800131Mutex CameraManagerGlobal::sLock;
Avichal Rakeshf099b232022-10-27 15:44:50 -0700132wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800133
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200134DeviceContext::DeviceContext() {
135 deviceId = getCurrentDeviceId();
136 policy = getDevicePolicyForDeviceId(deviceId);
137}
138
Avichal Rakeshf099b232022-10-27 15:44:50 -0700139sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800140 Mutex::Autolock _l(sLock);
Avichal Rakeshf099b232022-10-27 15:44:50 -0700141 sp<CameraManagerGlobal> instance = sInstance.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800142 if (instance == nullptr) {
143 instance = new CameraManagerGlobal();
144 sInstance = instance;
145 }
Avichal Rakeshf099b232022-10-27 15:44:50 -0700146 return instance;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800147}
148
149CameraManagerGlobal::~CameraManagerGlobal() {
150 // clear sInstance so next getInstance call knows to create a new one
151 Mutex::Autolock _sl(sLock);
152 sInstance = nullptr;
153 Mutex::Autolock _l(mLock);
154 if (mCameraService != nullptr) {
155 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800156 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800157 }
158 mDeathNotifier.clear();
159 if (mCbLooper != nullptr) {
160 mCbLooper->unregisterHandler(mHandler->id());
161 mCbLooper->stop();
162 }
163 mCbLooper.clear();
164 mHandler.clear();
165 mCameraServiceListener.clear();
166 mCameraService.clear();
167}
168
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800169sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800170 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700171 return getCameraServiceLocked();
172}
173
174sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000175 if (mCameraService.get() != nullptr) {
176 return mCameraService;
177 }
178 if (CameraUtils::isCameraServiceDisabled()) {
179 return mCameraService;
180 }
Ivan Podogovee844a82016-09-15 11:32:41 +0100181
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000182 sp<IServiceManager> sm = defaultServiceManager();
183 sp<IBinder> binder;
184 binder = sm->checkService(String16(kCameraServiceName));
185 if (binder == nullptr) {
186 ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
187 return nullptr;
188 }
189 sp<hardware::ICameraService> cameraService = interface_cast<hardware::ICameraService>(binder);
190 if (mDeathNotifier == nullptr) {
191 mDeathNotifier = new DeathNotifier(this);
192 binder->linkToDeath(mDeathNotifier);
193 }
194
195 // Setup looper thread to perform availability callbacks
196 if (mCbLooper == nullptr) {
197 mCbLooper = new ALooper;
198 mCbLooper->setName("C2N-mgr-looper");
199 status_t err = mCbLooper->start(
200 /*runOnCallingThread*/false,
201 /*canCallJava*/ true,
202 PRIORITY_DEFAULT);
203 if (err != OK) {
204 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
205 __FUNCTION__, strerror(-err), err);
206 mCbLooper.clear();
Ankit Siddhapura959b7be2024-04-16 13:07:42 +0530207 return nullptr;
208 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000209 if (mHandler == nullptr) {
210 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800211 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000212 mCbLooper->registerHandler(mHandler);
213 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800214
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000215 // register ICameraServiceListener
216 std::vector<hardware::CameraStatus> cameraStatuses{};
217 if (mCameraServiceListener == nullptr) {
218 mCameraServiceListener = new CameraServiceListener(this);
219 cameraService->addListener(mCameraServiceListener, &cameraStatuses);
220 }
221
222 for (auto& c : cameraStatuses) {
223 onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
224
225 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
226 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
227 c.deviceId, c.cameraId, unavailablePhysicalId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800228 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000229 }
230 // setup vendor tags
231 if (!setupVendorTags(cameraService)) {
232 ALOGE("%s: Vendor tag descriptor cache couldn't be set up", __FUNCTION__);
233 return nullptr;
234 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800235
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000236 mCameraService = cameraService;
237 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
238 return mCameraService;
239}
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800240
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000241bool CameraManagerGlobal::setupVendorTags(sp<hardware::ICameraService> &cameraService) {
242 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
243 binder::Status ret = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
244 if (!ret.isOk()) {
245 if (ret.serviceSpecificErrorCode() ==
246 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800247 ALOGW("%s: Camera HAL too old; does not support vendor tags",
248 __FUNCTION__);
249 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
250 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800251 ALOGE("%s: Failed to get vendor tag descriptors: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000252 __FUNCTION__, ret.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800253 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000254 return false;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800255 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000256
257 if (0 < desc->getTagCount()) {
258 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
259 if (err != OK) {
260 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
261 __FUNCTION__, strerror(-err), err);
262 return false;
263 }
264 } else {
265 sp<VendorTagDescriptorCache> cache =
266 new VendorTagDescriptorCache();
267 binder::Status res =
268 cameraService->getCameraVendorTagCache(
269 /*out*/cache.get());
270 if (res.serviceSpecificErrorCode() ==
271 hardware::ICameraService::ERROR_DISCONNECTED) {
272 // No camera module available, not an error on devices with no cameras
273 VendorTagDescriptorCache::clearGlobalVendorTagCache();
274 } else if (res.isOk()) {
275 status_t err =
276 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
277 cache);
278 if (err != OK) {
279 ALOGE("%s: Failed to set vendor tag cache,"
280 "received error %s (%d)", __FUNCTION__,
281 strerror(-err), err);
282 return false;
283 }
284 } else {
285 VendorTagDescriptorCache::clearGlobalVendorTagCache();
286 ALOGE("%s: Failed to setup vendor tag cache: %s",
287 __FUNCTION__, res.toString8().c_str());
288 return false;
289 }
290 }
291
292 return true;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800293}
294
295void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
296{
297 ALOGE("Camera service binderDied!");
298 sp<CameraManagerGlobal> cm = mCameraManager.promote();
299 if (cm != nullptr) {
300 AutoMutex lock(cm->mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200301 std::vector<DeviceStatusMapKey> keysToRemove;
302 keysToRemove.reserve(cm->mDeviceStatusMap.size());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800303 for (auto& pair : cm->mDeviceStatusMap) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200304 keysToRemove.push_back(pair.first);
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000305 }
306
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200307 for (const DeviceStatusMapKey& key : keysToRemove) {
308 cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId,
309 key.cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800310 }
311 cm->mCameraService.clear();
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000312 cm->mCameraServiceListener.clear();
313 cm->mDeathNotifier.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800314 // TODO: consider adding re-connect call here?
315 }
316}
317
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800318void CameraManagerGlobal::registerExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200319 const DeviceContext& deviceContext,
320 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
321 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext,
322 callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800323}
324
325void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200326 const DeviceContext& deviceContext,
327 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800328 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700329
330 drainPendingCallbacksLocked();
331
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200332 Callback cb(deviceContext, callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800333 mCallbacks.erase(cb);
334}
335
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800336void CameraManagerGlobal::registerAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200337 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
338 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800339}
340
341void CameraManagerGlobal::unregisterAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200342 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800343 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700344
345 drainPendingCallbacksLocked();
346
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200347 Callback cb(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800348 mCallbacks.erase(cb);
349}
350
Shuzhen Wang7e540682020-04-10 13:30:25 -0700351void CameraManagerGlobal::onCallbackCalled() {
352 Mutex::Autolock _l(mLock);
353 if (mPendingCallbackCnt > 0) {
354 mPendingCallbackCnt--;
355 }
356 mCallbacksCond.signal();
357}
358
359void CameraManagerGlobal::drainPendingCallbacksLocked() {
360 while (mPendingCallbackCnt > 0) {
361 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
362 if (res != NO_ERROR) {
363 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
364 __FUNCTION__, strerror(-res), res);
365 break;
366 }
367 }
368}
369
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200370template <class T>
371void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext,
372 const T* callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800373 Mutex::Autolock _l(mLock);
Kwangkyu Park01f84432023-09-15 17:08:17 +0900374 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200375 Callback cb(deviceContext, callback);
376 const auto& [_, newlyRegistered] = mCallbacks.insert(cb);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800377 // Send initial callbacks if callback is newly registered
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200378 if (newlyRegistered) {
379 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
380 if (!isCameraAccessible(deviceContext, key.deviceId)) {
381 continue;
382 }
383 const std::string& cameraId = key.cameraId;
384 int32_t status = statusAndHAL3Support.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700385 // Don't send initial callbacks for camera ids which don't support
386 // camera2
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200387 if (!statusAndHAL3Support.supportsHAL3) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700388 continue;
389 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800390
391 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800392 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800393 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
394 cb.mAvailable : cb.mUnavailable;
395 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
396 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700397 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700398 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800399 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800400
401 // Physical camera unavailable callback
Austin Borger0fb3ad92023-06-01 16:51:35 -0700402 std::set<std::string> unavailablePhysicalCameras =
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200403 statusAndHAL3Support.getUnavailablePhysicalIds();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800404 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
405 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
406 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
407 cb.mPhysicalCamUnavailable;
408 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
409 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700410 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
411 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700412 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800413 msg->post();
414 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800415 }
416 }
417}
418
Austin Borger0fb3ad92023-06-01 16:51:35 -0700419bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700420 bool camera2Support = false;
421 auto cs = getCameraServiceLocked();
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000422 if (cs == nullptr) {
423 return false;
424 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700425 binder::Status serviceRet =
Austin Borger0fb3ad92023-06-01 16:51:35 -0700426 cs->supportsCameraApi(cameraId,
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700427 hardware::ICameraService::API_VERSION_2, &camera2Support);
428 if (!serviceRet.isOk()) {
429 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
430 __FUNCTION__, cameraId.c_str());
431 return false;
432 }
433 return camera2Support;
434}
435
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200436void CameraManagerGlobal::getCameraIdList(const DeviceContext& context,
437 std::vector<std::string>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800438 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800439 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700440 // Needed to make sure we're connected to cameraservice
441 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200442 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
443 if (!isCameraAccessible(context, key.deviceId)) {
444 continue;
445 }
446
447 int32_t status = statusAndHAL3Support.getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800448 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
449 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800450 continue;
451 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200452 if (!statusAndHAL3Support.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800453 continue;
454 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200455 cameraIds->push_back(key.cameraId);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800456 }
457}
458
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800459bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800460 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800461 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
462 case hardware::ICameraServiceListener::STATUS_PRESENT:
463 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
464 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800465 return true;
466 default:
467 return false;
468 }
469}
470
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800471bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800472 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800473 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800474 return true;
475 default:
476 return false;
477 }
478}
479
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800480void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700481 const sp<AMessage> &msg) {
482 onMessageReceivedInternal(msg);
483 if (msg->what() == kWhatSendSingleCallback ||
484 msg->what() == kWhatSendSingleAccessCallback ||
485 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
486 notifyParent();
487 }
488}
489
490void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800491 const sp<AMessage> &msg) {
492 switch (msg->what()) {
493 case kWhatSendSingleCallback:
494 {
495 ACameraManager_AvailabilityCallback cb;
496 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800497 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800498 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
499 if (!found) {
500 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
501 return;
502 }
503 found = msg->findPointer(kContextKey, &context);
504 if (!found) {
505 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
506 return;
507 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800508 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800509 if (!found) {
510 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
511 return;
512 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800513 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800514 break;
515 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800516 case kWhatSendSingleAccessCallback:
517 {
518 ACameraManager_AccessPrioritiesChangedCallback cb;
519 void* context;
520 AString cameraId;
521 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
522 if (!found) {
523 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
524 return;
525 }
526 found = msg->findPointer(kContextKey, &context);
527 if (!found) {
528 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
529 return;
530 }
531 (*cb)(context);
532 break;
533 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800534 case kWhatSendSinglePhysicalCameraCallback:
535 {
536 ACameraManager_PhysicalCameraAvailabilityCallback cb;
537 void* context;
538 AString cameraId;
539 AString physicalCameraId;
540 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
541 if (!found) {
542 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
543 return;
544 }
545 if (cb == nullptr) {
546 // Physical camera callback is null
547 return;
548 }
549 found = msg->findPointer(kContextKey, &context);
550 if (!found) {
551 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
552 return;
553 }
554 found = msg->findString(kCameraIdKey, &cameraId);
555 if (!found) {
556 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
557 return;
558 }
559 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
560 if (!found) {
561 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
562 return;
563 }
564 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
565 break;
566 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800567 default:
568 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
569 break;
570 }
571}
572
Shuzhen Wang7e540682020-04-10 13:30:25 -0700573void CameraManagerGlobal::CallbackHandler::notifyParent() {
574 sp<CameraManagerGlobal> parent = mParent.promote();
575 if (parent != nullptr) {
576 parent->onCallbackCalled();
577 }
578}
579
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800580binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
581 sp<CameraManagerGlobal> cm = mCameraManager.promote();
582 if (cm != nullptr) {
583 cm->onCameraAccessPrioritiesChanged();
584 } else {
585 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
586 }
587 return binder::Status::ok();
588}
589
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800590binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000591 int32_t status, const std::string& cameraId, int deviceId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800592 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800593 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200594 cm->onStatusChanged(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800595 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200596 ALOGE_IF(cm == nullptr,
597 "Cannot deliver physical camera status change. Global camera manager died");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800598 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800599}
600
Shuzhen Wang43858162020-01-10 13:42:15 -0800601binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000602 int32_t status, const std::string& cameraId, const std::string& physicalCameraId,
603 int deviceId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800604 sp<CameraManagerGlobal> cm = mCameraManager.promote();
605 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200606 cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800607 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200608 ALOGE_IF(cm == nullptr,
609 "Cannot deliver physical camera status change. Global camera manager died");
Shuzhen Wang43858162020-01-10 13:42:15 -0800610 return binder::Status::ok();
611}
612
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800613void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
614 Mutex::Autolock _l(mLock);
615 for (auto cb : mCallbacks) {
616 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
617 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
618 if (cbFp != nullptr) {
619 msg->setPointer(kCallbackFpKey, (void *) cbFp);
620 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700621 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800622 msg->post();
623 }
624 }
625}
626
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200627void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
628 const std::string& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800629 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200630 onStatusChangedLocked(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800631}
632
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200633void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
634 const std::string& cameraId) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800635 if (!validStatus(status)) {
636 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
637 return;
638 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800639
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200640 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
641
642 bool firstStatus = (mDeviceStatusMap.count(key) == 0);
643 int32_t oldStatus = firstStatus ? status : // first status
644 mDeviceStatusMap[key].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800645
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800646 if (!firstStatus &&
647 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
648 // No status update. No need to send callback
649 return;
650 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800651
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700652 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800653 if (firstStatus) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200654 mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key),
655 std::forward_as_tuple(status, supportsHAL3));
Shuzhen Wang43858162020-01-10 13:42:15 -0800656 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200657 mDeviceStatusMap[key].updateStatus(status);
Shuzhen Wang43858162020-01-10 13:42:15 -0800658 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800659 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700660 if (supportsHAL3) {
661 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200662 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
663 continue;
664 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700665 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
666 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
667 cb.mAvailable : cb.mUnavailable;
668 msg->setPointer(kCallbackFpKey, (void *) cbFp);
669 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700670 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700671 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700672 msg->post();
673 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800674 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100675 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200676 mDeviceStatusMap.erase(key);
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100677 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800678}
679
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200680void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
681 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800682 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200683 onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800684}
685
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200686void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
687 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800688 if (!validStatus(status)) {
689 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
690 return;
691 }
692
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200693 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
694 auto logicalStatus = mDeviceStatusMap.find(key);
Shuzhen Wang43858162020-01-10 13:42:15 -0800695 if (logicalStatus == mDeviceStatusMap.end()) {
696 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
697 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
698 return;
699 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200700 int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800701 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
702 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
703 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700704 __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
Shuzhen Wang43858162020-01-10 13:42:15 -0800705 return;
706 }
707
708 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
709
710 bool updated = false;
711 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200712 updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800713 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200714 updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800715 }
716
717 // Iterate through all registered callbacks
718 if (supportsHAL3 && updated) {
719 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200720 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
721 continue;
722 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800723 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
724 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
725 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
726 msg->setPointer(kCallbackFpKey, (void *) cbFp);
727 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700728 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
729 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700730 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800731 msg->post();
732 }
733 }
734}
735
736int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
737 std::lock_guard<std::mutex> lock(mLock);
738 return status;
739}
740
741void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
742 std::lock_guard<std::mutex> lock(mLock);
743 status = newStatus;
744}
745
746bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700747 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800748 std::lock_guard<std::mutex> lock(mLock);
749 auto result = unavailablePhysicalIds.insert(physicalCameraId);
750 return result.second;
751}
752
753bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700754 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800755 std::lock_guard<std::mutex> lock(mLock);
756 auto count = unavailablePhysicalIds.erase(physicalCameraId);
757 return count > 0;
758}
759
Austin Borger0fb3ad92023-06-01 16:51:35 -0700760std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800761 std::lock_guard<std::mutex> lock(mLock);
762 return unavailablePhysicalIds;
763}
764
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800765} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800766} // namespace android
767
768/**
769 * ACameraManger Implementation
770 */
771camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800772ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
773 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800774
Austin Borger0fb3ad92023-06-01 16:51:35 -0700775 std::vector<std::string> idList;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200776 mGlobalManager->getCameraIdList(mDeviceContext, &idList);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800777
778 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800779 ACameraIdList *out = new ACameraIdList;
780 if (!out) {
781 ALOGE("Allocate memory for ACameraIdList failed!");
782 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
783 }
784 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800785 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800786 if (!out->cameraIds) {
787 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800788 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800789 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
790 }
791 for (int i = 0; i < numCameras; i++) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700792 const char* src = idList[i].c_str();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800793 size_t dstSize = strlen(src) + 1;
794 char* dst = new char[dstSize];
795 if (!dst) {
796 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800797 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800798 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
799 }
800 strlcpy(dst, src, dstSize);
801 out->cameraIds[i] = dst;
802 }
803 *cameraIdList = out;
804 return ACAMERA_OK;
805}
806
807void
808ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
809 if (cameraIdList != nullptr) {
810 if (cameraIdList->cameraIds != nullptr) {
811 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800812 if (cameraIdList->cameraIds[i] != nullptr) {
813 delete[] cameraIdList->cameraIds[i];
814 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800815 }
816 delete[] cameraIdList->cameraIds;
817 }
818 delete cameraIdList;
819 }
820}
821
822camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700823 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800824 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800825
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200826 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800827 if (cs == nullptr) {
828 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
829 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
830 }
Austin Borger3560b7e2022-10-27 12:20:29 -0700831
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800832 CameraMetadata rawMetadata;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700833 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700834
835 AttributionSourceState clientAttribution;
836 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
837 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
838 clientAttribution.deviceId = mDeviceContext.deviceId;
839
Austin Borger0fb3ad92023-06-01 16:51:35 -0700840 binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000841 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700842 clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
Biswarup Pal37a75182024-01-16 15:53:35 +0000843 &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800844 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800845 switch(serviceRet.serviceSpecificErrorCode()) {
846 case hardware::ICameraService::ERROR_DISCONNECTED:
847 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
848 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
849 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
850 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
851 return ACAMERA_ERROR_INVALID_PARAMETER;
852 default:
853 ALOGE("Get camera characteristics from camera service failed: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000854 serviceRet.toString8().c_str());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800855 return ACAMERA_ERROR_UNKNOWN; // should not reach here
856 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800857 }
858
859 *characteristics = new ACameraMetadata(
860 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
861 return ACAMERA_OK;
862}
863
864camera_status_t
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700865ACameraManager::isCameraDeviceSharingSupported(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800866 const char* cameraId,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700867 /*out*/bool* isSharingSupported) {
868 if (!flags::camera_multi_client()) {
869 return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
870 }
871 sp<ACameraMetadata> spChars;
872 camera_status_t ret = getCameraCharacteristics(cameraId, &spChars);
873 if (ret != ACAMERA_OK) {
874 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
875 __FUNCTION__, cameraId, ret);
876 return ret;
877 }
878
879 ACameraMetadata* chars = spChars.get();
880 ACameraMetadata_const_entry entry;
881 ret = ACameraMetadata_getConstEntry(chars, ANDROID_SHARED_SESSION_OUTPUT_CONFIGURATIONS,
882 &entry);
883 if (ret != ACAMERA_OK) {
884 return ret;
885 }
886 *isSharingSupported = (entry.count > 0) ? true : false;
887 return ACAMERA_OK;
888}
889
890camera_status_t
891ACameraManager::openCamera(
892 const char* cameraId, bool sharedMode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800893 ACameraDevice_StateCallbacks* callback,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700894 /*out*/ACameraDevice** outDevice, /*out*/bool* primaryClient) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700895 sp<ACameraMetadata> chars;
896 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800897 Mutex::Autolock _l(mLock);
898 if (ret != ACAMERA_OK) {
899 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
900 __FUNCTION__, cameraId, ret);
901 return ACAMERA_ERROR_INVALID_PARAMETER;
902 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800903
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700904 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars, sharedMode);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800905
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200906 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800907 if (cs == nullptr) {
908 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700909 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800910 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
911 }
912
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800913 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
914 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700915 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700916
917 AttributionSourceState clientAttribution;
918 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
919 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
920 clientAttribution.deviceId = mDeviceContext.deviceId;
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700921 clientAttribution.packageName = "";
922 clientAttribution.attributionTag = std::nullopt;
Austin Borger65e64642024-06-11 15:58:23 -0700923
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800924 // No way to get package name from native.
925 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800926 binder::Status serviceRet = cs->connectDevice(
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700927 callbacks, cameraId, /*oomScoreOffset*/0,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000928 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700929 clientAttribution, static_cast<int32_t>(mDeviceContext.policy), sharedMode,
Biswarup Pal37a75182024-01-16 15:53:35 +0000930 /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800931
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800932 if (!serviceRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000933 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().c_str());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700934 // Convert serviceRet to camera_status_t
935 switch(serviceRet.serviceSpecificErrorCode()) {
936 case hardware::ICameraService::ERROR_DISCONNECTED:
937 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
938 break;
939 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
940 ret = ACAMERA_ERROR_CAMERA_IN_USE;
941 break;
942 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
943 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
944 break;
945 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
946 ret = ACAMERA_ERROR_INVALID_PARAMETER;
947 break;
948 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
949 // Should not reach here since we filtered legacy HALs earlier
950 ret = ACAMERA_ERROR_INVALID_PARAMETER;
951 break;
952 case hardware::ICameraService::ERROR_DISABLED:
953 ret = ACAMERA_ERROR_CAMERA_DISABLED;
954 break;
955 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
956 ret = ACAMERA_ERROR_PERMISSION_DENIED;
957 break;
958 case hardware::ICameraService::ERROR_INVALID_OPERATION:
959 default:
960 ret = ACAMERA_ERROR_UNKNOWN;
961 break;
962 }
963
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800964 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700965 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800966 }
967 if (deviceRemote == nullptr) {
968 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
969 delete device;
970 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
971 }
972 device->setRemoteDevice(deviceRemote);
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700973 if (flags::camera_multi_client() && sharedMode) {
974 binder::Status remoteRet = deviceRemote->isPrimaryClient(primaryClient);
975 if (!remoteRet.isOk()) {
976 delete device;
977 return ACAMERA_ERROR_UNKNOWN;
978 }
979 device->setPrimaryClient(*primaryClient);
980 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800981 *outDevice = device;
982 return ACAMERA_OK;
983}
984
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200985void ACameraManager::registerAvailabilityCallback(
986 const ACameraManager_AvailabilityCallbacks* callback) {
987 mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback);
988}
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800989
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200990void ACameraManager::unregisterAvailabilityCallback(
991 const ACameraManager_AvailabilityCallbacks* callback) {
992 mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback);
993}
994
995void ACameraManager::registerExtendedAvailabilityCallback(
996 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
997 mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback);
998}
999
1000void ACameraManager::unregisterExtendedAvailabilityCallback(
1001 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
1002 mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001003}