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#ifndef _ACAMERA_MANAGER_H
180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#define _ACAMERA_MANAGER_H
190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include "NdkCameraManager.h"
210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
22d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <android/hardware/ICameraService.h>
23d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala#include <android/hardware/BnCameraServiceListener.h>
240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <camera/CameraMetadata.h>
250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <binder/IServiceManager.h>
260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <utils/StrongPointer.h>
270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <utils/Mutex.h>
280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <media/stagefright/foundation/ALooper.h>
300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <media/stagefright/foundation/AHandler.h>
310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <media/stagefright/foundation/AMessage.h>
320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <set>
340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#include <map>
350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehnamespace android {
370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/**
390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Per-process singleton instance of CameraManger. Shared by all ACameraManager
400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * instances. Created when first ACameraManager is created and destroyed when
410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * all ACameraManager instances are deleted.
420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh *
43f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala * TODO: maybe CameraManagerGlobal is better suited in libcameraclient?
440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */
450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehclass CameraManagerGlobal final : public RefBase {
460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh  public:
470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    static CameraManagerGlobal& getInstance();
48d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::ICameraService> getCameraService();
490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    void registerAvailabilityCallback(
510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            const ACameraManager_AvailabilityCallbacks *callback);
520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    void unregisterAvailabilityCallback(
530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            const ACameraManager_AvailabilityCallbacks *callback);
540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
55f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    /**
56f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     * Return camera IDs that support camera2
57f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala     */
58f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    void getCameraIdList(std::vector<String8> *cameraIds);
59f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala
600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh  private:
61d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    sp<hardware::ICameraService> mCameraService;
620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    const int          kCameraServicePollDelay = 500000; // 0.5s
630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    const char*        kCameraServiceName      = "media.camera";
640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    Mutex              mLock;
650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    class DeathNotifier : public IBinder::DeathRecipient {
670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh      public:
68d19d994770a04f02c204affd29985c5aeaa58baaChih-Hung Hsieh        explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh      protected:
700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        // IBinder::DeathRecipient implementation
710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        virtual void binderDied(const wp<IBinder>& who);
720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh      private:
730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const wp<CameraManagerGlobal> mCameraManager;
740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    };
750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<DeathNotifier> mDeathNotifier;
760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
77d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    class CameraServiceListener final : public hardware::BnCameraServiceListener {
780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh      public:
79d19d994770a04f02c204affd29985c5aeaa58baaChih-Hung Hsieh        explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
80f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala        virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId);
810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        // Torch API not implemented yet
83d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        virtual binder::Status onTorchStatusChanged(int32_t, const String16&) {
84d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            return binder::Status::ok();
85d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala        }
86d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala
870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh      private:
880dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        const wp<CameraManagerGlobal> mCameraManager;
890dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    };
900dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<CameraServiceListener> mCameraServiceListener;
910dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
920dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
930dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    struct Callback {
94d19d994770a04f02c204affd29985c5aeaa58baaChih-Hung Hsieh        explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mAvailable(callback->onCameraAvailable),
960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mUnavailable(callback->onCameraUnavailable),
970dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            mContext(callback->context) {}
980dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        bool operator == (const Callback& other) const {
1000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return (mAvailable == other.mAvailable &&
1010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    mUnavailable == other.mUnavailable &&
1020dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                    mContext == other.mContext);
1030dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1040dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        bool operator != (const Callback& other) const {
1050dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return !(*this == other);
1060dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1070dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        bool operator < (const Callback& other) const {
1080dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (*this == other) return false;
1090dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (mContext != other.mContext) return mContext < other.mContext;
1100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
1110dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return mUnavailable < other.mUnavailable;
1120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        bool operator > (const Callback& other) const {
1140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            return (*this != other && !(*this < other));
1150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        }
1160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ACameraManager_AvailabilityCallback mAvailable;
1170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        ACameraManager_AvailabilityCallback mUnavailable;
1180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        void*                               mContext;
1190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    };
1200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    std::set<Callback> mCallbacks;
1210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // definition of handler and message
1230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    enum {
1240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        kWhatSendSingleCallback
1250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    };
1260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    static const char* kCameraIdKey;
1270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    static const char* kCallbackFpKey;
1280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    static const char* kContextKey;
1290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    class CallbackHandler : public AHandler {
1300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh      public:
1310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        CallbackHandler() {}
1320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        void onMessageReceived(const sp<AMessage> &msg) override;
1330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    };
1340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<CallbackHandler> mHandler;
1350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
1360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
137f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    void onStatusChanged(int32_t status, const String8& cameraId);
138f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    void onStatusChangedLocked(int32_t status, const String8& cameraId);
1390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // Utils for status
140d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    static bool validStatus(int32_t status);
141d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    static bool isStatusAvailable(int32_t status);
1420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // Map camera_id -> status
144f51fca277eb5b86bd0b2e3fc90ecb2b63089de29Eino-Ville Talvala    std::map<String8, int32_t> mDeviceStatusMap;
1450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1460dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    // For the singleton instance
1470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    static Mutex sLock;
1480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    static CameraManagerGlobal* sInstance;
1490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    CameraManagerGlobal() {};
1500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ~CameraManagerGlobal();
1510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh};
1520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh} // namespace android;
1540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/**
1560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * ACameraManager opaque struct definition
1570dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Leave outside of android namespace because it's NDK struct
1580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */
1590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehstruct ACameraManager {
1600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ACameraManager() :
161d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala            mGlobalManager(&(android::CameraManagerGlobal::getInstance())) {}
1620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    ~ACameraManager();
1630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
1640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    static void     deleteCameraIdList(ACameraIdList* cameraIdList);
1650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    camera_status_t getCameraCharacteristics(
1670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh            const char *cameraId, ACameraMetadata **characteristics);
1680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    camera_status_t openCamera(const char* cameraId,
1690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                               ACameraDevice_StateCallbacks* callback,
1700dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh                               /*out*/ACameraDevice** device);
1710dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh  private:
1730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    enum {
1740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh        kCameraIdListNotInit = -1
1750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh    };
176d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    android::Mutex         mLock;
177d56db1d2bee182d1851097a9c712712fc094d117Eino-Ville Talvala    android::sp<android::CameraManagerGlobal> mGlobalManager;
1780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh};
1790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh
1800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh#endif //_ACAMERA_MANAGER_H
181