1 /*
2 * Copyright (c) 2022-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 #include "privacy_manager_client.h"
16
17 #include <algorithm>
18 #include "accesstoken_log.h"
19 #include "iservice_registry.h"
20 #include "privacy_error.h"
21 #include "privacy_manager_proxy.h"
22 #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE
23 #include "sec_comp_enhance_data_parcel.h"
24 #endif
25
26 namespace OHOS {
27 namespace Security {
28 namespace AccessToken {
29 namespace {
30 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
31 LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacyManagerClient"
32 };
33 const static int32_t MAX_CALLBACK_SIZE = 200;
34 const static int32_t MAX_PERM_LIST_SIZE = 1024;
35 constexpr const char* CAMERA_PERMISSION_NAME = "ohos.permission.CAMERA";
36 std::recursive_mutex g_instanceMutex;
37 } // namespace
38
GetInstance()39 PrivacyManagerClient& PrivacyManagerClient::GetInstance()
40 {
41 static PrivacyManagerClient* instance = nullptr;
42 if (instance == nullptr) {
43 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
44 if (instance == nullptr) {
45 instance = new PrivacyManagerClient();
46 }
47 }
48 return *instance;
49 }
50
PrivacyManagerClient()51 PrivacyManagerClient::PrivacyManagerClient()
52 {}
53
~PrivacyManagerClient()54 PrivacyManagerClient::~PrivacyManagerClient()
55 {
56 ACCESSTOKEN_LOG_ERROR(LABEL, "~PrivacyManagerClient");
57 std::lock_guard<std::mutex> lock(proxyMutex_);
58 ReleaseProxy();
59 }
60
AddPermissionUsedRecord(const AddPermParamInfo & info,bool asyncMode)61 int32_t PrivacyManagerClient::AddPermissionUsedRecord(const AddPermParamInfo& info, bool asyncMode)
62 {
63 auto proxy = GetProxy();
64 if (proxy == nullptr) {
65 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
66 return PrivacyError::ERR_SERVICE_ABNORMAL;
67 }
68 AddPermParamInfoParcel infoParcel;
69 infoParcel.info = info;
70 return proxy->AddPermissionUsedRecord(infoParcel, asyncMode);
71 }
72
StartUsingPermission(AccessTokenID tokenID,int32_t pid,const std::string & permissionName)73 int32_t PrivacyManagerClient::StartUsingPermission(
74 AccessTokenID tokenID, int32_t pid, const std::string& permissionName)
75 {
76 auto proxy = GetProxy();
77 if (proxy == nullptr) {
78 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
79 return PrivacyError::ERR_SERVICE_ABNORMAL;
80 }
81 return proxy->StartUsingPermission(tokenID, pid, permissionName);
82 }
83
CreateStateChangeCbk(uint64_t id,const std::shared_ptr<StateCustomizedCbk> & callback,sptr<StateChangeCallback> & callbackWrap)84 int32_t PrivacyManagerClient::CreateStateChangeCbk(uint64_t id,
85 const std::shared_ptr<StateCustomizedCbk>& callback, sptr<StateChangeCallback>& callbackWrap)
86 {
87 std::lock_guard<std::mutex> lock(stateCbkMutex_);
88 auto iter = stateChangeCallbackMap_.find(id);
89 if (iter != stateChangeCallbackMap_.end()) {
90 ACCESSTOKEN_LOG_ERROR(LABEL, " Callback has been used.");
91 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
92 } else {
93 callbackWrap = new (std::nothrow) StateChangeCallback(callback);
94 if (callbackWrap == nullptr) {
95 ACCESSTOKEN_LOG_ERROR(LABEL, "Memory allocation for callbackWrap failed!");
96 return PrivacyError::ERR_MALLOC_FAILED;
97 }
98 }
99 return RET_SUCCESS;
100 }
101
StartUsingPermission(AccessTokenID tokenId,int32_t pid,const std::string & permissionName,const std::shared_ptr<StateCustomizedCbk> & callback)102 int32_t PrivacyManagerClient::StartUsingPermission(
103 AccessTokenID tokenId, int32_t pid, const std::string& permissionName,
104 const std::shared_ptr<StateCustomizedCbk>& callback)
105 {
106 if (callback == nullptr) {
107 ACCESSTOKEN_LOG_ERROR(LABEL, "Callback is nullptr.");
108 return PrivacyError::ERR_PARAM_INVALID;
109 }
110
111 sptr<StateChangeCallback> callbackWrap = nullptr;
112 uint64_t id = GetUniqueId(tokenId, pid);
113 int32_t result = CreateStateChangeCbk(id, callback, callbackWrap);
114 if (result != RET_SUCCESS) {
115 return result;
116 }
117
118 auto proxy = GetProxy();
119 if (proxy == nullptr) {
120 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
121 return PrivacyError::ERR_SERVICE_ABNORMAL;
122 }
123
124 result = proxy->StartUsingPermission(tokenId, pid, permissionName, callbackWrap->AsObject());
125 if (result == RET_SUCCESS) {
126 std::lock_guard<std::mutex> lock(stateCbkMutex_);
127 stateChangeCallbackMap_[id] = callbackWrap;
128 ACCESSTOKEN_LOG_INFO(LABEL, "CallbackObject added.");
129 }
130 return result;
131 }
132
StopUsingPermission(AccessTokenID tokenID,int32_t pid,const std::string & permissionName)133 int32_t PrivacyManagerClient::StopUsingPermission(
134 AccessTokenID tokenID, int32_t pid, const std::string& permissionName)
135 {
136 auto proxy = GetProxy();
137 if (proxy == nullptr) {
138 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
139 return PrivacyError::ERR_SERVICE_ABNORMAL;
140 }
141 if (permissionName == CAMERA_PERMISSION_NAME) {
142 uint64_t id = GetUniqueId(tokenID, pid);
143 std::lock_guard<std::mutex> lock(stateCbkMutex_);
144 auto iter = stateChangeCallbackMap_.find(id);
145 if (iter != stateChangeCallbackMap_.end()) {
146 stateChangeCallbackMap_.erase(id);
147 }
148 }
149
150 return proxy->StopUsingPermission(tokenID, pid, permissionName);
151 }
152
RemovePermissionUsedRecords(AccessTokenID tokenID,const std::string & deviceID)153 int32_t PrivacyManagerClient::RemovePermissionUsedRecords(AccessTokenID tokenID, const std::string& deviceID)
154 {
155 auto proxy = GetProxy();
156 if (proxy == nullptr) {
157 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
158 return PrivacyError::ERR_SERVICE_ABNORMAL;
159 }
160 return proxy->RemovePermissionUsedRecords(tokenID, deviceID);
161 }
162
GetPermissionUsedRecords(const PermissionUsedRequest & request,PermissionUsedResult & result)163 int32_t PrivacyManagerClient::GetPermissionUsedRecords(
164 const PermissionUsedRequest& request, PermissionUsedResult& result)
165 {
166 auto proxy = GetProxy();
167 if (proxy == nullptr) {
168 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
169 return PrivacyError::ERR_SERVICE_ABNORMAL;
170 }
171
172 PermissionUsedRequestParcel requestParcel;
173 PermissionUsedResultParcel resultParcel;
174 requestParcel.request = request;
175 int32_t ret = proxy->GetPermissionUsedRecords(requestParcel, resultParcel);
176 result = resultParcel.result;
177 return ret;
178 }
179
GetPermissionUsedRecords(const PermissionUsedRequest & request,const sptr<OnPermissionUsedRecordCallback> & callback)180 int32_t PrivacyManagerClient::GetPermissionUsedRecords(const PermissionUsedRequest& request,
181 const sptr<OnPermissionUsedRecordCallback>& callback)
182 {
183 auto proxy = GetProxy();
184 if (proxy == nullptr) {
185 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
186 return PrivacyError::ERR_SERVICE_ABNORMAL;
187 }
188
189 PermissionUsedRequestParcel requestParcel;
190 requestParcel.request = request;
191 return proxy->GetPermissionUsedRecords(requestParcel, callback);
192 }
193
CreateActiveStatusChangeCbk(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback,sptr<PermActiveStatusChangeCallback> & callbackWrap)194 int32_t PrivacyManagerClient::CreateActiveStatusChangeCbk(
195 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback, sptr<PermActiveStatusChangeCallback>& callbackWrap)
196 {
197 std::lock_guard<std::mutex> lock(activeCbkMutex_);
198
199 if (activeCbkMap_.size() >= MAX_CALLBACK_SIZE) {
200 return PrivacyError::ERR_CALLBACKS_EXCEED_LIMITATION;
201 }
202
203 auto goalCallback = activeCbkMap_.find(callback);
204 if (goalCallback != activeCbkMap_.end()) {
205 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
206 } else {
207 callbackWrap =
208 new (std::nothrow) PermActiveStatusChangeCallback(callback);
209 if (!callbackWrap) {
210 return PrivacyError::ERR_MALLOC_FAILED;
211 }
212 }
213 return RET_SUCCESS;
214 }
215
RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)216 int32_t PrivacyManagerClient::RegisterPermActiveStatusCallback(
217 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
218 {
219 if (callback == nullptr) {
220 ACCESSTOKEN_LOG_ERROR(LABEL, "CustomizedCb is nullptr.");
221 return PrivacyError::ERR_PARAM_INVALID;
222 }
223
224 sptr<PermActiveStatusChangeCallback> callbackWrap = nullptr;
225 int32_t result = CreateActiveStatusChangeCbk(callback, callbackWrap);
226 if (result != RET_SUCCESS) {
227 ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to create callback, err: %{public}d.", result);
228 return result;
229 }
230
231 auto proxy = GetProxy();
232 if (proxy == nullptr) {
233 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
234 return PrivacyError::ERR_SERVICE_ABNORMAL;
235 }
236 std::vector<std::string> permList;
237 callback->GetPermList(permList);
238 if (permList.size() > MAX_PERM_LIST_SIZE) {
239 return PrivacyError::ERR_PARAM_INVALID;
240 }
241
242 result = proxy->RegisterPermActiveStatusCallback(permList, callbackWrap->AsObject());
243 if (result == RET_SUCCESS) {
244 std::lock_guard<std::mutex> lock(activeCbkMutex_);
245 activeCbkMap_[callback] = callbackWrap;
246 ACCESSTOKEN_LOG_INFO(LABEL, "CallbackObject added.");
247 }
248 return result;
249 }
250
UnRegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)251 int32_t PrivacyManagerClient::UnRegisterPermActiveStatusCallback(
252 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
253 {
254 auto proxy = GetProxy();
255 if (proxy == nullptr) {
256 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
257 return PrivacyError::ERR_SERVICE_ABNORMAL;
258 }
259
260 std::lock_guard<std::mutex> lock(activeCbkMutex_);
261 auto goalCallback = activeCbkMap_.find(callback);
262 if (goalCallback == activeCbkMap_.end()) {
263 ACCESSTOKEN_LOG_ERROR(LABEL, "GoalCallback already is not exist.");
264 return PrivacyError::ERR_CALLBACK_NOT_EXIST;
265 }
266
267 int32_t result = proxy->UnRegisterPermActiveStatusCallback(goalCallback->second->AsObject());
268 if (result == RET_SUCCESS) {
269 activeCbkMap_.erase(goalCallback);
270 }
271 return result;
272 }
273
IsAllowedUsingPermission(AccessTokenID tokenID,const std::string & permissionName)274 bool PrivacyManagerClient::IsAllowedUsingPermission(AccessTokenID tokenID, const std::string& permissionName)
275 {
276 auto proxy = GetProxy();
277 if (proxy == nullptr) {
278 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
279 return false;
280 }
281 return proxy->IsAllowedUsingPermission(tokenID, permissionName);
282 }
283
284 #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE
RegisterSecCompEnhance(const SecCompEnhanceData & enhance)285 int32_t PrivacyManagerClient::RegisterSecCompEnhance(const SecCompEnhanceData& enhance)
286 {
287 auto proxy = GetProxy();
288 if (proxy == nullptr) {
289 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
290 return PrivacyError::ERR_PARAM_INVALID;
291 }
292 SecCompEnhanceDataParcel registerParcel;
293 registerParcel.enhanceData = enhance;
294 return proxy->RegisterSecCompEnhance(registerParcel);
295 }
296
UpdateSecCompEnhance(int32_t pid,uint32_t seqNum)297 int32_t PrivacyManagerClient::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum)
298 {
299 auto proxy = GetProxy();
300 if (proxy == nullptr) {
301 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
302 return PrivacyError::ERR_PARAM_INVALID;
303 }
304 return proxy->UpdateSecCompEnhance(pid, seqNum);
305 }
306
GetSecCompEnhance(int32_t pid,SecCompEnhanceData & enhance)307 int32_t PrivacyManagerClient::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhance)
308 {
309 auto proxy = GetProxy();
310 if (proxy == nullptr) {
311 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
312 return PrivacyError::ERR_PARAM_INVALID;
313 }
314 SecCompEnhanceDataParcel parcel;
315 int32_t res = proxy->GetSecCompEnhance(pid, parcel);
316 if (res != RET_SUCCESS) {
317 return res;
318 }
319 enhance = parcel.enhanceData;
320 return RET_SUCCESS;
321 }
322
GetSpecialSecCompEnhance(const std::string & bundleName,std::vector<SecCompEnhanceData> & enhanceList)323 int32_t PrivacyManagerClient::GetSpecialSecCompEnhance(const std::string& bundleName,
324 std::vector<SecCompEnhanceData>& enhanceList)
325 {
326 auto proxy = GetProxy();
327 if (proxy == nullptr) {
328 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
329 return PrivacyError::ERR_PARAM_INVALID;
330 }
331 std::vector<SecCompEnhanceDataParcel> parcelList;
332 int32_t res = proxy->GetSpecialSecCompEnhance(bundleName, parcelList);
333 if (res != RET_SUCCESS) {
334 return res;
335 }
336
337 std::transform(parcelList.begin(), parcelList.end(), std::back_inserter(enhanceList),
338 [](SecCompEnhanceDataParcel pair) { return pair.enhanceData; });
339 return RET_SUCCESS;
340 }
341 #endif
342
GetPermissionUsedTypeInfos(const AccessTokenID tokenId,const std::string & permissionName,std::vector<PermissionUsedTypeInfo> & results)343 int32_t PrivacyManagerClient::GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName,
344 std::vector<PermissionUsedTypeInfo>& results)
345 {
346 auto proxy = GetProxy();
347 if (proxy == nullptr) {
348 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
349 return PrivacyError::ERR_SERVICE_ABNORMAL;
350 }
351
352 std::vector<PermissionUsedTypeInfoParcel> resultsParcel;
353 int32_t res = proxy->GetPermissionUsedTypeInfos(tokenId, permissionName, resultsParcel);
354 if (res != RET_SUCCESS) {
355 return res;
356 }
357
358 std::transform(resultsParcel.begin(), resultsParcel.end(), std::back_inserter(results),
359 [](PermissionUsedTypeInfoParcel parcel) { return parcel.info; });
360 return RET_SUCCESS;
361 }
362
SetMutePolicy(uint32_t policyType,uint32_t callerType,bool isMute)363 int32_t PrivacyManagerClient::SetMutePolicy(uint32_t policyType, uint32_t callerType, bool isMute)
364 {
365 auto proxy = GetProxy();
366 if (proxy == nullptr) {
367 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
368 return PrivacyError::ERR_SERVICE_ABNORMAL;
369 }
370 return proxy->SetMutePolicy(policyType, callerType, isMute);
371 }
372
SetHapWithFGReminder(uint32_t tokenId,bool isAllowed)373 int32_t PrivacyManagerClient::SetHapWithFGReminder(uint32_t tokenId, bool isAllowed)
374 {
375 auto proxy = GetProxy();
376 if (proxy == nullptr) {
377 ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
378 return PrivacyError::ERR_SERVICE_ABNORMAL;
379 }
380 return proxy->SetHapWithFGReminder(tokenId, isAllowed);
381 }
382
GetUniqueId(uint32_t tokenId,int32_t pid) const383 uint64_t PrivacyManagerClient::GetUniqueId(uint32_t tokenId, int32_t pid) const
384 {
385 uint32_t tmpPid = (pid <= 0) ? 0 : static_cast<uint32_t>(pid);
386 return (static_cast<uint64_t>(tmpPid) << 32) | (static_cast<uint64_t>(tokenId) & 0xFFFFFFFF); // 32: bit
387 }
388
InitProxy()389 void PrivacyManagerClient::InitProxy()
390 {
391 if (proxy_ == nullptr) {
392 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
393 if (sam == nullptr) {
394 ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbilityManager is null");
395 return;
396 }
397 auto privacySa = sam->CheckSystemAbility(IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
398 if (privacySa == nullptr) {
399 ACCESSTOKEN_LOG_DEBUG(LABEL, "CheckSystemAbility %{public}d is null",
400 IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
401 return;
402 }
403
404 serviceDeathObserver_ = sptr<PrivacyDeathRecipient>::MakeSptr();
405 if (serviceDeathObserver_ != nullptr) {
406 privacySa->AddDeathRecipient(serviceDeathObserver_);
407 }
408 proxy_ = new PrivacyManagerProxy(privacySa);
409 if (proxy_ == nullptr) {
410 ACCESSTOKEN_LOG_DEBUG(LABEL, "Iface_cast get null");
411 }
412 }
413 }
414
OnRemoteDiedHandle()415 void PrivacyManagerClient::OnRemoteDiedHandle()
416 {
417 std::lock_guard<std::mutex> lock(proxyMutex_);
418 ReleaseProxy();
419 InitProxy();
420 }
421
GetProxy()422 sptr<IPrivacyManager> PrivacyManagerClient::GetProxy()
423 {
424 std::lock_guard<std::mutex> lock(proxyMutex_);
425 if (proxy_ == nullptr) {
426 InitProxy();
427 }
428 return proxy_;
429 }
430
ReleaseProxy()431 void PrivacyManagerClient::ReleaseProxy()
432 {
433 if (proxy_ != nullptr && serviceDeathObserver_ != nullptr) {
434 proxy_->AsObject()->RemoveDeathRecipient(serviceDeathObserver_);
435 }
436 proxy_ = nullptr;
437 serviceDeathObserver_ = nullptr;
438 }
439 } // namespace AccessToken
440 } // namespace Security
441 } // namespace OHOS
442