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