1 /*
2  * Copyright 2021 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 #ifndef ANDROID_CARSERVICE_EVS_SERVICE_WRAPPER_H
17 #define ANDROID_CARSERVICE_EVS_SERVICE_WRAPPER_H
18 
19 #include "EvsCallbackThread.h"
20 #include "EvsServiceCallback.h"
21 #include "IEvsServiceFactory.h"
22 #include "LinkUnlinkToDeathBase.h"
23 #include "StreamHandler.h"
24 
25 #include <aidl/android/hardware/automotive/evs/BufferDesc.h>
26 #include <aidl/android/hardware/automotive/evs/EvsEventDesc.h>
27 #include <aidl/android/hardware/automotive/evs/IEvsCamera.h>
28 #include <aidl/android/hardware/automotive/evs/IEvsDisplay.h>
29 #include <aidl/android/hardware/automotive/evs/IEvsEnumerator.h>
30 
31 #include <mutex>
32 #include <set>
33 
34 namespace android::automotive::evs {
35 
36 class ProdServiceFactory final : public IEvsServiceFactory {
37 public:
ProdServiceFactory(const char * serviceName)38     explicit ProdServiceFactory(const char* serviceName) : mServiceName(serviceName) {}
39     ~ProdServiceFactory() = default;
40 
41     bool init() override;
getService()42     aidl::android::hardware::automotive::evs::IEvsEnumerator* getService() override {
43         return mService.get();
44     }
clear()45     void clear() override { mService.reset(); }
46 
47 private:
48     std::string mServiceName;
49     std::shared_ptr<aidl::android::hardware::automotive::evs::IEvsEnumerator> mService;
50 };
51 
52 class ProdLinkUnlinkToDeath final : public LinkUnlinkToDeathBase {
53 public:
54     binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
55                                 void* cookie) override;
56     binder_status_t unlinkToDeath(AIBinder* binder) override;
57     void* getCookie() override;
58 };
59 
60 /*
61  * This class wraps around HIDL transactions to the Extended View System service
62  * and the video stream managements.
63  */
64 class EvsServiceContext final : public EvsServiceCallback {
65 public:
66     static EvsServiceContext* create(JavaVM* vm, jclass clazz);
67     static EvsServiceContext* create(JavaVM* vm, jclass clazz,
68                                      std::unique_ptr<IEvsServiceFactory> serviceFactory,
69                                      std::unique_ptr<LinkUnlinkToDeathBase> linkUnlinkImpl);
70 
71     virtual ~EvsServiceContext();
72 
73     /*
74      * Initializes the service context and connects to the native Extended View
75      * System service.
76      *
77      * @param env A pointer to the JNI environment
78      * @param env A reference to CarEvsService object
79      * @return false if it fails to connect to the native Extended View System
80      *         service or to register a death recipient.
81      *         true otherwise.
82      */
83     bool initialize(JNIEnv* env, jobject thiz) EXCLUDES(mLock);
84 
85     /*
86      * Deinitialize the service context and releases the resources.
87      */
88     void deinitialize() EXCLUDES(mLock);
89 
90     /*
91      * Requests to open a target camera device.
92      *
93      * @param id a string camera device identifier
94      * @return bool false if it has not connected to EVS service, fails to open
95      *              a camera device, or fails to initialize a stream handler;
96      *              true otherwise.
97      */
98     bool openCamera(const char* id) EXCLUDES(mLock);
99 
100     /*
101      * Requests to close an active camera device.
102      */
103     void closeCamera() EXCLUDES(mLock);
104 
105     /*
106      * Requests to start a video stream from a successfully opened camera device.
107      */
108     bool startVideoStream() EXCLUDES(mLock);
109 
110     /*
111      * Requests to stop an active video stream.
112      */
113     void stopVideoStream() EXCLUDES(mLock);
114 
115     /*
116      * Notifies that the client finishes with this buffer.
117      *
118      * @param frame a consumed frame buffer
119      */
120     void doneWithFrame(int bufferId) EXCLUDES(mLock);
121 
122     /*
123      * Tells whether or not we're connected to the Extended View System service
124      */
isAvailable()125     bool isAvailable() EXCLUDES(mLock) {
126         std::lock_guard<std::mutex> lock(mLock);
127         return isAvailableLocked();
128     }
129 
isAvailableLocked()130     bool isAvailableLocked() REQUIRES(mLock) {
131         return mServiceFactory != nullptr && mServiceFactory->getService() != nullptr;
132     }
133 
134     /*
135      * Tells whether or not a target camera device is opened
136      */
isCameraOpenedLocked()137     bool isCameraOpenedLocked() REQUIRES(mLock) {
138         return mCamera != nullptr;
139     }
140 
141     /*
142      * Implements EvsServiceCallback methods
143      */
144     void onNewEvent(const ::aidl::android::hardware::automotive::evs::EvsEventDesc&) override;
145     bool onNewFrame(const ::aidl::android::hardware::automotive::evs::BufferDesc&) override;
146 
147     /*
148      * Triggers a binder died callback.
149      */
150     void triggerBinderDied();
151 
152 private:
153     EvsServiceContext(JavaVM* vm, JNIEnv* env, jclass clazz,
154                       std::unique_ptr<IEvsServiceFactory> serviceFactory,
155                       std::unique_ptr<LinkUnlinkToDeathBase> linkUnlinkImpl);
156 
157     // Death recipient callback that is called when IEvsEnumerator service dies.
158     // The cookie is a pointer to a EvsServiceContext object.
159     static void onEvsServiceBinderDied(void* cookie);
160     void onEvsServiceDiedImpl();
161 
162     // Acquires the camera and the display exclusive ownerships.
163     void acquireCameraAndDisplayLocked() REQUIRES(mLock);
164 
165     // A mutex to protect shared resources
166     mutable std::mutex mLock;
167 
168     // A proxy to manage the Extended View System service.
169     std::unique_ptr<IEvsServiceFactory> mServiceFactory GUARDED_BY(mLock);
170 
171     // A proxy to manage the binder death recipient.
172     std::unique_ptr<LinkUnlinkToDeathBase> mLinkUnlinkImpl GUARDED_BY(mLock);
173 
174     // A camera device opened for the rearview service
175     std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsCamera> mCamera
176             GUARDED_BY(mLock);
177 
178     // A handler of a video stream from the rearview camera device
179     std::shared_ptr<StreamHandler> mStreamHandler GUARDED_BY(mLock);
180 
181     // Extended View System display handle.  This would not be used but held by
182     // us to prevent other EVS clients from using EvsDisplay.
183     std::shared_ptr<::aidl::android::hardware::automotive::evs::IEvsDisplay> mDisplay;
184 
185     // Java VM
186     JavaVM* mVm;
187 
188     // Background thread to handle callbacks from the native Extended View
189     // System service
190     EvsCallbackThread mCallbackThread;
191 
192     // Reference to CarEvsService object
193     jobject mCarEvsServiceObj;
194 
195     // CarEvsService object's method to handle the accidental death of the
196     // native Extended View System service
197     jmethodID mDeathHandlerMethodId;
198 
199     // CarEvsService object's method to handle a new frame buffer
200     jmethodID mFrameHandlerMethodId;
201 
202     // CarEvsService object's method to handle a new stream event
203     jmethodID mEventHandlerMethodId;
204 
205     // Bookkeeps descriptors of received frame buffer IDs.
206     std::set<int> mBufferRecords GUARDED_BY(mLock);
207 
208     // A name of the camera device currently in use.
209     std::string mCameraIdInUse;
210 
211     // List of available camera devices
212     std::vector<::aidl::android::hardware::automotive::evs::CameraDesc> mCameraList
213             GUARDED_BY(mLock);
214 
215     // Service name for EVS enumerator
216     static const char* kServiceName;
217 
218     // Maximum number of frames CarEvsService can hold.  This number has been
219     // chosen heuristically.
220     static constexpr int kMaxNumFramesInFlight = 10;
221 
222     // EVS service reserves a display ID 255 to allow the clients to open the main
223     // display exclusively.
224     static constexpr uint8_t kExclusiveMainDisplayId = 0xFF;
225 };
226 
227 }  // namespace android::automotive::evs
228 
229 #endif  // ANDROID_CARSERVICE_EVS_SERVICE_WRAPPER_H
230