ACameraManager.h revision d19d994770a04f02c204affd29985c5aeaa58baa
13a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright (C) 2015 The Android Open Source Project
3f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *      http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
17c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#ifndef _ACAMERA_MANAGER_H
186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#define _ACAMERA_MANAGER_H
19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "NdkCameraManager.h"
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <android/hardware/ICameraService.h>
239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include <android/hardware/BnCameraServiceListener.h>
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <camera/CameraMetadata.h>
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <binder/IServiceManager.h>
26d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines#include <utils/StrongPointer.h>
27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <utils/Mutex.h>
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <media/stagefright/foundation/ALooper.h>
306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <media/stagefright/foundation/AHandler.h>
3189273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang#include <media/stagefright/foundation/AMessage.h>
326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
338d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael#include <set>
346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <map>
356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
36593a894650e81be54173106ec266f0311cebebd3Stephen Hinesnamespace android {
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr/**
394cc499d6e5ec602309501873449c938af61170b2Stephen Hines * Per-process singleton instance of CameraManger. Shared by all ACameraManager
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines * instances. Created when first ACameraManager is created and destroyed when
416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr * all ACameraManager instances are deleted.
422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet *
439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao * TODO: maybe CameraManagerGlobal is better sutied in libcameraclient?
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */
452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletclass CameraManagerGlobal final : public RefBase {
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao  public:
472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static CameraManagerGlobal& getInstance();
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    sp<hardware::ICameraService> getCameraService();
493a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
503a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray    void registerAvailabilityCallback(
513a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray            const ACameraManager_AvailabilityCallbacks *callback);
522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    void unregisterAvailabilityCallback(
532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            const ACameraManager_AvailabilityCallbacks *callback);
542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao  private:
562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    sp<hardware::ICameraService> mCameraService;
572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const int          kCameraServicePollDelay = 500000; // 0.5s
582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const char*        kCameraServiceName      = "media.camera";
592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    Mutex              mLock;
602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    class DeathNotifier : public IBinder::DeathRecipient {
622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      public:
63a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines        explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      protected:
651f6c331d622ac645ab68a016aa4c577998547373Stephen Hines        // IBinder::DeathRecipient implementation
662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        virtual void binderDied(const wp<IBinder>& who);
67d2936939ec10879e25746322db60071f79f28c1bStephen Hines      private:
682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        const wp<CameraManagerGlobal> mCameraManager;
692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    };
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    sp<DeathNotifier> mDeathNotifier;
712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    class CameraServiceListener final : public hardware::BnCameraServiceListener {
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao      public:
74e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines        explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        virtual binder::Status onStatusChanged(int32_t status, int32_t cameraId);
76c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
77c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        // Torch API not implemented yet
78c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        virtual binder::Status onTorchStatusChanged(int32_t, const String16&) {
79c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            return binder::Status::ok();
80c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        }
81c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
82c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet      private:
83c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        const wp<CameraManagerGlobal> mCameraManager;
84c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    };
85c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    sp<CameraServiceListener> mCameraServiceListener;
86c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
87c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
88c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    struct Callback {
89c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
90c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            mAvailable(callback->onCameraAvailable),
91c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            mUnavailable(callback->onCameraUnavailable),
92c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            mContext(callback->context) {}
93c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
94c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        bool operator == (const Callback& other) const {
95c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            return (mAvailable == other.mAvailable &&
96c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                    mUnavailable == other.mUnavailable &&
97c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                    mContext == other.mContext);
98c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        }
99c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        bool operator != (const Callback& other) const {
100c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            return !(*this == other);
101c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        }
102c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet        bool operator < (const Callback& other) const {
103c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            if (*this == other) return false;
104c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            if (mContext != other.mContext) return mContext < other.mContext;
105c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
106c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet            return mUnavailable < other.mUnavailable;
10792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        }
1082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        bool operator > (const Callback& other) const {
1092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            return (*this != other && !(*this < other));
1102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
11192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        ACameraManager_AvailabilityCallback mAvailable;
11292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        ACameraManager_AvailabilityCallback mUnavailable;
11392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        void*                               mContext;
1142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    };
1152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::set<Callback> mCallbacks;
11692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1176e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    // definition of handler and message
11892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    enum {
11992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        kWhatSendSingleCallback
12092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    };
1216e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    static const char* kCameraIdKey;
1222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static const char* kCallbackFpKey;
1232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static const char* kContextKey;
1242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    class CallbackHandler : public AHandler {
1252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      public:
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        CallbackHandler() {}
127324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao        void onMessageReceived(const sp<AMessage> &msg) override;
1282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet      private:
1296e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        inline void sendSingleCallback(
130324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao                int32_t cameraId, void* context,
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                ACameraManager_AvailabilityCallback cb) const;
132324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    };
133324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    sp<CallbackHandler> mHandler;
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
1356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
1362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    void onStatusChanged(int32_t status, int32_t cameraId);
1372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    void onStatusChangedLocked(int32_t status, int32_t cameraId);
1382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Utils for status
1392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static bool validStatus(int32_t status);
1402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static bool isStatusAvailable(int32_t status);
1412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Map camera_id -> status
1432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::map<int32_t, int32_t> mDeviceStatusMap;
1442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // For the singleton instance
1462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static Mutex sLock;
1472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static CameraManagerGlobal* sInstance;
1482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    CameraManagerGlobal() {};
1492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ~CameraManagerGlobal();
1502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet};
1512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet} // namespace android;
1532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet/**
1552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet * ACameraManager opaque struct definition
1562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet * Leave outside of android namespace because it's NDK struct
1572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet */
1582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstruct ACameraManager {
1592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ACameraManager() :
1602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            mCachedCameraIdList({kCameraIdListNotInit, nullptr}),
1612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            mGlobalManager(&(android::CameraManagerGlobal::getInstance())) {}
1622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ~ACameraManager();
1632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
1642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    static void     deleteCameraIdList(ACameraIdList* cameraIdList);
1652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    camera_status_t getCameraCharacteristics(
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            const char *cameraId, ACameraMetadata **characteristics);
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    camera_status_t openCamera(const char* cameraId,
1692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                               ACameraDevice_StateCallbacks* callback,
1702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                               /*out*/ACameraDevice** device);
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1726e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines  private:
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    camera_status_t getOrCreateCameraIdListLocked(ACameraIdList** cameraIdList);
174462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    enum {
176d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        kCameraIdListNotInit = -1
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    };
1782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    android::Mutex         mLock;
1792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    std::set<int> mCameraIds;          // Init by getOrCreateCameraIdListLocked
1802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    ACameraIdList mCachedCameraIdList; // Init by getOrCreateCameraIdListLocked
1812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    android::sp<android::CameraManagerGlobal> mGlobalManager;
1822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet};
1832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif //_ACAMERA_MANAGER_H
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao