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()) {
13471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            if (0 < desc->getTagCount()) {
13571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                status_t err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
13671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                if (err != OK) {
13771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    ALOGE("%s: Failed to set vendor tag descriptors, received error %s (%d)",
13871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                            __FUNCTION__, strerror(-err), err);
13971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                }
14071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev            } else {
14171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                sp<VendorTagDescriptorCache> cache =
14271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                        new VendorTagDescriptorCache();
14371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                binder::Status res =
14471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                        mCameraService->getCameraVendorTagCache(
14571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                                /*out*/cache.get());
14671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                if (res.serviceSpecificErrorCode() ==
14771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                        hardware::ICameraService::ERROR_DISCONNECTED) {
14871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    // No camera module available, not an error on devices with no cameras
14971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    VendorTagDescriptorCache::clearGlobalVendorTagCache();
15071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                } else if (res.isOk()) {
15171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    status_t err =
15271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                            VendorTagDescriptorCache::setAsGlobalVendorTagCache(
15371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                                    cache);
15471c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    if (err != OK) {
15571c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                        ALOGE("%s: Failed to set vendor tag cache,"
15671c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                                "received error %s (%d)", __FUNCTION__,
15771c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                                strerror(-err), err);
15871c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    }
15971c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                } else {
16071c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    VendorTagDescriptorCache::clearGlobalVendorTagCache();
16171c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                    ALOGE("%s: Failed to setup vendor tag cache: %s",
16271c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                            __FUNCTION__, res.toString8().string());
16371c73a2985a7ac65ee597be3441ab300fa56e22eEmilian Peev                }
1640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
165d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        } else if (ret.serviceSpecificErrorCode() ==
166d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                hardware::ICameraService::ERROR_DEPRECATED_HAL) {
1670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGW("%s: Camera HAL too old; does not support vendor tags",
1680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    __FUNCTION__);
1690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            VendorTagDescriptor::clearGlobalVendorTagDescriptor();
1700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        } else {
171d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            ALOGE("%s: Failed to get vendor tag descriptors: %s",
172d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    __FUNCTION__, ret.toString8().string());
1730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
1750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ALOGE_IF(mCameraService == nullptr, "no CameraService!?");
1760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return mCameraService;
1770dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
1780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::DeathNotifier::binderDied(const wp<IBinder>&)
1800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh{
1810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ALOGE("Camera service binderDied!");
1820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<CameraManagerGlobal> cm = mCameraManager.promote();
1830dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cm != nullptr) {
1840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        AutoMutex lock(cm->mLock);
185f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        for (auto& pair : cm->mDeviceStatusMap) {
186f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            const String8 &cameraId = pair.first;
1870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            cm->onStatusChangedLocked(
188d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala                    CameraServiceListener::STATUS_NOT_PRESENT, cameraId);
1890dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1900dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        cm->mCameraService.clear();
1910dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        // TODO: consider adding re-connect call here?
1920dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
1930dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
1940dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::registerAvailabilityCallback(
1960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const ACameraManager_AvailabilityCallbacks *callback) {
1970dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
1980dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Callback cb(callback);
1990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    auto pair = mCallbacks.insert(cb);
2000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // Send initial callbacks if callback is newly registered
2010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (pair.second) {
202f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        for (auto& pair : mDeviceStatusMap) {
203f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            const String8& cameraId = pair.first;
204d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            int32_t status = pair.second;
2050dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
2060dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
2070dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
2080dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    callback->onCameraAvailable : callback->onCameraUnavailable;
2090dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            msg->setPointer(kCallbackFpKey, (void *) cb);
2100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            msg->setPointer(kContextKey, callback->context);
211f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            msg->setString(kCameraIdKey, AString(cameraId));
2120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            msg->post();
2130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
2140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
2170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::unregisterAvailabilityCallback(
2180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const ACameraManager_AvailabilityCallbacks *callback) {
2190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
2200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Callback cb(callback);
2210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    mCallbacks.erase(cb);
2220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
224f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvalavoid CameraManagerGlobal::getCameraIdList(std::vector<String8> *cameraIds) {
225f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // Ensure that we have initialized/refreshed the list of available devices
226f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    auto cs = getCameraService();
227f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    Mutex::Autolock _l(mLock);
228f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
229f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    for(auto& deviceStatus : mDeviceStatusMap) {
230f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (deviceStatus.second == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
231f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                deviceStatus.second == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
232f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            continue;
233f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
234f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        bool camera2Support = false;
235f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        binder::Status serviceRet = cs->supportsCameraApi(String16(deviceStatus.first),
236f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                hardware::ICameraService::API_VERSION_2, &camera2Support);
237f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        if (!serviceRet.isOk() || !camera2Support) {
238f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            continue;
239f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
240f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        cameraIds->push_back(deviceStatus.first);
241f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
242f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala}
243f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
244d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabool CameraManagerGlobal::validStatus(int32_t status) {
2450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    switch (status) {
246d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_NOT_PRESENT:
247d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_PRESENT:
248d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_ENUMERATING:
249d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_NOT_AVAILABLE:
2500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return true;
2510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        default:
2520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return false;
2530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
256d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabool CameraManagerGlobal::isStatusAvailable(int32_t status) {
2570dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    switch (status) {
258d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        case hardware::ICameraServiceListener::STATUS_PRESENT:
2590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return true;
2600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        default:
2610dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return false;
2620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
2650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::CallbackHandler::onMessageReceived(
2660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const sp<AMessage> &msg) {
2670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    switch (msg->what()) {
2680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        case kWhatSendSingleCallback:
2690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        {
2700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ACameraManager_AvailabilityCallback cb;
2710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            void* context;
272f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            AString cameraId;
2730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
2740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (!found) {
2750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
2760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                return;
2770dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
2780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            found = msg->findPointer(kContextKey, &context);
2790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (!found) {
2800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                ALOGE("%s: Cannot find callback context!", __FUNCTION__);
2810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                return;
2820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
283f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            found = msg->findString(kCameraIdKey, &cameraId);
2840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (!found) {
2850dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
2860dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                return;
2870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
288f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            (*cb)(context, cameraId.c_str());
2890dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            break;
2900dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
2910dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        default:
2920dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
2930dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            break;
2940dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
2950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
2960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
297d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvalabinder::Status CameraManagerGlobal::CameraServiceListener::onStatusChanged(
298f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int32_t status, const String16& cameraId) {
2990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<CameraManagerGlobal> cm = mCameraManager.promote();
300d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (cm != nullptr) {
301f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        cm->onStatusChanged(status, String8(cameraId));
302d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    } else {
303ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh        ALOGE("Cannot deliver status change. Global camera manager died");
3040dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
305d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    return binder::Status::ok();
3060dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
3070dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3080dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::onStatusChanged(
309f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int32_t status, const String8& cameraId) {
3100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
3110dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    onStatusChangedLocked(status, cameraId);
3120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
3130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid CameraManagerGlobal::onStatusChangedLocked(
315f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        int32_t status, const String8& cameraId) {
316f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (!validStatus(status)) {
317f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ALOGE("%s: Invalid status %d", __FUNCTION__, status);
318f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
319f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
3200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
321f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
322f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int32_t oldStatus = firstStatus ?
323f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            status : // first status
324f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            mDeviceStatusMap[cameraId];
3250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
326f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    if (!firstStatus &&
327f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
328f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        // No status update. No need to send callback
329f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        return;
330f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
3310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
332f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    // Iterate through all registered callbacks
333f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    mDeviceStatusMap[cameraId] = status;
334f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    for (auto cb : mCallbacks) {
335f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
336f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
337f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                cb.mAvailable : cb.mUnavailable;
338f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->setPointer(kCallbackFpKey, (void *) cbFp);
339f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->setPointer(kContextKey, cb.mContext);
340f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->setString(kCameraIdKey, AString(cameraId));
341f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        msg->post();
342f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    }
3430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
3440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh} // namespace android
3460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/**
3480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * ACameraManger Implementation
3490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */
3500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehcamera_status_t
3510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
3520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
3530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
354f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    std::vector<String8> idList;
355f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    CameraManagerGlobal::getInstance().getCameraIdList(&idList);
356f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
357f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    int numCameras = idList.size();
3580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ACameraIdList *out = new ACameraIdList;
3590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (!out) {
3600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("Allocate memory for ACameraIdList failed!");
3610dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
3620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    out->numCameras = numCameras;
3641a5954c3adc4dd6c265a7f454cc5d94825a0d1eeBjoern Johansson    out->cameraIds = new const char*[numCameras];
3650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (!out->cameraIds) {
3660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("Allocate memory for ACameraIdList failed!");
367f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        deleteCameraIdList(out);
3680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
3690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    for (int i = 0; i < numCameras; i++) {
371f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        const char* src = idList[i].string();
3720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        size_t dstSize = strlen(src) + 1;
3730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        char* dst = new char[dstSize];
3740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (!dst) {
3750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            ALOGE("Allocate memory for ACameraIdList failed!");
376f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            deleteCameraIdList(out);
3770dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
3780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
3790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        strlcpy(dst, src, dstSize);
3800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        out->cameraIds[i] = dst;
3810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    *cameraIdList = out;
3830dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return ACAMERA_OK;
3840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
3850dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
3860dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehvoid
3870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
3880dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cameraIdList != nullptr) {
3890dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        if (cameraIdList->cameraIds != nullptr) {
3900dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            for (int i = 0; i < cameraIdList->numCameras; i ++) {
391f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                if (cameraIdList->cameraIds[i] != nullptr) {
392f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                    delete[] cameraIdList->cameraIds[i];
393f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                }
3940dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            }
3950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            delete[] cameraIdList->cameraIds;
3960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
3970dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        delete cameraIdList;
3980dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
3990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
4000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehcamera_status_t ACameraManager::getCameraCharacteristics(
4020dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const char *cameraIdStr, ACameraMetadata **characteristics) {
4030dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
404f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
405d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
4060dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cs == nullptr) {
4070dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
4080dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
4090dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    CameraMetadata rawMetadata;
411f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    binder::Status serviceRet = cs->getCameraCharacteristics(String16(cameraIdStr), &rawMetadata);
412d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!serviceRet.isOk()) {
413f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        switch(serviceRet.serviceSpecificErrorCode()) {
414f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            case hardware::ICameraService::ERROR_DISCONNECTED:
415f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("%s: Camera %s has been disconnected", __FUNCTION__, cameraIdStr);
416f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                return ACAMERA_ERROR_CAMERA_DISCONNECTED;
417f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
418f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraIdStr);
419f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                return ACAMERA_ERROR_INVALID_PARAMETER;
420f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            default:
421f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                ALOGE("Get camera characteristics from camera service failed: %s",
422f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                        serviceRet.toString8().string());
423f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala                return ACAMERA_ERROR_UNKNOWN; // should not reach here
424f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        }
4250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    *characteristics = new ACameraMetadata(
4280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
4290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return ACAMERA_OK;
4300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
4310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehcamera_status_t
4330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::openCamera(
4340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const char* cameraId,
4350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ACameraDevice_StateCallbacks* callback,
4360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        /*out*/ACameraDevice** outDevice) {
4370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ACameraMetadata* rawChars;
4380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
4390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex::Autolock _l(mLock);
4400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (ret != ACAMERA_OK) {
4410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
4420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                __FUNCTION__, cameraId, ret);
4430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_INVALID_PARAMETER;
4440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    std::unique_ptr<ACameraMetadata> chars(rawChars);
4460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    rawChars = nullptr;
4470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
4480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(chars));
4490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
450d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
4510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (cs == nullptr) {
4520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
453b01d8f7d7853e6cd4ea1256fe3dfb2e4a79cf09aYunlian Jiang        delete device;
4540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
4550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
4560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
457d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = device->getServiceCallback();
458d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::camera2::ICameraDeviceUser> deviceRemote;
4590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // No way to get package name from native.
4600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // Send a zero length package name and let camera service figure it out from UID
461d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    binder::Status serviceRet = cs->connectDevice(
462f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala            callbacks, String16(cameraId), String16(""),
463d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
4640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
465d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    if (!serviceRet.isOk()) {
466d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        ALOGE("%s: connect camera device failed: %s", __FUNCTION__, serviceRet.toString8().string());
4673e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        // Convert serviceRet to camera_status_t
4683e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        switch(serviceRet.serviceSpecificErrorCode()) {
4693e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_DISCONNECTED:
4703e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_CAMERA_DISCONNECTED;
4713e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4723e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_CAMERA_IN_USE:
4733e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_CAMERA_IN_USE;
4743e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4753e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_MAX_CAMERAS_IN_USE:
4763e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_MAX_CAMERA_IN_USE;
4773e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4783e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
4793e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_INVALID_PARAMETER;
4803e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4813e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_DEPRECATED_HAL:
4823e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                // Should not reach here since we filtered legacy HALs earlier
4833e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_INVALID_PARAMETER;
4843e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4853e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_DISABLED:
4863e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_CAMERA_DISABLED;
4873e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4883e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_PERMISSION_DENIED:
4893e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_PERMISSION_DENIED;
4903e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4913e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            case hardware::ICameraService::ERROR_INVALID_OPERATION:
4923e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh            default:
4933e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                ret = ACAMERA_ERROR_UNKNOWN;
4943e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh                break;
4953e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        }
4963e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh
4970dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        delete device;
4983e49be17d8c8c53f50bb0d39affbbc36f6a12488Yin-Chia Yeh        return ret;
4990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
5000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    if (deviceRemote == nullptr) {
5010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
5020dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        delete device;
5030dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        return ACAMERA_ERROR_CAMERA_DISCONNECTED;
5040dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    }
5050dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    device->setRemoteDevice(deviceRemote);
5060dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    *outDevice = device;
5070dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    return ACAMERA_OK;
5080dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
5090dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
5100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia YehACameraManager::~ACameraManager() {
511f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
5120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}
513