blob: 9dc262f42ba4a76404819c7a5e5dfab7c2a11691 [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
20#include <memory>
21#include "ACameraManager.h"
22#include "ACameraMetadata.h"
23#include "ACameraDevice.h"
24#include <utils/Vector.h>
Ivan Podogovee844a82016-09-15 11:32:41 +010025#include <cutils/properties.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080026#include <stdlib.h>
Jayant Chowdharyf5b9cc62020-09-08 16:25:17 -070027#include <camera/CameraUtils.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080028#include <camera/VendorTagDescriptor.h>
29
Jayant Chowdhary6df26072018-11-06 23:55:12 -080030using namespace android::acam;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080031
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080032namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080033namespace acam {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080034// Static member definitions
35const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
Shuzhen Wang43858162020-01-10 13:42:15 -080036const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080037const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
38const char* CameraManagerGlobal::kContextKey = "CallbackContext";
Shuzhen Wang7e540682020-04-10 13:30:25 -070039const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080040Mutex CameraManagerGlobal::sLock;
Avichal Rakeshf099b232022-10-27 15:44:50 -070041wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080042
Avichal Rakeshf099b232022-10-27 15:44:50 -070043sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080044 Mutex::Autolock _l(sLock);
Avichal Rakeshf099b232022-10-27 15:44:50 -070045 sp<CameraManagerGlobal> instance = sInstance.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080046 if (instance == nullptr) {
47 instance = new CameraManagerGlobal();
48 sInstance = instance;
49 }
Avichal Rakeshf099b232022-10-27 15:44:50 -070050 return instance;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080051}
52
53CameraManagerGlobal::~CameraManagerGlobal() {
54 // clear sInstance so next getInstance call knows to create a new one
55 Mutex::Autolock _sl(sLock);
56 sInstance = nullptr;
57 Mutex::Autolock _l(mLock);
58 if (mCameraService != nullptr) {
59 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -080060 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080061 }
62 mDeathNotifier.clear();
63 if (mCbLooper != nullptr) {
64 mCbLooper->unregisterHandler(mHandler->id());
65 mCbLooper->stop();
66 }
67 mCbLooper.clear();
68 mHandler.clear();
69 mCameraServiceListener.clear();
70 mCameraService.clear();
71}
72
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080073sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080074 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -070075 return getCameraServiceLocked();
76}
77
78sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080079 if (mCameraService.get() == nullptr) {
Jayant Chowdharyf5b9cc62020-09-08 16:25:17 -070080 if (CameraUtils::isCameraServiceDisabled()) {
Ivan Podogovee844a82016-09-15 11:32:41 +010081 return mCameraService;
82 }
83
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080084 sp<IServiceManager> sm = defaultServiceManager();
85 sp<IBinder> binder;
86 do {
87 binder = sm->getService(String16(kCameraServiceName));
88 if (binder != nullptr) {
89 break;
90 }
91 ALOGW("CameraService not published, waiting...");
92 usleep(kCameraServicePollDelay);
93 } while(true);
94 if (mDeathNotifier == nullptr) {
95 mDeathNotifier = new DeathNotifier(this);
96 }
97 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080098 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080099
100 // Setup looper thread to perfrom availiability callbacks
101 if (mCbLooper == nullptr) {
102 mCbLooper = new ALooper;
103 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800104 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800105 /*runOnCallingThread*/false,
106 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800107 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800108 if (err != OK) {
109 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
110 __FUNCTION__, strerror(-err), err);
111 mCbLooper.clear();
112 return nullptr;
113 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800114 if (mHandler == nullptr) {
Shuzhen Wang7e540682020-04-10 13:30:25 -0700115 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800116 }
117 mCbLooper->registerHandler(mHandler);
118 }
119
120 // register ICameraServiceListener
121 if (mCameraServiceListener == nullptr) {
122 mCameraServiceListener = new CameraServiceListener(this);
123 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800124 std::vector<hardware::CameraStatus> cameraStatuses{};
125 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
126 for (auto& c : cameraStatuses) {
127 onStatusChangedLocked(c.status, c.cameraId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800128
129 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
130 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
131 c.cameraId, unavailablePhysicalId);
132 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800133 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800134
135 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800136 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
137 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800138
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800139 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000140 if (0 < desc->getTagCount()) {
141 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
142 if (err != OK) {
143 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
144 __FUNCTION__, strerror(-err), err);
145 }
146 } else {
147 sp<VendorTagDescriptorCache> cache =
148 new VendorTagDescriptorCache();
149 binder::Status res =
150 mCameraService->getCameraVendorTagCache(
151 /*out*/cache.get());
152 if (res.serviceSpecificErrorCode() ==
153 hardware::ICameraService::ERROR_DISCONNECTED) {
154 // No camera module available, not an error on devices with no cameras
155 VendorTagDescriptorCache::clearGlobalVendorTagCache();
156 } else if (res.isOk()) {
157 status_t err =
158 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
159 cache);
160 if (err != OK) {
161 ALOGE("%s: Failed to set vendor tag cache,"
162 "received error %s (%d)", __FUNCTION__,
163 strerror(-err), err);
164 }
165 } else {
166 VendorTagDescriptorCache::clearGlobalVendorTagCache();
167 ALOGE("%s: Failed to setup vendor tag cache: %s",
168 __FUNCTION__, res.toString8().string());
169 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800170 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800171 } else if (ret.serviceSpecificErrorCode() ==
172 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800173 ALOGW("%s: Camera HAL too old; does not support vendor tags",
174 __FUNCTION__);
175 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
176 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800177 ALOGE("%s: Failed to get vendor tag descriptors: %s",
178 __FUNCTION__, ret.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800179 }
180 }
181 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
182 return mCameraService;
183}
184
185void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
186{
187 ALOGE("Camera service binderDied!");
188 sp<CameraManagerGlobal> cm = mCameraManager.promote();
189 if (cm != nullptr) {
190 AutoMutex lock(cm->mLock);
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000191 std::vector<String8> cameraIdList;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800192 for (auto& pair : cm->mDeviceStatusMap) {
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000193 cameraIdList.push_back(pair.first);
194 }
195
196 for (String8 cameraId : cameraIdList) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800197 cm->onStatusChangedLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800198 CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800199 }
200 cm->mCameraService.clear();
201 // TODO: consider adding re-connect call here?
202 }
203}
204
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800205void CameraManagerGlobal::registerExtendedAvailabilityCallback(
206 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800207 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800208}
209
210void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
211 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
212 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700213
214 drainPendingCallbacksLocked();
215
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800216 Callback cb(callback);
217 mCallbacks.erase(cb);
218}
219
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800220void CameraManagerGlobal::registerAvailabilityCallback(
221 const ACameraManager_AvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800222 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback);
223}
224
225void CameraManagerGlobal::unregisterAvailabilityCallback(
226 const ACameraManager_AvailabilityCallbacks *callback) {
227 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700228
229 drainPendingCallbacksLocked();
230
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800231 Callback cb(callback);
232 mCallbacks.erase(cb);
233}
234
Shuzhen Wang7e540682020-04-10 13:30:25 -0700235void CameraManagerGlobal::onCallbackCalled() {
236 Mutex::Autolock _l(mLock);
237 if (mPendingCallbackCnt > 0) {
238 mPendingCallbackCnt--;
239 }
240 mCallbacksCond.signal();
241}
242
243void CameraManagerGlobal::drainPendingCallbacksLocked() {
244 while (mPendingCallbackCnt > 0) {
245 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
246 if (res != NO_ERROR) {
247 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
248 __FUNCTION__, strerror(-res), res);
249 break;
250 }
251 }
252}
253
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800254template<class T>
255void CameraManagerGlobal::registerAvailCallback(const T *callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800256 Mutex::Autolock _l(mLock);
257 Callback cb(callback);
258 auto pair = mCallbacks.insert(cb);
259 // Send initial callbacks if callback is newly registered
260 if (pair.second) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800261 for (auto& pair : mDeviceStatusMap) {
262 const String8& cameraId = pair.first;
Shuzhen Wang43858162020-01-10 13:42:15 -0800263 int32_t status = pair.second.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700264 // Don't send initial callbacks for camera ids which don't support
265 // camera2
266 if (!pair.second.supportsHAL3) {
267 continue;
268 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800269
270 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800271 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800272 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
273 cb.mAvailable : cb.mUnavailable;
274 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
275 msg->setPointer(kContextKey, cb.mContext);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800276 msg->setString(kCameraIdKey, AString(cameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700277 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800278 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800279
280 // Physical camera unavailable callback
281 std::set<String8> unavailablePhysicalCameras =
282 pair.second.getUnavailablePhysicalIds();
283 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
284 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
285 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
286 cb.mPhysicalCamUnavailable;
287 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
288 msg->setPointer(kContextKey, cb.mContext);
289 msg->setString(kCameraIdKey, AString(cameraId));
290 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700291 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800292 msg->post();
293 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800294 }
295 }
296}
297
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700298bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
299 bool camera2Support = false;
300 auto cs = getCameraServiceLocked();
301 binder::Status serviceRet =
302 cs->supportsCameraApi(String16(cameraId),
303 hardware::ICameraService::API_VERSION_2, &camera2Support);
304 if (!serviceRet.isOk()) {
305 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
306 __FUNCTION__, cameraId.c_str());
307 return false;
308 }
309 return camera2Support;
310}
311
Yin-Chia Yeh03f55752018-03-14 15:28:02 -0700312void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800313 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800314 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700315 // Needed to make sure we're connected to cameraservice
316 getCameraServiceLocked();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800317 for(auto& deviceStatus : mDeviceStatusMap) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800318 int32_t status = deviceStatus.second.getStatus();
319 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
320 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800321 continue;
322 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700323 if (!deviceStatus.second.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800324 continue;
325 }
326 cameraIds->push_back(deviceStatus.first);
327 }
328}
329
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800330bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800331 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800332 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
333 case hardware::ICameraServiceListener::STATUS_PRESENT:
334 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
335 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800336 return true;
337 default:
338 return false;
339 }
340}
341
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800342bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800343 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800344 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800345 return true;
346 default:
347 return false;
348 }
349}
350
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800351void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700352 const sp<AMessage> &msg) {
353 onMessageReceivedInternal(msg);
354 if (msg->what() == kWhatSendSingleCallback ||
355 msg->what() == kWhatSendSingleAccessCallback ||
356 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
357 notifyParent();
358 }
359}
360
361void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800362 const sp<AMessage> &msg) {
363 switch (msg->what()) {
364 case kWhatSendSingleCallback:
365 {
366 ACameraManager_AvailabilityCallback cb;
367 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800368 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800369 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
370 if (!found) {
371 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
372 return;
373 }
374 found = msg->findPointer(kContextKey, &context);
375 if (!found) {
376 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
377 return;
378 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800379 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800380 if (!found) {
381 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
382 return;
383 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800384 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800385 break;
386 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800387 case kWhatSendSingleAccessCallback:
388 {
389 ACameraManager_AccessPrioritiesChangedCallback cb;
390 void* context;
391 AString cameraId;
392 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
393 if (!found) {
394 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
395 return;
396 }
397 found = msg->findPointer(kContextKey, &context);
398 if (!found) {
399 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
400 return;
401 }
402 (*cb)(context);
403 break;
404 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800405 case kWhatSendSinglePhysicalCameraCallback:
406 {
407 ACameraManager_PhysicalCameraAvailabilityCallback cb;
408 void* context;
409 AString cameraId;
410 AString physicalCameraId;
411 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
412 if (!found) {
413 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
414 return;
415 }
416 if (cb == nullptr) {
417 // Physical camera callback is null
418 return;
419 }
420 found = msg->findPointer(kContextKey, &context);
421 if (!found) {
422 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
423 return;
424 }
425 found = msg->findString(kCameraIdKey, &cameraId);
426 if (!found) {
427 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
428 return;
429 }
430 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
431 if (!found) {
432 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
433 return;
434 }
435 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
436 break;
437 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800438 default:
439 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
440 break;
441 }
442}
443
Shuzhen Wang7e540682020-04-10 13:30:25 -0700444void CameraManagerGlobal::CallbackHandler::notifyParent() {
445 sp<CameraManagerGlobal> parent = mParent.promote();
446 if (parent != nullptr) {
447 parent->onCallbackCalled();
448 }
449}
450
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800451binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
452 sp<CameraManagerGlobal> cm = mCameraManager.promote();
453 if (cm != nullptr) {
454 cm->onCameraAccessPrioritiesChanged();
455 } else {
456 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
457 }
458 return binder::Status::ok();
459}
460
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800461binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800462 int32_t status, const String16& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800463 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800464 if (cm != nullptr) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800465 cm->onStatusChanged(status, String8(cameraId));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800466 } else {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800467 ALOGE("Cannot deliver status change. Global camera manager died");
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800468 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800469 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800470}
471
Shuzhen Wang43858162020-01-10 13:42:15 -0800472binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
473 int32_t status, const String16& cameraId, const String16& physicalCameraId) {
474 sp<CameraManagerGlobal> cm = mCameraManager.promote();
475 if (cm != nullptr) {
476 cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
477 } else {
478 ALOGE("Cannot deliver physical camera status change. Global camera manager died");
479 }
480 return binder::Status::ok();
481}
482
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800483void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
484 Mutex::Autolock _l(mLock);
485 for (auto cb : mCallbacks) {
486 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
487 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
488 if (cbFp != nullptr) {
489 msg->setPointer(kCallbackFpKey, (void *) cbFp);
490 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700491 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800492 msg->post();
493 }
494 }
495}
496
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800497void CameraManagerGlobal::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800498 int32_t status, const String8& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800499 Mutex::Autolock _l(mLock);
500 onStatusChangedLocked(status, cameraId);
501}
502
503void CameraManagerGlobal::onStatusChangedLocked(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800504 int32_t status, const String8& cameraId) {
505 if (!validStatus(status)) {
506 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
507 return;
508 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800509
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800510 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
511 int32_t oldStatus = firstStatus ?
512 status : // first status
Shuzhen Wang43858162020-01-10 13:42:15 -0800513 mDeviceStatusMap[cameraId].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800514
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800515 if (!firstStatus &&
516 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
517 // No status update. No need to send callback
518 return;
519 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800520
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700521 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800522 if (firstStatus) {
523 mDeviceStatusMap.emplace(std::piecewise_construct,
524 std::forward_as_tuple(cameraId),
525 std::forward_as_tuple(status, supportsHAL3));
526 } else {
527 mDeviceStatusMap[cameraId].updateStatus(status);
528 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800529 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700530 if (supportsHAL3) {
531 for (auto cb : mCallbacks) {
532 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
533 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
534 cb.mAvailable : cb.mUnavailable;
535 msg->setPointer(kCallbackFpKey, (void *) cbFp);
536 msg->setPointer(kContextKey, cb.mContext);
537 msg->setString(kCameraIdKey, AString(cameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700538 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700539 msg->post();
540 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800541 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100542 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
543 mDeviceStatusMap.erase(cameraId);
544 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800545}
546
Shuzhen Wang43858162020-01-10 13:42:15 -0800547void CameraManagerGlobal::onStatusChanged(
548 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
549 Mutex::Autolock _l(mLock);
550 onStatusChangedLocked(status, cameraId, physicalCameraId);
551}
552
553void CameraManagerGlobal::onStatusChangedLocked(
554 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
555 if (!validStatus(status)) {
556 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
557 return;
558 }
559
560 auto logicalStatus = mDeviceStatusMap.find(cameraId);
561 if (logicalStatus == mDeviceStatusMap.end()) {
562 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
563 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
564 return;
565 }
566 int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
567 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
568 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
569 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
570 __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
571 return;
572 }
573
574 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
575
576 bool updated = false;
577 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
578 updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
579 } else {
580 updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
581 }
582
583 // Iterate through all registered callbacks
584 if (supportsHAL3 && updated) {
585 for (auto cb : mCallbacks) {
586 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
587 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
588 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
589 msg->setPointer(kCallbackFpKey, (void *) cbFp);
590 msg->setPointer(kContextKey, cb.mContext);
591 msg->setString(kCameraIdKey, AString(cameraId));
592 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700593 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800594 msg->post();
595 }
596 }
597}
598
599int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
600 std::lock_guard<std::mutex> lock(mLock);
601 return status;
602}
603
604void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
605 std::lock_guard<std::mutex> lock(mLock);
606 status = newStatus;
607}
608
609bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
610 const String8& physicalCameraId) {
611 std::lock_guard<std::mutex> lock(mLock);
612 auto result = unavailablePhysicalIds.insert(physicalCameraId);
613 return result.second;
614}
615
616bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
617 const String8& physicalCameraId) {
618 std::lock_guard<std::mutex> lock(mLock);
619 auto count = unavailablePhysicalIds.erase(physicalCameraId);
620 return count > 0;
621}
622
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800623std::set<String8> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
624 std::lock_guard<std::mutex> lock(mLock);
625 return unavailablePhysicalIds;
626}
627
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800628} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800629} // namespace android
630
631/**
632 * ACameraManger Implementation
633 */
634camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800635ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
636 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800637
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800638 std::vector<String8> idList;
Avichal Rakeshf099b232022-10-27 15:44:50 -0700639 CameraManagerGlobal::getInstance()->getCameraIdList(&idList);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800640
641 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800642 ACameraIdList *out = new ACameraIdList;
643 if (!out) {
644 ALOGE("Allocate memory for ACameraIdList failed!");
645 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
646 }
647 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800648 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800649 if (!out->cameraIds) {
650 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800651 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800652 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
653 }
654 for (int i = 0; i < numCameras; i++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800655 const char* src = idList[i].string();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800656 size_t dstSize = strlen(src) + 1;
657 char* dst = new char[dstSize];
658 if (!dst) {
659 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800660 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800661 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
662 }
663 strlcpy(dst, src, dstSize);
664 out->cameraIds[i] = dst;
665 }
666 *cameraIdList = out;
667 return ACAMERA_OK;
668}
669
670void
671ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
672 if (cameraIdList != nullptr) {
673 if (cameraIdList->cameraIds != nullptr) {
674 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800675 if (cameraIdList->cameraIds[i] != nullptr) {
676 delete[] cameraIdList->cameraIds[i];
677 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800678 }
679 delete[] cameraIdList->cameraIds;
680 }
681 delete cameraIdList;
682 }
683}
684
685camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700686 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800687 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800688
Avichal Rakeshf099b232022-10-27 15:44:50 -0700689 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800690 if (cs == nullptr) {
691 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
692 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
693 }
Austin Borger18b30a72022-10-27 12:20:29 -0700694
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800695 CameraMetadata rawMetadata;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700696 int targetSdkVersion = android_get_application_target_sdk_version();
697 binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr),
Austin Borger18b30a72022-10-27 12:20:29 -0700698 targetSdkVersion, /*overrideToPortrait*/true, &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800699 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800700 switch(serviceRet.serviceSpecificErrorCode()) {
701 case hardware::ICameraService::ERROR_DISCONNECTED:
702 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
703 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
704 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
705 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
706 return ACAMERA_ERROR_INVALID_PARAMETER;
707 default:
708 ALOGE("Get camera characteristics from camera service failed: %s",
709 serviceRet.toString8().string());
710 return ACAMERA_ERROR_UNKNOWN; // should not reach here
711 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800712 }
713
714 *characteristics = new ACameraMetadata(
715 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
716 return ACAMERA_OK;
717}
718
719camera_status_t
720ACameraManager::openCamera(
721 const char* cameraId,
722 ACameraDevice_StateCallbacks* callback,
723 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700724 sp<ACameraMetadata> chars;
725 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800726 Mutex::Autolock _l(mLock);
727 if (ret != ACAMERA_OK) {
728 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
729 __FUNCTION__, cameraId, ret);
730 return ACAMERA_ERROR_INVALID_PARAMETER;
731 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800732
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700733 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800734
Avichal Rakeshf099b232022-10-27 15:44:50 -0700735 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800736 if (cs == nullptr) {
737 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700738 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800739 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
740 }
741
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800742 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
743 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700744 int targetSdkVersion = android_get_application_target_sdk_version();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800745 // No way to get package name from native.
746 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800747 binder::Status serviceRet = cs->connectDevice(
Jooyung Hanb3f7cd22020-01-23 12:27:18 +0900748 callbacks, String16(cameraId), String16(""), {},
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700749 hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,
Austin Borger18b30a72022-10-27 12:20:29 -0700750 targetSdkVersion, /*overrideToPortrait*/true, /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800751
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800752 if (!serviceRet.isOk()) {
753 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700754 // Convert serviceRet to camera_status_t
755 switch(serviceRet.serviceSpecificErrorCode()) {
756 case hardware::ICameraService::ERROR_DISCONNECTED:
757 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
758 break;
759 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
760 ret = ACAMERA_ERROR_CAMERA_IN_USE;
761 break;
762 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
763 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
764 break;
765 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
766 ret = ACAMERA_ERROR_INVALID_PARAMETER;
767 break;
768 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
769 // Should not reach here since we filtered legacy HALs earlier
770 ret = ACAMERA_ERROR_INVALID_PARAMETER;
771 break;
772 case hardware::ICameraService::ERROR_DISABLED:
773 ret = ACAMERA_ERROR_CAMERA_DISABLED;
774 break;
775 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
776 ret = ACAMERA_ERROR_PERMISSION_DENIED;
777 break;
778 case hardware::ICameraService::ERROR_INVALID_OPERATION:
779 default:
780 ret = ACAMERA_ERROR_UNKNOWN;
781 break;
782 }
783
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800784 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700785 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800786 }
787 if (deviceRemote == nullptr) {
788 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
789 delete device;
790 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
791 }
792 device->setRemoteDevice(deviceRemote);
793 *outDevice = device;
794 return ACAMERA_OK;
795}
796
797ACameraManager::~ACameraManager() {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800798
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800799}