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