ACameraManager.cpp revision 02bf03287652923b5bb5316667b065423565d6b4
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
28using namespace android;
29
30//constants shared between ACameraManager and CameraManagerGlobal
31namespace {
32    const int kMaxCameraIdLen = 32;
33}
34
35namespace android {
36// Static member definitions
37const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
38const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
39const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
40Mutex                CameraManagerGlobal::sLock;
41CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
42
43CameraManagerGlobal&
44CameraManagerGlobal::getInstance() {
45    Mutex::Autolock _l(sLock);
46    CameraManagerGlobal* instance = sInstance;
47    if (instance == nullptr) {
48        instance = new CameraManagerGlobal();
49        sInstance = instance;
50    }
51    return *instance;
52}
53
54CameraManagerGlobal::~CameraManagerGlobal() {
55    // clear sInstance so next getInstance call knows to create a new one
56    Mutex::Autolock _sl(sLock);
57    sInstance = nullptr;
58    Mutex::Autolock _l(mLock);
59    if (mCameraService != nullptr) {
60        IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
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
74sp<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
143void 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
159void 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
181void CameraManagerGlobal::unregisterAvailabilityCallback(
182        const ACameraManager_AvailabilityCallbacks *callback) {
183    Mutex::Autolock _l(mLock);
184    Callback cb(callback);
185    mCallbacks.erase(cb);
186}
187
188bool 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
200bool 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
209void 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
217void 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
249binder::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
260void CameraManagerGlobal::onStatusChanged(
261        int32_t status, int32_t cameraId) {
262    Mutex::Autolock _l(mLock);
263    onStatusChangedLocked(status, cameraId);
264}
265
266void 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 */
302camera_status_t
303ACameraManager::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
356camera_status_t
357ACameraManager::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
393void
394ACameraManager::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
406camera_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
439camera_status_t
440ACameraManager::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        delete device;
475        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
476    }
477    if (deviceRemote == nullptr) {
478        ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
479        delete device;
480        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
481    }
482    device->setRemoteDevice(deviceRemote);
483    *outDevice = device;
484    return ACAMERA_OK;
485}
486
487ACameraManager::~ACameraManager() {
488    Mutex::Autolock _l(mLock);
489    if (mCachedCameraIdList.numCameras != kCameraIdListNotInit) {
490        for (int i = 0; i < mCachedCameraIdList.numCameras; i++) {
491            delete[] mCachedCameraIdList.cameraIds[i];
492        }
493        delete[] mCachedCameraIdList.cameraIds;
494    }
495}
496