1 /*
2  * Copyright (C) 2019 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 CAR_LIB_EVS_SUPPORT_RESOURCEMANAGER_H
18 #define CAR_LIB_EVS_SUPPORT_RESOURCEMANAGER_H
19 
20 #include "StreamHandler.h"
21 
22 #include <android/hardware/automotive/evs/1.0/IEvsEnumerator.h>
23 #include <utils/RefBase.h>
24 
25 #include <mutex>
26 #include <unordered_map>
27 
28 namespace android {
29 namespace automotive {
30 namespace evs {
31 namespace support {
32 
33 using ::android::sp;
34 using ::android::hardware::automotive::evs::V1_0::IEvsCamera;
35 using ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
36 using ::android::hardware::automotive::evs::V1_0::IEvsEnumerator;
37 using ::std::mutex;
38 using ::std::string;
39 using ::std::unordered_map;
40 
41 /*
42  * Manages EVS related resources. E.g. evs camera, stream handler, and display.
43  *
44  * The methods in the class are guaranteed to be thread-safe.
45  */
46 class ResourceManager : public android::RefBase {
47 public:
48     /*
49      * Gets the singleton instance of the class.
50      */
51     static sp<ResourceManager> getInstance();
52 
53     /*
54      * Obtains a StreamHandler instance to receive evs camera imagery from the
55      * given camera.
56      *
57      * When this function is called with a new camera id the first time, an evs
58      * camera instance will be opened. An internal reference count will be
59      * incremented by one every time when this method is called with the same
60      * camera id. The count will be decreased by one when releaseStreamHandler
61      * method is called, and when the reference count for the camera is
62      * decreased to zero, the stream handler will be shut down and the evs
63      * camera instance will be closed.
64      *
65      * The method will block other stream handler related calls. For example,
66      * method releaseStreamHandler.
67      *
68      * @see releaseStreamHandler()
69      */
70     sp<StreamHandler> obtainStreamHandler(string pCameraId);
71 
72     /*
73      * Releases the StreamHandler associated with the given camera.
74      *
75      * An internal reference count will be decreased when this method is
76      * called. When the count is down to zero, the stream handler will be shut
77      * down and the evs camera instance will be closed.
78      *
79      * The method will block other stream handler related calls. For example,
80      * method obtainStreamHandler.
81      *
82      * @see obtainStreamHandler()
83      */
84     void releaseStreamHandler(string pCameraId);
85 
86     /*
87      * Obtains an interface object used to exclusively interact with the
88      * system's evs display.
89      *
90      * @see closeDisplay()
91      */
92     sp<IEvsDisplay> openDisplay();
93 
94     /*
95      * Releases the evs display interface.
96      *
97      * @see openDisplay()
98      */
99     void closeDisplay(sp<IEvsDisplay>);
100 
101     /**
102      * Returns true if display is opened by openDisplay method; returns false
103      * if display is never opened, or closed by closeDisplay method.
104      *
105      * @see openDisplay()
106      * @see closeDisplay()
107      */
108     bool isDisplayOpened();
109 
110 private:
111     static sp<IEvsEnumerator> getEvsEnumerator(string serviceName = kDefaultServiceName);
112 
113     static const string kDefaultServiceName;
114 
115     static sp<ResourceManager> sInstance;
116     static sp<IEvsEnumerator> sEvs;
117     static mutex sLockSingleton, sLockEvs;
118 
119     class CameraInstance : public RefBase {
120     public:
121         int useCaseCount = 0;
122         string cameraId;
123         sp<IEvsCamera> camera;
124         sp<StreamHandler> handler;
125 
126     private:
onLastStrongRef(const void *)127         void onLastStrongRef(const void* /*id*/) {
128             ALOGD("StreamHandler::onLastStrongRef");
129 
130             handler->shutdown();
131             ALOGD("Stream handler for camera id (%s) has been shutdown", cameraId.c_str());
132 
133             getEvsEnumerator()->closeCamera(camera);
134             ALOGD("Camera with id (%s) has been closed", cameraId.c_str());
135         }
136     };
137 
138     sp<IEvsDisplay> mDisplay;
139     unordered_map<string, sp<CameraInstance>> mCameraInstances;
140     mutex mLockStreamHandler, mLockDisplay;
141 };
142 
143 }  // namespace support
144 }  // namespace evs
145 }  // namespace automotive
146 }  // namespace android
147 
148 #endif  // CAR_LIB_EVS_SUPPORT_RESOURCEMANAGER_H
149