• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     activeCameras_.push_back(cameraHolder);
74     MEDIA_INFO_LOG("HCameraDeviceManager::AddDevice end");
75 }
76 
RemoveDevice(const std::string & cameraId)77 void HCameraDeviceManager::RemoveDevice(const std::string &cameraId)
78 {
79     MEDIA_INFO_LOG("HCameraDeviceManager::RemoveDevice cameraId=%{public}s start", cameraId.c_str());
80     std::lock_guard<std::mutex> lock(mapMutex_);
81     if (activeCameras_.empty()) {
82         return;
83     }
84     auto it = std::find_if(activeCameras_.begin(), activeCameras_.end(), [&](const sptr<HCameraDeviceHolder> &x) {
85         const std::string &curCameraId = x->GetDevice()->GetCameraId();
86         return cameraId == curCameraId;
87     });
88     if (it == activeCameras_.end()) {
89         MEDIA_ERR_LOG("HCameraDeviceManager::RemoveDevice error");
90         return;
91     }
92     pidToCameras_.Erase((*it)->GetPid());
93     activeCameras_.erase(it);
94     MEDIA_DEBUG_LOG("HCameraDeviceManager::RemoveDevice end");
95 }
96 
GetCameraHolderByPid(pid_t pidRequest)97 sptr<HCameraDeviceHolder> HCameraDeviceManager::GetCameraHolderByPid(pid_t pidRequest)
98 {
99     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraHolderByPid start");
100     std::lock_guard<std::mutex> lock(mapMutex_);
101     sptr<HCameraDeviceHolder> cameraHolder = nullptr;
102     pidToCameras_.Find(pidRequest, cameraHolder);
103     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraHolderByPid end");
104     return cameraHolder;
105 }
106 
GetCameraByPid(pid_t pidRequest)107 sptr<HCameraDevice> HCameraDeviceManager::GetCameraByPid(pid_t pidRequest)
108 {
109     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraByPid start");
110     std::lock_guard<std::mutex> lock(mapMutex_);
111     sptr<HCameraDeviceHolder> cameraHolder = nullptr;
112     pidToCameras_.Find(pidRequest, cameraHolder);
113     sptr<HCameraDevice> camera = nullptr;
114     if (cameraHolder != nullptr) {
115         camera = cameraHolder->GetDevice();
116     }
117     MEDIA_INFO_LOG("HCameraDeviceManager::GetCameraByPid end");
118     return camera;
119 }
120 
GetActiveClient()121 pid_t HCameraDeviceManager::GetActiveClient()
122 {
123     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient start");
124     std::lock_guard<std::mutex> lock(mapMutex_);
125     pid_t activeClientPid = -1;
126     if (!pidToCameras_.IsEmpty()) {
127         pidToCameras_.Iterate([&](pid_t pid, sptr<HCameraDeviceHolder> camerasHolder) {
128             activeClientPid = pid;
129         });
130     }
131     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient end");
132     return activeClientPid;
133 }
134 
GetActiveCameraHolders()135 std::vector<sptr<HCameraDeviceHolder>> HCameraDeviceManager::GetActiveCameraHolders()
136 {
137     std::lock_guard<std::mutex> lock(mapMutex_);
138     return activeCameras_;
139 }
140 
SetStateOfACamera(std::string cameraId,int32_t state)141 void HCameraDeviceManager::SetStateOfACamera(std::string cameraId, int32_t state)
142 {
143     MEDIA_INFO_LOG("HCameraDeviceManager::SetStateOfACamera start %{public}s, state: %{public}d",
144                    cameraId.c_str(), state);\
145     if (state == 0) {
146         stateOfACamera_.EnsureInsert(cameraId, state);
147     } else {
148         stateOfACamera_.Clear();
149     }
150     MEDIA_INFO_LOG("HCameraDeviceManager::SetStateOfACamera end");
151 }
152 
GetCameraStateOfASide()153 SafeMap<std::string, int32_t> &HCameraDeviceManager::GetCameraStateOfASide()
154 {
155     return stateOfACamera_;
156 }
157 
SetPeerCallback(sptr<ICameraBroker> & callback)158 void HCameraDeviceManager::SetPeerCallback(sptr<ICameraBroker>& callback)
159 {
160     CHECK_ERROR_RETURN_LOG(callback == nullptr, "HCameraDeviceManager::SetPeerCallback failed to set peer callback");
161     std::lock_guard<std::mutex> lock(peerCbMutex_);
162     peerCallback_ = callback;
163 }
164 
UnsetPeerCallback()165 void HCameraDeviceManager::UnsetPeerCallback()
166 {
167     std::lock_guard<std::mutex> lock(peerCbMutex_);
168     peerCallback_ = nullptr;
169 }
170 
GetConflictDevices(sptr<HCameraDevice> & cameraNeedEvict,sptr<HCameraDevice> cameraRequestOpen)171 bool HCameraDeviceManager::GetConflictDevices(sptr<HCameraDevice> &cameraNeedEvict,
172                                               sptr<HCameraDevice> cameraRequestOpen)
173 {
174     pid_t pidOfActiveClient = GetActiveClient();
175     pid_t pidOfOpenRequest = IPCSkeleton::GetCallingPid();
176     pid_t uidOfOpenRequest = IPCSkeleton::GetCallingUid();
177     uint32_t accessTokenIdOfRequestProc = IPCSkeleton::GetCallingTokenID();
178     MEDIA_INFO_LOG("GetConflictDevices get active: %{public}d, openRequestPid:%{public}d, openRequestUid:%{public}d",
179         pidOfActiveClient, pidOfOpenRequest, uidOfOpenRequest);
180     if (stateOfACamera_.Size() != 0) {
181         CHECK_ERROR_RETURN_RET_LOG(pidOfActiveClient != -1, false,
182             "HCameraDeviceManager::GetConflictDevices rgm and OH camera is turning on in the same time");
183         return IsAllowOpen(pidOfOpenRequest);
184     } else {
185         MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices no rgm camera active");
186     }
187     if (pidOfActiveClient == -1) {
188         return true;
189     }
190     sptr<HCameraDeviceHolder> activeCameraHolder = GetCameraHolderByPid(pidOfActiveClient);
191     if (activeCameraHolder == nullptr) {
192         return true;
193     }
194     if (pidOfActiveClient == pidOfOpenRequest) {
195         MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices is same pid");
196         if (!activeCameraHolder->GetDevice()->GetCameraId().compare(cameraRequestOpen->GetCameraId())) {
197             cameraNeedEvict = activeCameraHolder->GetDevice();
198             return true;
199         } else {
200             return false;
201         }
202     }
203     int32_t activeState = CameraAppManagerClient::GetInstance()->GetProcessState(pidOfActiveClient);
204     int32_t requestState = CameraAppManagerClient::GetInstance()->GetProcessState(pidOfOpenRequest);
205     MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices active pid:%{public}d state: %{public}d,"
206         "request pid:%{public}d state: %{public}d", pidOfActiveClient, activeState, pidOfOpenRequest, requestState);
207     UpdateProcessState(activeState, requestState,
208         activeCameraHolder->GetAccessTokenId(), accessTokenIdOfRequestProc);
209     pid_t focusWindowPid = -1;
210     CameraWindowManagerClient::GetInstance()->GetFocusWindowInfo(focusWindowPid);
211     if (focusWindowPid == -1) {
212         MEDIA_INFO_LOG("GetFocusWindowInfo faild");
213     }
214 
215     int32_t focusStateOfRequestProcess = focusWindowPid ==
216         pidOfOpenRequest ? FOCUSED_STATE_OF_PROCESS : UNFOCUSED_STATE_OF_PROCESS;
217     int32_t focusStateOfActiveProcess = focusWindowPid ==
218         pidOfActiveClient ? FOCUSED_STATE_OF_PROCESS : UNFOCUSED_STATE_OF_PROCESS;
219     activeCameraHolder->SetState(activeState);
220     activeCameraHolder->SetFocusState(focusStateOfActiveProcess);
221 
222     sptr<HCameraDeviceHolder> requestCameraHolder = new HCameraDeviceHolder(
223         pidOfOpenRequest, uidOfOpenRequest, requestState,
224         focusStateOfRequestProcess, cameraRequestOpen, accessTokenIdOfRequestProc);
225 
226     PrintClientInfo(activeCameraHolder, requestCameraHolder);
227     if (*(activeCameraHolder->GetPriority()) <= *(requestCameraHolder->GetPriority())) {
228         cameraNeedEvict = activeCameraHolder->GetDevice();
229         return true;
230     } else {
231         return false;
232     }
233 }
234 
GetACameraId()235 std::string HCameraDeviceManager::GetACameraId()
236 {
237     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient start");
238     std::string cameraId;
239     if (!stateOfACamera_.IsEmpty()) {
240         stateOfACamera_.Iterate([&](const std::string pid, int32_t state) {
241             cameraId = pid;
242         });
243     }
244     MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient end");
245     return cameraId;
246 }
247 
IsAllowOpen(pid_t pidOfOpenRequest)248 bool HCameraDeviceManager::IsAllowOpen(pid_t pidOfOpenRequest)
249 {
250     MEDIA_INFO_LOG("HCameraDeviceManager::isAllowOpen has a client open in A proxy");
251     CHECK_ERROR_RETURN_RET_LOG(pidOfOpenRequest == -1, false,
252         "HCameraDeviceManager::GetConflictDevices wrong pid of the process whitch is goning to turn on");
253     std::string cameraId = GetACameraId();
254     CHECK_ERROR_RETURN_RET_LOG(peerCallback_ == nullptr, false,
255         "HCameraDeviceManager::isAllowOpen falied to close peer device");
256     peerCallback_->NotifyCloseCamera(cameraId);
257     MEDIA_ERR_LOG("HCameraDeviceManager::isAllowOpen success to close peer device");
258     return true;
259 }
260 
UpdateProcessState(int32_t & activeState,int32_t & requestState,uint32_t activeAccessTokenId,uint32_t requestAccessTokenId)261 void HCameraDeviceManager::UpdateProcessState(int32_t& activeState, int32_t& requestState,
262     uint32_t activeAccessTokenId, uint32_t requestAccessTokenId)
263 {
264     sptr<IWindowManagerAgent> winMgrAgent = CameraWindowManagerClient::GetInstance()->GetWindowManagerAgent();
265     uint32_t accessTokenIdInPip = 0;
266     if (winMgrAgent != nullptr) {
267         accessTokenIdInPip =
268             static_cast<CameraWindowManagerAgent*>(winMgrAgent.GetRefPtr())->GetAccessTokenId();
269         MEDIA_DEBUG_LOG("update current pip window accessTokenId");
270     }
271 
272     auto updateState = [accessTokenIdInPip](int32_t& state, uint32_t accessTokenId) {
273         auto it = APP_MGR_STATE_TO_CAMERA_STATE.find(state);
274         state = (it != APP_MGR_STATE_TO_CAMERA_STATE.end()) ? it->second : UNKNOW_STATE_OF_PROCESS;
275         if (accessTokenId == accessTokenIdInPip) {
276             state = PIP_STATE_OF_PROCESS;
277         }
278     };
279 
280     updateState(activeState, activeAccessTokenId);
281     updateState(requestState, requestAccessTokenId);
282 }
283 
PrintClientInfo(sptr<HCameraDeviceHolder> activeCameraHolder,sptr<HCameraDeviceHolder> requestCameraHolder)284 void HCameraDeviceManager::PrintClientInfo(sptr<HCameraDeviceHolder> activeCameraHolder,
285     sptr<HCameraDeviceHolder> requestCameraHolder)
286 {
287     MEDIA_INFO_LOG("activeInfo: uid: %{public}d, pid:%{public}d, processState:%{public}d,"
288         "focusState:%{public}d, cameraId:%{public}s",
289         activeCameraHolder->GetPriority()->GetUid(), activeCameraHolder->GetPid(),
290         activeCameraHolder->GetPriority()->GetState(),
291         activeCameraHolder->GetPriority()->GetFocusState(),
292         activeCameraHolder->GetDevice()->GetCameraId().c_str());
293 
294     MEDIA_INFO_LOG("requestInfo: uid: %{public}d, pid:%{public}d, processState:%{public}d,"
295         "focusState:%{public}d, cameraId:%{public}s",
296         requestCameraHolder->GetPriority()->GetUid(), requestCameraHolder->GetPid(),
297         requestCameraHolder->GetPriority()->GetState(),
298         requestCameraHolder->GetPriority()->GetFocusState(),
299         requestCameraHolder->GetDevice()->GetCameraId().c_str());
300 }
301 } // namespace CameraStandard
302 } // namespace OHOS