blob: 53c4489877bcb177172ec8cb7a5eb6e001c06e8c [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"
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080031
Jayant Chowdhary6df26072018-11-06 23:55:12 -080032using namespace android::acam;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020033namespace vd_flags = android::companion::virtualdevice::flags;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080034
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080035namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080036namespace acam {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020037namespace {
Biswarup Pal37a75182024-01-16 15:53:35 +000038
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +020039using ::android::binder::Status;
40using ::android::companion::virtualnative::IVirtualDeviceManagerNative;
41
42// Return binder connection to VirtualDeviceManager.
43//
44// Subsequent calls return the same cached instance.
45sp<IVirtualDeviceManagerNative> getVirtualDeviceManager() {
46 auto connectToVirtualDeviceManagerNative = []() {
47 sp<IBinder> binder =
48 defaultServiceManager()->checkService(String16("virtualdevice_native"));
49 if (binder == nullptr) {
50 ALOGW("%s: Cannot get virtualdevice_native service", __func__);
51 return interface_cast<IVirtualDeviceManagerNative>(nullptr);
52 }
53 return interface_cast<IVirtualDeviceManagerNative>(binder);
54 };
55
56 static sp<IVirtualDeviceManagerNative> vdm = connectToVirtualDeviceManagerNative();
57 return vdm;
58}
59
60// Returns device id calling process is running on.
61// If the process cannot be attributed to single virtual device id, returns default device id.
62int getCurrentDeviceId() {
63 if (!vd_flags::camera_device_awareness()) {
64 return kDefaultDeviceId;
65 }
66
67 auto vdm = getVirtualDeviceManager();
68 if (vdm == nullptr) {
69 return kDefaultDeviceId;
70 }
71
72 const uid_t myUid = getuid();
73 std::vector<int> deviceIds;
74 Status status = vdm->getDeviceIdsForUid(myUid, &deviceIds);
75 if (!status.isOk() || deviceIds.empty()) {
76 ALOGE("%s: Failed to call getDeviceIdsForUid to determine device id for uid %d: %s",
77 __func__, myUid, status.toString8().c_str());
78 return kDefaultDeviceId;
79 }
80
81 // If the UID is associated with multiple virtual devices, use the default device's
82 // camera as we cannot disambiguate here. This effectively means that the app has
83 // activities on different devices at the same time.
84 if (deviceIds.size() != 1) {
85 return kDefaultDeviceId;
86 }
87 return deviceIds[0];
88}
89
90// Returns device policy for POLICY_TYPE_CAMERA corresponding to deviceId.
91DevicePolicy getDevicePolicyForDeviceId(const int deviceId) {
92 if (!vd_flags::camera_device_awareness() || deviceId == kDefaultDeviceId) {
93 return DevicePolicy::DEVICE_POLICY_DEFAULT;
94 }
95
96 auto vdm = getVirtualDeviceManager();
97 if (vdm == nullptr) {
98 return DevicePolicy::DEVICE_POLICY_DEFAULT;
99 }
100
101 int policy = IVirtualDeviceManagerNative::DEVICE_POLICY_DEFAULT;
102 Status status = vdm->getDevicePolicy(deviceId, IVirtualDeviceManagerNative::POLICY_TYPE_CAMERA,
103 &policy);
104 if (!status.isOk()) {
105 ALOGE("%s: Failed to call getDevicePolicy to determine camera policy for device id %d: %s",
106 __func__, deviceId, status.toString8().c_str());
107 return DevicePolicy::DEVICE_POLICY_DEFAULT;
108 }
109 return static_cast<DevicePolicy>(policy);
110}
111
112// Returns true if camera owned by device cameraDeviceId can be accessed within deviceContext.
113bool isCameraAccessible(const DeviceContext deviceContext, const int cameraDeviceId) {
114 if (!vd_flags::camera_device_awareness() ||
115 deviceContext.policy == DevicePolicy::DEVICE_POLICY_DEFAULT) {
116 return cameraDeviceId == kDefaultDeviceId;
117 }
118 return deviceContext.deviceId == cameraDeviceId;
119}
120
121} // namespace
Biswarup Pal37a75182024-01-16 15:53:35 +0000122
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800123// Static member definitions
124const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
Shuzhen Wang43858162020-01-10 13:42:15 -0800125const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800126const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
127const char* CameraManagerGlobal::kContextKey = "CallbackContext";
Shuzhen Wang7e540682020-04-10 13:30:25 -0700128const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800129Mutex CameraManagerGlobal::sLock;
Avichal Rakeshf099b232022-10-27 15:44:50 -0700130wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800131
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200132DeviceContext::DeviceContext() {
133 deviceId = getCurrentDeviceId();
134 policy = getDevicePolicyForDeviceId(deviceId);
135}
136
Avichal Rakeshf099b232022-10-27 15:44:50 -0700137sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800138 Mutex::Autolock _l(sLock);
Avichal Rakeshf099b232022-10-27 15:44:50 -0700139 sp<CameraManagerGlobal> instance = sInstance.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800140 if (instance == nullptr) {
141 instance = new CameraManagerGlobal();
142 sInstance = instance;
143 }
Avichal Rakeshf099b232022-10-27 15:44:50 -0700144 return instance;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800145}
146
147CameraManagerGlobal::~CameraManagerGlobal() {
148 // clear sInstance so next getInstance call knows to create a new one
149 Mutex::Autolock _sl(sLock);
150 sInstance = nullptr;
151 Mutex::Autolock _l(mLock);
152 if (mCameraService != nullptr) {
153 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -0800154 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800155 }
156 mDeathNotifier.clear();
157 if (mCbLooper != nullptr) {
158 mCbLooper->unregisterHandler(mHandler->id());
159 mCbLooper->stop();
160 }
161 mCbLooper.clear();
162 mHandler.clear();
163 mCameraServiceListener.clear();
164 mCameraService.clear();
165}
166
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800167sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800168 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700169 return getCameraServiceLocked();
170}
171
172sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000173 if (mCameraService.get() != nullptr) {
174 return mCameraService;
175 }
176 if (CameraUtils::isCameraServiceDisabled()) {
177 return mCameraService;
178 }
Ivan Podogovee844a82016-09-15 11:32:41 +0100179
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000180 sp<IServiceManager> sm = defaultServiceManager();
181 sp<IBinder> binder;
182 binder = sm->checkService(String16(kCameraServiceName));
183 if (binder == nullptr) {
184 ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
185 return nullptr;
186 }
187 sp<hardware::ICameraService> cameraService = interface_cast<hardware::ICameraService>(binder);
188 if (mDeathNotifier == nullptr) {
189 mDeathNotifier = new DeathNotifier(this);
190 binder->linkToDeath(mDeathNotifier);
191 }
192
193 // Setup looper thread to perform availability callbacks
194 if (mCbLooper == nullptr) {
195 mCbLooper = new ALooper;
196 mCbLooper->setName("C2N-mgr-looper");
197 status_t err = mCbLooper->start(
198 /*runOnCallingThread*/false,
199 /*canCallJava*/ true,
200 PRIORITY_DEFAULT);
201 if (err != OK) {
202 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
203 __FUNCTION__, strerror(-err), err);
204 mCbLooper.clear();
Ankit Siddhapura959b7be2024-04-16 13:07:42 +0530205 return nullptr;
206 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000207 if (mHandler == nullptr) {
208 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800209 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000210 mCbLooper->registerHandler(mHandler);
211 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800212
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000213 // register ICameraServiceListener
214 std::vector<hardware::CameraStatus> cameraStatuses{};
215 if (mCameraServiceListener == nullptr) {
216 mCameraServiceListener = new CameraServiceListener(this);
217 cameraService->addListener(mCameraServiceListener, &cameraStatuses);
218 }
219
220 for (auto& c : cameraStatuses) {
221 onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
222
223 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
224 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
225 c.deviceId, c.cameraId, unavailablePhysicalId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800226 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000227 }
228 // setup vendor tags
229 if (!setupVendorTags(cameraService)) {
230 ALOGE("%s: Vendor tag descriptor cache couldn't be set up", __FUNCTION__);
231 return nullptr;
232 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800233
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000234 mCameraService = cameraService;
235 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
236 return mCameraService;
237}
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800238
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000239bool CameraManagerGlobal::setupVendorTags(sp<hardware::ICameraService> &cameraService) {
240 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
241 binder::Status ret = cameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
242 if (!ret.isOk()) {
243 if (ret.serviceSpecificErrorCode() ==
244 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800245 ALOGW("%s: Camera HAL too old; does not support vendor tags",
246 __FUNCTION__);
247 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
248 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800249 ALOGE("%s: Failed to get vendor tag descriptors: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000250 __FUNCTION__, ret.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800251 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000252 return false;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800253 }
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000254
255 if (0 < desc->getTagCount()) {
256 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
257 if (err != OK) {
258 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
259 __FUNCTION__, strerror(-err), err);
260 return false;
261 }
262 } else {
263 sp<VendorTagDescriptorCache> cache =
264 new VendorTagDescriptorCache();
265 binder::Status res =
266 cameraService->getCameraVendorTagCache(
267 /*out*/cache.get());
268 if (res.serviceSpecificErrorCode() ==
269 hardware::ICameraService::ERROR_DISCONNECTED) {
270 // No camera module available, not an error on devices with no cameras
271 VendorTagDescriptorCache::clearGlobalVendorTagCache();
272 } else if (res.isOk()) {
273 status_t err =
274 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
275 cache);
276 if (err != OK) {
277 ALOGE("%s: Failed to set vendor tag cache,"
278 "received error %s (%d)", __FUNCTION__,
279 strerror(-err), err);
280 return false;
281 }
282 } else {
283 VendorTagDescriptorCache::clearGlobalVendorTagCache();
284 ALOGE("%s: Failed to setup vendor tag cache: %s",
285 __FUNCTION__, res.toString8().c_str());
286 return false;
287 }
288 }
289
290 return true;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800291}
292
293void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
294{
295 ALOGE("Camera service binderDied!");
296 sp<CameraManagerGlobal> cm = mCameraManager.promote();
297 if (cm != nullptr) {
298 AutoMutex lock(cm->mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200299 std::vector<DeviceStatusMapKey> keysToRemove;
300 keysToRemove.reserve(cm->mDeviceStatusMap.size());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800301 for (auto& pair : cm->mDeviceStatusMap) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200302 keysToRemove.push_back(pair.first);
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000303 }
304
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200305 for (const DeviceStatusMapKey& key : keysToRemove) {
306 cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId,
307 key.cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800308 }
309 cm->mCameraService.clear();
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000310 cm->mCameraServiceListener.clear();
311 cm->mDeathNotifier.clear();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800312 // TODO: consider adding re-connect call here?
313 }
314}
315
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800316void CameraManagerGlobal::registerExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200317 const DeviceContext& deviceContext,
318 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
319 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext,
320 callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800321}
322
323void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200324 const DeviceContext& deviceContext,
325 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800326 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700327
328 drainPendingCallbacksLocked();
329
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200330 Callback cb(deviceContext, callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800331 mCallbacks.erase(cb);
332}
333
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800334void CameraManagerGlobal::registerAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200335 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
336 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800337}
338
339void CameraManagerGlobal::unregisterAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200340 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800341 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700342
343 drainPendingCallbacksLocked();
344
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200345 Callback cb(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800346 mCallbacks.erase(cb);
347}
348
Shuzhen Wang7e540682020-04-10 13:30:25 -0700349void CameraManagerGlobal::onCallbackCalled() {
350 Mutex::Autolock _l(mLock);
351 if (mPendingCallbackCnt > 0) {
352 mPendingCallbackCnt--;
353 }
354 mCallbacksCond.signal();
355}
356
357void CameraManagerGlobal::drainPendingCallbacksLocked() {
358 while (mPendingCallbackCnt > 0) {
359 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
360 if (res != NO_ERROR) {
361 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
362 __FUNCTION__, strerror(-res), res);
363 break;
364 }
365 }
366}
367
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200368template <class T>
369void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext,
370 const T* callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800371 Mutex::Autolock _l(mLock);
Kwangkyu Park01f84432023-09-15 17:08:17 +0900372 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200373 Callback cb(deviceContext, callback);
374 const auto& [_, newlyRegistered] = mCallbacks.insert(cb);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800375 // Send initial callbacks if callback is newly registered
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200376 if (newlyRegistered) {
377 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
378 if (!isCameraAccessible(deviceContext, key.deviceId)) {
379 continue;
380 }
381 const std::string& cameraId = key.cameraId;
382 int32_t status = statusAndHAL3Support.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700383 // Don't send initial callbacks for camera ids which don't support
384 // camera2
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200385 if (!statusAndHAL3Support.supportsHAL3) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700386 continue;
387 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800388
389 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800390 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800391 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
392 cb.mAvailable : cb.mUnavailable;
393 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
394 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700395 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700396 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800397 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800398
399 // Physical camera unavailable callback
Austin Borger0fb3ad92023-06-01 16:51:35 -0700400 std::set<std::string> unavailablePhysicalCameras =
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200401 statusAndHAL3Support.getUnavailablePhysicalIds();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800402 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
403 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
404 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
405 cb.mPhysicalCamUnavailable;
406 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
407 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700408 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
409 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700410 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800411 msg->post();
412 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800413 }
414 }
415}
416
Austin Borger0fb3ad92023-06-01 16:51:35 -0700417bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700418 bool camera2Support = false;
419 auto cs = getCameraServiceLocked();
Jayant Chowdhary615e1602024-10-02 20:22:08 +0000420 if (cs == nullptr) {
421 return false;
422 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700423 binder::Status serviceRet =
Austin Borger0fb3ad92023-06-01 16:51:35 -0700424 cs->supportsCameraApi(cameraId,
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700425 hardware::ICameraService::API_VERSION_2, &camera2Support);
426 if (!serviceRet.isOk()) {
427 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
428 __FUNCTION__, cameraId.c_str());
429 return false;
430 }
431 return camera2Support;
432}
433
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200434void CameraManagerGlobal::getCameraIdList(const DeviceContext& context,
435 std::vector<std::string>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800436 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800437 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700438 // Needed to make sure we're connected to cameraservice
439 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200440 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
441 if (!isCameraAccessible(context, key.deviceId)) {
442 continue;
443 }
444
445 int32_t status = statusAndHAL3Support.getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800446 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
447 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800448 continue;
449 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200450 if (!statusAndHAL3Support.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800451 continue;
452 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200453 cameraIds->push_back(key.cameraId);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800454 }
455}
456
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800457bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800458 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800459 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
460 case hardware::ICameraServiceListener::STATUS_PRESENT:
461 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
462 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800463 return true;
464 default:
465 return false;
466 }
467}
468
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800469bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800470 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800471 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800472 return true;
473 default:
474 return false;
475 }
476}
477
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800478void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700479 const sp<AMessage> &msg) {
480 onMessageReceivedInternal(msg);
481 if (msg->what() == kWhatSendSingleCallback ||
482 msg->what() == kWhatSendSingleAccessCallback ||
483 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
484 notifyParent();
485 }
486}
487
488void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800489 const sp<AMessage> &msg) {
490 switch (msg->what()) {
491 case kWhatSendSingleCallback:
492 {
493 ACameraManager_AvailabilityCallback cb;
494 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800495 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800496 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
497 if (!found) {
498 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
499 return;
500 }
501 found = msg->findPointer(kContextKey, &context);
502 if (!found) {
503 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
504 return;
505 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800506 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800507 if (!found) {
508 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
509 return;
510 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800511 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800512 break;
513 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800514 case kWhatSendSingleAccessCallback:
515 {
516 ACameraManager_AccessPrioritiesChangedCallback cb;
517 void* context;
518 AString cameraId;
519 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
520 if (!found) {
521 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
522 return;
523 }
524 found = msg->findPointer(kContextKey, &context);
525 if (!found) {
526 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
527 return;
528 }
529 (*cb)(context);
530 break;
531 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800532 case kWhatSendSinglePhysicalCameraCallback:
533 {
534 ACameraManager_PhysicalCameraAvailabilityCallback cb;
535 void* context;
536 AString cameraId;
537 AString physicalCameraId;
538 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
539 if (!found) {
540 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
541 return;
542 }
543 if (cb == nullptr) {
544 // Physical camera callback is null
545 return;
546 }
547 found = msg->findPointer(kContextKey, &context);
548 if (!found) {
549 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
550 return;
551 }
552 found = msg->findString(kCameraIdKey, &cameraId);
553 if (!found) {
554 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
555 return;
556 }
557 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
558 if (!found) {
559 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
560 return;
561 }
562 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
563 break;
564 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800565 default:
566 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
567 break;
568 }
569}
570
Shuzhen Wang7e540682020-04-10 13:30:25 -0700571void CameraManagerGlobal::CallbackHandler::notifyParent() {
572 sp<CameraManagerGlobal> parent = mParent.promote();
573 if (parent != nullptr) {
574 parent->onCallbackCalled();
575 }
576}
577
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800578binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
579 sp<CameraManagerGlobal> cm = mCameraManager.promote();
580 if (cm != nullptr) {
581 cm->onCameraAccessPrioritiesChanged();
582 } else {
583 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
584 }
585 return binder::Status::ok();
586}
587
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800588binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000589 int32_t status, const std::string& cameraId, int deviceId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800590 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800591 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200592 cm->onStatusChanged(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800593 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200594 ALOGE_IF(cm == nullptr,
595 "Cannot deliver physical camera status change. Global camera manager died");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800596 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800597}
598
Shuzhen Wang43858162020-01-10 13:42:15 -0800599binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000600 int32_t status, const std::string& cameraId, const std::string& physicalCameraId,
601 int deviceId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800602 sp<CameraManagerGlobal> cm = mCameraManager.promote();
603 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200604 cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800605 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200606 ALOGE_IF(cm == nullptr,
607 "Cannot deliver physical camera status change. Global camera manager died");
Shuzhen Wang43858162020-01-10 13:42:15 -0800608 return binder::Status::ok();
609}
610
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800611void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
612 Mutex::Autolock _l(mLock);
613 for (auto cb : mCallbacks) {
614 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
615 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
616 if (cbFp != nullptr) {
617 msg->setPointer(kCallbackFpKey, (void *) cbFp);
618 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700619 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800620 msg->post();
621 }
622 }
623}
624
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200625void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
626 const std::string& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800627 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200628 onStatusChangedLocked(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800629}
630
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200631void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
632 const std::string& cameraId) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800633 if (!validStatus(status)) {
634 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
635 return;
636 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800637
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200638 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
639
640 bool firstStatus = (mDeviceStatusMap.count(key) == 0);
641 int32_t oldStatus = firstStatus ? status : // first status
642 mDeviceStatusMap[key].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800643
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800644 if (!firstStatus &&
645 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
646 // No status update. No need to send callback
647 return;
648 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800649
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700650 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800651 if (firstStatus) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200652 mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key),
653 std::forward_as_tuple(status, supportsHAL3));
Shuzhen Wang43858162020-01-10 13:42:15 -0800654 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200655 mDeviceStatusMap[key].updateStatus(status);
Shuzhen Wang43858162020-01-10 13:42:15 -0800656 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800657 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700658 if (supportsHAL3) {
659 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200660 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
661 continue;
662 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700663 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
664 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
665 cb.mAvailable : cb.mUnavailable;
666 msg->setPointer(kCallbackFpKey, (void *) cbFp);
667 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700668 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700669 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700670 msg->post();
671 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800672 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100673 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200674 mDeviceStatusMap.erase(key);
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100675 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800676}
677
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200678void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
679 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800680 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200681 onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800682}
683
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200684void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
685 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800686 if (!validStatus(status)) {
687 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
688 return;
689 }
690
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200691 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
692 auto logicalStatus = mDeviceStatusMap.find(key);
Shuzhen Wang43858162020-01-10 13:42:15 -0800693 if (logicalStatus == mDeviceStatusMap.end()) {
694 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
695 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
696 return;
697 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200698 int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800699 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
700 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
701 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700702 __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
Shuzhen Wang43858162020-01-10 13:42:15 -0800703 return;
704 }
705
706 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
707
708 bool updated = false;
709 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200710 updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800711 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200712 updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800713 }
714
715 // Iterate through all registered callbacks
716 if (supportsHAL3 && updated) {
717 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200718 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
719 continue;
720 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800721 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
722 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
723 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
724 msg->setPointer(kCallbackFpKey, (void *) cbFp);
725 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700726 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
727 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700728 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800729 msg->post();
730 }
731 }
732}
733
734int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
735 std::lock_guard<std::mutex> lock(mLock);
736 return status;
737}
738
739void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
740 std::lock_guard<std::mutex> lock(mLock);
741 status = newStatus;
742}
743
744bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700745 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800746 std::lock_guard<std::mutex> lock(mLock);
747 auto result = unavailablePhysicalIds.insert(physicalCameraId);
748 return result.second;
749}
750
751bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700752 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800753 std::lock_guard<std::mutex> lock(mLock);
754 auto count = unavailablePhysicalIds.erase(physicalCameraId);
755 return count > 0;
756}
757
Austin Borger0fb3ad92023-06-01 16:51:35 -0700758std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800759 std::lock_guard<std::mutex> lock(mLock);
760 return unavailablePhysicalIds;
761}
762
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800763} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800764} // namespace android
765
766/**
767 * ACameraManger Implementation
768 */
769camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800770ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
771 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800772
Austin Borger0fb3ad92023-06-01 16:51:35 -0700773 std::vector<std::string> idList;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200774 mGlobalManager->getCameraIdList(mDeviceContext, &idList);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800775
776 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800777 ACameraIdList *out = new ACameraIdList;
778 if (!out) {
779 ALOGE("Allocate memory for ACameraIdList failed!");
780 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
781 }
782 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800783 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800784 if (!out->cameraIds) {
785 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800786 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800787 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
788 }
789 for (int i = 0; i < numCameras; i++) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700790 const char* src = idList[i].c_str();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800791 size_t dstSize = strlen(src) + 1;
792 char* dst = new char[dstSize];
793 if (!dst) {
794 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800795 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800796 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
797 }
798 strlcpy(dst, src, dstSize);
799 out->cameraIds[i] = dst;
800 }
801 *cameraIdList = out;
802 return ACAMERA_OK;
803}
804
805void
806ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
807 if (cameraIdList != nullptr) {
808 if (cameraIdList->cameraIds != nullptr) {
809 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800810 if (cameraIdList->cameraIds[i] != nullptr) {
811 delete[] cameraIdList->cameraIds[i];
812 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800813 }
814 delete[] cameraIdList->cameraIds;
815 }
816 delete cameraIdList;
817 }
818}
819
820camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700821 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800822 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800823
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200824 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800825 if (cs == nullptr) {
826 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
827 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
828 }
Austin Borger3560b7e2022-10-27 12:20:29 -0700829
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800830 CameraMetadata rawMetadata;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700831 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700832
833 AttributionSourceState clientAttribution;
834 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
835 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
836 clientAttribution.deviceId = mDeviceContext.deviceId;
837
Austin Borger0fb3ad92023-06-01 16:51:35 -0700838 binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000839 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700840 clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
Biswarup Pal37a75182024-01-16 15:53:35 +0000841 &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800842 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800843 switch(serviceRet.serviceSpecificErrorCode()) {
844 case hardware::ICameraService::ERROR_DISCONNECTED:
845 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
846 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
847 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
848 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
849 return ACAMERA_ERROR_INVALID_PARAMETER;
850 default:
851 ALOGE("Get camera characteristics from camera service failed: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000852 serviceRet.toString8().c_str());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800853 return ACAMERA_ERROR_UNKNOWN; // should not reach here
854 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800855 }
856
857 *characteristics = new ACameraMetadata(
858 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
859 return ACAMERA_OK;
860}
861
862camera_status_t
863ACameraManager::openCamera(
864 const char* cameraId,
865 ACameraDevice_StateCallbacks* callback,
866 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700867 sp<ACameraMetadata> chars;
868 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800869 Mutex::Autolock _l(mLock);
870 if (ret != ACAMERA_OK) {
871 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
872 __FUNCTION__, cameraId, ret);
873 return ACAMERA_ERROR_INVALID_PARAMETER;
874 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800875
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700876 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800877
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200878 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800879 if (cs == nullptr) {
880 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700881 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800882 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
883 }
884
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800885 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
886 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700887 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700888
889 AttributionSourceState clientAttribution;
890 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
891 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
892 clientAttribution.deviceId = mDeviceContext.deviceId;
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700893 clientAttribution.packageName = "";
894 clientAttribution.attributionTag = std::nullopt;
Austin Borger65e64642024-06-11 15:58:23 -0700895
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800896 // No way to get package name from native.
897 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800898 binder::Status serviceRet = cs->connectDevice(
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700899 callbacks, cameraId, /*oomScoreOffset*/0,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000900 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700901 clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
Biswarup Pal37a75182024-01-16 15:53:35 +0000902 /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800903
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800904 if (!serviceRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000905 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().c_str());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700906 // Convert serviceRet to camera_status_t
907 switch(serviceRet.serviceSpecificErrorCode()) {
908 case hardware::ICameraService::ERROR_DISCONNECTED:
909 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
910 break;
911 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
912 ret = ACAMERA_ERROR_CAMERA_IN_USE;
913 break;
914 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
915 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
916 break;
917 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
918 ret = ACAMERA_ERROR_INVALID_PARAMETER;
919 break;
920 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
921 // Should not reach here since we filtered legacy HALs earlier
922 ret = ACAMERA_ERROR_INVALID_PARAMETER;
923 break;
924 case hardware::ICameraService::ERROR_DISABLED:
925 ret = ACAMERA_ERROR_CAMERA_DISABLED;
926 break;
927 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
928 ret = ACAMERA_ERROR_PERMISSION_DENIED;
929 break;
930 case hardware::ICameraService::ERROR_INVALID_OPERATION:
931 default:
932 ret = ACAMERA_ERROR_UNKNOWN;
933 break;
934 }
935
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800936 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700937 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800938 }
939 if (deviceRemote == nullptr) {
940 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
941 delete device;
942 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
943 }
944 device->setRemoteDevice(deviceRemote);
945 *outDevice = device;
946 return ACAMERA_OK;
947}
948
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200949void ACameraManager::registerAvailabilityCallback(
950 const ACameraManager_AvailabilityCallbacks* callback) {
951 mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback);
952}
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800953
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200954void ACameraManager::unregisterAvailabilityCallback(
955 const ACameraManager_AvailabilityCallbacks* callback) {
956 mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback);
957}
958
959void ACameraManager::registerExtendedAvailabilityCallback(
960 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
961 mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback);
962}
963
964void ACameraManager::unregisterExtendedAvailabilityCallback(
965 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
966 mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800967}