ACameraManager.cpp revision f51fca277eb5b86bd0b2e3fc90ecb2b63089de29
10dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/*
20dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Copyright (C) 2015 The Android Open Source Project
30dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh *
40dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Licensed under the Apache License, Version 2.0 (the "License");
50dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * you may not use this file except in compliance with the License.
60dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * You may obtain a copy of the License at
70dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh *
80dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh *      http://www.apache.org/licenses/LICENSE-2.0
90dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh *
100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Unless required by applicable law or agreed to in writing, software
110dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * distributed under the License is distributed on an "AS IS" BASIS,
120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * See the License for the specific language governing permissions and
140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * limitations under the License.
150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */
160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh//#define LOG_NDEBUG 0
180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#define LOG_TAG "ACameraManager"
190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <memory>
210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include "ACameraManager.h"
220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include "ACameraMetadata.h"
230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include "ACameraDevice.h"
240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <utils/Vector.h>
25ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov#include <cutils/properties.h>
260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <stdlib.h>
270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <camera/VendorTagDescriptor.h>
280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehusing namespace android;
300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehnamespace android {
320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh// Static member definitions
330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehconst char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehconst char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehconst char* CameraManagerGlobal::kContextKey    = "CallbackContext";
360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehMutex                CameraManagerGlobal::sLock;
370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehCameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehCameraManagerGlobal&
400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehCameraManagerGlobal::getInstance() {
410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(sLock);
420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    CameraManagerGlobal* instance = sInstance;
430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (instance == nullptr) {
440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        instance = new CameraManagerGlobal();
450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sInstance = instance;
460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return *instance;
480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehCameraManagerGlobal::~CameraManagerGlobal() {
510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // clear sInstance so next getInstance call knows to create a new one
520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _sl(sLock);
530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sInstance = nullptr;
540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (mCameraService != nullptr) {
560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        IInterface::asBinder(mCameraService)->unlinkToDeath(mDeathNotifier);
57ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh        mCameraService->removeListener(mCameraServiceListener);
580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mDeathNotifier.clear();
600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (mCbLooper != nullptr) {
610dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        mCbLooper->unregisterHandler(mHandler->id());
620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        mCbLooper->stop();
630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mCbLooper.clear();
650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mHandler.clear();
660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mCameraServiceListener.clear();
670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mCameraService.clear();
680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
70ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogovstatic bool isCameraServiceDisabled() {
71ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov    char value[PROPERTY_VALUE_MAX];
72ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov    property_get("config.disable_cameraservice", value, "0");
73ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov    return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
74ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov}
75ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov
76d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalasp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
770dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (mCameraService.get() == nullptr) {
79ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov        if (isCameraServiceDisabled()) {
80ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov            return mCameraService;
81ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov        }
82ee844a800889eca5dfe658fbd953946ca1920faeIvan Podogov
830dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IServiceManager> sm = defaultServiceManager();
840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        sp<IBinder> binder;
850dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        do {
860dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            binder = sm->getService(String16(kCameraServiceName));
870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (binder != nullptr) {
880dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                break;
890dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
900dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGW("CameraService not published, waiting...");
910dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            usleep(kCameraServicePollDelay);
920dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        } while(true);
930dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (mDeathNotifier == nullptr) {
940dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mDeathNotifier = new DeathNotifier(this);
950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        binder->linkToDeath(mDeathNotifier);
97d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        mCameraService = interface_cast<hardware::ICameraService>(binder);
980dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        // Setup looper thread to perfrom availiability callbacks
1000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (mCbLooper == nullptr) {
1010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mCbLooper = new ALooper;
1020dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mCbLooper->setName("C2N-mgr-looper");
10302bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala            status_t err = mCbLooper->start(
1040dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    /*runOnCallingThread*/false,
1050dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    /*canCallJava*/       true,
106ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh                    PRIORITY_DEFAULT);
10702bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala            if (err != OK) {
10802bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala                ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
10902bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala                        __FUNCTION__, strerror(-err), err);
11002bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala                mCbLooper.clear();
11102bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala                return nullptr;
11202bf03287652923b5bb5316667b065423565d6b4Eino-Ville Talvala            }
1130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (mHandler == nullptr) {
1140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                mHandler = new CallbackHandler();
1150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
1160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mCbLooper->registerHandler(mHandler);
1170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        // register ICameraServiceListener
1200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (mCameraServiceListener == nullptr) {
1210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mCameraServiceListener = new CameraServiceListener(this);
1220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
123f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        std::vector<hardware::CameraStatus> cameraStatuses{};
124f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        mCameraService->addListener(mCameraServiceListener, &cameraStatuses);
125f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        for (auto& c : cameraStatuses) {
126f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            onStatusChangedLocked(c.status, c.cameraId);
127f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
1280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        // setup vendor tags
130d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
131d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        binder::Status ret = mCameraService->getCameraVendorTagDescriptor(/*out*/desc.get());
1320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
133d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        if (ret.isOk()) {
134d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
135d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            if (err != OK) {
1360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
137d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                        __FUNCTION__, strerror(-err), err);
1380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
139d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        } else if (ret.serviceSpecificErrorCode() ==
140d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                hardware::ICameraService::ERROR_DEPRECATED_HAL) {
1410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGW("%s: Camera HAL too old; does not support vendor tags",
1420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    __FUNCTION__);
1430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            VendorTagDescriptor::clearGlobalVendorTagDescriptor();
1440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        } else {
145d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: Failed to get vendor tag descriptors: %s",
146d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __FUNCTION__, ret.toString8().string());
1470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
1490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
1500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return mCameraService;
1510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
1520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
1540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh{
1550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ALOGE("Camera service binderDied!");
1560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<CameraManagerGlobal> cm = mCameraManager.promote();
1570dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cm != nullptr) {
1580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        AutoMutex lock(cm->mLock);
159f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        for (auto& pair : cm->mDeviceStatusMap) {
160f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            const String8 &cameraId = pair.first;
1610dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            cm->onStatusChangedLocked(
162d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
1630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        cm->mCameraService.clear();
1650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        // TODO: consider adding re-connect call here?
1660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
1670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
1680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::registerAvailabilityCallback(
1700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const ACameraManager_AvailabilityCallbacks *callback) {
1710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
1720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Callback cb(callback);
1730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    auto pair = mCallbacks.insert(cb);
1740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // Send initial callbacks if callback is newly registered
1750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (pair.second) {
176f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        for (auto& pair : mDeviceStatusMap) {
177f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            const String8& cameraId = pair.first;
178d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            int32_t status = pair.second;
1790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
1810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
1820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    callback->onCameraAvailable : callback->onCameraUnavailable;
1830dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            msg->setPointer(kCallbackFpKey, (void *) cb);
1840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            msg->setPointer(kContextKey, callback->context);
185f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            msg->setString(kCameraIdKey, AString(cameraId));
1860dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            msg->post();
1870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1880dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
1890dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
1900dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1910dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::unregisterAvailabilityCallback(
1920dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const ACameraManager_AvailabilityCallbacks *callback) {
1930dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
1940dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Callback cb(callback);
1950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mCallbacks.erase(cb);
1960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
1970dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
198f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraManagerGlobal::getCameraIdList(std::vector<String8> *cameraIds) {
199f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // Ensure that we have initialized/refreshed the list of available devices
200f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    auto cs = getCameraService();
201f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    Mutex::Autolock _l(mLock);
202f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
203f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    for(auto& deviceStatus : mDeviceStatusMap) {
204f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (deviceStatus.second == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
205f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                deviceStatus.second == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
206f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            continue;
207f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
208f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        bool camera2Support = false;
209f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        binder::Status serviceRet = cs->supportsCameraApi(String16(deviceStatus.first),
210f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                hardware::ICameraService::API_VERSION_2, &camera2Support);
211f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (!serviceRet.isOk() || !camera2Support) {
212f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            continue;
213f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
214f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        cameraIds->push_back(deviceStatus.first);
215f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
216f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
217f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
218d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabool CameraManagerGlobal::validStatus(int32_t status) {
2190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    switch (status) {
220d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
221d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_PRESENT:
222d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_ENUMERATING:
223d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
2240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return true;
2250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        default:
2260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return false;
2270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
230d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabool CameraManagerGlobal::isStatusAvailable(int32_t status) {
2310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    switch (status) {
232d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_PRESENT:
2330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return true;
2340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        default:
2350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return false;
2360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
2390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::CallbackHandler::onMessageReceived(
2400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const sp<AMessage> &msg) {
2410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    switch (msg->what()) {
2420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        case kWhatSendSingleCallback:
2430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        {
2440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ACameraManager_AvailabilityCallback cb;
2450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            void* context;
246f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            AString cameraId;
2470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
2480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (!found) {
2490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
2500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                return;
2510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
2520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            found = msg->findPointer(kContextKey, &context);
2530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (!found) {
2540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                ALOGE("%s: Cannot find callback context!", __FUNCTION__);
2550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                return;
2560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
257f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            found = msg->findString(kCameraIdKey, &cameraId);
2580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (!found) {
2590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
2600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                return;
2610dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
262f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (*cb)(context, cameraId.c_str());
2630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            break;
2640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
2650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        default:
2660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
2670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            break;
2680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
271d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
272f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int32_t status, const String16& cameraId) {
2730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<CameraManagerGlobal> cm = mCameraManager.promote();
274d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (cm != nullptr) {
275f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        cm->onStatusChanged(status, String8(cameraId));
276d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
277ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh        ALOGE("Cannot deliver status change. Global camera manager died");
2780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
279d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return binder::Status::ok();
2800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
2820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::onStatusChanged(
283f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int32_t status, const String8& cameraId) {
2840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
2850dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    onStatusChangedLocked(status, cameraId);
2860dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
2880dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::onStatusChangedLocked(
289f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int32_t status, const String8& cameraId) {
290f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (!validStatus(status)) {
291f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ALOGE("%s: Invalid status %d", __FUNCTION__, status);
292f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
293f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
2940dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
295f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
296f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t oldStatus = firstStatus ?
297f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            status : // first status
298f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mDeviceStatusMap[cameraId];
2990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
300f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (!firstStatus &&
301f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
302f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // No status update. No need to send callback
303f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
304f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
3050dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
306f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // Iterate through all registered callbacks
307f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mDeviceStatusMap[cameraId] = status;
308f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    for (auto cb : mCallbacks) {
309f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
310f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
311f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                cb.mAvailable : cb.mUnavailable;
312f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->setPointer(kCallbackFpKey, (void *) cbFp);
313f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->setPointer(kContextKey, cb.mContext);
314f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->setString(kCameraIdKey, AString(cameraId));
315f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->post();
316f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
3170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
3180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh} // namespace android
3200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/**
3220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * ACameraManger Implementation
3230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */
3240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehcamera_status_t
3250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
3260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
3270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
328f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    std::vector<String8> idList;
329f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    CameraManagerGlobal::getInstance().getCameraIdList(&idList);
330f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
331f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int numCameras = idList.size();
3320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ACameraIdList *out = new ACameraIdList;
3330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (!out) {
3340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("Allocate memory for ACameraIdList failed!");
3350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
3360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    out->numCameras = numCameras;
338f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    out->cameraIds = new const char*[numCameras] {nullptr};
3390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (!out->cameraIds) {
3400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("Allocate memory for ACameraIdList failed!");
341f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        deleteCameraIdList(out);
3420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
3430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    for (int i = 0; i < numCameras; i++) {
345f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const char* src = idList[i].string();
3460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        size_t dstSize = strlen(src) + 1;
3470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        char* dst = new char[dstSize];
3480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (!dst) {
3490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("Allocate memory for ACameraIdList failed!");
350f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            deleteCameraIdList(out);
3510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
3520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
3530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        strlcpy(dst, src, dstSize);
3540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        out->cameraIds[i] = dst;
3550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    *cameraIdList = out;
3570dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return ACAMERA_OK;
3580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
3590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid
3610dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
3620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cameraIdList != nullptr) {
3630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (cameraIdList->cameraIds != nullptr) {
3640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            for (int i = 0; i < cameraIdList->numCameras; i ++) {
365f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (cameraIdList->cameraIds[i] != nullptr) {
366f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    delete[] cameraIdList->cameraIds[i];
367f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                }
3680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
3690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            delete[] cameraIdList->cameraIds;
3700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
3710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        delete cameraIdList;
3720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
3740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehcamera_status_t ACameraManager::getCameraCharacteristics(
3760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const char *cameraIdStr, ACameraMetadata **characteristics) {
3770dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
378f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
379d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
3800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cs == nullptr) {
3810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
3820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
3830dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    CameraMetadata rawMetadata;
385f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr), &rawMetadata);
386d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!serviceRet.isOk()) {
387f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        switch(serviceRet.serviceSpecificErrorCode()) {
388f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            case hardware::ICameraService::ERROR_DISCONNECTED:
389f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
390f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                return ACAMERA_ERROR_CAMERA_DISCONNECTED;
391f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
392f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
393f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                return ACAMERA_ERROR_INVALID_PARAMETER;
394f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            default:
395f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("Get camera characteristics from camera service failed: %s",
396f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                        serviceRet.toString8().string());
397f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                return ACAMERA_ERROR_UNKNOWN; // should not reach here
398f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
3990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    *characteristics = new ACameraMetadata(
4020dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
4030dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return ACAMERA_OK;
4040dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
4050dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4060dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehcamera_status_t
4070dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::openCamera(
4080dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const char* cameraId,
4090dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ACameraDevice_StateCallbacks* callback,
4100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        /*out*/ACameraDevice** outDevice) {
4110dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ACameraMetadata* rawChars;
4120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
4130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
4140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (ret != ACAMERA_OK) {
4150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
4160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                __FUNCTION__, cameraId, ret);
4170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_INVALID_PARAMETER;
4180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    std::unique_ptr<ACameraMetadata> chars(rawChars);
4200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    rawChars = nullptr;
4210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars));
4230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
424d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
4250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cs == nullptr) {
4260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
427b01d8f7d7853e6cd4ea1256fe3dfb2e4a79cf09aYunlian Jiang        delete device;
4280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
4290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
431d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
432d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
4330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // No way to get package name from native.
4340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // Send a zero length package name and let camera service figure it out from UID
435d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status serviceRet = cs->connectDevice(
436f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            callbacks, String16(cameraId), String16(""),
437d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
4380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
439d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!serviceRet.isOk()) {
440d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
4413e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        // Convert serviceRet to camera_status_t
4423e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        switch(serviceRet.serviceSpecificErrorCode()) {
4433e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_DISCONNECTED:
4443e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
4453e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4463e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_CAMERA_IN_USE:
4473e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_CAMERA_IN_USE;
4483e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4493e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
4503e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
4513e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4523e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
4533e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_INVALID_PARAMETER;
4543e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4553e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_DEPRECATED_HAL:
4563e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                // Should not reach here since we filtered legacy HALs earlier
4573e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_INVALID_PARAMETER;
4583e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4593e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_DISABLED:
4603e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_CAMERA_DISABLED;
4613e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4623e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_PERMISSION_DENIED:
4633e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_PERMISSION_DENIED;
4643e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4653e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_INVALID_OPERATION:
4663e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            default:
4673e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_UNKNOWN;
4683e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4693e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        }
4703e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh
4710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        delete device;
4723e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        return ret;
4730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (deviceRemote == nullptr) {
4750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
4760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        delete device;
4770dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
4780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    device->setRemoteDevice(deviceRemote);
4800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    *outDevice = device;
4810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return ACAMERA_OK;
4820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
4830dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::~ACameraManager() {
485f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
4860dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
487