blob: 5892f1ad0f19c9d2498983fea7291379b8ef2834 [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;
41CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
42
43CameraManagerGlobal&
44CameraManagerGlobal::getInstance() {
45 Mutex::Autolock _l(sLock);
46 CameraManagerGlobal* instance = sInstance;
47 if (instance == nullptr) {
48 instance = new CameraManagerGlobal();
49 sInstance = instance;
50 }
51 return *instance;
52}
53
54CameraManagerGlobal::~CameraManagerGlobal() {
55 // clear sInstance so next getInstance call knows to create a new one
56 Mutex::Autolock _sl(sLock);
57 sInstance = nullptr;
58 Mutex::Autolock _l(mLock);
59 if (mCameraService != nullptr) {
60 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -080061 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080062 }
63 mDeathNotifier.clear();
64 if (mCbLooper != nullptr) {
65 mCbLooper->unregisterHandler(mHandler->id());
66 mCbLooper->stop();
67 }
68 mCbLooper.clear();
69 mHandler.clear();
70 mCameraServiceListener.clear();
71 mCameraService.clear();
72}
73
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080074sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080075 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -070076 return getCameraServiceLocked();
77}
78
79sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080080 if (mCameraService.get() == nullptr) {
Jayant Chowdharyf5b9cc62020-09-08 16:25:17 -070081 if (CameraUtils::isCameraServiceDisabled()) {
Ivan Podogovee844a82016-09-15 11:32:41 +010082 return mCameraService;
83 }
84
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080085 sp<IServiceManager> sm = defaultServiceManager();
86 sp<IBinder> binder;
87 do {
88 binder = sm->getService(String16(kCameraServiceName));
89 if (binder != nullptr) {
90 break;
91 }
92 ALOGW("CameraService not published, waiting...");
93 usleep(kCameraServicePollDelay);
94 } while(true);
95 if (mDeathNotifier == nullptr) {
96 mDeathNotifier = new DeathNotifier(this);
97 }
98 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080099 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800100
101 // Setup looper thread to perfrom availiability callbacks
102 if (mCbLooper == nullptr) {
103 mCbLooper = new ALooper;
104 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800105 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800106 /*runOnCallingThread*/false,
107 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800108 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800109 if (err != OK) {
110 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
111 __FUNCTION__, strerror(-err), err);
112 mCbLooper.clear();
113 return nullptr;
114 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800115 if (mHandler == nullptr) {
Shuzhen Wang7e540682020-04-10 13:30:25 -0700116 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800117 }
118 mCbLooper->registerHandler(mHandler);
119 }
120
121 // register ICameraServiceListener
122 if (mCameraServiceListener == nullptr) {
123 mCameraServiceListener = new CameraServiceListener(this);
124 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800125 std::vector<hardware::CameraStatus> cameraStatuses{};
126 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
127 for (auto& c : cameraStatuses) {
128 onStatusChangedLocked(c.status, c.cameraId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800129
130 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
131 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
132 c.cameraId, unavailablePhysicalId);
133 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800134 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800135
136 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800137 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
138 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800139
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800140 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000141 if (0 < desc->getTagCount()) {
142 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
143 if (err != OK) {
144 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
145 __FUNCTION__, strerror(-err), err);
146 }
147 } else {
148 sp<VendorTagDescriptorCache> cache =
149 new VendorTagDescriptorCache();
150 binder::Status res =
151 mCameraService->getCameraVendorTagCache(
152 /*out*/cache.get());
153 if (res.serviceSpecificErrorCode() ==
154 hardware::ICameraService::ERROR_DISCONNECTED) {
155 // No camera module available, not an error on devices with no cameras
156 VendorTagDescriptorCache::clearGlobalVendorTagCache();
157 } else if (res.isOk()) {
158 status_t err =
159 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
160 cache);
161 if (err != OK) {
162 ALOGE("%s: Failed to set vendor tag cache,"
163 "received error %s (%d)", __FUNCTION__,
164 strerror(-err), err);
165 }
166 } else {
167 VendorTagDescriptorCache::clearGlobalVendorTagCache();
168 ALOGE("%s: Failed to setup vendor tag cache: %s",
169 __FUNCTION__, res.toString8().string());
170 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800171 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800172 } else if (ret.serviceSpecificErrorCode() ==
173 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800174 ALOGW("%s: Camera HAL too old; does not support vendor tags",
175 __FUNCTION__);
176 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
177 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800178 ALOGE("%s: Failed to get vendor tag descriptors: %s",
179 __FUNCTION__, ret.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800180 }
181 }
182 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
183 return mCameraService;
184}
185
186void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
187{
188 ALOGE("Camera service binderDied!");
189 sp<CameraManagerGlobal> cm = mCameraManager.promote();
190 if (cm != nullptr) {
191 AutoMutex lock(cm->mLock);
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000192 std::vector<String8> cameraIdList;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800193 for (auto& pair : cm->mDeviceStatusMap) {
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000194 cameraIdList.push_back(pair.first);
195 }
196
197 for (String8 cameraId : cameraIdList) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800198 cm->onStatusChangedLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800199 CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800200 }
201 cm->mCameraService.clear();
202 // TODO: consider adding re-connect call here?
203 }
204}
205
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800206void CameraManagerGlobal::registerExtendedAvailabilityCallback(
207 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800208 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800209}
210
211void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
212 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
213 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700214
215 drainPendingCallbacksLocked();
216
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800217 Callback cb(callback);
218 mCallbacks.erase(cb);
219}
220
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800221void CameraManagerGlobal::registerAvailabilityCallback(
222 const ACameraManager_AvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800223 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback);
224}
225
226void CameraManagerGlobal::unregisterAvailabilityCallback(
227 const ACameraManager_AvailabilityCallbacks *callback) {
228 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700229
230 drainPendingCallbacksLocked();
231
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800232 Callback cb(callback);
233 mCallbacks.erase(cb);
234}
235
Shuzhen Wang7e540682020-04-10 13:30:25 -0700236void CameraManagerGlobal::onCallbackCalled() {
237 Mutex::Autolock _l(mLock);
238 if (mPendingCallbackCnt > 0) {
239 mPendingCallbackCnt--;
240 }
241 mCallbacksCond.signal();
242}
243
244void CameraManagerGlobal::drainPendingCallbacksLocked() {
245 while (mPendingCallbackCnt > 0) {
246 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
247 if (res != NO_ERROR) {
248 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
249 __FUNCTION__, strerror(-res), res);
250 break;
251 }
252 }
253}
254
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800255template<class T>
256void CameraManagerGlobal::registerAvailCallback(const T *callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800257 Mutex::Autolock _l(mLock);
258 Callback cb(callback);
259 auto pair = mCallbacks.insert(cb);
260 // Send initial callbacks if callback is newly registered
261 if (pair.second) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800262 for (auto& pair : mDeviceStatusMap) {
263 const String8& cameraId = pair.first;
Shuzhen Wang43858162020-01-10 13:42:15 -0800264 int32_t status = pair.second.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700265 // Don't send initial callbacks for camera ids which don't support
266 // camera2
267 if (!pair.second.supportsHAL3) {
268 continue;
269 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800270
271 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800272 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800273 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
274 cb.mAvailable : cb.mUnavailable;
275 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
276 msg->setPointer(kContextKey, cb.mContext);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800277 msg->setString(kCameraIdKey, AString(cameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700278 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800279 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800280
281 // Physical camera unavailable callback
282 std::set<String8> unavailablePhysicalCameras =
283 pair.second.getUnavailablePhysicalIds();
284 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
285 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
286 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
287 cb.mPhysicalCamUnavailable;
288 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
289 msg->setPointer(kContextKey, cb.mContext);
290 msg->setString(kCameraIdKey, AString(cameraId));
291 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700292 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800293 msg->post();
294 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800295 }
296 }
297}
298
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700299bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
300 bool camera2Support = false;
301 auto cs = getCameraServiceLocked();
302 binder::Status serviceRet =
303 cs->supportsCameraApi(String16(cameraId),
304 hardware::ICameraService::API_VERSION_2, &camera2Support);
305 if (!serviceRet.isOk()) {
306 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
307 __FUNCTION__, cameraId.c_str());
308 return false;
309 }
310 return camera2Support;
311}
312
Yin-Chia Yeh03f55752018-03-14 15:28:02 -0700313void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800314 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800315 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700316 // Needed to make sure we're connected to cameraservice
317 getCameraServiceLocked();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800318 for(auto& deviceStatus : mDeviceStatusMap) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800319 int32_t status = deviceStatus.second.getStatus();
320 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
321 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800322 continue;
323 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700324 if (!deviceStatus.second.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800325 continue;
326 }
327 cameraIds->push_back(deviceStatus.first);
328 }
329}
330
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800331bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800332 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800333 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
334 case hardware::ICameraServiceListener::STATUS_PRESENT:
335 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
336 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800337 return true;
338 default:
339 return false;
340 }
341}
342
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800343bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800344 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800345 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800346 return true;
347 default:
348 return false;
349 }
350}
351
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800352void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700353 const sp<AMessage> &msg) {
354 onMessageReceivedInternal(msg);
355 if (msg->what() == kWhatSendSingleCallback ||
356 msg->what() == kWhatSendSingleAccessCallback ||
357 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
358 notifyParent();
359 }
360}
361
362void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800363 const sp<AMessage> &msg) {
364 switch (msg->what()) {
365 case kWhatSendSingleCallback:
366 {
367 ACameraManager_AvailabilityCallback cb;
368 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800369 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800370 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
371 if (!found) {
372 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
373 return;
374 }
375 found = msg->findPointer(kContextKey, &context);
376 if (!found) {
377 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
378 return;
379 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800380 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800381 if (!found) {
382 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
383 return;
384 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800385 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800386 break;
387 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800388 case kWhatSendSingleAccessCallback:
389 {
390 ACameraManager_AccessPrioritiesChangedCallback cb;
391 void* context;
392 AString cameraId;
393 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
394 if (!found) {
395 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
396 return;
397 }
398 found = msg->findPointer(kContextKey, &context);
399 if (!found) {
400 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
401 return;
402 }
403 (*cb)(context);
404 break;
405 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800406 case kWhatSendSinglePhysicalCameraCallback:
407 {
408 ACameraManager_PhysicalCameraAvailabilityCallback cb;
409 void* context;
410 AString cameraId;
411 AString physicalCameraId;
412 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
413 if (!found) {
414 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
415 return;
416 }
417 if (cb == nullptr) {
418 // Physical camera callback is null
419 return;
420 }
421 found = msg->findPointer(kContextKey, &context);
422 if (!found) {
423 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
424 return;
425 }
426 found = msg->findString(kCameraIdKey, &cameraId);
427 if (!found) {
428 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
429 return;
430 }
431 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
432 if (!found) {
433 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
434 return;
435 }
436 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
437 break;
438 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800439 default:
440 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
441 break;
442 }
443}
444
Shuzhen Wang7e540682020-04-10 13:30:25 -0700445void CameraManagerGlobal::CallbackHandler::notifyParent() {
446 sp<CameraManagerGlobal> parent = mParent.promote();
447 if (parent != nullptr) {
448 parent->onCallbackCalled();
449 }
450}
451
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800452binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
453 sp<CameraManagerGlobal> cm = mCameraManager.promote();
454 if (cm != nullptr) {
455 cm->onCameraAccessPrioritiesChanged();
456 } else {
457 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
458 }
459 return binder::Status::ok();
460}
461
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800462binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800463 int32_t status, const String16& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800464 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800465 if (cm != nullptr) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800466 cm->onStatusChanged(status, String8(cameraId));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800467 } else {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800468 ALOGE("Cannot deliver status change. Global camera manager died");
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800469 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800470 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800471}
472
Shuzhen Wang43858162020-01-10 13:42:15 -0800473binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
474 int32_t status, const String16& cameraId, const String16& physicalCameraId) {
475 sp<CameraManagerGlobal> cm = mCameraManager.promote();
476 if (cm != nullptr) {
477 cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
478 } else {
479 ALOGE("Cannot deliver physical camera status change. Global camera manager died");
480 }
481 return binder::Status::ok();
482}
483
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800484void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
485 Mutex::Autolock _l(mLock);
486 for (auto cb : mCallbacks) {
487 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
488 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
489 if (cbFp != nullptr) {
490 msg->setPointer(kCallbackFpKey, (void *) cbFp);
491 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700492 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800493 msg->post();
494 }
495 }
496}
497
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800498void CameraManagerGlobal::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800499 int32_t status, const String8& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800500 Mutex::Autolock _l(mLock);
501 onStatusChangedLocked(status, cameraId);
502}
503
504void CameraManagerGlobal::onStatusChangedLocked(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800505 int32_t status, const String8& cameraId) {
506 if (!validStatus(status)) {
507 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
508 return;
509 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800510
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800511 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
512 int32_t oldStatus = firstStatus ?
513 status : // first status
Shuzhen Wang43858162020-01-10 13:42:15 -0800514 mDeviceStatusMap[cameraId].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800515
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800516 if (!firstStatus &&
517 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
518 // No status update. No need to send callback
519 return;
520 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800521
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700522 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800523 if (firstStatus) {
524 mDeviceStatusMap.emplace(std::piecewise_construct,
525 std::forward_as_tuple(cameraId),
526 std::forward_as_tuple(status, supportsHAL3));
527 } else {
528 mDeviceStatusMap[cameraId].updateStatus(status);
529 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800530 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700531 if (supportsHAL3) {
532 for (auto cb : mCallbacks) {
533 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
534 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
535 cb.mAvailable : cb.mUnavailable;
536 msg->setPointer(kCallbackFpKey, (void *) cbFp);
537 msg->setPointer(kContextKey, cb.mContext);
538 msg->setString(kCameraIdKey, AString(cameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700539 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700540 msg->post();
541 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800542 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100543 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
544 mDeviceStatusMap.erase(cameraId);
545 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800546}
547
Shuzhen Wang43858162020-01-10 13:42:15 -0800548void CameraManagerGlobal::onStatusChanged(
549 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
550 Mutex::Autolock _l(mLock);
551 onStatusChangedLocked(status, cameraId, physicalCameraId);
552}
553
554void CameraManagerGlobal::onStatusChangedLocked(
555 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
556 if (!validStatus(status)) {
557 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
558 return;
559 }
560
561 auto logicalStatus = mDeviceStatusMap.find(cameraId);
562 if (logicalStatus == mDeviceStatusMap.end()) {
563 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
564 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
565 return;
566 }
567 int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
568 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
569 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
570 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
571 __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
572 return;
573 }
574
575 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
576
577 bool updated = false;
578 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
579 updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
580 } else {
581 updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
582 }
583
584 // Iterate through all registered callbacks
585 if (supportsHAL3 && updated) {
586 for (auto cb : mCallbacks) {
587 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
588 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
589 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
590 msg->setPointer(kCallbackFpKey, (void *) cbFp);
591 msg->setPointer(kContextKey, cb.mContext);
592 msg->setString(kCameraIdKey, AString(cameraId));
593 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700594 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800595 msg->post();
596 }
597 }
598}
599
600int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
601 std::lock_guard<std::mutex> lock(mLock);
602 return status;
603}
604
605void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
606 std::lock_guard<std::mutex> lock(mLock);
607 status = newStatus;
608}
609
610bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
611 const String8& physicalCameraId) {
612 std::lock_guard<std::mutex> lock(mLock);
613 auto result = unavailablePhysicalIds.insert(physicalCameraId);
614 return result.second;
615}
616
617bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
618 const String8& physicalCameraId) {
619 std::lock_guard<std::mutex> lock(mLock);
620 auto count = unavailablePhysicalIds.erase(physicalCameraId);
621 return count > 0;
622}
623
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800624std::set<String8> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
625 std::lock_guard<std::mutex> lock(mLock);
626 return unavailablePhysicalIds;
627}
628
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800629} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800630} // namespace android
631
632/**
633 * ACameraManger Implementation
634 */
635camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800636ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
637 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800638
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800639 std::vector<String8> idList;
640 CameraManagerGlobal::getInstance().getCameraIdList(&idList);
641
642 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800643 ACameraIdList *out = new ACameraIdList;
644 if (!out) {
645 ALOGE("Allocate memory for ACameraIdList failed!");
646 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
647 }
648 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800649 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800650 if (!out->cameraIds) {
651 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800652 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800653 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
654 }
655 for (int i = 0; i < numCameras; i++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800656 const char* src = idList[i].string();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800657 size_t dstSize = strlen(src) + 1;
658 char* dst = new char[dstSize];
659 if (!dst) {
660 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800661 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800662 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
663 }
664 strlcpy(dst, src, dstSize);
665 out->cameraIds[i] = dst;
666 }
667 *cameraIdList = out;
668 return ACAMERA_OK;
669}
670
671void
672ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
673 if (cameraIdList != nullptr) {
674 if (cameraIdList->cameraIds != nullptr) {
675 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800676 if (cameraIdList->cameraIds[i] != nullptr) {
677 delete[] cameraIdList->cameraIds[i];
678 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800679 }
680 delete[] cameraIdList->cameraIds;
681 }
682 delete cameraIdList;
683 }
684}
685
686camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700687 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800688 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800689
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800690 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800691 if (cs == nullptr) {
692 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
693 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
694 }
695 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),
698 targetSdkVersion, &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
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800735 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,
750 targetSdkVersion, /*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}