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