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_log.h"
17 #include "ipc_skeleton.h"
18 #include "hcamera_service_proxy.h"
19 #include "system_ability_definition.h"
20 #include "iservice_registry.h"
21 #include "hcamera_device_manager.h"
22
23 namespace OHOS {
24 namespace CameraStandard {
25 static const int32_t SERVICE_ID_OF_DH = 66850;
26 static const int32_t PRIORITY_OF_FOREGROUND = 0;
27 static const int32_t PRIORITY_OF_BACKGROUND = 400;
28 sptr<HCameraDeviceManager> HCameraDeviceManager::cameraDeviceManager_;
29 std::mutex HCameraDeviceManager::instanceMutex_;
30
HCameraDeviceManager()31 HCameraDeviceManager::HCameraDeviceManager() {}
32
~HCameraDeviceManager()33 HCameraDeviceManager::~HCameraDeviceManager()
34 {
35 HCameraDeviceManager::cameraDeviceManager_ = nullptr;
36 }
37
GetInstance()38 sptr<HCameraDeviceManager> &HCameraDeviceManager::GetInstance()
39 {
40 if (HCameraDeviceManager::cameraDeviceManager_ == nullptr) {
41 std::unique_lock<std::mutex> lock(instanceMutex_);
42 if (HCameraDeviceManager::cameraDeviceManager_ == nullptr) {
43 MEDIA_INFO_LOG("Initializing camera device manager instance");
44 HCameraDeviceManager::cameraDeviceManager_ = new(std::nothrow) HCameraDeviceManager();
45 }
46 }
47 return HCameraDeviceManager::cameraDeviceManager_;
48 }
49
AddDevice(pid_t pid,sptr<HCameraDevice> device)50 void HCameraDeviceManager::AddDevice(pid_t pid, sptr<HCameraDevice> device)
51 {
52 MEDIA_DEBUG_LOG("HCameraDeviceManager::AddDevice start");
53 pidToCameras_.EnsureInsert(pid, device);
54 MEDIA_DEBUG_LOG("HCameraDeviceManager::AddDevice end");
55 }
56
RemoveDevice()57 void HCameraDeviceManager::RemoveDevice()
58 {
59 MEDIA_DEBUG_LOG("HCameraDeviceManager::RemoveDevice start");
60 pidToCameras_.Clear();
61 MEDIA_DEBUG_LOG("HCameraDeviceManager::RemoveDevice end");
62 }
63
GetCameraByPid(pid_t pidRequest)64 sptr<HCameraDevice> HCameraDeviceManager::GetCameraByPid(pid_t pidRequest)
65 {
66 MEDIA_DEBUG_LOG("HCameraDeviceManager::GetCameraByPid start");
67 sptr<HCameraDevice> camera = nullptr;
68 pidToCameras_.Find(pidRequest, camera);
69 MEDIA_DEBUG_LOG("HCameraDeviceManager::GetCameraByPid end");
70 return camera;
71 }
72
GetActiveClient()73 pid_t HCameraDeviceManager::GetActiveClient()
74 {
75 MEDIA_DEBUG_LOG("HCameraDeviceManager::GetActiveClient start");
76 pid_t activeClientPid = -1;
77 if (!pidToCameras_.IsEmpty()) {
78 pidToCameras_.Iterate([&](pid_t pid, sptr<HCameraDevice> cameras) {
79 activeClientPid = pid;
80 });
81 }
82 MEDIA_DEBUG_LOG("HCameraDeviceManager::GetActiveClient end");
83 return activeClientPid;
84 }
85
SetStateOfACamera(std::string cameraId,int32_t state)86 void HCameraDeviceManager::SetStateOfACamera(std::string cameraId, int32_t state)
87 {
88 MEDIA_INFO_LOG("HCameraDeviceManager::SetStateOfACamera start %{public}s, state: %{public}d",
89 cameraId.c_str(), state);\
90 if (state == 0) {
91 stateOfACamera_.EnsureInsert(cameraId, state);
92 } else {
93 stateOfACamera_.Clear();
94 }
95 MEDIA_INFO_LOG("HCameraDeviceManager::SetStateOfACamera end");
96 }
97
GetCameraStateOfASide()98 SafeMap<std::string, int32_t> &HCameraDeviceManager::GetCameraStateOfASide()
99 {
100 return stateOfACamera_;
101 }
102
GetConflictDevices(sptr<HCameraDevice> & cameraNeedEvict,sptr<HCameraDevice> cameraIdRequestOpen)103 bool HCameraDeviceManager::GetConflictDevices(sptr<HCameraDevice> &cameraNeedEvict,
104 sptr<HCameraDevice> cameraIdRequestOpen)
105 {
106 pid_t activeClient = GetActiveClient();
107 pid_t pidOfOpenRequest = IPCSkeleton::GetCallingPid();
108 if (stateOfACamera_.Size() != 0) {
109 if (activeClient != -1) {
110 MEDIA_ERR_LOG("HCameraDeviceManager::GetConflictDevices A and OH camera is turning on in the same time");
111 return false;
112 }
113 return isAllowOpen(pidOfOpenRequest);
114 } else {
115 MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices no A camera active");
116 }
117 if (activeClient == -1) {
118 return true;
119 }
120 sptr<HCameraDevice> activeCamera = GetCameraByPid(activeClient);
121 if (activeCamera == nullptr) {
122 return true;
123 }
124 int32_t priorityOfOpenRequestPid = 1001;
125 int32_t result = Memory::MemMgrClient::GetInstance().
126 GetReclaimPriorityByPid(pidOfOpenRequest, priorityOfOpenRequestPid);
127 MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices callerPid:%{public}d, priority score: %{public}d",
128 pidOfOpenRequest, priorityOfOpenRequestPid);
129 if (!result) {
130 if (activeClient == pidOfOpenRequest) {
131 MEDIA_INFO_LOG("HCameraDeviceManager::GetConflictDevices is same pid");
132 if (!activeCamera->GetCameraId().compare(cameraIdRequestOpen->GetCameraId())) {
133 cameraNeedEvict = activeCamera;
134 return true;
135 } else {
136 return false;
137 }
138 }
139 int32_t priorityOfIterPid = 1001;
140 int32_t iterResult = Memory::MemMgrClient::GetInstance().
141 GetReclaimPriorityByPid(activeClient, priorityOfIterPid);
142 MEDIA_INFO_LOG("HCameraDeviceManager::canOpenCamera pid:%{public}d, priority score: %{public}d",
143 activeClient, priorityOfIterPid);
144 if (!iterResult && priorityOfOpenRequestPid <= priorityOfIterPid) {
145 cameraNeedEvict= activeCamera;
146 return true;
147 } else {
148 return false;
149 }
150 } else {
151 MEDIA_ERR_LOG("HCameraDeviceManager::GetConflictDevices falied to get priority");
152 return false;
153 }
154 }
155
GetACameraId()156 std::string HCameraDeviceManager::GetACameraId()
157 {
158 MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient start");
159 std::string cameraId;
160 if (!stateOfACamera_.IsEmpty()) {
161 stateOfACamera_.Iterate([&](std::string pid, int32_t state) {
162 cameraId = pid;
163 });
164 }
165 MEDIA_INFO_LOG("HCameraDeviceManager::GetActiveClient end");
166 return cameraId;
167 }
168
GetAdjForCameraState(std::string cameraId)169 int32_t HCameraDeviceManager::GetAdjForCameraState(std::string cameraId)
170 {
171 int32_t state = 1;
172 stateOfACamera_.Find(cameraId, state);
173 MEDIA_INFO_LOG("HCameraDeviceManager::SetStateOfACamera start %{public}s, state: %{public}d",
174 cameraId.c_str(), state);
175 return state == 0 ? PRIORITY_OF_FOREGROUND : PRIORITY_OF_BACKGROUND;
176 }
177
isAllowOpen(pid_t pidOfOpenRequest)178 bool HCameraDeviceManager::isAllowOpen(pid_t pidOfOpenRequest)
179 {
180 MEDIA_INFO_LOG("HCameraDeviceManager::isAllowOpen has a client open in A proxy");
181 if (pidOfOpenRequest != -1) {
182 std::string cameraId = GetACameraId();
183 sptr<IRemoteObject> object = nullptr;
184 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
185 if (samgr == nullptr) {
186 MEDIA_ERR_LOG("Failed to get System ability manager");
187 return false;
188 }
189 object = samgr->GetSystemAbility(SERVICE_ID_OF_DH);
190 if (object == nullptr) {
191 MEDIA_ERR_LOG("object is null");
192 return false;
193 }
194 sptr<ICameraProxy> ancoCallback = iface_cast<ICameraProxy>(object);
195 if (ancoCallback == nullptr) {
196 MEDIA_ERR_LOG("serviceProxy_ is null.");
197 return false;
198 }
199 ancoCallback->NotifyCloseCamera(cameraId);
200 return true;
201 } else {
202 MEDIA_ERR_LOG("HCameraDeviceManager::GetConflictDevices wrong pid of the process whitch is goning to turn on");
203 return false;
204 }
205 }
206 } // namespace CameraStandard
207 } // namespace OHOS