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 #include "camera_app_manager_client.h"
17 #include "camera_log.h"
18 #include "camera_window_manager_agent.h"
19 #include "camera_window_manager_client.h"
20 #include "ipc_skeleton.h"
21 #include "hcamera_service_proxy.h"
22 #include "system_ability_definition.h"
23 #include "iservice_registry.h"
24 #include "hcamera_device_manager.h"
25 #include <mutex>
26 
27 namespace OHOS {
28 namespace CameraStandard {
29 static const int32_t FOREGROUND_STATE_OF_PROCESS = 0;
30 static const int32_t PIP_STATE_OF_PROCESS = 1;
31 static const int32_t BCAKGROUND_STATE_OF_PROCESS = 2;
32 static const int32_t UNKNOW_STATE_OF_PROCESS = 3;
33 static const std::unordered_map<int32_t, int32_t> APP_MGR_STATE_TO_CAMERA_STATE = {
34     {2,  FOREGROUND_STATE_OF_PROCESS},
35     {4,  BCAKGROUND_STATE_OF_PROCESS}
36 };
37 static const int32_t FOCUSED_STATE_OF_PROCESS = 1;
38 static const int32_t UNFOCUSED_STATE_OF_PROCESS = 0;
39 sptr<HCameraDeviceManager> HCameraDeviceManager::cameraDeviceManager_;
40 std::mutex HCameraDeviceManager::instanceMutex_;
41 
HCameraDeviceManager()42 HCameraDeviceManager::HCameraDeviceManager() {}
43 
~HCameraDeviceManager()44 HCameraDeviceManager::~HCameraDeviceManager()
45 {
46     HCameraDeviceManager::cameraDeviceManager_ = nullptr;
47 }
48 
GetInstance()49 sptr<HCameraDeviceManager> &HCameraDeviceManager::GetInstance()
50 {
51     if (HCameraDeviceManager::cameraDeviceManager_ == nullptr) {
52         std::unique_lock<std::mutex> lock(instanceMutex_);
53         if (HCameraDeviceManager::cameraDeviceManager_ == nullptr) {
54             MEDIA_INFO_LOG("Initializing camera device manager instance");
55             HCameraDeviceManager::cameraDeviceManager_ = new HCameraDeviceManager();
56             CameraWindowManagerClient::GetInstance();
57         }
58     }
59     return HCameraDeviceManager::cameraDeviceManager_;
60 }
61 
AddDevice(pid_t pid,sptr<HCameraDevice> device)62 void HCameraDeviceManager::AddDevice(pid_t pid, sptr<HCameraDevice> device)
63 {
64     MEDIA_INFO_LOG("HCameraDeviceManager::AddDevice start");
65     std::lock_guard<std::mutex> lock(mapMutex_);
66     int32_t uidOfRequestProcess = IPCSkeleton::GetCallingUid();
67     int32_t pidOfRequestProcess = IPCSkeleton::GetCallingPid();
68     uint32_t accessTokenIdOfRequestProc = IPCSkeleton::GetCallingTokenID();
69     sptr<HCameraDeviceHolder> cameraHolder = new HCameraDeviceHolder(
70         pidOfRequestProcess, uidOfRequestProcess, FOREGROUND_STATE_OF_PROCESS,
71         FOCUSED_STATE_OF_PROCESS, device, accessTokenIdOfRequestProc);
72     pidToCameras_.EnsureInsert(pid, cameraHolder);
73     MEDIA_INFO_LOG("HCameraDeviceManager::AddDevice end");
74 }
75 
RemoveDevice()76 void HCameraDeviceManager::RemoveDevice()
77 {
78     MEDIA_INFO_LOG("HCameraDeviceManager::RemoveDevice start");
79     std::lock_guard<std::mutex> lock(mapMutex_);
80     pidToCameras_.Clear();
81     MEDIA_INFO_LOG("HCameraDeviceManager::RemoveDevice end");
82 }
83 
GetCameraHolderByPid(pid_t pidRequest)84 sptr<HCameraDeviceHolder> HCameraDeviceManager::GetCameraHolderByPid(pid_t pidRequest)
85 {
86     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraHolderByPid start");
87     std::lock_guard<std::mutex> lock(mapMutex_);
88     sptr<HCameraDeviceHolder> cameraHolder = nullptr;
89     pidToCameras_.Find(pidRequest, cameraHolder);
90     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraHolderByPid end");
91     return cameraHolder;
92 }
93 
GetCameraByPid(pid_t pidRequest)94 sptr<HCameraDevice> HCameraDeviceManager::GetCameraByPid(pid_t pidRequest)
95 {
96     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraByPid start");
97     std::lock_guard<std::mutex> lock(mapMutex_);
98     sptr<HCameraDeviceHolder> cameraHolder = nullptr;
99     pidToCameras_.Find(pidRequest, cameraHolder);
100     sptr<HCameraDevice> camera = nullptr;
101     if (cameraHolder != nullptr) {
102         camera = cameraHolder->GetDevice();
103     }
104     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraByPid end");
105     return camera;
106 }
107 
GetActiveClient()108 pid_t HCameraDeviceManager::GetActiveClient()
109 {
110     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient start");
111     std::lock_guard<std::mutex> lock(mapMutex_);
112     pid_t activeClientPid = -1;
113     if (!pidToCameras_.IsEmpty()) {
114         pidToCameras_.Iterate([&](pid_t pid, sptr<HCameraDeviceHolder> camerasHolder) {
115             activeClientPid = pid;
116         });
117     }
118     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient end");
119     return activeClientPid;
120 }
121 
SetStateOfACamera(std::string cameraId,int32_t state)122 void HCameraDeviceManager::SetStateOfACamera(std::string cameraId, int32_t state)
123 {
124     MEDIA_INFO_LOG("HCameraDeviceManager::SetStateOfACamera start %{public}s, state: %{public}d",
125                    cameraId.c_str(), state);\
126     if (state == 0) {
127         stateOfACamera_.EnsureInsert(cameraId, state);
128     } else {
129         stateOfACamera_.Clear();
130     }
131     MEDIA_INFO_LOG("HCameraDeviceManager::SetStateOfACamera end");
132 }
133 
GetCameraStateOfASide()134 SafeMap<std::string, int32_t> &HCameraDeviceManager::GetCameraStateOfASide()
135 {
136     return stateOfACamera_;
137 }
138 
SetPeerCallback(sptr<ICameraBroker> & callback)139 void HCameraDeviceManager::SetPeerCallback(sptr<ICameraBroker>& callback)
140 {
141     CHECK_ERROR_RETURN_LOG(callback == nullptr, "HCameraDeviceManager::SetPeerCallback failed to set peer callback");
142     std::lock_guard<std::mutex> lock(peerCbMutex_);
143     peerCallback_ = callback;
144 }
145 
UnsetPeerCallback()146 void HCameraDeviceManager::UnsetPeerCallback()
147 {
148     std::lock_guard<std::mutex> lock(peerCbMutex_);
149     peerCallback_ = nullptr;
150 }
151 
GetConflictDevices(sptr<HCameraDevice> & cameraNeedEvict,sptr<HCameraDevice> cameraRequestOpen)152 bool HCameraDeviceManager::GetConflictDevices(sptr<HCameraDevice> &cameraNeedEvict,
153                                               sptr<HCameraDevice> cameraRequestOpen)
154 {
155     pid_t pidOfActiveClient = GetActiveClient();
156     pid_t pidOfOpenRequest = IPCSkeleton::GetCallingPid();
157     pid_t uidOfOpenRequest = IPCSkeleton::GetCallingUid();
158     uint32_t accessTokenIdOfRequestProc = IPCSkeleton::GetCallingTokenID();
159     MEDIA_INFO_LOG("GetConflictDevices get active: %{public}d, openRequestPid:%{public}d, openRequestUid:%{public}d",
160         pidOfActiveClient, pidOfOpenRequest, uidOfOpenRequest);
161     if (stateOfACamera_.Size() != 0) {
162         CHECK_ERROR_RETURN_RET_LOG(pidOfActiveClient != -1, false,
163             "HCameraDeviceManager::GetConflictDevices rgm and OH camera is turning on in the same time");
164         return IsAllowOpen(pidOfOpenRequest);
165     } else {
166         MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices no rgm camera active");
167     }
168     if (pidOfActiveClient == -1) {
169         return true;
170     }
171     sptr<HCameraDeviceHolder> activeCameraHolder = GetCameraHolderByPid(pidOfActiveClient);
172     if (activeCameraHolder == nullptr) {
173         return true;
174     }
175     if (pidOfActiveClient == pidOfOpenRequest) {
176         MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices is same pid");
177         if (!activeCameraHolder->GetDevice()->GetCameraId().compare(cameraRequestOpen->GetCameraId())) {
178             cameraNeedEvict = activeCameraHolder->GetDevice();
179             return true;
180         } else {
181             return false;
182         }
183     }
184     int32_t activeState = CameraAppManagerClient::GetInstance()->GetProcessState(pidOfActiveClient);
185     int32_t requestState = CameraAppManagerClient::GetInstance()->GetProcessState(pidOfOpenRequest);
186     MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices active pid:%{public}d state: %{public}d,"
187         "request pid:%{public}d state: %{public}d", pidOfActiveClient, activeState, pidOfOpenRequest, requestState);
188     UpdateProcessState(activeState, requestState,
189         activeCameraHolder->GetAccessTokenId(), accessTokenIdOfRequestProc);
190     pid_t focusWindowPid = -1;
191     CameraWindowManagerClient::GetInstance()->GetFocusWindowInfo(focusWindowPid);
192     if (focusWindowPid == -1) {
193         MEDIA_INFO_LOG("GetFocusWindowInfo faild");
194     }
195 
196     int32_t focusStateOfRequestProcess = focusWindowPid ==
197         pidOfOpenRequest ? FOCUSED_STATE_OF_PROCESS : UNFOCUSED_STATE_OF_PROCESS;
198     int32_t focusStateOfActiveProcess = focusWindowPid ==
199         pidOfActiveClient ? FOCUSED_STATE_OF_PROCESS : UNFOCUSED_STATE_OF_PROCESS;
200     activeCameraHolder->SetState(activeState);
201     activeCameraHolder->SetFocusState(focusStateOfActiveProcess);
202 
203     sptr<HCameraDeviceHolder> requestCameraHolder = new HCameraDeviceHolder(
204         pidOfOpenRequest, uidOfOpenRequest, requestState,
205         focusStateOfRequestProcess, cameraRequestOpen, accessTokenIdOfRequestProc);
206 
207     PrintClientInfo(activeCameraHolder, requestCameraHolder);
208     if (*(activeCameraHolder->GetPriority()) <= *(requestCameraHolder->GetPriority())) {
209         cameraNeedEvict = activeCameraHolder->GetDevice();
210         return true;
211     } else {
212         return false;
213     }
214 }
215 
GetACameraId()216 std::string HCameraDeviceManager::GetACameraId()
217 {
218     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient start");
219     std::string cameraId;
220     if (!stateOfACamera_.IsEmpty()) {
221         stateOfACamera_.Iterate([&](const std::string pid, int32_t state) {
222             cameraId = pid;
223         });
224     }
225     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient end");
226     return cameraId;
227 }
228 
IsAllowOpen(pid_t pidOfOpenRequest)229 bool HCameraDeviceManager::IsAllowOpen(pid_t pidOfOpenRequest)
230 {
231     MEDIA_INFO_LOG("HCameraDeviceManager::isAllowOpen has a client open in A proxy");
232     CHECK_ERROR_RETURN_RET_LOG(pidOfOpenRequest == -1, false,
233         "HCameraDeviceManager::GetConflictDevices wrong pid of the process whitch is goning to turn on");
234     std::string cameraId = GetACameraId();
235     CHECK_ERROR_RETURN_RET_LOG(peerCallback_ == nullptr, false,
236         "HCameraDeviceManager::isAllowOpen falied to close peer device");
237     peerCallback_->NotifyCloseCamera(cameraId);
238     MEDIA_ERR_LOG("HCameraDeviceManager::isAllowOpen success to close peer device");
239     return true;
240 }
241 
UpdateProcessState(int32_t & activeState,int32_t & requestState,uint32_t activeAccessTokenId,uint32_t requestAccessTokenId)242 void HCameraDeviceManager::UpdateProcessState(int32_t& activeState, int32_t& requestState,
243     uint32_t activeAccessTokenId, uint32_t requestAccessTokenId)
244 {
245     sptr<IWindowManagerAgent> winMgrAgent = CameraWindowManagerClient::GetInstance()->GetWindowManagerAgent();
246     uint32_t accessTokenIdInPip = 0;
247     if (winMgrAgent != nullptr) {
248         accessTokenIdInPip =
249             static_cast<CameraWindowManagerAgent*>(winMgrAgent.GetRefPtr())->GetAccessTokenId();
250         MEDIA_DEBUG_LOG("update current pip window accessTokenId");
251     }
252 
253     auto updateState = [accessTokenIdInPip](int32_t& state, uint32_t accessTokenId) {
254         auto it = APP_MGR_STATE_TO_CAMERA_STATE.find(state);
255         state = (it != APP_MGR_STATE_TO_CAMERA_STATE.end()) ? it->second : UNKNOW_STATE_OF_PROCESS;
256         if (accessTokenId == accessTokenIdInPip) {
257             state = PIP_STATE_OF_PROCESS;
258         }
259     };
260 
261     updateState(activeState, activeAccessTokenId);
262     updateState(requestState, requestAccessTokenId);
263 }
264 
PrintClientInfo(sptr<HCameraDeviceHolder> activeCameraHolder,sptr<HCameraDeviceHolder> requestCameraHolder)265 void HCameraDeviceManager::PrintClientInfo(sptr<HCameraDeviceHolder> activeCameraHolder,
266     sptr<HCameraDeviceHolder> requestCameraHolder)
267 {
268     MEDIA_INFO_LOG("activeInfo: uid: %{public}d, pid:%{public}d, processState:%{public}d,"
269         "focusState:%{public}d, cameraId:%{public}s",
270         activeCameraHolder->GetPriority()->GetUid(), activeCameraHolder->GetPid(),
271         activeCameraHolder->GetPriority()->GetState(),
272         activeCameraHolder->GetPriority()->GetFocusState(),
273         activeCameraHolder->GetDevice()->GetCameraId().c_str());
274 
275     MEDIA_INFO_LOG("requestInfo: uid: %{public}d, pid:%{public}d, processState:%{public}d,"
276         "focusState:%{public}d, cameraId:%{public}s",
277         requestCameraHolder->GetPriority()->GetUid(), requestCameraHolder->GetPid(),
278         requestCameraHolder->GetPriority()->GetState(),
279         requestCameraHolder->GetPriority()->GetFocusState(),
280         requestCameraHolder->GetDevice()->GetCameraId().c_str());
281 }
282 } // namespace CameraStandard
283 } // namespace OHOS