ACameraManager.cpp revision f51fca277eb5b86bd0b2e3fc90ecb2b63089de29
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
29using namespace android;
30
31namespace android {
32// Static member definitions
33const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
34const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
35const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
36Mutex                CameraManagerGlobal::sLock;
37CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
38
39CameraManagerGlobal&
40CameraManagerGlobal::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
50CameraManagerGlobal::~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
70static 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
76sp<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            status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
135            if (err != OK) {
136                ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
137                        __FUNCTION__, strerror(-err), err);
138            }
139        } else if (ret.serviceSpecificErrorCode() ==
140                hardware::ICameraService::ERROR_DEPRECATED_HAL) {
141            ALOGW("%s: Camera HAL too old; does not support vendor tags",
142                    __FUNCTION__);
143            VendorTagDescriptor::clearGlobalVendorTagDescriptor();
144        } else {
145            ALOGE("%s: Failed to get vendor tag descriptors: %s",
146                    __FUNCTION__, ret.toString8().string());
147        }
148    }
149    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
150    return mCameraService;
151}
152
153void CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
154{
155    ALOGE("Camera service binderDied!");
156    sp<CameraManagerGlobal> cm = mCameraManager.promote();
157    if (cm != nullptr) {
158        AutoMutex lock(cm->mLock);
159        for (auto& pair : cm->mDeviceStatusMap) {
160            const String8 &cameraId = pair.first;
161            cm->onStatusChangedLocked(
162                    CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
163        }
164        cm->mCameraService.clear();
165        // TODO: consider adding re-connect call here?
166    }
167}
168
169void CameraManagerGlobal::registerAvailabilityCallback(
170        const ACameraManager_AvailabilityCallbacks *callback) {
171    Mutex::Autolock _l(mLock);
172    Callback cb(callback);
173    auto pair = mCallbacks.insert(cb);
174    // Send initial callbacks if callback is newly registered
175    if (pair.second) {
176        for (auto& pair : mDeviceStatusMap) {
177            const String8& cameraId = pair.first;
178            int32_t status = pair.second;
179
180            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
181            ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
182                    callback->onCameraAvailable : callback->onCameraUnavailable;
183            msg->setPointer(kCallbackFpKey, (void *) cb);
184            msg->setPointer(kContextKey, callback->context);
185            msg->setString(kCameraIdKey, AString(cameraId));
186            msg->post();
187        }
188    }
189}
190
191void CameraManagerGlobal::unregisterAvailabilityCallback(
192        const ACameraManager_AvailabilityCallbacks *callback) {
193    Mutex::Autolock _l(mLock);
194    Callback cb(callback);
195    mCallbacks.erase(cb);
196}
197
198void CameraManagerGlobal::getCameraIdList(std::vector<String8> *cameraIds) {
199    // Ensure that we have initialized/refreshed the list of available devices
200    auto cs = getCameraService();
201    Mutex::Autolock _l(mLock);
202
203    for(auto& deviceStatus : mDeviceStatusMap) {
204        if (deviceStatus.second == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
205                deviceStatus.second == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
206            continue;
207        }
208        bool camera2Support = false;
209        binder::Status serviceRet = cs->supportsCameraApi(String16(deviceStatus.first),
210                hardware::ICameraService::API_VERSION_2, &camera2Support);
211        if (!serviceRet.isOk() || !camera2Support) {
212            continue;
213        }
214        cameraIds->push_back(deviceStatus.first);
215    }
216}
217
218bool CameraManagerGlobal::validStatus(int32_t status) {
219    switch (status) {
220        case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
221        case hardware::ICameraServiceListener::STATUS_PRESENT:
222        case hardware::ICameraServiceListener::STATUS_ENUMERATING:
223        case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
224            return true;
225        default:
226            return false;
227    }
228}
229
230bool CameraManagerGlobal::isStatusAvailable(int32_t status) {
231    switch (status) {
232        case hardware::ICameraServiceListener::STATUS_PRESENT:
233            return true;
234        default:
235            return false;
236    }
237}
238
239void CameraManagerGlobal::CallbackHandler::onMessageReceived(
240        const sp<AMessage> &msg) {
241    switch (msg->what()) {
242        case kWhatSendSingleCallback:
243        {
244            ACameraManager_AvailabilityCallback cb;
245            void* context;
246            AString cameraId;
247            bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
248            if (!found) {
249                ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
250                return;
251            }
252            found = msg->findPointer(kContextKey, &context);
253            if (!found) {
254                ALOGE("%s: Cannot find callback context!", __FUNCTION__);
255                return;
256            }
257            found = msg->findString(kCameraIdKey, &cameraId);
258            if (!found) {
259                ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
260                return;
261            }
262            (*cb)(context, cameraId.c_str());
263            break;
264        }
265        default:
266            ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
267            break;
268    }
269}
270
271binder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
272        int32_t status, const String16& cameraId) {
273    sp<CameraManagerGlobal> cm = mCameraManager.promote();
274    if (cm != nullptr) {
275        cm->onStatusChanged(status, String8(cameraId));
276    } else {
277        ALOGE("Cannot deliver status change. Global camera manager died");
278    }
279    return binder::Status::ok();
280}
281
282void CameraManagerGlobal::onStatusChanged(
283        int32_t status, const String8& cameraId) {
284    Mutex::Autolock _l(mLock);
285    onStatusChangedLocked(status, cameraId);
286}
287
288void CameraManagerGlobal::onStatusChangedLocked(
289        int32_t status, const String8& cameraId) {
290    if (!validStatus(status)) {
291        ALOGE("%s: Invalid status %d", __FUNCTION__, status);
292        return;
293    }
294
295    bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
296    int32_t oldStatus = firstStatus ?
297            status : // first status
298            mDeviceStatusMap[cameraId];
299
300    if (!firstStatus &&
301            isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
302        // No status update. No need to send callback
303        return;
304    }
305
306    // Iterate through all registered callbacks
307    mDeviceStatusMap[cameraId] = status;
308    for (auto cb : mCallbacks) {
309        sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
310        ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
311                cb.mAvailable : cb.mUnavailable;
312        msg->setPointer(kCallbackFpKey, (void *) cbFp);
313        msg->setPointer(kContextKey, cb.mContext);
314        msg->setString(kCameraIdKey, AString(cameraId));
315        msg->post();
316    }
317}
318
319} // namespace android
320
321/**
322 * ACameraManger Implementation
323 */
324camera_status_t
325ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
326    Mutex::Autolock _l(mLock);
327
328    std::vector<String8> idList;
329    CameraManagerGlobal::getInstance().getCameraIdList(&idList);
330
331    int numCameras = idList.size();
332    ACameraIdList *out = new ACameraIdList;
333    if (!out) {
334        ALOGE("Allocate memory for ACameraIdList failed!");
335        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
336    }
337    out->numCameras = numCameras;
338    out->cameraIds = new const char*[numCameras] {nullptr};
339    if (!out->cameraIds) {
340        ALOGE("Allocate memory for ACameraIdList failed!");
341        deleteCameraIdList(out);
342        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
343    }
344    for (int i = 0; i < numCameras; i++) {
345        const char* src = idList[i].string();
346        size_t dstSize = strlen(src) + 1;
347        char* dst = new char[dstSize];
348        if (!dst) {
349            ALOGE("Allocate memory for ACameraIdList failed!");
350            deleteCameraIdList(out);
351            return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
352        }
353        strlcpy(dst, src, dstSize);
354        out->cameraIds[i] = dst;
355    }
356    *cameraIdList = out;
357    return ACAMERA_OK;
358}
359
360void
361ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
362    if (cameraIdList != nullptr) {
363        if (cameraIdList->cameraIds != nullptr) {
364            for (int i = 0; i < cameraIdList->numCameras; i ++) {
365                if (cameraIdList->cameraIds[i] != nullptr) {
366                    delete[] cameraIdList->cameraIds[i];
367                }
368            }
369            delete[] cameraIdList->cameraIds;
370        }
371        delete cameraIdList;
372    }
373}
374
375camera_status_t ACameraManager::getCameraCharacteristics(
376        const char *cameraIdStr, ACameraMetadata **characteristics) {
377    Mutex::Autolock _l(mLock);
378
379    sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
380    if (cs == nullptr) {
381        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
382        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
383    }
384    CameraMetadata rawMetadata;
385    binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr), &rawMetadata);
386    if (!serviceRet.isOk()) {
387        switch(serviceRet.serviceSpecificErrorCode()) {
388            case hardware::ICameraService::ERROR_DISCONNECTED:
389                ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
390                return ACAMERA_ERROR_CAMERA_DISCONNECTED;
391            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
392                ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
393                return ACAMERA_ERROR_INVALID_PARAMETER;
394            default:
395                ALOGE("Get camera characteristics from camera service failed: %s",
396                        serviceRet.toString8().string());
397                return ACAMERA_ERROR_UNKNOWN; // should not reach here
398        }
399    }
400
401    *characteristics = new ACameraMetadata(
402            rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
403    return ACAMERA_OK;
404}
405
406camera_status_t
407ACameraManager::openCamera(
408        const char* cameraId,
409        ACameraDevice_StateCallbacks* callback,
410        /*out*/ACameraDevice** outDevice) {
411    ACameraMetadata* rawChars;
412    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
413    Mutex::Autolock _l(mLock);
414    if (ret != ACAMERA_OK) {
415        ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
416                __FUNCTION__, cameraId, ret);
417        return ACAMERA_ERROR_INVALID_PARAMETER;
418    }
419    std::unique_ptr<ACameraMetadata> chars(rawChars);
420    rawChars = nullptr;
421
422    ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars));
423
424    sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
425    if (cs == nullptr) {
426        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
427        delete device;
428        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
429    }
430
431    sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
432    sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
433    // No way to get package name from native.
434    // Send a zero length package name and let camera service figure it out from UID
435    binder::Status serviceRet = cs->connectDevice(
436            callbacks, String16(cameraId), String16(""),
437            hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
438
439    if (!serviceRet.isOk()) {
440        ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
441        // Convert serviceRet to camera_status_t
442        switch(serviceRet.serviceSpecificErrorCode()) {
443            case hardware::ICameraService::ERROR_DISCONNECTED:
444                ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
445                break;
446            case hardware::ICameraService::ERROR_CAMERA_IN_USE:
447                ret = ACAMERA_ERROR_CAMERA_IN_USE;
448                break;
449            case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
450                ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
451                break;
452            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
453                ret = ACAMERA_ERROR_INVALID_PARAMETER;
454                break;
455            case hardware::ICameraService::ERROR_DEPRECATED_HAL:
456                // Should not reach here since we filtered legacy HALs earlier
457                ret = ACAMERA_ERROR_INVALID_PARAMETER;
458                break;
459            case hardware::ICameraService::ERROR_DISABLED:
460                ret = ACAMERA_ERROR_CAMERA_DISABLED;
461                break;
462            case hardware::ICameraService::ERROR_PERMISSION_DENIED:
463                ret = ACAMERA_ERROR_PERMISSION_DENIED;
464                break;
465            case hardware::ICameraService::ERROR_INVALID_OPERATION:
466            default:
467                ret = ACAMERA_ERROR_UNKNOWN;
468                break;
469        }
470
471        delete device;
472        return ret;
473    }
474    if (deviceRemote == nullptr) {
475        ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
476        delete device;
477        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
478    }
479    device->setRemoteDevice(deviceRemote);
480    *outDevice = device;
481    return ACAMERA_OK;
482}
483
484ACameraManager::~ACameraManager() {
485
486}
487