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