• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
23 namespace OHOS {
24 namespace Security {
25 namespace AccessToken {
26 namespace {
27 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
28     LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacyManagerClient"
29 };
30 } // namespace
31 
32 const static int32_t MAX_CALLBACK_SIZE = 200;
33 const static int32_t MAX_PERM_LIST_SIZE = 1024;
34 
GetInstance()35 PrivacyManagerClient& PrivacyManagerClient::GetInstance()
36 {
37     static PrivacyManagerClient instance;
38     return instance;
39 }
40 
PrivacyManagerClient()41 PrivacyManagerClient::PrivacyManagerClient()
42 {}
43 
~PrivacyManagerClient()44 PrivacyManagerClient::~PrivacyManagerClient()
45 {}
46 
AddPermissionUsedRecord(AccessTokenID tokenID,const std::string & permissionName,int32_t successCount,int32_t failCount)47 int32_t PrivacyManagerClient::AddPermissionUsedRecord(
48     AccessTokenID tokenID, const std::string& permissionName, int32_t successCount, int32_t failCount)
49 {
50     auto proxy = GetProxy();
51     if (proxy == nullptr) {
52         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
53         return PrivacyError::ERR_SERVICE_ABNORMAL;
54     }
55     return proxy->AddPermissionUsedRecord(tokenID, permissionName, successCount, failCount);
56 }
57 
StartUsingPermission(AccessTokenID tokenID,const std::string & permissionName)58 int32_t PrivacyManagerClient::StartUsingPermission(AccessTokenID tokenID, const std::string& permissionName)
59 {
60     auto proxy = GetProxy();
61     if (proxy == nullptr) {
62         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
63         return PrivacyError::ERR_SERVICE_ABNORMAL;
64     }
65     return proxy->StartUsingPermission(tokenID, permissionName);
66 }
67 
CreateStateChangeCbk(const std::shared_ptr<StateCustomizedCbk> & callback,sptr<StateChangeCallback> & callbackWrap)68 int32_t PrivacyManagerClient::CreateStateChangeCbk(
69     const std::shared_ptr<StateCustomizedCbk>& callback, sptr<StateChangeCallback>& callbackWrap)
70 {
71     std::lock_guard<std::mutex> lock(stateCbkMutex_);
72 
73     if (stateChangeCallback_ != nullptr) {
74         ACCESSTOKEN_LOG_ERROR(LABEL, " callback has been used");
75         return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
76     } else {
77         callbackWrap = new (std::nothrow) StateChangeCallback(callback);
78         if (callbackWrap == nullptr) {
79             ACCESSTOKEN_LOG_ERROR(LABEL, "memory allocation for callbackWrap failed!");
80             return PrivacyError::ERR_SERVICE_ABNORMAL;
81         }
82     }
83     return RET_SUCCESS;
84 }
85 
StartUsingPermission(AccessTokenID tokenId,const std::string & permissionName,const std::shared_ptr<StateCustomizedCbk> & callback)86 int32_t PrivacyManagerClient::StartUsingPermission(AccessTokenID tokenId, const std::string& permissionName,
87     const std::shared_ptr<StateCustomizedCbk>& callback)
88 {
89     if (callback == nullptr) {
90         ACCESSTOKEN_LOG_ERROR(LABEL, "customizedCb is nullptr");
91         return PrivacyError::ERR_PARAM_INVALID;
92     }
93 
94     sptr<StateChangeCallback> callbackWrap = nullptr;
95     int32_t result = CreateStateChangeCbk(callback, callbackWrap);
96     if (result != RET_SUCCESS) {
97         return result;
98     }
99 
100     auto proxy = GetProxy();
101     if (proxy == nullptr) {
102         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
103         return PrivacyError::ERR_SERVICE_ABNORMAL;
104     }
105 
106     result = proxy->StartUsingPermission(tokenId, permissionName, callbackWrap->AsObject());
107     if (result == RET_SUCCESS) {
108         std::lock_guard<std::mutex> lock(stateCbkMutex_);
109         stateChangeCallback_ = callbackWrap;
110         ACCESSTOKEN_LOG_INFO(LABEL, "callbackObject added");
111     }
112     return result;
113 }
114 
StopUsingPermission(AccessTokenID tokenID,const std::string & permissionName)115 int32_t PrivacyManagerClient::StopUsingPermission(AccessTokenID tokenID, const std::string& permissionName)
116 {
117     auto proxy = GetProxy();
118     if (proxy == nullptr) {
119         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
120         return PrivacyError::ERR_SERVICE_ABNORMAL;
121     }
122     {
123         std::lock_guard<std::mutex> lock(stateCbkMutex_);
124         stateChangeCallback_ = nullptr;
125     }
126 
127     return proxy->StopUsingPermission(tokenID, permissionName);
128 }
129 
RemovePermissionUsedRecords(AccessTokenID tokenID,const std::string & deviceID)130 int32_t PrivacyManagerClient::RemovePermissionUsedRecords(AccessTokenID tokenID, const std::string& deviceID)
131 {
132     auto proxy = GetProxy();
133     if (proxy == nullptr) {
134         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
135         return PrivacyError::ERR_SERVICE_ABNORMAL;
136     }
137     return proxy->RemovePermissionUsedRecords(tokenID, deviceID);
138 }
139 
GetPermissionUsedRecords(const PermissionUsedRequest & request,PermissionUsedResult & result)140 int32_t PrivacyManagerClient::GetPermissionUsedRecords(
141     const PermissionUsedRequest& request, PermissionUsedResult& result)
142 {
143     auto proxy = GetProxy();
144     if (proxy == nullptr) {
145         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
146         return PrivacyError::ERR_SERVICE_ABNORMAL;
147     }
148 
149     PermissionUsedRequestParcel requestParcel;
150     PermissionUsedResultParcel resultParcel;
151     requestParcel.request = request;
152     int32_t ret = proxy->GetPermissionUsedRecords(requestParcel, resultParcel);
153     result = resultParcel.result;
154     return ret;
155 }
156 
GetPermissionUsedRecords(const PermissionUsedRequest & request,const sptr<OnPermissionUsedRecordCallback> & callback)157 int32_t PrivacyManagerClient::GetPermissionUsedRecords(const PermissionUsedRequest& request,
158     const sptr<OnPermissionUsedRecordCallback>& callback)
159 {
160     auto proxy = GetProxy();
161     if (proxy == nullptr) {
162         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
163         return PrivacyError::ERR_SERVICE_ABNORMAL;
164     }
165 
166     PermissionUsedRequestParcel requestParcel;
167     requestParcel.request = request;
168     return proxy->GetPermissionUsedRecords(requestParcel, callback);
169 }
170 
CreateActiveStatusChangeCbk(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback,sptr<PermActiveStatusChangeCallback> & callbackWrap)171 int32_t PrivacyManagerClient::CreateActiveStatusChangeCbk(
172     const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback, sptr<PermActiveStatusChangeCallback>& callbackWrap)
173 {
174     std::lock_guard<std::mutex> lock(activeCbkMutex_);
175 
176     if (activeCbkMap_.size() >= MAX_CALLBACK_SIZE) {
177         ACCESSTOKEN_LOG_ERROR(LABEL, "the maximum number of subscribers has been reached");
178         return PrivacyError::ERR_CALLBACKS_EXCEED_LIMITATION;
179     }
180 
181     auto goalCallback = activeCbkMap_.find(callback);
182     if (goalCallback != activeCbkMap_.end()) {
183         ACCESSTOKEN_LOG_ERROR(LABEL, "activeCbkMap_ already has such callback");
184         return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
185     } else {
186         callbackWrap =
187             new (std::nothrow) PermActiveStatusChangeCallback(callback);
188         if (!callbackWrap) {
189             ACCESSTOKEN_LOG_ERROR(LABEL, "memory allocation for callbackWrap failed!");
190             return PrivacyError::ERR_MALLOC_FAILED;
191         }
192     }
193     return RET_SUCCESS;
194 }
195 
RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)196 int32_t PrivacyManagerClient::RegisterPermActiveStatusCallback(
197     const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
198 {
199     ACCESSTOKEN_LOG_INFO(LABEL, "called!");
200     if (callback == nullptr) {
201         ACCESSTOKEN_LOG_ERROR(LABEL, "customizedCb is nullptr");
202         return PrivacyError::ERR_PARAM_INVALID;
203     }
204 
205     sptr<PermActiveStatusChangeCallback> callbackWrap = nullptr;
206     int32_t result = CreateActiveStatusChangeCbk(callback, callbackWrap);
207     if (result != RET_SUCCESS) {
208         return result;
209     }
210 
211     auto proxy = GetProxy();
212     if (proxy == nullptr) {
213         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
214         return PrivacyError::ERR_SERVICE_ABNORMAL;
215     }
216     std::vector<std::string> permList;
217     callback->GetPermList(permList);
218     if (permList.size() > MAX_PERM_LIST_SIZE) {
219         return PrivacyError::ERR_PARAM_INVALID;
220     }
221 
222     result = proxy->RegisterPermActiveStatusCallback(permList, callbackWrap->AsObject());
223     if (result == RET_SUCCESS) {
224         std::lock_guard<std::mutex> lock(activeCbkMutex_);
225         activeCbkMap_[callback] = callbackWrap;
226         ACCESSTOKEN_LOG_INFO(LABEL, "callbackObject added");
227     }
228     return result;
229 }
230 
UnRegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)231 int32_t PrivacyManagerClient::UnRegisterPermActiveStatusCallback(
232     const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
233 {
234     ACCESSTOKEN_LOG_INFO(LABEL, "called!");
235 
236     auto proxy = GetProxy();
237     if (proxy == nullptr) {
238         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
239         return PrivacyError::ERR_SERVICE_ABNORMAL;
240     }
241 
242     std::lock_guard<std::mutex> lock(activeCbkMutex_);
243     auto goalCallback = activeCbkMap_.find(callback);
244     if (goalCallback == activeCbkMap_.end()) {
245         ACCESSTOKEN_LOG_ERROR(LABEL, "goalCallback already is not exist");
246         return PrivacyError::ERR_CALLBACK_NOT_EXIST;
247     }
248 
249     int32_t result = proxy->UnRegisterPermActiveStatusCallback(goalCallback->second->AsObject());
250     if (result == RET_SUCCESS) {
251         activeCbkMap_.erase(goalCallback);
252     }
253     return result;
254 }
255 
IsAllowedUsingPermission(AccessTokenID tokenID,const std::string & permissionName)256 bool PrivacyManagerClient::IsAllowedUsingPermission(AccessTokenID tokenID, const std::string& permissionName)
257 {
258     auto proxy = GetProxy();
259     if (proxy == nullptr) {
260         ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
261         return false;
262     }
263     return proxy->IsAllowedUsingPermission(tokenID, permissionName);
264 }
265 
InitProxy()266 void PrivacyManagerClient::InitProxy()
267 {
268     std::lock_guard<std::mutex> lock(proxyMutex_);
269     if (proxy_ == nullptr) {
270         auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
271         if (sam == nullptr) {
272             ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbilityManager is null");
273             return;
274         }
275         auto privacySa = sam->GetSystemAbility(IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
276         if (privacySa == nullptr) {
277             ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbility %{public}d is null",
278                 IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
279             return;
280         }
281 
282         serviceDeathObserver_ = new (std::nothrow) PrivacyDeathRecipient();
283         if (serviceDeathObserver_ != nullptr) {
284             privacySa->AddDeathRecipient(serviceDeathObserver_);
285         }
286         proxy_ = iface_cast<IPrivacyManager>(privacySa);
287         if (proxy_ == nullptr) {
288             ACCESSTOKEN_LOG_DEBUG(LABEL, "iface_cast get null");
289         }
290     }
291 }
292 
OnRemoteDiedHandle()293 void PrivacyManagerClient::OnRemoteDiedHandle()
294 {
295     {
296         std::lock_guard<std::mutex> lock(proxyMutex_);
297         proxy_ = nullptr;
298     }
299     InitProxy();
300 }
301 
GetProxy()302 sptr<IPrivacyManager> PrivacyManagerClient::GetProxy()
303 {
304     if (proxy_ == nullptr) {
305         InitProxy();
306     }
307     return proxy_;
308 }
309 } // namespace AccessToken
310 } // namespace Security
311 } // namespace OHOS
312