• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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