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