1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _ACAMERA_MANAGER_H
18#define _ACAMERA_MANAGER_H
19
20#include <camera/NdkCameraManager.h>
21
22#include <android-base/parseint.h>
23#include <android/hardware/ICameraService.h>
24#include <android/hardware/BnCameraServiceListener.h>
25#include <camera/CameraMetadata.h>
26#include <binder/IServiceManager.h>
27#include <utils/StrongPointer.h>
28#include <utils/Mutex.h>
29
30#include <media/stagefright/foundation/ALooper.h>
31#include <media/stagefright/foundation/AHandler.h>
32#include <media/stagefright/foundation/AMessage.h>
33
34#include <set>
35#include <map>
36
37namespace android {
38
39/**
40 * Per-process singleton instance of CameraManger. Shared by all ACameraManager
41 * instances. Created when first ACameraManager is created and destroyed when
42 * all ACameraManager instances are deleted.
43 *
44 * TODO: maybe CameraManagerGlobal is better suited in libcameraclient?
45 */
46class CameraManagerGlobal final : public RefBase {
47  public:
48    static CameraManagerGlobal& getInstance();
49    sp<hardware::ICameraService> getCameraService();
50
51    void registerAvailabilityCallback(
52            const ACameraManager_AvailabilityCallbacks *callback);
53    void unregisterAvailabilityCallback(
54            const ACameraManager_AvailabilityCallbacks *callback);
55
56    /**
57     * Return camera IDs that support camera2
58     */
59    void getCameraIdList(std::vector<String8> *cameraIds);
60
61  private:
62    sp<hardware::ICameraService> mCameraService;
63    const int          kCameraServicePollDelay = 500000; // 0.5s
64    const char*        kCameraServiceName      = "media.camera";
65    Mutex              mLock;
66
67    class DeathNotifier : public IBinder::DeathRecipient {
68      public:
69        explicit DeathNotifier(CameraManagerGlobal* cm) : mCameraManager(cm) {}
70      protected:
71        // IBinder::DeathRecipient implementation
72        virtual void binderDied(const wp<IBinder>& who);
73      private:
74        const wp<CameraManagerGlobal> mCameraManager;
75    };
76    sp<DeathNotifier> mDeathNotifier;
77
78    class CameraServiceListener final : public hardware::BnCameraServiceListener {
79      public:
80        explicit CameraServiceListener(CameraManagerGlobal* cm) : mCameraManager(cm) {}
81        virtual binder::Status onStatusChanged(int32_t status, const String16& cameraId);
82
83        // Torch API not implemented yet
84        virtual binder::Status onTorchStatusChanged(int32_t, const String16&) {
85            return binder::Status::ok();
86        }
87
88      private:
89        const wp<CameraManagerGlobal> mCameraManager;
90    };
91    sp<CameraServiceListener> mCameraServiceListener;
92
93    // Wrapper of ACameraManager_AvailabilityCallbacks so we can store it in std::set
94    struct Callback {
95        explicit Callback(const ACameraManager_AvailabilityCallbacks *callback) :
96            mAvailable(callback->onCameraAvailable),
97            mUnavailable(callback->onCameraUnavailable),
98            mContext(callback->context) {}
99
100        bool operator == (const Callback& other) const {
101            return (mAvailable == other.mAvailable &&
102                    mUnavailable == other.mUnavailable &&
103                    mContext == other.mContext);
104        }
105        bool operator != (const Callback& other) const {
106            return !(*this == other);
107        }
108        bool operator < (const Callback& other) const {
109            if (*this == other) return false;
110            if (mContext != other.mContext) return mContext < other.mContext;
111            if (mAvailable != other.mAvailable) return mAvailable < other.mAvailable;
112            return mUnavailable < other.mUnavailable;
113        }
114        bool operator > (const Callback& other) const {
115            return (*this != other && !(*this < other));
116        }
117        ACameraManager_AvailabilityCallback mAvailable;
118        ACameraManager_AvailabilityCallback mUnavailable;
119        void*                               mContext;
120    };
121    std::set<Callback> mCallbacks;
122
123    // definition of handler and message
124    enum {
125        kWhatSendSingleCallback
126    };
127    static const char* kCameraIdKey;
128    static const char* kCallbackFpKey;
129    static const char* kContextKey;
130    class CallbackHandler : public AHandler {
131      public:
132        CallbackHandler() {}
133        void onMessageReceived(const sp<AMessage> &msg) override;
134    };
135    sp<CallbackHandler> mHandler;
136    sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
137
138    void onStatusChanged(int32_t status, const String8& cameraId);
139    void onStatusChangedLocked(int32_t status, const String8& cameraId);
140    // Utils for status
141    static bool validStatus(int32_t status);
142    static bool isStatusAvailable(int32_t status);
143
144    // The sort logic must match the logic in
145    // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
146    struct CameraIdComparator {
147        bool operator()(const String8& a, const String8& b) const {
148            uint32_t aUint = 0, bUint = 0;
149            bool aIsUint = base::ParseUint(a.c_str(), &aUint);
150            bool bIsUint = base::ParseUint(b.c_str(), &bUint);
151
152            // Uint device IDs first
153            if (aIsUint && bIsUint) {
154                return aUint < bUint;
155            } else if (aIsUint) {
156                return true;
157            } else if (bIsUint) {
158                return false;
159            }
160            // Simple string compare if both id are not uint
161            return a < b;
162        }
163    };
164
165    // Map camera_id -> status
166    std::map<String8, int32_t, CameraIdComparator> mDeviceStatusMap;
167
168    // For the singleton instance
169    static Mutex sLock;
170    static CameraManagerGlobal* sInstance;
171    CameraManagerGlobal() {};
172    ~CameraManagerGlobal();
173};
174
175} // namespace android;
176
177/**
178 * ACameraManager opaque struct definition
179 * Leave outside of android namespace because it's NDK struct
180 */
181struct ACameraManager {
182    ACameraManager() :
183            mGlobalManager(&(android::CameraManagerGlobal::getInstance())) {}
184    ~ACameraManager();
185    camera_status_t getCameraIdList(ACameraIdList** cameraIdList);
186    static void     deleteCameraIdList(ACameraIdList* cameraIdList);
187
188    camera_status_t getCameraCharacteristics(
189            const char *cameraId, ACameraMetadata **characteristics);
190    camera_status_t openCamera(const char* cameraId,
191                               ACameraDevice_StateCallbacks* callback,
192                               /*out*/ACameraDevice** device);
193
194  private:
195    enum {
196        kCameraIdListNotInit = -1
197    };
198    android::Mutex         mLock;
199    android::sp<android::CameraManagerGlobal> mGlobalManager;
200};
201
202#endif //_ACAMERA_MANAGER_H
203