blob: c3bec0aa7288520ccaa05a5af34de908ddcc413c [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() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800173 if (mCameraService.get() == nullptr) {
Jayant Chowdharyf5b9cc62020-09-08 16:25:17 -0700174 if (CameraUtils::isCameraServiceDisabled()) {
Ivan Podogovee844a82016-09-15 11:32:41 +0100175 return mCameraService;
176 }
177
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800178 sp<IServiceManager> sm = defaultServiceManager();
179 sp<IBinder> binder;
180 do {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700181 binder = sm->getService(toString16(kCameraServiceName));
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800182 if (binder != nullptr) {
183 break;
184 }
185 ALOGW("CameraService not published, waiting...");
186 usleep(kCameraServicePollDelay);
187 } while(true);
188 if (mDeathNotifier == nullptr) {
189 mDeathNotifier = new DeathNotifier(this);
190 }
191 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800192 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800193
194 // Setup looper thread to perfrom availiability callbacks
195 if (mCbLooper == nullptr) {
196 mCbLooper = new ALooper;
197 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800198 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800199 /*runOnCallingThread*/false,
200 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800201 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800202 if (err != OK) {
203 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
204 __FUNCTION__, strerror(-err), err);
205 mCbLooper.clear();
206 return nullptr;
207 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800208 if (mHandler == nullptr) {
Shuzhen Wang7e540682020-04-10 13:30:25 -0700209 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800210 }
211 mCbLooper->registerHandler(mHandler);
212 }
213
214 // register ICameraServiceListener
215 if (mCameraServiceListener == nullptr) {
216 mCameraServiceListener = new CameraServiceListener(this);
217 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800218 std::vector<hardware::CameraStatus> cameraStatuses{};
219 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
220 for (auto& c : cameraStatuses) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200221 onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800222
223 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
224 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200225 c.deviceId, c.cameraId, unavailablePhysicalId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800226 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800227 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800228
229 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800230 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
231 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800232
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800233 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000234 if (0 < desc->getTagCount()) {
235 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
236 if (err != OK) {
237 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
238 __FUNCTION__, strerror(-err), err);
239 }
240 } else {
241 sp<VendorTagDescriptorCache> cache =
242 new VendorTagDescriptorCache();
243 binder::Status res =
244 mCameraService->getCameraVendorTagCache(
245 /*out*/cache.get());
246 if (res.serviceSpecificErrorCode() ==
247 hardware::ICameraService::ERROR_DISCONNECTED) {
248 // No camera module available, not an error on devices with no cameras
249 VendorTagDescriptorCache::clearGlobalVendorTagCache();
250 } else if (res.isOk()) {
251 status_t err =
252 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
253 cache);
254 if (err != OK) {
255 ALOGE("%s: Failed to set vendor tag cache,"
256 "received error %s (%d)", __FUNCTION__,
257 strerror(-err), err);
258 }
259 } else {
260 VendorTagDescriptorCache::clearGlobalVendorTagCache();
261 ALOGE("%s: Failed to setup vendor tag cache: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000262 __FUNCTION__, res.toString8().c_str());
Emilian Peev71c73a22017-03-21 16:35:51 +0000263 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800264 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800265 } else if (ret.serviceSpecificErrorCode() ==
266 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800267 ALOGW("%s: Camera HAL too old; does not support vendor tags",
268 __FUNCTION__);
269 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
270 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800271 ALOGE("%s: Failed to get vendor tag descriptors: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000272 __FUNCTION__, ret.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800273 }
274 }
275 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
276 return mCameraService;
277}
278
279void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
280{
281 ALOGE("Camera service binderDied!");
282 sp<CameraManagerGlobal> cm = mCameraManager.promote();
283 if (cm != nullptr) {
284 AutoMutex lock(cm->mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200285 std::vector<DeviceStatusMapKey> keysToRemove;
286 keysToRemove.reserve(cm->mDeviceStatusMap.size());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800287 for (auto& pair : cm->mDeviceStatusMap) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200288 keysToRemove.push_back(pair.first);
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000289 }
290
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200291 for (const DeviceStatusMapKey& key : keysToRemove) {
292 cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId,
293 key.cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800294 }
295 cm->mCameraService.clear();
296 // TODO: consider adding re-connect call here?
297 }
298}
299
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800300void CameraManagerGlobal::registerExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200301 const DeviceContext& deviceContext,
302 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
303 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext,
304 callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800305}
306
307void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200308 const DeviceContext& deviceContext,
309 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800310 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700311
312 drainPendingCallbacksLocked();
313
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200314 Callback cb(deviceContext, callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800315 mCallbacks.erase(cb);
316}
317
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800318void CameraManagerGlobal::registerAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200319 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
320 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800321}
322
323void CameraManagerGlobal::unregisterAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200324 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800325 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700326
327 drainPendingCallbacksLocked();
328
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200329 Callback cb(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800330 mCallbacks.erase(cb);
331}
332
Shuzhen Wang7e540682020-04-10 13:30:25 -0700333void CameraManagerGlobal::onCallbackCalled() {
334 Mutex::Autolock _l(mLock);
335 if (mPendingCallbackCnt > 0) {
336 mPendingCallbackCnt--;
337 }
338 mCallbacksCond.signal();
339}
340
341void CameraManagerGlobal::drainPendingCallbacksLocked() {
342 while (mPendingCallbackCnt > 0) {
343 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
344 if (res != NO_ERROR) {
345 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
346 __FUNCTION__, strerror(-res), res);
347 break;
348 }
349 }
350}
351
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200352template <class T>
353void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext,
354 const T* callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800355 Mutex::Autolock _l(mLock);
Kwangkyu Park01f84432023-09-15 17:08:17 +0900356 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200357 Callback cb(deviceContext, callback);
358 const auto& [_, newlyRegistered] = mCallbacks.insert(cb);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800359 // Send initial callbacks if callback is newly registered
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200360 if (newlyRegistered) {
361 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
362 if (!isCameraAccessible(deviceContext, key.deviceId)) {
363 continue;
364 }
365 const std::string& cameraId = key.cameraId;
366 int32_t status = statusAndHAL3Support.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700367 // Don't send initial callbacks for camera ids which don't support
368 // camera2
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200369 if (!statusAndHAL3Support.supportsHAL3) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700370 continue;
371 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800372
373 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800374 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800375 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
376 cb.mAvailable : cb.mUnavailable;
377 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
378 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700379 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700380 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800381 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800382
383 // Physical camera unavailable callback
Austin Borger0fb3ad92023-06-01 16:51:35 -0700384 std::set<std::string> unavailablePhysicalCameras =
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200385 statusAndHAL3Support.getUnavailablePhysicalIds();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800386 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
387 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
388 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
389 cb.mPhysicalCamUnavailable;
390 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
391 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700392 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
393 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700394 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800395 msg->post();
396 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800397 }
398 }
399}
400
Austin Borger0fb3ad92023-06-01 16:51:35 -0700401bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700402 bool camera2Support = false;
403 auto cs = getCameraServiceLocked();
404 binder::Status serviceRet =
Austin Borger0fb3ad92023-06-01 16:51:35 -0700405 cs->supportsCameraApi(cameraId,
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700406 hardware::ICameraService::API_VERSION_2, &camera2Support);
407 if (!serviceRet.isOk()) {
408 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
409 __FUNCTION__, cameraId.c_str());
410 return false;
411 }
412 return camera2Support;
413}
414
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200415void CameraManagerGlobal::getCameraIdList(const DeviceContext& context,
416 std::vector<std::string>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800417 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800418 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700419 // Needed to make sure we're connected to cameraservice
420 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200421 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
422 if (!isCameraAccessible(context, key.deviceId)) {
423 continue;
424 }
425
426 int32_t status = statusAndHAL3Support.getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800427 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
428 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800429 continue;
430 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200431 if (!statusAndHAL3Support.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800432 continue;
433 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200434 cameraIds->push_back(key.cameraId);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800435 }
436}
437
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800438bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800439 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800440 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
441 case hardware::ICameraServiceListener::STATUS_PRESENT:
442 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
443 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800444 return true;
445 default:
446 return false;
447 }
448}
449
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800450bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800451 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800452 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800453 return true;
454 default:
455 return false;
456 }
457}
458
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800459void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700460 const sp<AMessage> &msg) {
461 onMessageReceivedInternal(msg);
462 if (msg->what() == kWhatSendSingleCallback ||
463 msg->what() == kWhatSendSingleAccessCallback ||
464 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
465 notifyParent();
466 }
467}
468
469void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800470 const sp<AMessage> &msg) {
471 switch (msg->what()) {
472 case kWhatSendSingleCallback:
473 {
474 ACameraManager_AvailabilityCallback cb;
475 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800476 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800477 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
478 if (!found) {
479 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
480 return;
481 }
482 found = msg->findPointer(kContextKey, &context);
483 if (!found) {
484 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
485 return;
486 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800487 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800488 if (!found) {
489 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
490 return;
491 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800492 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800493 break;
494 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800495 case kWhatSendSingleAccessCallback:
496 {
497 ACameraManager_AccessPrioritiesChangedCallback cb;
498 void* context;
499 AString cameraId;
500 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
501 if (!found) {
502 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
503 return;
504 }
505 found = msg->findPointer(kContextKey, &context);
506 if (!found) {
507 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
508 return;
509 }
510 (*cb)(context);
511 break;
512 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800513 case kWhatSendSinglePhysicalCameraCallback:
514 {
515 ACameraManager_PhysicalCameraAvailabilityCallback cb;
516 void* context;
517 AString cameraId;
518 AString physicalCameraId;
519 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
520 if (!found) {
521 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
522 return;
523 }
524 if (cb == nullptr) {
525 // Physical camera callback is null
526 return;
527 }
528 found = msg->findPointer(kContextKey, &context);
529 if (!found) {
530 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
531 return;
532 }
533 found = msg->findString(kCameraIdKey, &cameraId);
534 if (!found) {
535 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
536 return;
537 }
538 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
539 if (!found) {
540 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
541 return;
542 }
543 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
544 break;
545 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800546 default:
547 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
548 break;
549 }
550}
551
Shuzhen Wang7e540682020-04-10 13:30:25 -0700552void CameraManagerGlobal::CallbackHandler::notifyParent() {
553 sp<CameraManagerGlobal> parent = mParent.promote();
554 if (parent != nullptr) {
555 parent->onCallbackCalled();
556 }
557}
558
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800559binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
560 sp<CameraManagerGlobal> cm = mCameraManager.promote();
561 if (cm != nullptr) {
562 cm->onCameraAccessPrioritiesChanged();
563 } else {
564 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
565 }
566 return binder::Status::ok();
567}
568
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800569binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000570 int32_t status, const std::string& cameraId, int deviceId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800571 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800572 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200573 cm->onStatusChanged(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800574 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200575 ALOGE_IF(cm == nullptr,
576 "Cannot deliver physical camera status change. Global camera manager died");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800577 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800578}
579
Shuzhen Wang43858162020-01-10 13:42:15 -0800580binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000581 int32_t status, const std::string& cameraId, const std::string& physicalCameraId,
582 int deviceId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800583 sp<CameraManagerGlobal> cm = mCameraManager.promote();
584 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200585 cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800586 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200587 ALOGE_IF(cm == nullptr,
588 "Cannot deliver physical camera status change. Global camera manager died");
Shuzhen Wang43858162020-01-10 13:42:15 -0800589 return binder::Status::ok();
590}
591
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800592void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
593 Mutex::Autolock _l(mLock);
594 for (auto cb : mCallbacks) {
595 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
596 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
597 if (cbFp != nullptr) {
598 msg->setPointer(kCallbackFpKey, (void *) cbFp);
599 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700600 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800601 msg->post();
602 }
603 }
604}
605
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200606void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
607 const std::string& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800608 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200609 onStatusChangedLocked(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800610}
611
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200612void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
613 const std::string& cameraId) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800614 if (!validStatus(status)) {
615 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
616 return;
617 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800618
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200619 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
620
621 bool firstStatus = (mDeviceStatusMap.count(key) == 0);
622 int32_t oldStatus = firstStatus ? status : // first status
623 mDeviceStatusMap[key].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800624
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800625 if (!firstStatus &&
626 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
627 // No status update. No need to send callback
628 return;
629 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800630
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700631 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800632 if (firstStatus) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200633 mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key),
634 std::forward_as_tuple(status, supportsHAL3));
Shuzhen Wang43858162020-01-10 13:42:15 -0800635 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200636 mDeviceStatusMap[key].updateStatus(status);
Shuzhen Wang43858162020-01-10 13:42:15 -0800637 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800638 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700639 if (supportsHAL3) {
640 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200641 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
642 continue;
643 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700644 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
645 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
646 cb.mAvailable : cb.mUnavailable;
647 msg->setPointer(kCallbackFpKey, (void *) cbFp);
648 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700649 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700650 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700651 msg->post();
652 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800653 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100654 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200655 mDeviceStatusMap.erase(key);
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100656 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800657}
658
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200659void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
660 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800661 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200662 onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800663}
664
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200665void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
666 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800667 if (!validStatus(status)) {
668 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
669 return;
670 }
671
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200672 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
673 auto logicalStatus = mDeviceStatusMap.find(key);
Shuzhen Wang43858162020-01-10 13:42:15 -0800674 if (logicalStatus == mDeviceStatusMap.end()) {
675 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
676 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
677 return;
678 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200679 int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800680 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
681 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
682 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700683 __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
Shuzhen Wang43858162020-01-10 13:42:15 -0800684 return;
685 }
686
687 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
688
689 bool updated = false;
690 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200691 updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800692 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200693 updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800694 }
695
696 // Iterate through all registered callbacks
697 if (supportsHAL3 && updated) {
698 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200699 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
700 continue;
701 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800702 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
703 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
704 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
705 msg->setPointer(kCallbackFpKey, (void *) cbFp);
706 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700707 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
708 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700709 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800710 msg->post();
711 }
712 }
713}
714
715int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
716 std::lock_guard<std::mutex> lock(mLock);
717 return status;
718}
719
720void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
721 std::lock_guard<std::mutex> lock(mLock);
722 status = newStatus;
723}
724
725bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700726 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800727 std::lock_guard<std::mutex> lock(mLock);
728 auto result = unavailablePhysicalIds.insert(physicalCameraId);
729 return result.second;
730}
731
732bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700733 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800734 std::lock_guard<std::mutex> lock(mLock);
735 auto count = unavailablePhysicalIds.erase(physicalCameraId);
736 return count > 0;
737}
738
Austin Borger0fb3ad92023-06-01 16:51:35 -0700739std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800740 std::lock_guard<std::mutex> lock(mLock);
741 return unavailablePhysicalIds;
742}
743
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800744} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800745} // namespace android
746
747/**
748 * ACameraManger Implementation
749 */
750camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800751ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
752 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800753
Austin Borger0fb3ad92023-06-01 16:51:35 -0700754 std::vector<std::string> idList;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200755 mGlobalManager->getCameraIdList(mDeviceContext, &idList);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800756
757 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800758 ACameraIdList *out = new ACameraIdList;
759 if (!out) {
760 ALOGE("Allocate memory for ACameraIdList failed!");
761 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
762 }
763 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800764 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800765 if (!out->cameraIds) {
766 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800767 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800768 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
769 }
770 for (int i = 0; i < numCameras; i++) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700771 const char* src = idList[i].c_str();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800772 size_t dstSize = strlen(src) + 1;
773 char* dst = new char[dstSize];
774 if (!dst) {
775 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800776 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800777 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
778 }
779 strlcpy(dst, src, dstSize);
780 out->cameraIds[i] = dst;
781 }
782 *cameraIdList = out;
783 return ACAMERA_OK;
784}
785
786void
787ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
788 if (cameraIdList != nullptr) {
789 if (cameraIdList->cameraIds != nullptr) {
790 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800791 if (cameraIdList->cameraIds[i] != nullptr) {
792 delete[] cameraIdList->cameraIds[i];
793 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800794 }
795 delete[] cameraIdList->cameraIds;
796 }
797 delete cameraIdList;
798 }
799}
800
801camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700802 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800803 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800804
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200805 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800806 if (cs == nullptr) {
807 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
808 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
809 }
Austin Borger3560b7e2022-10-27 12:20:29 -0700810
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800811 CameraMetadata rawMetadata;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700812 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700813
814 AttributionSourceState clientAttribution;
815 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
816 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
817 clientAttribution.deviceId = mDeviceContext.deviceId;
818
Austin Borger0fb3ad92023-06-01 16:51:35 -0700819 binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000820 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700821 clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
Biswarup Pal37a75182024-01-16 15:53:35 +0000822 &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800823 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800824 switch(serviceRet.serviceSpecificErrorCode()) {
825 case hardware::ICameraService::ERROR_DISCONNECTED:
826 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
827 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
828 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
829 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
830 return ACAMERA_ERROR_INVALID_PARAMETER;
831 default:
832 ALOGE("Get camera characteristics from camera service failed: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000833 serviceRet.toString8().c_str());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800834 return ACAMERA_ERROR_UNKNOWN; // should not reach here
835 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800836 }
837
838 *characteristics = new ACameraMetadata(
839 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
840 return ACAMERA_OK;
841}
842
843camera_status_t
844ACameraManager::openCamera(
845 const char* cameraId,
846 ACameraDevice_StateCallbacks* callback,
847 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700848 sp<ACameraMetadata> chars;
849 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800850 Mutex::Autolock _l(mLock);
851 if (ret != ACAMERA_OK) {
852 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
853 __FUNCTION__, cameraId, ret);
854 return ACAMERA_ERROR_INVALID_PARAMETER;
855 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800856
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700857 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800858
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200859 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800860 if (cs == nullptr) {
861 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700862 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800863 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
864 }
865
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800866 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
867 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700868 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700869
870 AttributionSourceState clientAttribution;
871 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
872 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
873 clientAttribution.deviceId = mDeviceContext.deviceId;
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700874 clientAttribution.packageName = "";
875 clientAttribution.attributionTag = std::nullopt;
Austin Borger65e64642024-06-11 15:58:23 -0700876
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800877 // No way to get package name from native.
878 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800879 binder::Status serviceRet = cs->connectDevice(
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700880 callbacks, cameraId, /*oomScoreOffset*/0,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000881 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700882 clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
Biswarup Pal37a75182024-01-16 15:53:35 +0000883 /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800884
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800885 if (!serviceRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000886 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().c_str());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700887 // Convert serviceRet to camera_status_t
888 switch(serviceRet.serviceSpecificErrorCode()) {
889 case hardware::ICameraService::ERROR_DISCONNECTED:
890 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
891 break;
892 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
893 ret = ACAMERA_ERROR_CAMERA_IN_USE;
894 break;
895 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
896 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
897 break;
898 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
899 ret = ACAMERA_ERROR_INVALID_PARAMETER;
900 break;
901 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
902 // Should not reach here since we filtered legacy HALs earlier
903 ret = ACAMERA_ERROR_INVALID_PARAMETER;
904 break;
905 case hardware::ICameraService::ERROR_DISABLED:
906 ret = ACAMERA_ERROR_CAMERA_DISABLED;
907 break;
908 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
909 ret = ACAMERA_ERROR_PERMISSION_DENIED;
910 break;
911 case hardware::ICameraService::ERROR_INVALID_OPERATION:
912 default:
913 ret = ACAMERA_ERROR_UNKNOWN;
914 break;
915 }
916
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800917 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700918 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800919 }
920 if (deviceRemote == nullptr) {
921 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
922 delete device;
923 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
924 }
925 device->setRemoteDevice(deviceRemote);
926 *outDevice = device;
927 return ACAMERA_OK;
928}
929
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200930void ACameraManager::registerAvailabilityCallback(
931 const ACameraManager_AvailabilityCallbacks* callback) {
932 mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback);
933}
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800934
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200935void ACameraManager::unregisterAvailabilityCallback(
936 const ACameraManager_AvailabilityCallbacks* callback) {
937 mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback);
938}
939
940void ACameraManager::registerExtendedAvailabilityCallback(
941 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
942 mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback);
943}
944
945void ACameraManager::unregisterExtendedAvailabilityCallback(
946 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
947 mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800948}