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