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 CPP_EVS_MANAGER_AIDL_INCLUDE_HALCAMERA_H
18 #define CPP_EVS_MANAGER_AIDL_INCLUDE_HALCAMERA_H
19 
20 #include "stats/include/CameraUsageStats.h"
21 
22 #include <aidl/android/hardware/automotive/evs/BnEvsCameraStream.h>
23 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
24 #include <aidl/android/hardware/automotive/evs/CameraParam.h>
25 #include <aidl/android/hardware/automotive/evs/EvsEventDesc.h>
26 #include <aidl/android/hardware/automotive/evs/EvsResult.h>
27 #include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
28 #include <aidl/android/hardware/automotive/evs/Stream.h>
29 #include <utils/Mutex.h>
30 
31 #include <deque>
32 #include <list>
33 
34 namespace aidl::android::automotive::evs::implementation {
35 
36 namespace aidlevs = ::aidl::android::hardware::automotive::evs;
37 
38 class VirtualCamera;  // From VirtualCamera.h
39 
40 // This class wraps the actual hardware IEvsCamera objects.  There is a one to many
41 // relationship between instances of this class and instances of the VirtualCamera class.
42 // This class implements the IEvsCameraStream interface so that it can receive the video
43 // stream from the hardware camera and distribute it to the associated VirtualCamera objects.
44 class HalCamera : public ::aidl::android::hardware::automotive::evs::BnEvsCameraStream {
45 public:
46     // Methods from ::aidl::android::hardware::automotive::evs::IEvsCameraStream follow.
47     ::ndk::ScopedAStatus deliverFrame(const std::vector<aidlevs::BufferDesc>& buffer) override;
48     ::ndk::ScopedAStatus notify(const aidlevs::EvsEventDesc& event) override;
49 
50     HalCamera(const std::shared_ptr<aidlevs::IEvsCamera>& hwCamera, std::string deviceId = "",
51               int32_t recordId = 0, aidlevs::Stream cfg = {}) :
mHwCamera(hwCamera)52           mHwCamera(hwCamera),
53           mId(deviceId),
54           mStreamConfig(cfg),
55           mTimeCreatedMs(::android::uptimeMillis()),
56           mUsageStats(new CameraUsageStats(recordId)) {}
57 
58     virtual ~HalCamera();
59 
60     // Factory methods for client VirtualCameras
61     std::shared_ptr<VirtualCamera> makeVirtualCamera();
62     bool ownVirtualCamera(const std::shared_ptr<VirtualCamera>& virtualCamera);
63     void disownVirtualCamera(const VirtualCamera* virtualCamera);
64 
65     // Implementation details
getHwCamera()66     std::shared_ptr<aidlevs::IEvsCamera>& getHwCamera() { return mHwCamera; }
getClientCount()67     unsigned getClientCount() { return mClients.size(); };
getId()68     std::string getId() { return mId; }
getStreamConfig()69     aidlevs::Stream& getStreamConfig() { return mStreamConfig; }
70     bool changeFramesInFlight(int delta);
71     bool changeFramesInFlight(const std::vector<aidlevs::BufferDesc>& buffers, int* delta);
72     void requestNewFrame(std::shared_ptr<VirtualCamera> virtualCamera, int64_t timestamp);
73 
74     ::ndk::ScopedAStatus clientStreamStarting();
75     void clientStreamEnding(const VirtualCamera* client);
76     ::ndk::ScopedAStatus doneWithFrame(aidlevs::BufferDesc buffer);
77     ::ndk::ScopedAStatus setPrimaryClient(const std::shared_ptr<VirtualCamera>& virtualCamera);
78     ::ndk::ScopedAStatus forcePrimaryClient(const std::shared_ptr<VirtualCamera>& virtualCamera);
79     ::ndk::ScopedAStatus unsetPrimaryClient(const VirtualCamera* virtualCamera);
80     ::ndk::ScopedAStatus setParameter(const std::shared_ptr<VirtualCamera>& virtualCamera,
81                                       aidlevs::CameraParam id, int32_t* value);
82     ::ndk::ScopedAStatus getParameter(aidlevs::CameraParam id, int32_t* value);
83 
84     // Returns a snapshot of collected usage statistics
85     CameraUsageStatsRecord getStats() const;
86 
87     // Returns active stream configuration
88     aidlevs::Stream getStreamConfiguration() const;
89 
90     // Returns a string showing the current status
91     std::string toString(const char* indent = "") const;
92 
93     // Returns a string showing current stream configuration
94     static std::string toString(aidlevs::Stream configuration, const char* indent = "");
95 
96 private:
97     std::shared_ptr<aidlevs::IEvsCamera> mHwCamera;
98     std::list<std::weak_ptr<VirtualCamera>> mClients;
99 
100     enum {
101         STOPPED,
102         RUNNING,
103         STOPPING,
104     } mStreamState GUARDED_BY(mFrameMutex) = STOPPED;
105 
106     struct FrameRecord {
107         uint32_t frameId;
108         uint32_t refCount;
FrameRecordFrameRecord109         FrameRecord(uint32_t id) : frameId(id), refCount(0) {};
FrameRecordFrameRecord110         FrameRecord(uint32_t id, uint32_t count) : frameId(id), refCount(count) {};
111     };
112     std::vector<FrameRecord> mFrames GUARDED_BY(mFrameMutex);
113     std::weak_ptr<VirtualCamera> mPrimaryClient;
114     std::string mId;
115     aidlevs::Stream mStreamConfig;
116 
117     struct FrameRequest {
118         std::weak_ptr<VirtualCamera> client;
119         int64_t timestamp = -1;
120     };
121 
122     // synchronization
123     mutable std::mutex mFrameMutex;
124     std::condition_variable mFrameOpDone;
125     bool mFrameOpInProgress GUARDED_BY(mFrameMutex) = false;
126     std::deque<FrameRequest> mNextRequests GUARDED_BY(mFrameMutex);
127 
128     // Time this object was created
129     int64_t mTimeCreatedMs;
130 
131     // usage statistics to collect
132     ::android::sp<CameraUsageStats> mUsageStats;
133 };
134 
135 }  // namespace aidl::android::automotive::evs::implementation
136 
137 #endif  // CPP_EVS_MANAGER_AIDL_INCLUDE_HALCAMERA_H
138