• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,AccessTokenID tokenID)363 int32_t PrivacyManagerClient::SetMutePolicy(uint32_t policyType, uint32_t callerType, bool isMute,
364     AccessTokenID tokenID)
365 {
366     auto proxy = GetProxy();
367     if (proxy == nullptr) {
368         ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
369         return PrivacyError::ERR_SERVICE_ABNORMAL;
370     }
371     return proxy->SetMutePolicy(policyType, callerType, isMute, tokenID);
372 }
373 
SetHapWithFGReminder(uint32_t tokenId,bool isAllowed)374 int32_t PrivacyManagerClient::SetHapWithFGReminder(uint32_t tokenId, bool isAllowed)
375 {
376     auto proxy = GetProxy();
377     if (proxy == nullptr) {
378         ACCESSTOKEN_LOG_ERROR(LABEL, "Proxy is null.");
379         return PrivacyError::ERR_SERVICE_ABNORMAL;
380     }
381     return proxy->SetHapWithFGReminder(tokenId, isAllowed);
382 }
383 
GetUniqueId(uint32_t tokenId,int32_t pid) const384 uint64_t PrivacyManagerClient::GetUniqueId(uint32_t tokenId, int32_t pid) const
385 {
386     uint32_t tmpPid = (pid <= 0) ? 0 : static_cast<uint32_t>(pid);
387     return (static_cast<uint64_t>(tmpPid) << 32) | (static_cast<uint64_t>(tokenId) & 0xFFFFFFFF); // 32: bit
388 }
389 
InitProxy()390 void PrivacyManagerClient::InitProxy()
391 {
392     if (proxy_ == nullptr) {
393         auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
394         if (sam == nullptr) {
395             ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbilityManager is null");
396             return;
397         }
398         auto privacySa = sam->CheckSystemAbility(IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
399         if (privacySa == nullptr) {
400             ACCESSTOKEN_LOG_DEBUG(LABEL, "CheckSystemAbility %{public}d is null",
401                 IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
402             return;
403         }
404 
405         serviceDeathObserver_ = sptr<PrivacyDeathRecipient>::MakeSptr();
406         if (serviceDeathObserver_ != nullptr) {
407             privacySa->AddDeathRecipient(serviceDeathObserver_);
408         }
409         proxy_ = new PrivacyManagerProxy(privacySa);
410         if (proxy_ == nullptr) {
411             ACCESSTOKEN_LOG_DEBUG(LABEL, "Iface_cast get null");
412         }
413     }
414 }
415 
OnRemoteDiedHandle()416 void PrivacyManagerClient::OnRemoteDiedHandle()
417 {
418     std::lock_guard<std::mutex> lock(proxyMutex_);
419     ReleaseProxy();
420     InitProxy();
421 }
422 
GetProxy()423 sptr<IPrivacyManager> PrivacyManagerClient::GetProxy()
424 {
425     std::lock_guard<std::mutex> lock(proxyMutex_);
426     if (proxy_ == nullptr) {
427         InitProxy();
428     }
429     return proxy_;
430 }
431 
ReleaseProxy()432 void PrivacyManagerClient::ReleaseProxy()
433 {
434     if (proxy_ != nullptr && serviceDeathObserver_ != nullptr) {
435         proxy_->AsObject()->RemoveDeathRecipient(serviceDeathObserver_);
436     }
437     proxy_ = nullptr;
438     serviceDeathObserver_ = nullptr;
439 }
440 } // namespace AccessToken
441 } // namespace Security
442 } // namespace OHOS
443