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