blob: 6d29ef52e193145cf035a509b124f52db1f91ee1 [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;
Ankit Siddhapura959b7be2024-04-16 13:07:42 +0530180 binder = sm->checkService(String16(kCameraServiceName));
181 if (binder == nullptr) {
182 ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
183 return nullptr;
184 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800185 if (mDeathNotifier == nullptr) {
186 mDeathNotifier = new DeathNotifier(this);
187 }
188 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800189 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800190
191 // Setup looper thread to perfrom availiability callbacks
192 if (mCbLooper == nullptr) {
193 mCbLooper = new ALooper;
194 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800195 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800196 /*runOnCallingThread*/false,
197 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800198 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800199 if (err != OK) {
200 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
201 __FUNCTION__, strerror(-err), err);
202 mCbLooper.clear();
203 return nullptr;
204 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800205 if (mHandler == nullptr) {
Shuzhen Wang7e540682020-04-10 13:30:25 -0700206 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800207 }
208 mCbLooper->registerHandler(mHandler);
209 }
210
211 // register ICameraServiceListener
212 if (mCameraServiceListener == nullptr) {
213 mCameraServiceListener = new CameraServiceListener(this);
214 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800215 std::vector<hardware::CameraStatus> cameraStatuses{};
216 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
217 for (auto& c : cameraStatuses) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200218 onStatusChangedLocked(c.status, c.deviceId, c.cameraId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800219
220 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
221 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200222 c.deviceId, c.cameraId, unavailablePhysicalId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800223 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800224 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800225
226 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800227 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
228 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800229
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800230 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000231 if (0 < desc->getTagCount()) {
232 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
233 if (err != OK) {
234 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
235 __FUNCTION__, strerror(-err), err);
236 }
237 } else {
238 sp<VendorTagDescriptorCache> cache =
239 new VendorTagDescriptorCache();
240 binder::Status res =
241 mCameraService->getCameraVendorTagCache(
242 /*out*/cache.get());
243 if (res.serviceSpecificErrorCode() ==
244 hardware::ICameraService::ERROR_DISCONNECTED) {
245 // No camera module available, not an error on devices with no cameras
246 VendorTagDescriptorCache::clearGlobalVendorTagCache();
247 } else if (res.isOk()) {
248 status_t err =
249 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
250 cache);
251 if (err != OK) {
252 ALOGE("%s: Failed to set vendor tag cache,"
253 "received error %s (%d)", __FUNCTION__,
254 strerror(-err), err);
255 }
256 } else {
257 VendorTagDescriptorCache::clearGlobalVendorTagCache();
258 ALOGE("%s: Failed to setup vendor tag cache: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000259 __FUNCTION__, res.toString8().c_str());
Emilian Peev71c73a22017-03-21 16:35:51 +0000260 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800261 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800262 } else if (ret.serviceSpecificErrorCode() ==
263 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800264 ALOGW("%s: Camera HAL too old; does not support vendor tags",
265 __FUNCTION__);
266 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
267 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800268 ALOGE("%s: Failed to get vendor tag descriptors: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000269 __FUNCTION__, ret.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800270 }
271 }
272 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
273 return mCameraService;
274}
275
276void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
277{
278 ALOGE("Camera service binderDied!");
279 sp<CameraManagerGlobal> cm = mCameraManager.promote();
280 if (cm != nullptr) {
281 AutoMutex lock(cm->mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200282 std::vector<DeviceStatusMapKey> keysToRemove;
283 keysToRemove.reserve(cm->mDeviceStatusMap.size());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800284 for (auto& pair : cm->mDeviceStatusMap) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200285 keysToRemove.push_back(pair.first);
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000286 }
287
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200288 for (const DeviceStatusMapKey& key : keysToRemove) {
289 cm->onStatusChangedLocked(CameraServiceListener::STATUS_NOT_PRESENT, key.deviceId,
290 key.cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800291 }
292 cm->mCameraService.clear();
293 // TODO: consider adding re-connect call here?
294 }
295}
296
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800297void CameraManagerGlobal::registerExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200298 const DeviceContext& deviceContext,
299 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
300 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(deviceContext,
301 callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800302}
303
304void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200305 const DeviceContext& deviceContext,
306 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800307 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700308
309 drainPendingCallbacksLocked();
310
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200311 Callback cb(deviceContext, callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800312 mCallbacks.erase(cb);
313}
314
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800315void CameraManagerGlobal::registerAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200316 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
317 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800318}
319
320void CameraManagerGlobal::unregisterAvailabilityCallback(
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200321 const DeviceContext& deviceContext, const ACameraManager_AvailabilityCallbacks* callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800322 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700323
324 drainPendingCallbacksLocked();
325
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200326 Callback cb(deviceContext, callback);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800327 mCallbacks.erase(cb);
328}
329
Shuzhen Wang7e540682020-04-10 13:30:25 -0700330void CameraManagerGlobal::onCallbackCalled() {
331 Mutex::Autolock _l(mLock);
332 if (mPendingCallbackCnt > 0) {
333 mPendingCallbackCnt--;
334 }
335 mCallbacksCond.signal();
336}
337
338void CameraManagerGlobal::drainPendingCallbacksLocked() {
339 while (mPendingCallbackCnt > 0) {
340 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
341 if (res != NO_ERROR) {
342 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
343 __FUNCTION__, strerror(-res), res);
344 break;
345 }
346 }
347}
348
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200349template <class T>
350void CameraManagerGlobal::registerAvailCallback(const DeviceContext& deviceContext,
351 const T* callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800352 Mutex::Autolock _l(mLock);
Kwangkyu Park01f84432023-09-15 17:08:17 +0900353 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200354 Callback cb(deviceContext, callback);
355 const auto& [_, newlyRegistered] = mCallbacks.insert(cb);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800356 // Send initial callbacks if callback is newly registered
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200357 if (newlyRegistered) {
358 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
359 if (!isCameraAccessible(deviceContext, key.deviceId)) {
360 continue;
361 }
362 const std::string& cameraId = key.cameraId;
363 int32_t status = statusAndHAL3Support.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700364 // Don't send initial callbacks for camera ids which don't support
365 // camera2
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200366 if (!statusAndHAL3Support.supportsHAL3) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700367 continue;
368 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800369
370 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800371 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800372 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
373 cb.mAvailable : cb.mUnavailable;
374 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
375 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700376 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700377 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800378 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800379
380 // Physical camera unavailable callback
Austin Borger0fb3ad92023-06-01 16:51:35 -0700381 std::set<std::string> unavailablePhysicalCameras =
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200382 statusAndHAL3Support.getUnavailablePhysicalIds();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800383 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
384 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
385 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
386 cb.mPhysicalCamUnavailable;
387 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
388 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700389 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
390 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700391 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800392 msg->post();
393 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800394 }
395 }
396}
397
Austin Borger0fb3ad92023-06-01 16:51:35 -0700398bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700399 bool camera2Support = false;
400 auto cs = getCameraServiceLocked();
401 binder::Status serviceRet =
Austin Borger0fb3ad92023-06-01 16:51:35 -0700402 cs->supportsCameraApi(cameraId,
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700403 hardware::ICameraService::API_VERSION_2, &camera2Support);
404 if (!serviceRet.isOk()) {
405 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
406 __FUNCTION__, cameraId.c_str());
407 return false;
408 }
409 return camera2Support;
410}
411
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200412void CameraManagerGlobal::getCameraIdList(const DeviceContext& context,
413 std::vector<std::string>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800414 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800415 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700416 // Needed to make sure we're connected to cameraservice
417 getCameraServiceLocked();
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200418 for (auto& [key, statusAndHAL3Support] : mDeviceStatusMap) {
419 if (!isCameraAccessible(context, key.deviceId)) {
420 continue;
421 }
422
423 int32_t status = statusAndHAL3Support.getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800424 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
425 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800426 continue;
427 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200428 if (!statusAndHAL3Support.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800429 continue;
430 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200431 cameraIds->push_back(key.cameraId);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800432 }
433}
434
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800435bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800436 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800437 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
438 case hardware::ICameraServiceListener::STATUS_PRESENT:
439 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
440 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800441 return true;
442 default:
443 return false;
444 }
445}
446
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800447bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800448 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800449 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800450 return true;
451 default:
452 return false;
453 }
454}
455
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800456void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700457 const sp<AMessage> &msg) {
458 onMessageReceivedInternal(msg);
459 if (msg->what() == kWhatSendSingleCallback ||
460 msg->what() == kWhatSendSingleAccessCallback ||
461 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
462 notifyParent();
463 }
464}
465
466void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800467 const sp<AMessage> &msg) {
468 switch (msg->what()) {
469 case kWhatSendSingleCallback:
470 {
471 ACameraManager_AvailabilityCallback cb;
472 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800473 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800474 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
475 if (!found) {
476 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
477 return;
478 }
479 found = msg->findPointer(kContextKey, &context);
480 if (!found) {
481 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
482 return;
483 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800484 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800485 if (!found) {
486 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
487 return;
488 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800489 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800490 break;
491 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800492 case kWhatSendSingleAccessCallback:
493 {
494 ACameraManager_AccessPrioritiesChangedCallback cb;
495 void* context;
496 AString cameraId;
497 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
498 if (!found) {
499 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
500 return;
501 }
502 found = msg->findPointer(kContextKey, &context);
503 if (!found) {
504 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
505 return;
506 }
507 (*cb)(context);
508 break;
509 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800510 case kWhatSendSinglePhysicalCameraCallback:
511 {
512 ACameraManager_PhysicalCameraAvailabilityCallback cb;
513 void* context;
514 AString cameraId;
515 AString physicalCameraId;
516 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
517 if (!found) {
518 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
519 return;
520 }
521 if (cb == nullptr) {
522 // Physical camera callback is null
523 return;
524 }
525 found = msg->findPointer(kContextKey, &context);
526 if (!found) {
527 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
528 return;
529 }
530 found = msg->findString(kCameraIdKey, &cameraId);
531 if (!found) {
532 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
533 return;
534 }
535 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
536 if (!found) {
537 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
538 return;
539 }
540 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
541 break;
542 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800543 default:
544 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
545 break;
546 }
547}
548
Shuzhen Wang7e540682020-04-10 13:30:25 -0700549void CameraManagerGlobal::CallbackHandler::notifyParent() {
550 sp<CameraManagerGlobal> parent = mParent.promote();
551 if (parent != nullptr) {
552 parent->onCallbackCalled();
553 }
554}
555
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800556binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
557 sp<CameraManagerGlobal> cm = mCameraManager.promote();
558 if (cm != nullptr) {
559 cm->onCameraAccessPrioritiesChanged();
560 } else {
561 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
562 }
563 return binder::Status::ok();
564}
565
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800566binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000567 int32_t status, const std::string& cameraId, int deviceId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800568 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800569 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200570 cm->onStatusChanged(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800571 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200572 ALOGE_IF(cm == nullptr,
573 "Cannot deliver physical camera status change. Global camera manager died");
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800574 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800575}
576
Shuzhen Wang43858162020-01-10 13:42:15 -0800577binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
Biswarup Pal37a75182024-01-16 15:53:35 +0000578 int32_t status, const std::string& cameraId, const std::string& physicalCameraId,
579 int deviceId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800580 sp<CameraManagerGlobal> cm = mCameraManager.promote();
581 if (cm != nullptr) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200582 cm->onStatusChanged(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800583 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200584 ALOGE_IF(cm == nullptr,
585 "Cannot deliver physical camera status change. Global camera manager died");
Shuzhen Wang43858162020-01-10 13:42:15 -0800586 return binder::Status::ok();
587}
588
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800589void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
590 Mutex::Autolock _l(mLock);
591 for (auto cb : mCallbacks) {
592 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
593 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
594 if (cbFp != nullptr) {
595 msg->setPointer(kCallbackFpKey, (void *) cbFp);
596 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700597 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800598 msg->post();
599 }
600 }
601}
602
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200603void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
604 const std::string& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800605 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200606 onStatusChangedLocked(status, deviceId, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800607}
608
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200609void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
610 const std::string& cameraId) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800611 if (!validStatus(status)) {
612 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
613 return;
614 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800615
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200616 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
617
618 bool firstStatus = (mDeviceStatusMap.count(key) == 0);
619 int32_t oldStatus = firstStatus ? status : // first status
620 mDeviceStatusMap[key].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800621
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800622 if (!firstStatus &&
623 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
624 // No status update. No need to send callback
625 return;
626 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800627
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700628 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800629 if (firstStatus) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200630 mDeviceStatusMap.emplace(std::piecewise_construct, std::forward_as_tuple(key),
631 std::forward_as_tuple(status, supportsHAL3));
Shuzhen Wang43858162020-01-10 13:42:15 -0800632 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200633 mDeviceStatusMap[key].updateStatus(status);
Shuzhen Wang43858162020-01-10 13:42:15 -0800634 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800635 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700636 if (supportsHAL3) {
637 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200638 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
639 continue;
640 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700641 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
642 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
643 cb.mAvailable : cb.mUnavailable;
644 msg->setPointer(kCallbackFpKey, (void *) cbFp);
645 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700646 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700647 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700648 msg->post();
649 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800650 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100651 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200652 mDeviceStatusMap.erase(key);
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100653 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800654}
655
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200656void CameraManagerGlobal::onStatusChanged(int32_t status, const int deviceId,
657 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800658 Mutex::Autolock _l(mLock);
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200659 onStatusChangedLocked(status, deviceId, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800660}
661
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200662void CameraManagerGlobal::onStatusChangedLocked(int32_t status, const int deviceId,
663 const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800664 if (!validStatus(status)) {
665 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
666 return;
667 }
668
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200669 DeviceStatusMapKey key{.deviceId = deviceId, .cameraId = cameraId};
670 auto logicalStatus = mDeviceStatusMap.find(key);
Shuzhen Wang43858162020-01-10 13:42:15 -0800671 if (logicalStatus == mDeviceStatusMap.end()) {
672 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
673 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
674 return;
675 }
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200676 int32_t logicalCamStatus = mDeviceStatusMap[key].getStatus();
Shuzhen Wang43858162020-01-10 13:42:15 -0800677 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
678 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
679 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700680 __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
Shuzhen Wang43858162020-01-10 13:42:15 -0800681 return;
682 }
683
684 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
685
686 bool updated = false;
687 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200688 updated = mDeviceStatusMap[key].removeUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800689 } else {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200690 updated = mDeviceStatusMap[key].addUnavailablePhysicalId(physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800691 }
692
693 // Iterate through all registered callbacks
694 if (supportsHAL3 && updated) {
695 for (auto cb : mCallbacks) {
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200696 if (!isCameraAccessible(cb.mDeviceContext, deviceId)) {
697 continue;
698 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800699 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
700 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
701 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
702 msg->setPointer(kCallbackFpKey, (void *) cbFp);
703 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700704 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
705 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700706 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800707 msg->post();
708 }
709 }
710}
711
712int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
713 std::lock_guard<std::mutex> lock(mLock);
714 return status;
715}
716
717void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
718 std::lock_guard<std::mutex> lock(mLock);
719 status = newStatus;
720}
721
722bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700723 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800724 std::lock_guard<std::mutex> lock(mLock);
725 auto result = unavailablePhysicalIds.insert(physicalCameraId);
726 return result.second;
727}
728
729bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700730 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800731 std::lock_guard<std::mutex> lock(mLock);
732 auto count = unavailablePhysicalIds.erase(physicalCameraId);
733 return count > 0;
734}
735
Austin Borger0fb3ad92023-06-01 16:51:35 -0700736std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800737 std::lock_guard<std::mutex> lock(mLock);
738 return unavailablePhysicalIds;
739}
740
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800741} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800742} // namespace android
743
744/**
745 * ACameraManger Implementation
746 */
747camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800748ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
749 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800750
Austin Borger0fb3ad92023-06-01 16:51:35 -0700751 std::vector<std::string> idList;
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200752 mGlobalManager->getCameraIdList(mDeviceContext, &idList);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800753
754 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800755 ACameraIdList *out = new ACameraIdList;
756 if (!out) {
757 ALOGE("Allocate memory for ACameraIdList failed!");
758 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
759 }
760 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800761 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800762 if (!out->cameraIds) {
763 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800764 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800765 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
766 }
767 for (int i = 0; i < numCameras; i++) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700768 const char* src = idList[i].c_str();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800769 size_t dstSize = strlen(src) + 1;
770 char* dst = new char[dstSize];
771 if (!dst) {
772 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800773 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800774 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
775 }
776 strlcpy(dst, src, dstSize);
777 out->cameraIds[i] = dst;
778 }
779 *cameraIdList = out;
780 return ACAMERA_OK;
781}
782
783void
784ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
785 if (cameraIdList != nullptr) {
786 if (cameraIdList->cameraIds != nullptr) {
787 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800788 if (cameraIdList->cameraIds[i] != nullptr) {
789 delete[] cameraIdList->cameraIds[i];
790 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800791 }
792 delete[] cameraIdList->cameraIds;
793 }
794 delete cameraIdList;
795 }
796}
797
798camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700799 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800800 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800801
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200802 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800803 if (cs == nullptr) {
804 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
805 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
806 }
Austin Borger3560b7e2022-10-27 12:20:29 -0700807
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800808 CameraMetadata rawMetadata;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700809 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700810
811 AttributionSourceState clientAttribution;
812 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
813 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
814 clientAttribution.deviceId = mDeviceContext.deviceId;
815
Austin Borger0fb3ad92023-06-01 16:51:35 -0700816 binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000817 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700818 clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
Biswarup Pal37a75182024-01-16 15:53:35 +0000819 &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800820 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800821 switch(serviceRet.serviceSpecificErrorCode()) {
822 case hardware::ICameraService::ERROR_DISCONNECTED:
823 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
824 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
825 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
826 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
827 return ACAMERA_ERROR_INVALID_PARAMETER;
828 default:
829 ALOGE("Get camera characteristics from camera service failed: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000830 serviceRet.toString8().c_str());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800831 return ACAMERA_ERROR_UNKNOWN; // should not reach here
832 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800833 }
834
835 *characteristics = new ACameraMetadata(
836 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
837 return ACAMERA_OK;
838}
839
840camera_status_t
841ACameraManager::openCamera(
842 const char* cameraId,
843 ACameraDevice_StateCallbacks* callback,
844 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700845 sp<ACameraMetadata> chars;
846 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800847 Mutex::Autolock _l(mLock);
848 if (ret != ACAMERA_OK) {
849 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
850 __FUNCTION__, cameraId, ret);
851 return ACAMERA_ERROR_INVALID_PARAMETER;
852 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800853
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700854 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800855
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200856 sp<hardware::ICameraService> cs = mGlobalManager->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800857 if (cs == nullptr) {
858 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700859 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800860 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
861 }
862
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800863 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
864 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700865 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger65e64642024-06-11 15:58:23 -0700866
867 AttributionSourceState clientAttribution;
868 clientAttribution.uid = hardware::ICameraService::USE_CALLING_UID;
869 clientAttribution.pid = hardware::ICameraService::USE_CALLING_PID;
870 clientAttribution.deviceId = mDeviceContext.deviceId;
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700871 clientAttribution.packageName = "";
872 clientAttribution.attributionTag = std::nullopt;
Austin Borger65e64642024-06-11 15:58:23 -0700873
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800874 // No way to get package name from native.
875 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800876 binder::Status serviceRet = cs->connectDevice(
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700877 callbacks, cameraId, /*oomScoreOffset*/0,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000878 targetSdkVersion, /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700879 clientAttribution, static_cast<int32_t>(mDeviceContext.policy),
Biswarup Pal37a75182024-01-16 15:53:35 +0000880 /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800881
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800882 if (!serviceRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000883 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().c_str());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700884 // Convert serviceRet to camera_status_t
885 switch(serviceRet.serviceSpecificErrorCode()) {
886 case hardware::ICameraService::ERROR_DISCONNECTED:
887 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
888 break;
889 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
890 ret = ACAMERA_ERROR_CAMERA_IN_USE;
891 break;
892 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
893 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
894 break;
895 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
896 ret = ACAMERA_ERROR_INVALID_PARAMETER;
897 break;
898 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
899 // Should not reach here since we filtered legacy HALs earlier
900 ret = ACAMERA_ERROR_INVALID_PARAMETER;
901 break;
902 case hardware::ICameraService::ERROR_DISABLED:
903 ret = ACAMERA_ERROR_CAMERA_DISABLED;
904 break;
905 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
906 ret = ACAMERA_ERROR_PERMISSION_DENIED;
907 break;
908 case hardware::ICameraService::ERROR_INVALID_OPERATION:
909 default:
910 ret = ACAMERA_ERROR_UNKNOWN;
911 break;
912 }
913
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800914 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700915 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800916 }
917 if (deviceRemote == nullptr) {
918 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
919 delete device;
920 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
921 }
922 device->setRemoteDevice(deviceRemote);
923 *outDevice = device;
924 return ACAMERA_OK;
925}
926
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200927void ACameraManager::registerAvailabilityCallback(
928 const ACameraManager_AvailabilityCallbacks* callback) {
929 mGlobalManager->registerAvailabilityCallback(mDeviceContext, callback);
930}
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800931
Jan Sebechlebsky952e3c42024-04-05 13:13:11 +0200932void ACameraManager::unregisterAvailabilityCallback(
933 const ACameraManager_AvailabilityCallbacks* callback) {
934 mGlobalManager->unregisterAvailabilityCallback(mDeviceContext, callback);
935}
936
937void ACameraManager::registerExtendedAvailabilityCallback(
938 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
939 mGlobalManager->registerExtendedAvailabilityCallback(mDeviceContext, callback);
940}
941
942void ACameraManager::unregisterExtendedAvailabilityCallback(
943 const ACameraManager_ExtendedAvailabilityCallbacks* callback) {
944 mGlobalManager->unregisterExtendedAvailabilityCallback(mDeviceContext, callback);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800945}