• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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>
25 #include <stdlib.h>
26 #include <camera/VendorTagDescriptor.h>
27 
28 using namespace android;
29 
30 //constants shared between ACameraManager and CameraManagerGlobal
31 namespace {
32     const int kMaxCameraIdLen = 32;
33 }
34 
35 namespace android {
36 // Static member definitions
37 const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
38 const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
39 const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
40 Mutex                CameraManagerGlobal::sLock;
41 CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
42 
43 CameraManagerGlobal&
getInstance()44 CameraManagerGlobal::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 
~CameraManagerGlobal()54 CameraManagerGlobal::~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);
61         mCameraService->removeListener(mCameraServiceListener);
62     }
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 
getCameraService()74 sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
75     Mutex::Autolock _l(mLock);
76     if (mCameraService.get() == nullptr) {
77         sp<IServiceManager> sm = defaultServiceManager();
78         sp<IBinder> binder;
79         do {
80             binder = sm->getService(String16(kCameraServiceName));
81             if (binder != nullptr) {
82                 break;
83             }
84             ALOGW("CameraService not published, waiting...");
85             usleep(kCameraServicePollDelay);
86         } while(true);
87         if (mDeathNotifier == nullptr) {
88             mDeathNotifier = new DeathNotifier(this);
89         }
90         binder->linkToDeath(mDeathNotifier);
91         mCameraService = interface_cast<hardware::ICameraService>(binder);
92 
93         // Setup looper thread to perfrom availiability callbacks
94         if (mCbLooper == nullptr) {
95             mCbLooper = new ALooper;
96             mCbLooper->setName("C2N-mgr-looper");
97             status_t err = mCbLooper->start(
98                     /*runOnCallingThread*/false,
99                     /*canCallJava*/       true,
100                     PRIORITY_DEFAULT);
101             if (err != OK) {
102                 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
103                         __FUNCTION__, strerror(-err), err);
104                 mCbLooper.clear();
105                 return nullptr;
106             }
107             if (mHandler == nullptr) {
108                 mHandler = new CallbackHandler();
109             }
110             mCbLooper->registerHandler(mHandler);
111         }
112 
113         // register ICameraServiceListener
114         if (mCameraServiceListener == nullptr) {
115             mCameraServiceListener = new CameraServiceListener(this);
116         }
117         mCameraService->addListener(mCameraServiceListener);
118 
119         // setup vendor tags
120         sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
121         binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
122 
123         if (ret.isOk()) {
124             status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
125             if (err != OK) {
126                 ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
127                         __FUNCTION__, strerror(-err), err);
128             }
129         } else if (ret.serviceSpecificErrorCode() ==
130                 hardware::ICameraService::ERROR_DEPRECATED_HAL) {
131             ALOGW("%s: Camera HAL too old; does not support vendor tags",
132                     __FUNCTION__);
133             VendorTagDescriptor::clearGlobalVendorTagDescriptor();
134         } else {
135             ALOGE("%s: Failed to get vendor tag descriptors: %s",
136                     __FUNCTION__, ret.toString8().string());
137         }
138     }
139     ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
140     return mCameraService;
141 }
142 
binderDied(const wp<IBinder> &)143 void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
144 {
145     ALOGE("Camera service binderDied!");
146     sp<CameraManagerGlobal> cm = mCameraManager.promote();
147     if (cm != nullptr) {
148         AutoMutex lock(cm->mLock);
149         for (auto pair : cm->mDeviceStatusMap) {
150             int32_t cameraId = pair.first;
151             cm->onStatusChangedLocked(
152                     CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
153         }
154         cm->mCameraService.clear();
155         // TODO: consider adding re-connect call here?
156     }
157 }
158 
registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks * callback)159 void CameraManagerGlobal::registerAvailabilityCallback(
160         const ACameraManager_AvailabilityCallbacks *callback) {
161     Mutex::Autolock _l(mLock);
162     Callback cb(callback);
163     auto pair = mCallbacks.insert(cb);
164     // Send initial callbacks if callback is newly registered
165     if (pair.second) {
166         for (auto pair : mDeviceStatusMap) {
167             int32_t cameraId = pair.first;
168             int32_t status = pair.second;
169 
170             sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
171             ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
172                     callback->onCameraAvailable : callback->onCameraUnavailable;
173             msg->setPointer(kCallbackFpKey, (void *) cb);
174             msg->setPointer(kContextKey, callback->context);
175             msg->setInt32(kCameraIdKey, cameraId);
176             msg->post();
177         }
178     }
179 }
180 
unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks * callback)181 void CameraManagerGlobal::unregisterAvailabilityCallback(
182         const ACameraManager_AvailabilityCallbacks *callback) {
183     Mutex::Autolock _l(mLock);
184     Callback cb(callback);
185     mCallbacks.erase(cb);
186 }
187 
validStatus(int32_t status)188 bool CameraManagerGlobal::validStatus(int32_t status) {
189     switch (status) {
190         case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
191         case hardware::ICameraServiceListener::STATUS_PRESENT:
192         case hardware::ICameraServiceListener::STATUS_ENUMERATING:
193         case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
194             return true;
195         default:
196             return false;
197     }
198 }
199 
isStatusAvailable(int32_t status)200 bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
201     switch (status) {
202         case hardware::ICameraServiceListener::STATUS_PRESENT:
203             return true;
204         default:
205             return false;
206     }
207 }
208 
sendSingleCallback(int32_t cameraId,void * context,ACameraManager_AvailabilityCallback cb) const209 void CameraManagerGlobal::CallbackHandler::sendSingleCallback(
210         int32_t cameraId, void* context,
211         ACameraManager_AvailabilityCallback cb) const {
212     char cameraIdStr[kMaxCameraIdLen];
213     snprintf(cameraIdStr, sizeof(cameraIdStr), "%d", cameraId);
214     (*cb)(context, cameraIdStr);
215 }
216 
onMessageReceived(const sp<AMessage> & msg)217 void CameraManagerGlobal::CallbackHandler::onMessageReceived(
218         const sp<AMessage> &msg) {
219     switch (msg->what()) {
220         case kWhatSendSingleCallback:
221         {
222             ACameraManager_AvailabilityCallback cb;
223             void* context;
224             int32_t cameraId;
225             bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
226             if (!found) {
227                 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
228                 return;
229             }
230             found = msg->findPointer(kContextKey, &context);
231             if (!found) {
232                 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
233                 return;
234             }
235             found = msg->findInt32(kCameraIdKey, &cameraId);
236             if (!found) {
237                 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
238                 return;
239             }
240             sendSingleCallback(cameraId, context, cb);
241             break;
242         }
243         default:
244             ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
245             break;
246     }
247 }
248 
onStatusChanged(int32_t status,int32_t cameraId)249 binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
250         int32_t status, int32_t cameraId) {
251     sp<CameraManagerGlobal> cm = mCameraManager.promote();
252     if (cm != nullptr) {
253         cm->onStatusChanged(status, cameraId);
254     } else {
255         ALOGE("Cannot deliver status change. Global camera manager died");
256     }
257     return binder::Status::ok();
258 }
259 
onStatusChanged(int32_t status,int32_t cameraId)260 void CameraManagerGlobal::onStatusChanged(
261         int32_t status, int32_t cameraId) {
262     Mutex::Autolock _l(mLock);
263     onStatusChangedLocked(status, cameraId);
264 }
265 
onStatusChangedLocked(int32_t status,int32_t cameraId)266 void CameraManagerGlobal::onStatusChangedLocked(
267         int32_t status, int32_t cameraId) {
268         if (!validStatus(status)) {
269             ALOGE("%s: Invalid status %d", __FUNCTION__, status);
270             return;
271         }
272 
273         bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
274         int32_t oldStatus = firstStatus ?
275                 status : // first status
276                 mDeviceStatusMap[cameraId];
277 
278         if (!firstStatus &&
279                 isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
280             // No status update. No need to send callback
281             return;
282         }
283 
284         // Iterate through all registered callbacks
285         mDeviceStatusMap[cameraId] = status;
286         for (auto cb : mCallbacks) {
287             sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
288             ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
289                     cb.mAvailable : cb.mUnavailable;
290             msg->setPointer(kCallbackFpKey, (void *) cbFp);
291             msg->setPointer(kContextKey, cb.mContext);
292             msg->setInt32(kCameraIdKey, cameraId);
293             msg->post();
294         }
295 }
296 
297 } // namespace android
298 
299 /**
300  * ACameraManger Implementation
301  */
302 camera_status_t
getOrCreateCameraIdListLocked(ACameraIdList ** cameraIdList)303 ACameraManager::getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList) {
304     if (mCachedCameraIdList.numCameras == kCameraIdListNotInit) {
305         int numCameras = 0;
306         Vector<char *> cameraIds;
307         sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
308         if (cs == nullptr) {
309             ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
310             return ACAMERA_ERROR_CAMERA_DISCONNECTED;
311         }
312         // Get number of cameras
313         int numAllCameras = 0;
314         binder::Status serviceRet = cs->getNumberOfCameras(hardware::ICameraService::CAMERA_TYPE_ALL,
315                 &numAllCameras);
316         if (!serviceRet.isOk()) {
317             ALOGE("%s: Error getting camera count: %s", __FUNCTION__,
318                     serviceRet.toString8().string());
319             numAllCameras = 0;
320         }
321         // Filter API2 compatible cameras and push to cameraIds
322         for (int i = 0; i < numAllCameras; i++) {
323             // TODO: Only suppot HALs that supports API2 directly now
324             bool camera2Support = false;
325             serviceRet = cs->supportsCameraApi(i, hardware::ICameraService::API_VERSION_2,
326                     &camera2Support);
327             char buf[kMaxCameraIdLen];
328             if (camera2Support) {
329                 numCameras++;
330                 mCameraIds.insert(i);
331                 snprintf(buf, sizeof(buf), "%d", i);
332                 size_t cameraIdSize = strlen(buf) + 1;
333                 char *cameraId = new char[cameraIdSize];
334                 if (!cameraId) {
335                     ALOGE("Allocate memory for ACameraIdList failed!");
336                     return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
337                 }
338                 strlcpy(cameraId, buf, cameraIdSize);
339                 cameraIds.push(cameraId);
340             }
341         }
342         mCachedCameraIdList.numCameras = numCameras;
343         mCachedCameraIdList.cameraIds = new const char*[numCameras];
344         if (!mCachedCameraIdList.cameraIds) {
345             ALOGE("Allocate memory for ACameraIdList failed!");
346             return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
347         }
348         for (int i = 0; i < numCameras; i++) {
349             mCachedCameraIdList.cameraIds[i] = cameraIds[i];
350         }
351     }
352     *cameraIdList = &mCachedCameraIdList;
353     return ACAMERA_OK;
354 }
355 
356 camera_status_t
getCameraIdList(ACameraIdList ** cameraIdList)357 ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
358     Mutex::Autolock _l(mLock);
359     ACameraIdList* cachedList;
360     camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList);
361     if (ret != ACAMERA_OK) {
362         ALOGE("Get camera ID list failed! err: %d", ret);
363         return ret;
364     }
365 
366     int numCameras = cachedList->numCameras;
367     ACameraIdList *out = new ACameraIdList;
368     if (!out) {
369         ALOGE("Allocate memory for ACameraIdList failed!");
370         return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
371     }
372     out->numCameras = numCameras;
373     out->cameraIds = new const char*[numCameras];
374     if (!out->cameraIds) {
375         ALOGE("Allocate memory for ACameraIdList failed!");
376         return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
377     }
378     for (int i = 0; i < numCameras; i++) {
379         const char* src = cachedList->cameraIds[i];
380         size_t dstSize = strlen(src) + 1;
381         char* dst = new char[dstSize];
382         if (!dst) {
383             ALOGE("Allocate memory for ACameraIdList failed!");
384             return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
385         }
386         strlcpy(dst, src, dstSize);
387         out->cameraIds[i] = dst;
388     }
389     *cameraIdList = out;
390     return ACAMERA_OK;
391 }
392 
393 void
deleteCameraIdList(ACameraIdList * cameraIdList)394 ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
395     if (cameraIdList != nullptr) {
396         if (cameraIdList->cameraIds != nullptr) {
397             for (int i = 0; i < cameraIdList->numCameras; i ++) {
398                 delete[] cameraIdList->cameraIds[i];
399             }
400             delete[] cameraIdList->cameraIds;
401         }
402         delete cameraIdList;
403     }
404 }
405 
getCameraCharacteristics(const char * cameraIdStr,ACameraMetadata ** characteristics)406 camera_status_t ACameraManager::getCameraCharacteristics(
407         const char *cameraIdStr, ACameraMetadata **characteristics) {
408     Mutex::Autolock _l(mLock);
409     ACameraIdList* cachedList;
410     // Make sure mCameraIds is initialized
411     camera_status_t ret = getOrCreateCameraIdListLocked(&cachedList);
412     if (ret != ACAMERA_OK) {
413         ALOGE("%s: Get camera ID list failed! err: %d", __FUNCTION__, ret);
414         return ret;
415     }
416     int cameraId = atoi(cameraIdStr);
417     if (mCameraIds.count(cameraId) == 0) {
418         ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
419         return ACAMERA_ERROR_INVALID_PARAMETER;
420     }
421     sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
422     if (cs == nullptr) {
423         ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
424         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
425     }
426     CameraMetadata rawMetadata;
427     binder::Status serviceRet = cs->getCameraCharacteristics(cameraId, &rawMetadata);
428     if (!serviceRet.isOk()) {
429         ALOGE("Get camera characteristics from camera service failed: %s",
430                 serviceRet.toString8().string());
431         return ACAMERA_ERROR_UNKNOWN; // should not reach here
432     }
433 
434     *characteristics = new ACameraMetadata(
435             rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
436     return ACAMERA_OK;
437 }
438 
439 camera_status_t
openCamera(const char * cameraId,ACameraDevice_StateCallbacks * callback,ACameraDevice ** outDevice)440 ACameraManager::openCamera(
441         const char* cameraId,
442         ACameraDevice_StateCallbacks* callback,
443         /*out*/ACameraDevice** outDevice) {
444     ACameraMetadata* rawChars;
445     camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
446     Mutex::Autolock _l(mLock);
447     if (ret != ACAMERA_OK) {
448         ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
449                 __FUNCTION__, cameraId, ret);
450         return ACAMERA_ERROR_INVALID_PARAMETER;
451     }
452     std::unique_ptr<ACameraMetadata> chars(rawChars);
453     rawChars = nullptr;
454 
455     ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars));
456 
457     sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
458     if (cs == nullptr) {
459         ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
460         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
461     }
462 
463     int id = atoi(cameraId);
464     sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
465     sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
466     // No way to get package name from native.
467     // Send a zero length package name and let camera service figure it out from UID
468     binder::Status serviceRet = cs->connectDevice(
469             callbacks, id, String16(""),
470             hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
471 
472     if (!serviceRet.isOk()) {
473         ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
474         // Convert serviceRet to camera_status_t
475         switch(serviceRet.serviceSpecificErrorCode()) {
476             case hardware::ICameraService::ERROR_DISCONNECTED:
477                 ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
478                 break;
479             case hardware::ICameraService::ERROR_CAMERA_IN_USE:
480                 ret = ACAMERA_ERROR_CAMERA_IN_USE;
481                 break;
482             case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
483                 ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
484                 break;
485             case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
486                 ret = ACAMERA_ERROR_INVALID_PARAMETER;
487                 break;
488             case hardware::ICameraService::ERROR_DEPRECATED_HAL:
489                 // Should not reach here since we filtered legacy HALs earlier
490                 ret = ACAMERA_ERROR_INVALID_PARAMETER;
491                 break;
492             case hardware::ICameraService::ERROR_DISABLED:
493                 ret = ACAMERA_ERROR_CAMERA_DISABLED;
494                 break;
495             case hardware::ICameraService::ERROR_PERMISSION_DENIED:
496                 ret = ACAMERA_ERROR_PERMISSION_DENIED;
497                 break;
498             case hardware::ICameraService::ERROR_INVALID_OPERATION:
499             default:
500                 ret = ACAMERA_ERROR_UNKNOWN;
501                 break;
502         }
503 
504         delete device;
505         return ret;
506     }
507     if (deviceRemote == nullptr) {
508         ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
509         delete device;
510         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
511     }
512     device->setRemoteDevice(deviceRemote);
513     *outDevice = device;
514     return ACAMERA_OK;
515 }
516 
~ACameraManager()517 ACameraManager::~ACameraManager() {
518     Mutex::Autolock _l(mLock);
519     if (mCachedCameraIdList.numCameras != kCameraIdListNotInit) {
520         for (int i = 0; i < mCachedCameraIdList.numCameras; i++) {
521             delete[] mCachedCameraIdList.cameraIds[i];
522         }
523         delete[] mCachedCameraIdList.cameraIds;
524     }
525 }
526