blob: 3a678be5ccfd0d40a8935a6771cd540da9fee338 [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>
27#include <camera/VendorTagDescriptor.h>
28
Jayant Chowdhary6df26072018-11-06 23:55:12 -080029using namespace android::acam;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080030
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080031namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080032namespace acam {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080033// Static member definitions
34const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
Shuzhen Wang43858162020-01-10 13:42:15 -080035const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080036const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
37const char* CameraManagerGlobal::kContextKey = "CallbackContext";
38Mutex CameraManagerGlobal::sLock;
39CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
40
41CameraManagerGlobal&
42CameraManagerGlobal::getInstance() {
43 Mutex::Autolock _l(sLock);
44 CameraManagerGlobal* instance = sInstance;
45 if (instance == nullptr) {
46 instance = new CameraManagerGlobal();
47 sInstance = instance;
48 }
49 return *instance;
50}
51
52CameraManagerGlobal::~CameraManagerGlobal() {
53 // clear sInstance so next getInstance call knows to create a new one
54 Mutex::Autolock _sl(sLock);
55 sInstance = nullptr;
56 Mutex::Autolock _l(mLock);
57 if (mCameraService != nullptr) {
58 IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
Yin-Chia Yehead91462016-01-06 16:45:08 -080059 mCameraService->removeListener(mCameraServiceListener);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080060 }
61 mDeathNotifier.clear();
62 if (mCbLooper != nullptr) {
63 mCbLooper->unregisterHandler(mHandler->id());
64 mCbLooper->stop();
65 }
66 mCbLooper.clear();
67 mHandler.clear();
68 mCameraServiceListener.clear();
69 mCameraService.clear();
70}
71
Ivan Podogovee844a82016-09-15 11:32:41 +010072static bool isCameraServiceDisabled() {
73 char value[PROPERTY_VALUE_MAX];
74 property_get("config.disable_cameraservice", value, "0");
75 return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
76}
77
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080078sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080079 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -070080 return getCameraServiceLocked();
81}
82
83sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080084 if (mCameraService.get() == nullptr) {
Ivan Podogovee844a82016-09-15 11:32:41 +010085 if (isCameraServiceDisabled()) {
86 return mCameraService;
87 }
88
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080089 sp<IServiceManager> sm = defaultServiceManager();
90 sp<IBinder> binder;
91 do {
92 binder = sm->getService(String16(kCameraServiceName));
93 if (binder != nullptr) {
94 break;
95 }
96 ALOGW("CameraService not published, waiting...");
97 usleep(kCameraServicePollDelay);
98 } while(true);
99 if (mDeathNotifier == nullptr) {
100 mDeathNotifier = new DeathNotifier(this);
101 }
102 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800103 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800104
105 // Setup looper thread to perfrom availiability callbacks
106 if (mCbLooper == nullptr) {
107 mCbLooper = new ALooper;
108 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800109 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800110 /*runOnCallingThread*/false,
111 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800112 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800113 if (err != OK) {
114 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
115 __FUNCTION__, strerror(-err), err);
116 mCbLooper.clear();
117 return nullptr;
118 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800119 if (mHandler == nullptr) {
120 mHandler = new CallbackHandler();
121 }
122 mCbLooper->registerHandler(mHandler);
123 }
124
125 // register ICameraServiceListener
126 if (mCameraServiceListener == nullptr) {
127 mCameraServiceListener = new CameraServiceListener(this);
128 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800129 std::vector<hardware::CameraStatus> cameraStatuses{};
130 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
131 for (auto& c : cameraStatuses) {
132 onStatusChangedLocked(c.status, c.cameraId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800133
134 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
135 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
136 c.cameraId, unavailablePhysicalId);
137 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800138 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800139
140 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800141 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
142 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800143
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800144 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000145 if (0 < desc->getTagCount()) {
146 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
147 if (err != OK) {
148 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
149 __FUNCTION__, strerror(-err), err);
150 }
151 } else {
152 sp<VendorTagDescriptorCache> cache =
153 new VendorTagDescriptorCache();
154 binder::Status res =
155 mCameraService->getCameraVendorTagCache(
156 /*out*/cache.get());
157 if (res.serviceSpecificErrorCode() ==
158 hardware::ICameraService::ERROR_DISCONNECTED) {
159 // No camera module available, not an error on devices with no cameras
160 VendorTagDescriptorCache::clearGlobalVendorTagCache();
161 } else if (res.isOk()) {
162 status_t err =
163 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
164 cache);
165 if (err != OK) {
166 ALOGE("%s: Failed to set vendor tag cache,"
167 "received error %s (%d)", __FUNCTION__,
168 strerror(-err), err);
169 }
170 } else {
171 VendorTagDescriptorCache::clearGlobalVendorTagCache();
172 ALOGE("%s: Failed to setup vendor tag cache: %s",
173 __FUNCTION__, res.toString8().string());
174 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800175 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800176 } else if (ret.serviceSpecificErrorCode() ==
177 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800178 ALOGW("%s: Camera HAL too old; does not support vendor tags",
179 __FUNCTION__);
180 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
181 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800182 ALOGE("%s: Failed to get vendor tag descriptors: %s",
183 __FUNCTION__, ret.toString8().string());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800184 }
185 }
186 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
187 return mCameraService;
188}
189
190void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
191{
192 ALOGE("Camera service binderDied!");
193 sp<CameraManagerGlobal> cm = mCameraManager.promote();
194 if (cm != nullptr) {
195 AutoMutex lock(cm->mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800196 for (auto& pair : cm->mDeviceStatusMap) {
197 const String8 &cameraId = pair.first;
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);
214 Callback cb(callback);
215 mCallbacks.erase(cb);
216}
217
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800218void CameraManagerGlobal::registerAvailabilityCallback(
219 const ACameraManager_AvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800220 return registerAvailCallback<ACameraManager_AvailabilityCallbacks>(callback);
221}
222
223void CameraManagerGlobal::unregisterAvailabilityCallback(
224 const ACameraManager_AvailabilityCallbacks *callback) {
225 Mutex::Autolock _l(mLock);
226 Callback cb(callback);
227 mCallbacks.erase(cb);
228}
229
230template<class T>
231void CameraManagerGlobal::registerAvailCallback(const T *callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800232 Mutex::Autolock _l(mLock);
233 Callback cb(callback);
234 auto pair = mCallbacks.insert(cb);
235 // Send initial callbacks if callback is newly registered
236 if (pair.second) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800237 for (auto& pair : mDeviceStatusMap) {
238 const String8& cameraId = pair.first;
Shuzhen Wang43858162020-01-10 13:42:15 -0800239 int32_t status = pair.second.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700240 // Don't send initial callbacks for camera ids which don't support
241 // camera2
242 if (!pair.second.supportsHAL3) {
243 continue;
244 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800245
246 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800247 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800248 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
249 cb.mAvailable : cb.mUnavailable;
250 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
251 msg->setPointer(kContextKey, cb.mContext);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800252 msg->setString(kCameraIdKey, AString(cameraId));
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800253 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800254
255 // Physical camera unavailable callback
256 std::set<String8> unavailablePhysicalCameras =
257 pair.second.getUnavailablePhysicalIds();
258 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
259 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
260 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
261 cb.mPhysicalCamUnavailable;
262 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
263 msg->setPointer(kContextKey, cb.mContext);
264 msg->setString(kCameraIdKey, AString(cameraId));
265 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
266 msg->post();
267 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800268 }
269 }
270}
271
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700272bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
273 bool camera2Support = false;
274 auto cs = getCameraServiceLocked();
275 binder::Status serviceRet =
276 cs->supportsCameraApi(String16(cameraId),
277 hardware::ICameraService::API_VERSION_2, &camera2Support);
278 if (!serviceRet.isOk()) {
279 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
280 __FUNCTION__, cameraId.c_str());
281 return false;
282 }
283 return camera2Support;
284}
285
Yin-Chia Yeh03f55752018-03-14 15:28:02 -0700286void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800287 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800288 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700289 // Needed to make sure we're connected to cameraservice
290 getCameraServiceLocked();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800291 for(auto& deviceStatus : mDeviceStatusMap) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800292 int32_t status = deviceStatus.second.getStatus();
293 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
294 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800295 continue;
296 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700297 if (!deviceStatus.second.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800298 continue;
299 }
300 cameraIds->push_back(deviceStatus.first);
301 }
302}
303
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800304bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800305 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800306 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
307 case hardware::ICameraServiceListener::STATUS_PRESENT:
308 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
309 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800310 return true;
311 default:
312 return false;
313 }
314}
315
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800316bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800317 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800318 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800319 return true;
320 default:
321 return false;
322 }
323}
324
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800325void CameraManagerGlobal::CallbackHandler::onMessageReceived(
326 const sp<AMessage> &msg) {
327 switch (msg->what()) {
328 case kWhatSendSingleCallback:
329 {
330 ACameraManager_AvailabilityCallback cb;
331 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800332 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800333 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
334 if (!found) {
335 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
336 return;
337 }
338 found = msg->findPointer(kContextKey, &context);
339 if (!found) {
340 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
341 return;
342 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800343 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800344 if (!found) {
345 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
346 return;
347 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800348 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800349 break;
350 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800351 case kWhatSendSingleAccessCallback:
352 {
353 ACameraManager_AccessPrioritiesChangedCallback cb;
354 void* context;
355 AString cameraId;
356 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
357 if (!found) {
358 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
359 return;
360 }
361 found = msg->findPointer(kContextKey, &context);
362 if (!found) {
363 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
364 return;
365 }
366 (*cb)(context);
367 break;
368 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800369 case kWhatSendSinglePhysicalCameraCallback:
370 {
371 ACameraManager_PhysicalCameraAvailabilityCallback cb;
372 void* context;
373 AString cameraId;
374 AString physicalCameraId;
375 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
376 if (!found) {
377 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
378 return;
379 }
380 if (cb == nullptr) {
381 // Physical camera callback is null
382 return;
383 }
384 found = msg->findPointer(kContextKey, &context);
385 if (!found) {
386 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
387 return;
388 }
389 found = msg->findString(kCameraIdKey, &cameraId);
390 if (!found) {
391 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
392 return;
393 }
394 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
395 if (!found) {
396 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
397 return;
398 }
399 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
400 break;
401 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800402 default:
403 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
404 break;
405 }
406}
407
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800408binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
409 sp<CameraManagerGlobal> cm = mCameraManager.promote();
410 if (cm != nullptr) {
411 cm->onCameraAccessPrioritiesChanged();
412 } else {
413 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
414 }
415 return binder::Status::ok();
416}
417
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800418binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800419 int32_t status, const String16& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800420 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800421 if (cm != nullptr) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800422 cm->onStatusChanged(status, String8(cameraId));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800423 } else {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800424 ALOGE("Cannot deliver status change. Global camera manager died");
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800425 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800426 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800427}
428
Shuzhen Wang43858162020-01-10 13:42:15 -0800429binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
430 int32_t status, const String16& cameraId, const String16& physicalCameraId) {
431 sp<CameraManagerGlobal> cm = mCameraManager.promote();
432 if (cm != nullptr) {
433 cm->onStatusChanged(status, String8(cameraId), String8(physicalCameraId));
434 } else {
435 ALOGE("Cannot deliver physical camera status change. Global camera manager died");
436 }
437 return binder::Status::ok();
438}
439
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800440void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
441 Mutex::Autolock _l(mLock);
442 for (auto cb : mCallbacks) {
443 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
444 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
445 if (cbFp != nullptr) {
446 msg->setPointer(kCallbackFpKey, (void *) cbFp);
447 msg->setPointer(kContextKey, cb.mContext);
448 msg->post();
449 }
450 }
451}
452
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800453void CameraManagerGlobal::onStatusChanged(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800454 int32_t status, const String8& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800455 Mutex::Autolock _l(mLock);
456 onStatusChangedLocked(status, cameraId);
457}
458
459void CameraManagerGlobal::onStatusChangedLocked(
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800460 int32_t status, const String8& cameraId) {
461 if (!validStatus(status)) {
462 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
463 return;
464 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800465
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800466 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
467 int32_t oldStatus = firstStatus ?
468 status : // first status
Shuzhen Wang43858162020-01-10 13:42:15 -0800469 mDeviceStatusMap[cameraId].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800470
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800471 if (!firstStatus &&
472 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
473 // No status update. No need to send callback
474 return;
475 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800476
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700477 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800478 if (firstStatus) {
479 mDeviceStatusMap.emplace(std::piecewise_construct,
480 std::forward_as_tuple(cameraId),
481 std::forward_as_tuple(status, supportsHAL3));
482 } else {
483 mDeviceStatusMap[cameraId].updateStatus(status);
484 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800485 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700486 if (supportsHAL3) {
487 for (auto cb : mCallbacks) {
488 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
489 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
490 cb.mAvailable : cb.mUnavailable;
491 msg->setPointer(kCallbackFpKey, (void *) cbFp);
492 msg->setPointer(kContextKey, cb.mContext);
493 msg->setString(kCameraIdKey, AString(cameraId));
494 msg->post();
495 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800496 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100497 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
498 mDeviceStatusMap.erase(cameraId);
499 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800500}
501
Shuzhen Wang43858162020-01-10 13:42:15 -0800502void CameraManagerGlobal::onStatusChanged(
503 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
504 Mutex::Autolock _l(mLock);
505 onStatusChangedLocked(status, cameraId, physicalCameraId);
506}
507
508void CameraManagerGlobal::onStatusChangedLocked(
509 int32_t status, const String8& cameraId, const String8& physicalCameraId) {
510 if (!validStatus(status)) {
511 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
512 return;
513 }
514
515 auto logicalStatus = mDeviceStatusMap.find(cameraId);
516 if (logicalStatus == mDeviceStatusMap.end()) {
517 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
518 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
519 return;
520 }
521 int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
522 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
523 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
524 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
525 __FUNCTION__, physicalCameraId.string(), status, logicalCamStatus);
526 return;
527 }
528
529 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
530
531 bool updated = false;
532 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
533 updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
534 } else {
535 updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
536 }
537
538 // Iterate through all registered callbacks
539 if (supportsHAL3 && updated) {
540 for (auto cb : mCallbacks) {
541 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
542 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
543 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
544 msg->setPointer(kCallbackFpKey, (void *) cbFp);
545 msg->setPointer(kContextKey, cb.mContext);
546 msg->setString(kCameraIdKey, AString(cameraId));
547 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId));
548 msg->post();
549 }
550 }
551}
552
553int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
554 std::lock_guard<std::mutex> lock(mLock);
555 return status;
556}
557
558void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
559 std::lock_guard<std::mutex> lock(mLock);
560 status = newStatus;
561}
562
563bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
564 const String8& physicalCameraId) {
565 std::lock_guard<std::mutex> lock(mLock);
566 auto result = unavailablePhysicalIds.insert(physicalCameraId);
567 return result.second;
568}
569
570bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
571 const String8& physicalCameraId) {
572 std::lock_guard<std::mutex> lock(mLock);
573 auto count = unavailablePhysicalIds.erase(physicalCameraId);
574 return count > 0;
575}
576
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800577std::set<String8> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
578 std::lock_guard<std::mutex> lock(mLock);
579 return unavailablePhysicalIds;
580}
581
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800582} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800583} // namespace android
584
585/**
586 * ACameraManger Implementation
587 */
588camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800589ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
590 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800591
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800592 std::vector<String8> idList;
593 CameraManagerGlobal::getInstance().getCameraIdList(&idList);
594
595 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800596 ACameraIdList *out = new ACameraIdList;
597 if (!out) {
598 ALOGE("Allocate memory for ACameraIdList failed!");
599 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
600 }
601 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800602 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800603 if (!out->cameraIds) {
604 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800605 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800606 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
607 }
608 for (int i = 0; i < numCameras; i++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800609 const char* src = idList[i].string();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800610 size_t dstSize = strlen(src) + 1;
611 char* dst = new char[dstSize];
612 if (!dst) {
613 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800614 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800615 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
616 }
617 strlcpy(dst, src, dstSize);
618 out->cameraIds[i] = dst;
619 }
620 *cameraIdList = out;
621 return ACAMERA_OK;
622}
623
624void
625ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
626 if (cameraIdList != nullptr) {
627 if (cameraIdList->cameraIds != nullptr) {
628 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800629 if (cameraIdList->cameraIds[i] != nullptr) {
630 delete[] cameraIdList->cameraIds[i];
631 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800632 }
633 delete[] cameraIdList->cameraIds;
634 }
635 delete cameraIdList;
636 }
637}
638
639camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700640 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800641 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800642
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800643 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800644 if (cs == nullptr) {
645 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
646 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
647 }
648 CameraMetadata rawMetadata;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800649 binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr), &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800650 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800651 switch(serviceRet.serviceSpecificErrorCode()) {
652 case hardware::ICameraService::ERROR_DISCONNECTED:
653 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
654 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
655 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
656 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
657 return ACAMERA_ERROR_INVALID_PARAMETER;
658 default:
659 ALOGE("Get camera characteristics from camera service failed: %s",
660 serviceRet.toString8().string());
661 return ACAMERA_ERROR_UNKNOWN; // should not reach here
662 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800663 }
664
665 *characteristics = new ACameraMetadata(
666 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
667 return ACAMERA_OK;
668}
669
670camera_status_t
671ACameraManager::openCamera(
672 const char* cameraId,
673 ACameraDevice_StateCallbacks* callback,
674 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700675 sp<ACameraMetadata> chars;
676 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800677 Mutex::Autolock _l(mLock);
678 if (ret != ACAMERA_OK) {
679 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
680 __FUNCTION__, cameraId, ret);
681 return ACAMERA_ERROR_INVALID_PARAMETER;
682 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800683
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700684 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800685
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800686 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800687 if (cs == nullptr) {
688 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700689 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800690 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
691 }
692
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800693 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
694 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800695 // No way to get package name from native.
696 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800697 binder::Status serviceRet = cs->connectDevice(
Jooyung Hanb3f7cd22020-01-23 12:27:18 +0900698 callbacks, String16(cameraId), String16(""), {},
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800699 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800700
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800701 if (!serviceRet.isOk()) {
702 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700703 // Convert serviceRet to camera_status_t
704 switch(serviceRet.serviceSpecificErrorCode()) {
705 case hardware::ICameraService::ERROR_DISCONNECTED:
706 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
707 break;
708 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
709 ret = ACAMERA_ERROR_CAMERA_IN_USE;
710 break;
711 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
712 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
713 break;
714 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
715 ret = ACAMERA_ERROR_INVALID_PARAMETER;
716 break;
717 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
718 // Should not reach here since we filtered legacy HALs earlier
719 ret = ACAMERA_ERROR_INVALID_PARAMETER;
720 break;
721 case hardware::ICameraService::ERROR_DISABLED:
722 ret = ACAMERA_ERROR_CAMERA_DISABLED;
723 break;
724 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
725 ret = ACAMERA_ERROR_PERMISSION_DENIED;
726 break;
727 case hardware::ICameraService::ERROR_INVALID_OPERATION:
728 default:
729 ret = ACAMERA_ERROR_UNKNOWN;
730 break;
731 }
732
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800733 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700734 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800735 }
736 if (deviceRemote == nullptr) {
737 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
738 delete device;
739 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
740 }
741 device->setRemoteDevice(deviceRemote);
742 *outDevice = device;
743 return ACAMERA_OK;
744}
745
746ACameraManager::~ACameraManager() {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800747
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800748}