1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_CAMERA_H_CAMERA_DEVICE_MANAGER_H
17 #define OHOS_CAMERA_H_CAMERA_DEVICE_MANAGER_H
18 
19 #include <refbase.h>
20 #include <set>
21 #include "hcamera_device.h"
22 #include "camera_util.h"
23 #include "mem_mgr_client.h"
24 #include "safe_map.h"
25 
26 namespace OHOS {
27 namespace CameraStandard {
28 
29 
30 class CameraProcessPriority : public RefBase {
31 public:
CameraProcessPriority(int32_t uid, int32_t state, int32_t focusState)32     CameraProcessPriority(int32_t uid, int32_t state, int32_t focusState) : processUid_(uid),
33         processState_(state), focusState_(focusState) {}
34 
operator ==(const CameraProcessPriority& rhs) const35     inline bool operator == (const CameraProcessPriority& rhs) const
36     {
37         return (this->processState_ == rhs.processState_) && (this->focusState_ == rhs.focusState_);
38     }
39 
operator <(const CameraProcessPriority& rhs) const40     inline bool operator < (const CameraProcessPriority& rhs) const
41     {
42         if (this->processUid_ < maxSysUid_) {
43             MEDIA_DEBUG_LOG("this->processUid_ :%{public}d", this->processUid_);
44             return true;
45         } else if (this->processUid_ >= maxSysUid_ && rhs.processUid_ < maxSysUid_) {
46             MEDIA_DEBUG_LOG("this->processUid_ :%{public}d, rhs.processUid_ :%{public}d",
47                 this->processUid_, rhs.processUid_);
48             return false;
49         }
50         if (this->processState_ == rhs.processState_) {
51             MEDIA_DEBUG_LOG("this->processState_ :%{public}d == rhs.processState_: %{public}d",
52                 this->processState_, rhs.processState_);
53             return this->focusState_ < rhs.focusState_;
54         } else {
55             MEDIA_DEBUG_LOG("this->processState:%{public}d, rhs.processState_:%{public}d",
56                 this->processState_, rhs.processState_);
57             return this->processState_ > rhs.processState_;
58         }
59     }
60 
operator >(const CameraProcessPriority& rhs) const61     inline bool operator > (const CameraProcessPriority& rhs) const
62     {
63         return rhs < *this;
64     }
65 
operator <=(const CameraProcessPriority& rhs) const66     inline bool operator <= (const CameraProcessPriority& rhs) const
67     {
68         if (this->processUid_ < maxSysUid_ && rhs.processUid_ < maxSysUid_) {
69             return true;
70         }
71         return !(*this > rhs);
72     }
73 
operator >=(const CameraProcessPriority& rhs) const74     inline bool operator >= (const CameraProcessPriority& rhs) const
75     {
76         if (this->processUid_ < maxSysUid_ && rhs.processUid_ < maxSysUid_) {
77             return false;
78         }
79         return !(*this < rhs);
80     }
81 
SetProcessState(int32_t state)82     inline void SetProcessState(int32_t state)
83     {
84         processState_ = state;
85     }
86 
SetProcessFocusState(int32_t focusState)87     inline void SetProcessFocusState(int32_t focusState)
88     {
89         focusState_ = focusState;
90     }
91 
GetUid() const92     inline int32_t GetUid() const{ return processUid_; }
93 
GetState() const94     inline int32_t GetState() const { return processState_; }
95 
GetFocusState() const96     inline int32_t GetFocusState() const { return focusState_; }
97 
98 private:
99     const int32_t maxSysUid_ = 10000;
100     int32_t processUid_;
101     int32_t processState_;
102     int32_t focusState_;
103 };
104 
105 class HCameraDeviceHolder : public RefBase {
106 public:
HCameraDeviceHolder(int32_t pid, int32_t uid, int32_t state, int32_t focusState, sptr<HCameraDevice> device, uint32_t accessTokenId, int32_t cost, const std::set<std::string> &conflicting)107     HCameraDeviceHolder(int32_t pid, int32_t uid, int32_t state, int32_t focusState,
108         sptr<HCameraDevice> device, uint32_t accessTokenId, int32_t cost, const std::set<std::string> &conflicting)
109         :pid_(pid), uid_(uid), state_(state), focusState_(focusState), accessTokenId_(accessTokenId), device_(device),
110         cost_(cost), conflicting_(conflicting)
111     {
112         processPriority_ = new CameraProcessPriority(uid, state, focusState);
113     }
SetPid(int32_t pid)114     inline void SetPid(int32_t pid) { pid_ = pid; }
SetUid(int32_t uid)115     inline void SetUid(int32_t uid) { uid_ = uid; }
SetState(int32_t state)116     inline void SetState(int32_t state)
117     {
118         processPriority_->SetProcessState(state);
119         state_ = state;
120     }
SetFocusState(int32_t focusState)121     inline void SetFocusState(int32_t focusState)
122     {
123         processPriority_->SetProcessFocusState(focusState);
124         focusState_ = focusState;
125     }
126 
GetPid() const127     inline int32_t GetPid() const {return pid_;}
128 
GetUid() const129     inline int32_t GetUid() const{ return uid_; }
130 
GetState() const131     inline int32_t GetState() const { return state_; }
132 
GetFocusState() const133     inline int32_t GetFocusState() const { return focusState_; }
134 
GetAccessTokenId() const135     inline uint32_t GetAccessTokenId() const { return accessTokenId_; }
136 
GetDevice() const137     inline sptr<HCameraDevice> GetDevice() const { return device_; }
138 
GetPriority() const139     inline sptr<CameraProcessPriority> GetPriority() const {return processPriority_;}
140 
GetCost() const141     inline int32_t GetCost() const{ return cost_; }
142 
IsConflicting(const std::string &cameraId) const143     inline bool IsConflicting(const std::string &cameraId) const
144     {
145         std::string curCameraId = device_->GetCameraId();
146         if (cameraId == curCameraId) {
147             return true;
148         }
149         for (const auto &x : conflicting_) {
150             if (cameraId == x) {
151                 return true;
152             }
153         }
154         return false;
155     }
156 
GetConflicting() const157     inline std::set<std::string> GetConflicting() const { return conflicting_; }
158 
159 private:
160     int32_t pid_;
161     int32_t uid_;
162     int32_t state_;
163     int32_t focusState_;
164     uint32_t accessTokenId_;
165     sptr<CameraProcessPriority> processPriority_;
166     sptr<HCameraDevice> device_;
167     int32_t cost_;
168     std::set<std::string> conflicting_;
169 };
170 
171 class HCameraDeviceManager : public RefBase {
172 public:
173     /**
174     * @brief the default maxinum "cost" allowed before evicting.
175     *
176     */
177     static constexpr int32_t DEFAULT_MAX_COST = 100;
178 
179     ~HCameraDeviceManager();
180     /**
181     * @brief Get camera device manager instance.
182     *
183     * @return Returns pointer to camera device manager instance.
184     */
185     static sptr<HCameraDeviceManager> &GetInstance();
186 
187     /**
188     * @brief Add opened device in camera device manager.
189     *
190     * @param device Device that have been turned on.
191     * @param pid Pid for opening the device.
192     */
193     void AddDevice(pid_t pid, sptr<HCameraDevice> device);
194 
195     /**
196     * @brief remove camera in camera device manager.
197     *
198     * @param device Device that have been turned off.
199     */
200     void RemoveDevice(const std::string &cameraId);
201 
202     /**
203     * @brief Get cameraHolder by active process pid.
204     *
205     * @param pid Pid of active process.
206     */
207     sptr<HCameraDeviceHolder> GetCameraHolderByPid(pid_t pid);
208 
209     /**
210     * @brief Get cameras by active process pid.
211     *
212     * @param pid Pid of active process.
213     */
214     sptr<HCameraDevice> GetCameraByPid(pid_t pidRequest);
215 
216     /**
217     * @brief Get process pid device manager instance.
218     *
219     * @return Returns pointer to camera device manager instance.
220     */
221     pid_t GetActiveClient();
222 
223     std::vector<sptr<HCameraDeviceHolder>> GetActiveCameraHolders();
224 
225     void SetStateOfACamera(std::string cameraId, int32_t state);
226 
227     bool IsMultiCameraActive(int32_t pid);
228 
229     void SetPeerCallback(sptr<ICameraBroker>& callback);
230 
231     void UnsetPeerCallback();
232 
233     SafeMap<std::string, int32_t> &GetCameraStateOfASide();
234 
235     /**
236     * @brief remove camera in camera device manager.
237     *
238     * @param camerasNeedEvict Devices that need to be shut down.
239     * @param cameraIdRequestOpen device is requested to turn on.
240     */
241     bool GetConflictDevices(sptr<HCameraDevice> &camerasNeedEvict, sptr<HCameraDevice> cameraIdRequestOpen);
242 
243     /**
244     * @brief handle active camera evictions in camera device manager.
245     *
246     * @param evictedClients Devices that need to be shut down.
247     * @param cameraRequestOpen device is requested to turn on.
248     */
249     bool HandleCameraEvictions(std::vector<sptr<HCameraDeviceHolder>> &evictedClients,
250                                sptr<HCameraDeviceHolder> &cameraRequestOpen);
251 
252     std::mutex mapMutex_;
253 private:
254     HCameraDeviceManager();
255     static sptr<HCameraDeviceManager> cameraDeviceManager_;
256     static std::mutex instanceMutex_;
257     SafeMap<pid_t, sptr<HCameraDeviceHolder>> pidToCameras_;
258     SafeMap<std::string, int32_t> stateOfACamera_;
259     // LRU ordered, most recent at end
260     std::vector<sptr<HCameraDeviceHolder>> activeCameras_;
261     sptr<ICameraBroker> peerCallback_;
262     std::mutex peerCbMutex_;
263     std::string GetACameraId();
264     bool IsAllowOpen(pid_t activeClient);
265     int32_t GetCurrentCost() const;
266     std::vector<sptr<HCameraDeviceHolder>> WouldEvict(sptr<HCameraDeviceHolder> &cameraRequestOpen);
267     void UpdateProcessState(int32_t& activeState, int32_t& requestState,
268         uint32_t activeAccessTokenId, uint32_t requestAccessTokenId);
269     void PrintClientInfo(sptr<HCameraDeviceHolder> activeCameraHolder, sptr<HCameraDeviceHolder> requestCameraHolder);
270 };
271 } // namespace CameraStandard
272 } // namespace OHOS
273 #endif // OHOS_CAMERA_H_CAMERA_DEVICE_MANAGER_H