blob: 0bcceafc9f248e03c694186ac06fcc9dbd94e422 [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>
Austin Borger0fb3ad92023-06-01 16:51:35 -070028#include <camera/StringUtils.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080029#include <camera/VendorTagDescriptor.h>
30
Jayant Chowdhary6df26072018-11-06 23:55:12 -080031using namespace android::acam;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080032
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080033namespace android {
Jayant Chowdhary6df26072018-11-06 23:55:12 -080034namespace acam {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080035// Static member definitions
36const char* CameraManagerGlobal::kCameraIdKey = "CameraId";
Shuzhen Wang43858162020-01-10 13:42:15 -080037const char* CameraManagerGlobal::kPhysicalCameraIdKey = "PhysicalCameraId";
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080038const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
39const char* CameraManagerGlobal::kContextKey = "CallbackContext";
Shuzhen Wang7e540682020-04-10 13:30:25 -070040const nsecs_t CameraManagerGlobal::kCallbackDrainTimeout = 5000000; // 5 ms
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080041Mutex CameraManagerGlobal::sLock;
Avichal Rakeshf099b232022-10-27 15:44:50 -070042wp<CameraManagerGlobal> CameraManagerGlobal::sInstance = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080043
Avichal Rakeshf099b232022-10-27 15:44:50 -070044sp<CameraManagerGlobal> CameraManagerGlobal::getInstance() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080045 Mutex::Autolock _l(sLock);
Avichal Rakeshf099b232022-10-27 15:44:50 -070046 sp<CameraManagerGlobal> instance = sInstance.promote();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080047 if (instance == nullptr) {
48 instance = new CameraManagerGlobal();
49 sInstance = instance;
50 }
Avichal Rakeshf099b232022-10-27 15:44:50 -070051 return instance;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080052}
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;
Ankit Siddhapura959b7be2024-04-16 13:07:42 +053087 binder = sm->checkService(String16(kCameraServiceName));
88 if (binder == nullptr) {
89 ALOGE("%s: Could not get CameraService instance.", __FUNCTION__);
90 return nullptr;
91 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080092 if (mDeathNotifier == nullptr) {
93 mDeathNotifier = new DeathNotifier(this);
94 }
95 binder->linkToDeath(mDeathNotifier);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080096 mCameraService = interface_cast<hardware::ICameraService>(binder);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080097
98 // Setup looper thread to perfrom availiability callbacks
99 if (mCbLooper == nullptr) {
100 mCbLooper = new ALooper;
101 mCbLooper->setName("C2N-mgr-looper");
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800102 status_t err = mCbLooper->start(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800103 /*runOnCallingThread*/false,
104 /*canCallJava*/ true,
Yin-Chia Yehead91462016-01-06 16:45:08 -0800105 PRIORITY_DEFAULT);
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800106 if (err != OK) {
107 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
108 __FUNCTION__, strerror(-err), err);
109 mCbLooper.clear();
110 return nullptr;
111 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800112 if (mHandler == nullptr) {
Shuzhen Wang7e540682020-04-10 13:30:25 -0700113 mHandler = new CallbackHandler(this);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800114 }
115 mCbLooper->registerHandler(mHandler);
116 }
117
118 // register ICameraServiceListener
119 if (mCameraServiceListener == nullptr) {
120 mCameraServiceListener = new CameraServiceListener(this);
121 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800122 std::vector<hardware::CameraStatus> cameraStatuses{};
123 mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
124 for (auto& c : cameraStatuses) {
125 onStatusChangedLocked(c.status, c.cameraId);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800126
127 for (auto& unavailablePhysicalId : c.unavailablePhysicalIds) {
128 onStatusChangedLocked(hardware::ICameraServiceListener::STATUS_NOT_PRESENT,
129 c.cameraId, unavailablePhysicalId);
130 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800131 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800132
133 // setup vendor tags
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800134 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
135 binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800136
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800137 if (ret.isOk()) {
Emilian Peev71c73a22017-03-21 16:35:51 +0000138 if (0 < desc->getTagCount()) {
139 status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
140 if (err != OK) {
141 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
142 __FUNCTION__, strerror(-err), err);
143 }
144 } else {
145 sp<VendorTagDescriptorCache> cache =
146 new VendorTagDescriptorCache();
147 binder::Status res =
148 mCameraService->getCameraVendorTagCache(
149 /*out*/cache.get());
150 if (res.serviceSpecificErrorCode() ==
151 hardware::ICameraService::ERROR_DISCONNECTED) {
152 // No camera module available, not an error on devices with no cameras
153 VendorTagDescriptorCache::clearGlobalVendorTagCache();
154 } else if (res.isOk()) {
155 status_t err =
156 VendorTagDescriptorCache::setAsGlobalVendorTagCache(
157 cache);
158 if (err != OK) {
159 ALOGE("%s: Failed to set vendor tag cache,"
160 "received error %s (%d)", __FUNCTION__,
161 strerror(-err), err);
162 }
163 } else {
164 VendorTagDescriptorCache::clearGlobalVendorTagCache();
165 ALOGE("%s: Failed to setup vendor tag cache: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000166 __FUNCTION__, res.toString8().c_str());
Emilian Peev71c73a22017-03-21 16:35:51 +0000167 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800168 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800169 } else if (ret.serviceSpecificErrorCode() ==
170 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800171 ALOGW("%s: Camera HAL too old; does not support vendor tags",
172 __FUNCTION__);
173 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
174 } else {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800175 ALOGE("%s: Failed to get vendor tag descriptors: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000176 __FUNCTION__, ret.toString8().c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800177 }
178 }
179 ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
180 return mCameraService;
181}
182
183void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
184{
185 ALOGE("Camera service binderDied!");
186 sp<CameraManagerGlobal> cm = mCameraManager.promote();
187 if (cm != nullptr) {
188 AutoMutex lock(cm->mLock);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700189 std::vector<std::string> cameraIdList;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800190 for (auto& pair : cm->mDeviceStatusMap) {
Rucha Katakwarc6e64012021-08-12 06:32:42 +0000191 cameraIdList.push_back(pair.first);
192 }
193
Austin Borger0fb3ad92023-06-01 16:51:35 -0700194 for (const std::string& cameraId : cameraIdList) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800195 cm->onStatusChangedLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800196 CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800197 }
198 cm->mCameraService.clear();
199 // TODO: consider adding re-connect call here?
200 }
201}
202
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800203void CameraManagerGlobal::registerExtendedAvailabilityCallback(
204 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800205 return registerAvailCallback<ACameraManager_ExtendedAvailabilityCallbacks>(callback);
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800206}
207
208void CameraManagerGlobal::unregisterExtendedAvailabilityCallback(
209 const ACameraManager_ExtendedAvailabilityCallbacks *callback) {
210 Mutex::Autolock _l(mLock);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700211
212 drainPendingCallbacksLocked();
213
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800214 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);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700226
227 drainPendingCallbacksLocked();
228
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800229 Callback cb(callback);
230 mCallbacks.erase(cb);
231}
232
Shuzhen Wang7e540682020-04-10 13:30:25 -0700233void CameraManagerGlobal::onCallbackCalled() {
234 Mutex::Autolock _l(mLock);
235 if (mPendingCallbackCnt > 0) {
236 mPendingCallbackCnt--;
237 }
238 mCallbacksCond.signal();
239}
240
241void CameraManagerGlobal::drainPendingCallbacksLocked() {
242 while (mPendingCallbackCnt > 0) {
243 auto res = mCallbacksCond.waitRelative(mLock, kCallbackDrainTimeout);
244 if (res != NO_ERROR) {
245 ALOGE("%s: Error waiting to drain callbacks: %s(%d)",
246 __FUNCTION__, strerror(-res), res);
247 break;
248 }
249 }
250}
251
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800252template<class T>
253void CameraManagerGlobal::registerAvailCallback(const T *callback) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800254 Mutex::Autolock _l(mLock);
Kwangkyu Park01f84432023-09-15 17:08:17 +0900255 getCameraServiceLocked();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800256 Callback cb(callback);
257 auto pair = mCallbacks.insert(cb);
258 // Send initial callbacks if callback is newly registered
259 if (pair.second) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800260 for (auto& pair : mDeviceStatusMap) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700261 const std::string& cameraId = pair.first;
Shuzhen Wang43858162020-01-10 13:42:15 -0800262 int32_t status = pair.second.getStatus();
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700263 // Don't send initial callbacks for camera ids which don't support
264 // camera2
265 if (!pair.second.supportsHAL3) {
266 continue;
267 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800268
269 // Camera available/unavailable callback
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800270 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800271 ACameraManager_AvailabilityCallback cbFunc = isStatusAvailable(status) ?
272 cb.mAvailable : cb.mUnavailable;
273 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
274 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700275 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700276 mPendingCallbackCnt++;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800277 msg->post();
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800278
279 // Physical camera unavailable callback
Austin Borger0fb3ad92023-06-01 16:51:35 -0700280 std::set<std::string> unavailablePhysicalCameras =
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800281 pair.second.getUnavailablePhysicalIds();
282 for (const auto& physicalCameraId : unavailablePhysicalCameras) {
283 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
284 ACameraManager_PhysicalCameraAvailabilityCallback cbFunc =
285 cb.mPhysicalCamUnavailable;
286 msg->setPointer(kCallbackFpKey, (void *) cbFunc);
287 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700288 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
289 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700290 mPendingCallbackCnt++;
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800291 msg->post();
292 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800293 }
294 }
295}
296
Austin Borger0fb3ad92023-06-01 16:51:35 -0700297bool CameraManagerGlobal::supportsCamera2ApiLocked(const std::string &cameraId) {
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700298 bool camera2Support = false;
299 auto cs = getCameraServiceLocked();
300 binder::Status serviceRet =
Austin Borger0fb3ad92023-06-01 16:51:35 -0700301 cs->supportsCameraApi(cameraId,
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700302 hardware::ICameraService::API_VERSION_2, &camera2Support);
303 if (!serviceRet.isOk()) {
304 ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId %s",
305 __FUNCTION__, cameraId.c_str());
306 return false;
307 }
308 return camera2Support;
309}
310
Austin Borger0fb3ad92023-06-01 16:51:35 -0700311void CameraManagerGlobal::getCameraIdList(std::vector<std::string>* cameraIds) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800312 // Ensure that we have initialized/refreshed the list of available devices
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800313 Mutex::Autolock _l(mLock);
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700314 // Needed to make sure we're connected to cameraservice
315 getCameraServiceLocked();
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800316 for(auto& deviceStatus : mDeviceStatusMap) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800317 int32_t status = deviceStatus.second.getStatus();
318 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
319 status == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800320 continue;
321 }
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700322 if (!deviceStatus.second.supportsHAL3) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800323 continue;
324 }
325 cameraIds->push_back(deviceStatus.first);
326 }
327}
328
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800329bool CameraManagerGlobal::validStatus(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800330 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800331 case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
332 case hardware::ICameraServiceListener::STATUS_PRESENT:
333 case hardware::ICameraServiceListener::STATUS_ENUMERATING:
334 case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800335 return true;
336 default:
337 return false;
338 }
339}
340
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800341bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800342 switch (status) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800343 case hardware::ICameraServiceListener::STATUS_PRESENT:
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800344 return true;
345 default:
346 return false;
347 }
348}
349
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800350void CameraManagerGlobal::CallbackHandler::onMessageReceived(
Shuzhen Wang7e540682020-04-10 13:30:25 -0700351 const sp<AMessage> &msg) {
352 onMessageReceivedInternal(msg);
353 if (msg->what() == kWhatSendSingleCallback ||
354 msg->what() == kWhatSendSingleAccessCallback ||
355 msg->what() == kWhatSendSinglePhysicalCameraCallback) {
356 notifyParent();
357 }
358}
359
360void CameraManagerGlobal::CallbackHandler::onMessageReceivedInternal(
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800361 const sp<AMessage> &msg) {
362 switch (msg->what()) {
363 case kWhatSendSingleCallback:
364 {
365 ACameraManager_AvailabilityCallback cb;
366 void* context;
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800367 AString cameraId;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800368 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
369 if (!found) {
370 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
371 return;
372 }
373 found = msg->findPointer(kContextKey, &context);
374 if (!found) {
375 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
376 return;
377 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800378 found = msg->findString(kCameraIdKey, &cameraId);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800379 if (!found) {
380 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
381 return;
382 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800383 (*cb)(context, cameraId.c_str());
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800384 break;
385 }
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800386 case kWhatSendSingleAccessCallback:
387 {
388 ACameraManager_AccessPrioritiesChangedCallback cb;
389 void* context;
390 AString cameraId;
391 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
392 if (!found) {
393 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
394 return;
395 }
396 found = msg->findPointer(kContextKey, &context);
397 if (!found) {
398 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
399 return;
400 }
401 (*cb)(context);
402 break;
403 }
Shuzhen Wang43858162020-01-10 13:42:15 -0800404 case kWhatSendSinglePhysicalCameraCallback:
405 {
406 ACameraManager_PhysicalCameraAvailabilityCallback cb;
407 void* context;
408 AString cameraId;
409 AString physicalCameraId;
410 bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
411 if (!found) {
412 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
413 return;
414 }
415 if (cb == nullptr) {
416 // Physical camera callback is null
417 return;
418 }
419 found = msg->findPointer(kContextKey, &context);
420 if (!found) {
421 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
422 return;
423 }
424 found = msg->findString(kCameraIdKey, &cameraId);
425 if (!found) {
426 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
427 return;
428 }
429 found = msg->findString(kPhysicalCameraIdKey, &physicalCameraId);
430 if (!found) {
431 ALOGE("%s: Cannot find physical camera ID!", __FUNCTION__);
432 return;
433 }
434 (*cb)(context, cameraId.c_str(), physicalCameraId.c_str());
435 break;
436 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800437 default:
438 ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
439 break;
440 }
441}
442
Shuzhen Wang7e540682020-04-10 13:30:25 -0700443void CameraManagerGlobal::CallbackHandler::notifyParent() {
444 sp<CameraManagerGlobal> parent = mParent.promote();
445 if (parent != nullptr) {
446 parent->onCallbackCalled();
447 }
448}
449
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800450binder::Status CameraManagerGlobal::CameraServiceListener::onCameraAccessPrioritiesChanged() {
451 sp<CameraManagerGlobal> cm = mCameraManager.promote();
452 if (cm != nullptr) {
453 cm->onCameraAccessPrioritiesChanged();
454 } else {
455 ALOGE("Cannot deliver camera access priority callback. Global camera manager died");
456 }
457 return binder::Status::ok();
458}
459
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800460binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700461 int32_t status, const std::string& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800462 sp<CameraManagerGlobal> cm = mCameraManager.promote();
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800463 if (cm != nullptr) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700464 cm->onStatusChanged(status, cameraId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800465 } else {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800466 ALOGE("Cannot deliver status change. Global camera manager died");
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800467 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800468 return binder::Status::ok();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800469}
470
Shuzhen Wang43858162020-01-10 13:42:15 -0800471binder::Status CameraManagerGlobal::CameraServiceListener::onPhysicalCameraStatusChanged(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700472 int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800473 sp<CameraManagerGlobal> cm = mCameraManager.promote();
474 if (cm != nullptr) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700475 cm->onStatusChanged(status, cameraId, physicalCameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800476 } else {
477 ALOGE("Cannot deliver physical camera status change. Global camera manager died");
478 }
479 return binder::Status::ok();
480}
481
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800482void CameraManagerGlobal::onCameraAccessPrioritiesChanged() {
483 Mutex::Autolock _l(mLock);
484 for (auto cb : mCallbacks) {
485 sp<AMessage> msg = new AMessage(kWhatSendSingleAccessCallback, mHandler);
486 ACameraManager_AccessPrioritiesChangedCallback cbFp = cb.mAccessPriorityChanged;
487 if (cbFp != nullptr) {
488 msg->setPointer(kCallbackFpKey, (void *) cbFp);
489 msg->setPointer(kContextKey, cb.mContext);
Shuzhen Wang7e540682020-04-10 13:30:25 -0700490 mPendingCallbackCnt++;
Emilian Peevc6f2ab32019-03-04 11:18:59 -0800491 msg->post();
492 }
493 }
494}
495
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800496void CameraManagerGlobal::onStatusChanged(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700497 int32_t status, const std::string& cameraId) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800498 Mutex::Autolock _l(mLock);
499 onStatusChangedLocked(status, cameraId);
500}
501
502void CameraManagerGlobal::onStatusChangedLocked(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700503 int32_t status, const std::string& cameraId) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800504 if (!validStatus(status)) {
505 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
506 return;
507 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800508
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800509 bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
510 int32_t oldStatus = firstStatus ?
511 status : // first status
Shuzhen Wang43858162020-01-10 13:42:15 -0800512 mDeviceStatusMap[cameraId].getStatus();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800513
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800514 if (!firstStatus &&
515 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
516 // No status update. No need to send callback
517 return;
518 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800519
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700520 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
Shuzhen Wang43858162020-01-10 13:42:15 -0800521 if (firstStatus) {
522 mDeviceStatusMap.emplace(std::piecewise_construct,
523 std::forward_as_tuple(cameraId),
524 std::forward_as_tuple(status, supportsHAL3));
525 } else {
526 mDeviceStatusMap[cameraId].updateStatus(status);
527 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800528 // Iterate through all registered callbacks
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700529 if (supportsHAL3) {
530 for (auto cb : mCallbacks) {
531 sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
532 ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
533 cb.mAvailable : cb.mUnavailable;
534 msg->setPointer(kCallbackFpKey, (void *) cbFp);
535 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700536 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700537 mPendingCallbackCnt++;
Jayant Chowdhary80f128b2019-10-30 16:13:31 -0700538 msg->post();
539 }
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800540 }
Guennadi Liakhovetski6034bf52017-12-07 10:28:29 +0100541 if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
542 mDeviceStatusMap.erase(cameraId);
543 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800544}
545
Shuzhen Wang43858162020-01-10 13:42:15 -0800546void CameraManagerGlobal::onStatusChanged(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700547 int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800548 Mutex::Autolock _l(mLock);
549 onStatusChangedLocked(status, cameraId, physicalCameraId);
550}
551
552void CameraManagerGlobal::onStatusChangedLocked(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700553 int32_t status, const std::string& cameraId, const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800554 if (!validStatus(status)) {
555 ALOGE("%s: Invalid status %d", __FUNCTION__, status);
556 return;
557 }
558
559 auto logicalStatus = mDeviceStatusMap.find(cameraId);
560 if (logicalStatus == mDeviceStatusMap.end()) {
561 ALOGE("%s: Physical camera id %s status change on a non-present id %s",
562 __FUNCTION__, physicalCameraId.c_str(), cameraId.c_str());
563 return;
564 }
565 int32_t logicalCamStatus = mDeviceStatusMap[cameraId].getStatus();
566 if (logicalCamStatus != hardware::ICameraServiceListener::STATUS_PRESENT &&
567 logicalCamStatus != hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE) {
568 ALOGE("%s: Physical camera id %s status %d change for an invalid logical camera state %d",
Austin Borger0fb3ad92023-06-01 16:51:35 -0700569 __FUNCTION__, physicalCameraId.c_str(), status, logicalCamStatus);
Shuzhen Wang43858162020-01-10 13:42:15 -0800570 return;
571 }
572
573 bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
574
575 bool updated = false;
576 if (status == hardware::ICameraServiceListener::STATUS_PRESENT) {
577 updated = mDeviceStatusMap[cameraId].removeUnavailablePhysicalId(physicalCameraId);
578 } else {
579 updated = mDeviceStatusMap[cameraId].addUnavailablePhysicalId(physicalCameraId);
580 }
581
582 // Iterate through all registered callbacks
583 if (supportsHAL3 && updated) {
584 for (auto cb : mCallbacks) {
585 sp<AMessage> msg = new AMessage(kWhatSendSinglePhysicalCameraCallback, mHandler);
586 ACameraManager_PhysicalCameraAvailabilityCallback cbFp = isStatusAvailable(status) ?
587 cb.mPhysicalCamAvailable : cb.mPhysicalCamUnavailable;
588 msg->setPointer(kCallbackFpKey, (void *) cbFp);
589 msg->setPointer(kContextKey, cb.mContext);
Austin Borger0fb3ad92023-06-01 16:51:35 -0700590 msg->setString(kCameraIdKey, AString(cameraId.c_str()));
591 msg->setString(kPhysicalCameraIdKey, AString(physicalCameraId.c_str()));
Shuzhen Wang7e540682020-04-10 13:30:25 -0700592 mPendingCallbackCnt++;
Shuzhen Wang43858162020-01-10 13:42:15 -0800593 msg->post();
594 }
595 }
596}
597
598int32_t CameraManagerGlobal::StatusAndHAL3Support::getStatus() {
599 std::lock_guard<std::mutex> lock(mLock);
600 return status;
601}
602
603void CameraManagerGlobal::StatusAndHAL3Support::updateStatus(int32_t newStatus) {
604 std::lock_guard<std::mutex> lock(mLock);
605 status = newStatus;
606}
607
608bool CameraManagerGlobal::StatusAndHAL3Support::addUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700609 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800610 std::lock_guard<std::mutex> lock(mLock);
611 auto result = unavailablePhysicalIds.insert(physicalCameraId);
612 return result.second;
613}
614
615bool CameraManagerGlobal::StatusAndHAL3Support::removeUnavailablePhysicalId(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700616 const std::string& physicalCameraId) {
Shuzhen Wang43858162020-01-10 13:42:15 -0800617 std::lock_guard<std::mutex> lock(mLock);
618 auto count = unavailablePhysicalIds.erase(physicalCameraId);
619 return count > 0;
620}
621
Austin Borger0fb3ad92023-06-01 16:51:35 -0700622std::set<std::string> CameraManagerGlobal::StatusAndHAL3Support::getUnavailablePhysicalIds() {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800623 std::lock_guard<std::mutex> lock(mLock);
624 return unavailablePhysicalIds;
625}
626
Jayant Chowdhary6df26072018-11-06 23:55:12 -0800627} // namespace acam
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800628} // namespace android
629
630/**
631 * ACameraManger Implementation
632 */
633camera_status_t
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800634ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
635 Mutex::Autolock _l(mLock);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800636
Austin Borger0fb3ad92023-06-01 16:51:35 -0700637 std::vector<std::string> idList;
Avichal Rakeshf099b232022-10-27 15:44:50 -0700638 CameraManagerGlobal::getInstance()->getCameraIdList(&idList);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800639
640 int numCameras = idList.size();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800641 ACameraIdList *out = new ACameraIdList;
642 if (!out) {
643 ALOGE("Allocate memory for ACameraIdList failed!");
644 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
645 }
646 out->numCameras = numCameras;
Bjoern Johansson1a5954c2017-01-10 10:30:18 -0800647 out->cameraIds = new const char*[numCameras];
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800648 if (!out->cameraIds) {
649 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800650 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800651 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
652 }
653 for (int i = 0; i < numCameras; i++) {
Austin Borger0fb3ad92023-06-01 16:51:35 -0700654 const char* src = idList[i].c_str();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800655 size_t dstSize = strlen(src) + 1;
656 char* dst = new char[dstSize];
657 if (!dst) {
658 ALOGE("Allocate memory for ACameraIdList failed!");
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800659 deleteCameraIdList(out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800660 return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
661 }
662 strlcpy(dst, src, dstSize);
663 out->cameraIds[i] = dst;
664 }
665 *cameraIdList = out;
666 return ACAMERA_OK;
667}
668
669void
670ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
671 if (cameraIdList != nullptr) {
672 if (cameraIdList->cameraIds != nullptr) {
673 for (int i = 0; i < cameraIdList->numCameras; i ++) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800674 if (cameraIdList->cameraIds[i] != nullptr) {
675 delete[] cameraIdList->cameraIds[i];
676 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800677 }
678 delete[] cameraIdList->cameraIds;
679 }
680 delete cameraIdList;
681 }
682}
683
684camera_status_t ACameraManager::getCameraCharacteristics(
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700685 const char* cameraIdStr, sp<ACameraMetadata>* characteristics) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800686 Mutex::Autolock _l(mLock);
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800687
Avichal Rakeshf099b232022-10-27 15:44:50 -0700688 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800689 if (cs == nullptr) {
690 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
691 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
692 }
Austin Borger3560b7e2022-10-27 12:20:29 -0700693
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800694 CameraMetadata rawMetadata;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700695 int targetSdkVersion = android_get_application_target_sdk_version();
Austin Borger0fb3ad92023-06-01 16:51:35 -0700696 binder::Status serviceRet = cs->getCameraCharacteristics(cameraIdStr,
Austin Borger45ec7c22023-01-25 10:59:08 -0800697 targetSdkVersion, /*overrideToPortrait*/false, &rawMetadata);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800698 if (!serviceRet.isOk()) {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800699 switch(serviceRet.serviceSpecificErrorCode()) {
700 case hardware::ICameraService::ERROR_DISCONNECTED:
701 ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
702 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
703 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
704 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
705 return ACAMERA_ERROR_INVALID_PARAMETER;
706 default:
707 ALOGE("Get camera characteristics from camera service failed: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000708 serviceRet.toString8().c_str());
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800709 return ACAMERA_ERROR_UNKNOWN; // should not reach here
710 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800711 }
712
713 *characteristics = new ACameraMetadata(
714 rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
715 return ACAMERA_OK;
716}
717
718camera_status_t
719ACameraManager::openCamera(
720 const char* cameraId,
721 ACameraDevice_StateCallbacks* callback,
722 /*out*/ACameraDevice** outDevice) {
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700723 sp<ACameraMetadata> chars;
724 camera_status_t ret = getCameraCharacteristics(cameraId, &chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800725 Mutex::Autolock _l(mLock);
726 if (ret != ACAMERA_OK) {
727 ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
728 __FUNCTION__, cameraId, ret);
729 return ACAMERA_ERROR_INVALID_PARAMETER;
730 }
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800731
Yin-Chia Yehdd045bf2018-08-20 12:39:19 -0700732 ACameraDevice* device = new ACameraDevice(cameraId, callback, chars);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800733
Avichal Rakeshf099b232022-10-27 15:44:50 -0700734 sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance()->getCameraService();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800735 if (cs == nullptr) {
736 ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
Yunlian Jiangb01d8f72016-10-04 16:34:18 -0700737 delete device;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800738 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
739 }
740
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800741 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
742 sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700743 int targetSdkVersion = android_get_application_target_sdk_version();
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800744 // No way to get package name from native.
745 // Send a zero length package name and let camera service figure it out from UID
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800746 binder::Status serviceRet = cs->connectDevice(
Austin Borger0fb3ad92023-06-01 16:51:35 -0700747 callbacks, cameraId, "", {},
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700748 hardware::ICameraService::USE_CALLING_UID, /*oomScoreOffset*/0,
Austin Borger45ec7c22023-01-25 10:59:08 -0800749 targetSdkVersion, /*overrideToPortrait*/false, /*out*/&deviceRemote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800750
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800751 if (!serviceRet.isOk()) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000752 ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().c_str());
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700753 // Convert serviceRet to camera_status_t
754 switch(serviceRet.serviceSpecificErrorCode()) {
755 case hardware::ICameraService::ERROR_DISCONNECTED:
756 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
757 break;
758 case hardware::ICameraService::ERROR_CAMERA_IN_USE:
759 ret = ACAMERA_ERROR_CAMERA_IN_USE;
760 break;
761 case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
762 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
763 break;
764 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
765 ret = ACAMERA_ERROR_INVALID_PARAMETER;
766 break;
767 case hardware::ICameraService::ERROR_DEPRECATED_HAL:
768 // Should not reach here since we filtered legacy HALs earlier
769 ret = ACAMERA_ERROR_INVALID_PARAMETER;
770 break;
771 case hardware::ICameraService::ERROR_DISABLED:
772 ret = ACAMERA_ERROR_CAMERA_DISABLED;
773 break;
774 case hardware::ICameraService::ERROR_PERMISSION_DENIED:
775 ret = ACAMERA_ERROR_PERMISSION_DENIED;
776 break;
777 case hardware::ICameraService::ERROR_INVALID_OPERATION:
778 default:
779 ret = ACAMERA_ERROR_UNKNOWN;
780 break;
781 }
782
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800783 delete device;
Yin-Chia Yeh3e49be12016-04-12 16:00:33 -0700784 return ret;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800785 }
786 if (deviceRemote == nullptr) {
787 ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
788 delete device;
789 return ACAMERA_ERROR_CAMERA_DISCONNECTED;
790 }
791 device->setRemoteDevice(deviceRemote);
792 *outDevice = device;
793 return ACAMERA_OK;
794}
795
796ACameraManager::~ACameraManager() {
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800797
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800798}