1 /*
2 * Copyright (c) 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
16 #include "oaid_service_client.h"
17
18 #include <cinttypes>
19 #include <mutex>
20
21 #include "oaid_common.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 #include "system_ability_load_callback_stub.h"
25
26 using namespace OHOS::Security::AccessToken;
27
28 namespace OHOS {
29 namespace Cloud {
30 namespace {
31 static const int32_t OAID_SYSTME_ID = 6101; // The system component ID of the OAID is 6101.
32
33 static const std::string OAID_ALLZERO_STR = "00000000-0000-0000-0000-000000000000";
34
35 static const std::string OAID_TRACKING_CONSENT_PERMISSION = "ohos.permission.APP_TRACKING_CONSENT";
36
37 /**
38 * load time out: 10s
39 */
40 static const int8_t LOAD_TIME_OUT = 10;
41
42 static const int8_t RESET_OAID_DEFAULT_CODE = 0;
43 } // namespace
44
45 std::mutex OAIDServiceClient::instanceLock_;
46 sptr<OAIDServiceClient> OAIDServiceClient::instance_;
47
48 class OAIDServiceLoadCallback : public SystemAbilityLoadCallbackStub {
49 public:
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)50 void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject) override
51 {
52 if (systemAbilityId != OAID_SYSTME_ID) {
53 OAID_HILOGE(OAID_MODULE_SERVICE, "Start systemAbility is not oaid service: %{public}d.", systemAbilityId);
54 return;
55 }
56
57 OAIDServiceClient::GetInstance()->LoadServerSuccess(remoteObject);
58 }
59
OnLoadSystemAbilityFail(int32_t systemAbilityId)60 void OnLoadSystemAbilityFail(int32_t systemAbilityId) override
61 {
62 if (systemAbilityId != OAID_SYSTME_ID) {
63 OAID_HILOGE(OAID_MODULE_SERVICE, "Start systemAbility is not oaid service: %{public}d.", systemAbilityId);
64 return;
65 }
66
67 OAIDServiceClient::GetInstance()->LoadServerFail();
68 }
69 };
70
OAIDServiceClient()71 OAIDServiceClient::OAIDServiceClient()
72 {
73 deathRecipient_ = new (std::nothrow) OAIDSaDeathRecipient();
74 }
75
~OAIDServiceClient()76 OAIDServiceClient::~OAIDServiceClient()
77 {
78 if (oaidServiceProxy_ != nullptr) {
79 auto remoteObject = oaidServiceProxy_->AsObject();
80 if (remoteObject != nullptr && deathRecipient_ != nullptr) {
81 remoteObject->RemoveDeathRecipient(deathRecipient_);
82 }
83 }
84 }
85
GetInstance()86 sptr<OAIDServiceClient> OAIDServiceClient::GetInstance()
87 {
88 if (instance_ == nullptr) {
89 std::lock_guard<std::mutex> autoLock(instanceLock_);
90 if (instance_ == nullptr) {
91 instance_ = new OAIDServiceClient;
92 }
93 }
94 return instance_;
95 }
96
LoadService()97 bool OAIDServiceClient::LoadService()
98 {
99 if (loadServiceReady_) {
100 return true;
101 }
102
103 std::lock_guard<std::mutex> lock(loadServiceLock_);
104 if (loadServiceReady_) {
105 return true;
106 }
107
108 sptr<ISystemAbilityManager> systemAbilityManager =
109 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
110 if (systemAbilityManager == nullptr) {
111 OAID_HILOGE(OAID_MODULE_CLIENT, "Getting SystemAbilityManager failed.");
112 return false;
113 }
114
115 sptr<OAIDServiceLoadCallback> loadCallback = new (std::nothrow) OAIDServiceLoadCallback();
116 if (loadCallback == nullptr) {
117 OAID_HILOGE(OAID_MODULE_CLIENT, "New OAIDServiceLoadCallback failed.");
118 return false;
119 }
120
121 int32_t result = systemAbilityManager->LoadSystemAbility(OAID_SYSTME_ID, loadCallback);
122 if (result != ERR_OK) {
123 OAID_HILOGE(
124 OAID_MODULE_CLIENT, "LoadSystemAbility %{public}d failed, result: %{public}d.", OAID_SYSTME_ID, result);
125 return false;
126 }
127
128 std::unique_lock<std::mutex> conditionLock(loadServiceConditionLock_);
129 auto waitStatus = loadServiceCondition_.wait_for(
130 conditionLock, std::chrono::seconds(LOAD_TIME_OUT), [this]() { return loadServiceReady_; });
131 if (!waitStatus) {
132 OAID_HILOGE(OAID_MODULE_CLIENT, "LoadSystemAbility timeout.");
133 return false;
134 }
135
136 return true;
137 }
138
GetOAID()139 std::string OAIDServiceClient::GetOAID()
140 {
141 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin.");
142 std::unique_lock<std::mutex> lock(getOaidProxyMutex_);
143
144 if (!CheckPermission(OAID_TRACKING_CONSENT_PERMISSION)) {
145 OAID_HILOGW(
146 OAID_MODULE_SERVICE, "get oaid not granted the app tracking permission");
147 return OAID_ALLZERO_STR;
148 }
149
150 if (!LoadService()) {
151 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
152 LoadService();
153 }
154
155 if (oaidServiceProxy_ == nullptr) {
156 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
157 return OAID_ALLZERO_STR;
158 }
159
160 auto oaid = oaidServiceProxy_->GetOAID();
161 if (oaid == "") {
162 OAID_HILOGE(OAID_MODULE_CLIENT, "Get OAID failed.");
163 return OAID_ALLZERO_STR;
164 }
165 OAID_HILOGI(OAID_MODULE_SERVICE, "Get OAID id %{public}zu.", oaid.size());
166 return oaid;
167 }
168
ResetOAID()169 int32_t OAIDServiceClient::ResetOAID()
170 {
171 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin.");
172
173 if (!LoadService()) {
174 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
175 LoadService();
176 }
177
178 if (oaidServiceProxy_ == nullptr) {
179 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
180 return RESET_OAID_DEFAULT_CODE;
181 }
182
183 int32_t resetResult = oaidServiceProxy_->ResetOAID();
184 OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
185
186 return resetResult;
187 }
188
CheckPermission(const std::string & permissionName)189 bool OAIDServiceClient::CheckPermission(const std::string &permissionName)
190 {
191 // Verify the invoker's permission.
192 AccessTokenID callingToken = IPCSkeleton::GetCallingTokenID();
193 ATokenTypeEnum callingType = AccessTokenKit::GetTokenTypeFlag(callingToken);
194 OAID_HILOGD(OAID_MODULE_SERVICE, "callingToken = %{public}u", callingToken);
195 ErrCode result = TypePermissionState::PERMISSION_DENIED;
196 if (callingType == TOKEN_INVALID) {
197 OAID_HILOGE(OAID_MODULE_SERVICE, "callingToken is invalid");
198 return false;
199 } else {
200 result = AccessTokenKit::VerifyAccessToken(callingToken, permissionName);
201 }
202 if (result == TypePermissionState::PERMISSION_DENIED) {
203 OAID_HILOGI(OAID_MODULE_SERVICE, "the caller not granted the app tracking permission");
204 return false;
205 }
206 return true;
207 }
208
RegisterObserver(const sptr<IRemoteConfigObserver> & observer)209 int32_t OAIDServiceClient::RegisterObserver(const sptr<IRemoteConfigObserver>& observer)
210 {
211 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin RegisterObserver.");
212
213 if (!LoadService()) {
214 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
215 LoadService();
216 }
217
218 if (oaidServiceProxy_ == nullptr) {
219 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
220 return RESET_OAID_DEFAULT_CODE;
221 }
222
223 int32_t resetResult = oaidServiceProxy_->RegisterObserver(observer);
224 OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
225
226 return resetResult;
227 }
228
OnRemoteSaDied(const wptr<IRemoteObject> & remote)229 void OAIDServiceClient::OnRemoteSaDied(const wptr<IRemoteObject>& remote)
230 {
231 OAID_HILOGE(OAID_MODULE_CLIENT, "OnRemoteSaDied");
232 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
233 if (oaidServiceProxy_ != nullptr) {
234 auto remoteObject = oaidServiceProxy_->AsObject();
235 if (remoteObject != nullptr && deathRecipient_ != nullptr) {
236 remoteObject->RemoveDeathRecipient(deathRecipient_);
237 }
238 oaidServiceProxy_ = nullptr;
239 }
240 loadServiceReady_ = false;
241 }
242
LoadServerSuccess(const sptr<IRemoteObject> & remoteObject)243 void OAIDServiceClient::LoadServerSuccess(const sptr<IRemoteObject>& remoteObject)
244 {
245 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
246 if (remoteObject == nullptr) {
247 OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service is null.");
248 return;
249 }
250
251 if (deathRecipient_ != nullptr) {
252 remoteObject->AddDeathRecipient(deathRecipient_);
253 }
254 oaidServiceProxy_ = iface_cast<IOAIDService>(remoteObject);
255 loadServiceReady_ = true;
256 loadServiceCondition_.notify_one();
257 OAID_HILOGI(OAID_MODULE_CLIENT, "Load OAID service success.");
258 }
259
LoadServerFail()260 void OAIDServiceClient::LoadServerFail()
261 {
262 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
263 loadServiceReady_ = false;
264 OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service fail.");
265 }
266
OAIDSaDeathRecipient()267 OAIDSaDeathRecipient::OAIDSaDeathRecipient() {}
268
OnRemoteDied(const wptr<IRemoteObject> & object)269 void OAIDSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
270 {
271 OAID_HILOGW(OAID_MODULE_CLIENT, "Remote systemAbility died.");
272 OAIDServiceClient::GetInstance()->OnRemoteSaDied(object);
273 }
274 } // namespace Cloud
275 } // namespace OHOS
276