1 /**
2  * Copyright (C) 2022 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 IMS_MEDIA_CAMERA_H_INCLUDED
18 #define IMS_MEDIA_CAMERA_H_INCLUDED
19 
20 #include <ImsMediaDefine.h>
21 #include <ImsMediaCondition.h>
22 #include <string>
23 #include <vector>
24 #include <map>
25 #include <camera/NdkCameraManager.h>
26 #include <camera/NdkCameraError.h>
27 #include <camera/NdkCameraDevice.h>
28 #include <camera/NdkCameraMetadataTags.h>
29 
30 enum class CaptureSessionState : int32_t
31 {
32     kStateReady = 0,  // session is ready
33     kStateActive,     // session is busy
34     kStateClosed,     // session is closed(by itself or a new session evicts)
35     kStateMax
36 };
37 
38 class CameraId
39 {
40 public:
41     ACameraDevice* mDevice;
42     std::string mId;
43     int32_t mFacing;
44     bool mAvailable;
45     bool mOwner;
46     explicit CameraId(const char* id = nullptr) :
mDevice(nullptr)47             mDevice(nullptr),
48             mFacing(ACAMERA_LENS_FACING_FRONT),
49             mAvailable(false),
50             mOwner(false)
51     {
52         mId = (id != nullptr) ? id : "";
53     }
54 
55     CameraId& operator=(const CameraId& camera)
56     {
57         if (this != &camera)
58         {
59             mDevice = camera.mDevice;
60             mId = camera.mId;
61             mFacing = camera.mFacing;
62             mAvailable = camera.mAvailable;
63             mOwner = camera.mOwner;
64         }
65 
66         return *this;
67     }
68 };
69 
70 template <typename T>
71 class RangeValue
72 {
73 public:
74     T min, max;
75     /**
76      * return absolute value from relative value
77      * value: in percent (50 for 50%)
78      */
value(int percent)79     T value(int percent) { return static_cast<T>(min + (max - min) * percent / 100); }
RangeValue()80     RangeValue() { min = max = static_cast<T>(0); }
81     RangeValue& operator=(const RangeValue& rangeValue)
82     {
83         if (this != &rangeValue)
84         {
85             min = rangeValue.min;
86             max = rangeValue.max;
87         }
88 
89         return *this;
90     }
91 
Supported(void)92     bool Supported(void) const { return (min != max); }
93 };
94 
95 struct CaptureRequestInfo
96 {
97 public:
CaptureRequestInfoCaptureRequestInfo98     CaptureRequestInfo()
99     {
100         outputNativeWindows.clear();
101         sessionOutputs.clear();
102         targets.clear();
103         request = nullptr;
104     }
105     std::vector<ANativeWindow*> outputNativeWindows;
106     std::vector<ACaptureSessionOutput*> sessionOutputs;
107     std::vector<ACameraOutputTarget*> targets;
108     ACaptureRequest* request;
109     ACameraDevice_request_template requestTemplate;
110 };
111 
112 enum kCameraMode
113 {
114     kCameraModePreview = 0,
115     kCameraModeRecord,
116     kCameraModeCount,
117 };
118 
119 class ImsMediaCamera
120 {
121 private:
122     ImsMediaCamera();
123     virtual ~ImsMediaCamera();
124 
125 public:
126     static ImsMediaCamera* getInstance();
127 
128     /**
129      * @brief Creates camera manager and register the valid camera device to the list
130      */
131     void Initialize();
132 
133     /**
134      * @brief Deletes camera manager and clear the camera list
135      */
136     void DeInitialize();
137 
138     /**
139      * @brief Opens camera with pre configured camera configuration by SetCameraConfig.
140      *
141      * @return true Returns when open camera successfully
142      * @return false Returns when there is error during opening camera
143      */
144     bool OpenCamera();
145 
146     /**
147      * @brief Sets the Camera Config
148      *
149      * @param cameraId active camera id
150      * @param cameraZoom camera zoom level
151      * @param framerate framerate
152      */
153     void SetCameraConfig(int32_t cameraId, int32_t cameraZoom, int32_t framerate);
154 
155     /**
156      * @brief Creates a Session object
157      *
158      * @param preview The mandatory prameter to run the camera
159      * @param recording The optional parameter to run camera, it is mandatory if you want to run
160      * camera as recording mode
161      *
162      * @return true Returns when create camera session successfully
163      * @return false Returns when there is error during create camera session
164      */
165     bool CreateSession(ANativeWindow* preview, ANativeWindow* recording);
166 
167     /**
168      * @brief Delete the camera capture session, request and release the target surfaces and
169      * resources.
170      *
171      * @return true Deletes camera session and release the resources succeed
172      * @return false Failed when there is error during the release the resources
173      */
174     bool DeleteSession();
175 
176     /**
177      * @brief Starts camera preview or recording session
178      *
179      * @param bRecording Sets true to run recording session, it would be failed when the surface or
180      * camera id is not valid.
181      * @return true Starts camera session without error
182      * @return false Failed when there is any error during starting camera session
183      */
184     bool StartSession(bool bRecording);
185 
186     /**
187      * @brief Stops the running camera capture session.
188      *
189      * @return true Stop camera session succeed
190      * @return false Failed when there is any error during stopping camera session
191      */
192     bool StopSession();
193 
194     /**
195      * @brief Handles callback from ACameraManager
196      *
197      * @param id The camera id to update
198      * @param available The state of camera, set true when the camera is available
199      */
200     virtual void OnCameraStatusChanged(const char* id, bool available);
201 
202     /**
203      * @brief Handle Camera DeviceStateChanges msg, notify device is disconnected
204      * simply close the camera
205      *
206      * @param dev device instance to get state
207      */
208     virtual void OnDeviceState(ACameraDevice* dev);
209 
210     /**
211      * @brief Handles Camera's deviceErrorChanges message, no action; mainly debugging purpose
212      *
213      * @param dev The camera device object has error
214      * @param err The error code
215      */
216     virtual void OnDeviceError(ACameraDevice* dev, int err);
217 
218     /**
219      * @brief  Handles capture session state changes. Update into internal session state.
220      *
221      * @param ses The camera capture session object to change the state
222      * @param state The camera state to changes
223      */
224     virtual void OnSessionState(ACameraCaptureSession* ses, CaptureSessionState state);
225 
226     /**
227      * @brief Retrieve the camera facing and sensor orientation of requested camera id;
228      *
229      * @param cameraId the camera id to get the facing and sensor orientation
230      * @param facing retrieved camera facing, rear or front.
231      * @param angle retrieved camera sensor orientation in degree units.
232      * @return true true when it is succeeded to retrieve values.
233      * @return false fail in accessing camera instances.
234      */
235     bool GetSensorOrientation(const int cameraId, int32_t* facing, int32_t* angle);
236 
237 private:
238     /**
239      * @brief Loop through cameras on the system, store camera informations
240      */
241     void EnumerateCamera();
242 
243     /**
244      * Retrieve Camera Exposure adjustable range.
245      *
246      * @param min Camera minimium exposure time in nanoseconds
247      * @param max Camera maximum exposure time in nanoseconds
248      *
249      * @return true  min and max are loaded with the camera's exposure values
250      *         false camera has not initialized, no value available
251      */
252     bool GetExposureRange(int64_t* min, int64_t* max, int64_t* curVal);
253     /**
254 
255      * Retrieve Camera sensitivity range.
256      *
257      * @param min Camera minimium sensitivity
258      * @param max Camera maximum sensitivity
259      *
260      * @return true  min and max are loaded with the camera's sensitivity values
261      *         false camera has not initialized, no value available
262      */
263     bool GetSensitivityRange(int64_t* min, int64_t* max, int64_t* curVal);
264 
265     /**
266      * @brief Construct a camera manager listener on the fly and return to caller
267      *
268      * @return ACameraManager_AvailabilityCallback
269      */
270     ACameraManager_AvailabilityCallbacks* GetManagerListener();
271     ACameraDevice_stateCallbacks* GetDeviceListener();
272     ACameraCaptureSession_stateCallbacks* GetSessionListener();
273     bool MatchCaptureSizeRequest(ANativeWindow* window);
274 
275     static ImsMediaCamera gCamera;
276     static std::map<std::string, CameraId> gCameraIds;
277     static ImsMediaCondition gCondition;
278     ACameraManager* mManager;
279     CaptureRequestInfo mCaptureRequest;
280     ACaptureSessionOutputContainer* mSessionOutputContainer;
281     ACameraCaptureSession* mCaptureSession;
282     CaptureSessionState mCaptureSessionState;
283 
284     // set up exposure control
285     int64_t mExposureTime;
286     RangeValue<int64_t> mExposureRange;
287     int32_t mSensitivity;
288     RangeValue<int32_t> mSensitivityRange;
289     uint32_t mCameraMode;
290     uint32_t mCameraFacing;
291     uint32_t mCameraOrientation;
292     std::string mActiveCameraId;
293     int32_t mCameraZoom;
294     int32_t mFramerate;
295 };
296 
297 #endif