1c7afe287Sopenharmony_ci/*
2c7afe287Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3c7afe287Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c7afe287Sopenharmony_ci * you may not use this file except in compliance with the License.
5c7afe287Sopenharmony_ci * You may obtain a copy of the License at
6c7afe287Sopenharmony_ci *
7c7afe287Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8c7afe287Sopenharmony_ci *
9c7afe287Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c7afe287Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c7afe287Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c7afe287Sopenharmony_ci * See the License for the specific language governing permissions and
13c7afe287Sopenharmony_ci * limitations under the License.
14c7afe287Sopenharmony_ci */
15c7afe287Sopenharmony_ci
16c7afe287Sopenharmony_ci#include "oaid_service_client.h"
17c7afe287Sopenharmony_ci
18c7afe287Sopenharmony_ci#include <cinttypes>
19c7afe287Sopenharmony_ci#include <mutex>
20c7afe287Sopenharmony_ci
21c7afe287Sopenharmony_ci#include "oaid_common.h"
22c7afe287Sopenharmony_ci#include "iservice_registry.h"
23c7afe287Sopenharmony_ci#include "system_ability_definition.h"
24c7afe287Sopenharmony_ci#include "system_ability_load_callback_stub.h"
25c7afe287Sopenharmony_ci
26c7afe287Sopenharmony_cinamespace OHOS {
27c7afe287Sopenharmony_cinamespace Cloud {
28c7afe287Sopenharmony_cinamespace {
29c7afe287Sopenharmony_cistatic const int32_t OAID_SYSTME_ID = 6101; // The system component ID of the OAID is 6101.
30c7afe287Sopenharmony_ci
31c7afe287Sopenharmony_cistatic const std::string OAID_ALLZERO_STR = "00000000-0000-0000-0000-000000000000";
32c7afe287Sopenharmony_ci
33c7afe287Sopenharmony_ci/**
34c7afe287Sopenharmony_ci * load time out: 10s
35c7afe287Sopenharmony_ci */
36c7afe287Sopenharmony_cistatic const int8_t LOAD_TIME_OUT = 10;
37c7afe287Sopenharmony_ci
38c7afe287Sopenharmony_cistatic const int8_t RESET_OAID_DEFAULT_CODE = 0;
39c7afe287Sopenharmony_ci} // namespace
40c7afe287Sopenharmony_ci
41c7afe287Sopenharmony_cistd::mutex OAIDServiceClient::instanceLock_;
42c7afe287Sopenharmony_cisptr<OAIDServiceClient> OAIDServiceClient::instance_;
43c7afe287Sopenharmony_ci
44c7afe287Sopenharmony_ciclass OAIDServiceLoadCallback : public SystemAbilityLoadCallbackStub {
45c7afe287Sopenharmony_cipublic:
46c7afe287Sopenharmony_ci    void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject) override
47c7afe287Sopenharmony_ci    {
48c7afe287Sopenharmony_ci        if (systemAbilityId != OAID_SYSTME_ID) {
49c7afe287Sopenharmony_ci            OAID_HILOGE(OAID_MODULE_SERVICE, "Start systemAbility is not oaid service: %{public}d.", systemAbilityId);
50c7afe287Sopenharmony_ci            return;
51c7afe287Sopenharmony_ci        }
52c7afe287Sopenharmony_ci
53c7afe287Sopenharmony_ci        OAIDServiceClient::GetInstance()->LoadServerSuccess(remoteObject);
54c7afe287Sopenharmony_ci    }
55c7afe287Sopenharmony_ci
56c7afe287Sopenharmony_ci    void OnLoadSystemAbilityFail(int32_t systemAbilityId) override
57c7afe287Sopenharmony_ci    {
58c7afe287Sopenharmony_ci        if (systemAbilityId != OAID_SYSTME_ID) {
59c7afe287Sopenharmony_ci            OAID_HILOGE(OAID_MODULE_SERVICE, "Start systemAbility is not oaid service: %{public}d.", systemAbilityId);
60c7afe287Sopenharmony_ci            return;
61c7afe287Sopenharmony_ci        }
62c7afe287Sopenharmony_ci
63c7afe287Sopenharmony_ci        OAIDServiceClient::GetInstance()->LoadServerFail();
64c7afe287Sopenharmony_ci    }
65c7afe287Sopenharmony_ci};
66c7afe287Sopenharmony_ci
67c7afe287Sopenharmony_ciOAIDServiceClient::OAIDServiceClient()
68c7afe287Sopenharmony_ci{
69c7afe287Sopenharmony_ci    deathRecipient_ = new (std::nothrow) OAIDSaDeathRecipient();
70c7afe287Sopenharmony_ci}
71c7afe287Sopenharmony_ci
72c7afe287Sopenharmony_ciOAIDServiceClient::~OAIDServiceClient()
73c7afe287Sopenharmony_ci{
74c7afe287Sopenharmony_ci    if (oaidServiceProxy_ != nullptr) {
75c7afe287Sopenharmony_ci        auto remoteObject = oaidServiceProxy_->AsObject();
76c7afe287Sopenharmony_ci        if (remoteObject != nullptr && deathRecipient_ != nullptr) {
77c7afe287Sopenharmony_ci            remoteObject->RemoveDeathRecipient(deathRecipient_);
78c7afe287Sopenharmony_ci        }
79c7afe287Sopenharmony_ci    }
80c7afe287Sopenharmony_ci}
81c7afe287Sopenharmony_ci
82c7afe287Sopenharmony_cisptr<OAIDServiceClient> OAIDServiceClient::GetInstance()
83c7afe287Sopenharmony_ci{
84c7afe287Sopenharmony_ci    if (instance_ == nullptr) {
85c7afe287Sopenharmony_ci        std::lock_guard<std::mutex> autoLock(instanceLock_);
86c7afe287Sopenharmony_ci        if (instance_ == nullptr) {
87c7afe287Sopenharmony_ci            instance_ = new OAIDServiceClient;
88c7afe287Sopenharmony_ci        }
89c7afe287Sopenharmony_ci    }
90c7afe287Sopenharmony_ci    return instance_;
91c7afe287Sopenharmony_ci}
92c7afe287Sopenharmony_ci
93c7afe287Sopenharmony_cibool OAIDServiceClient::LoadService()
94c7afe287Sopenharmony_ci{
95c7afe287Sopenharmony_ci    if (loadServiceReady_) {
96c7afe287Sopenharmony_ci        return true;
97c7afe287Sopenharmony_ci    }
98c7afe287Sopenharmony_ci
99c7afe287Sopenharmony_ci    std::lock_guard<std::mutex> lock(loadServiceLock_);
100c7afe287Sopenharmony_ci    if (loadServiceReady_) {
101c7afe287Sopenharmony_ci        return true;
102c7afe287Sopenharmony_ci    }
103c7afe287Sopenharmony_ci
104c7afe287Sopenharmony_ci    sptr<ISystemAbilityManager> systemAbilityManager =
105c7afe287Sopenharmony_ci        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
106c7afe287Sopenharmony_ci    if (systemAbilityManager == nullptr) {
107c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "Getting SystemAbilityManager failed.");
108c7afe287Sopenharmony_ci        return false;
109c7afe287Sopenharmony_ci    }
110c7afe287Sopenharmony_ci
111c7afe287Sopenharmony_ci    sptr<OAIDServiceLoadCallback> loadCallback = new (std::nothrow) OAIDServiceLoadCallback();
112c7afe287Sopenharmony_ci    if (loadCallback == nullptr) {
113c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "New  OAIDServiceLoadCallback failed.");
114c7afe287Sopenharmony_ci        return false;
115c7afe287Sopenharmony_ci    }
116c7afe287Sopenharmony_ci
117c7afe287Sopenharmony_ci    int32_t result = systemAbilityManager->LoadSystemAbility(OAID_SYSTME_ID, loadCallback);
118c7afe287Sopenharmony_ci    if (result != ERR_OK) {
119c7afe287Sopenharmony_ci        OAID_HILOGE(
120c7afe287Sopenharmony_ci            OAID_MODULE_CLIENT, "LoadSystemAbility %{public}d failed, result: %{public}d.", OAID_SYSTME_ID, result);
121c7afe287Sopenharmony_ci        return false;
122c7afe287Sopenharmony_ci    }
123c7afe287Sopenharmony_ci
124c7afe287Sopenharmony_ci    std::unique_lock<std::mutex> conditionLock(loadServiceConditionLock_);
125c7afe287Sopenharmony_ci    auto waitStatus = loadServiceCondition_.wait_for(
126c7afe287Sopenharmony_ci        conditionLock, std::chrono::seconds(LOAD_TIME_OUT), [this]() { return loadServiceReady_; });
127c7afe287Sopenharmony_ci    if (!waitStatus) {
128c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "LoadSystemAbility timeout.");
129c7afe287Sopenharmony_ci        return false;
130c7afe287Sopenharmony_ci    }
131c7afe287Sopenharmony_ci
132c7afe287Sopenharmony_ci    return true;
133c7afe287Sopenharmony_ci}
134c7afe287Sopenharmony_ci
135c7afe287Sopenharmony_cistd::string OAIDServiceClient::GetOAID()
136c7afe287Sopenharmony_ci{
137c7afe287Sopenharmony_ci    OAID_HILOGI(OAID_MODULE_CLIENT, "Begin.");
138c7afe287Sopenharmony_ci
139c7afe287Sopenharmony_ci    if (!LoadService()) {
140c7afe287Sopenharmony_ci        OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
141c7afe287Sopenharmony_ci        LoadService();
142c7afe287Sopenharmony_ci    }
143c7afe287Sopenharmony_ci
144c7afe287Sopenharmony_ci    if (oaidServiceProxy_ == nullptr) {
145c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
146c7afe287Sopenharmony_ci        return OAID_ALLZERO_STR;
147c7afe287Sopenharmony_ci    }
148c7afe287Sopenharmony_ci
149c7afe287Sopenharmony_ci    auto oaid = oaidServiceProxy_->GetOAID();
150c7afe287Sopenharmony_ci    if (oaid == "") {
151c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "Get OAID failed.");
152c7afe287Sopenharmony_ci        return OAID_ALLZERO_STR;
153c7afe287Sopenharmony_ci    }
154c7afe287Sopenharmony_ci    OAID_HILOGI(OAID_MODULE_SERVICE, "Get OAID id %{public}zu.", oaid.size());
155c7afe287Sopenharmony_ci    return oaid;
156c7afe287Sopenharmony_ci}
157c7afe287Sopenharmony_ci
158c7afe287Sopenharmony_ciint32_t OAIDServiceClient::ResetOAID()
159c7afe287Sopenharmony_ci{
160c7afe287Sopenharmony_ci    OAID_HILOGI(OAID_MODULE_CLIENT, "Begin.");
161c7afe287Sopenharmony_ci
162c7afe287Sopenharmony_ci    if (!LoadService()) {
163c7afe287Sopenharmony_ci        OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
164c7afe287Sopenharmony_ci        LoadService();
165c7afe287Sopenharmony_ci    }
166c7afe287Sopenharmony_ci
167c7afe287Sopenharmony_ci    if (oaidServiceProxy_ == nullptr) {
168c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
169c7afe287Sopenharmony_ci        return RESET_OAID_DEFAULT_CODE;
170c7afe287Sopenharmony_ci    }
171c7afe287Sopenharmony_ci
172c7afe287Sopenharmony_ci    int32_t resetResult = oaidServiceProxy_->ResetOAID();
173c7afe287Sopenharmony_ci    OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
174c7afe287Sopenharmony_ci
175c7afe287Sopenharmony_ci    return resetResult;
176c7afe287Sopenharmony_ci}
177c7afe287Sopenharmony_ci
178c7afe287Sopenharmony_ciint32_t OAIDServiceClient::RegisterObserver(const sptr<IRemoteConfigObserver>& observer)
179c7afe287Sopenharmony_ci{
180c7afe287Sopenharmony_ci    OAID_HILOGI(OAID_MODULE_CLIENT, "Begin RegisterObserver.");
181c7afe287Sopenharmony_ci
182c7afe287Sopenharmony_ci    if (!LoadService()) {
183c7afe287Sopenharmony_ci        OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
184c7afe287Sopenharmony_ci        LoadService();
185c7afe287Sopenharmony_ci    }
186c7afe287Sopenharmony_ci
187c7afe287Sopenharmony_ci    if (oaidServiceProxy_ == nullptr) {
188c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
189c7afe287Sopenharmony_ci        return RESET_OAID_DEFAULT_CODE;
190c7afe287Sopenharmony_ci    }
191c7afe287Sopenharmony_ci
192c7afe287Sopenharmony_ci    int32_t resetResult = oaidServiceProxy_->RegisterObserver(observer);
193c7afe287Sopenharmony_ci    OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
194c7afe287Sopenharmony_ci
195c7afe287Sopenharmony_ci    return resetResult;
196c7afe287Sopenharmony_ci}
197c7afe287Sopenharmony_ci
198c7afe287Sopenharmony_civoid OAIDServiceClient::OnRemoteSaDied(const wptr<IRemoteObject>& remote)
199c7afe287Sopenharmony_ci{
200c7afe287Sopenharmony_ci    OAID_HILOGE(OAID_MODULE_CLIENT, "OnRemoteSaDied");
201c7afe287Sopenharmony_ci    std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
202c7afe287Sopenharmony_ci    if (oaidServiceProxy_ != nullptr) {
203c7afe287Sopenharmony_ci        auto remoteObject = oaidServiceProxy_->AsObject();
204c7afe287Sopenharmony_ci        if (remoteObject != nullptr && deathRecipient_ != nullptr) {
205c7afe287Sopenharmony_ci            remoteObject->RemoveDeathRecipient(deathRecipient_);
206c7afe287Sopenharmony_ci        }
207c7afe287Sopenharmony_ci        oaidServiceProxy_ = nullptr;
208c7afe287Sopenharmony_ci    }
209c7afe287Sopenharmony_ci    loadServiceReady_ = false;
210c7afe287Sopenharmony_ci}
211c7afe287Sopenharmony_ci
212c7afe287Sopenharmony_civoid OAIDServiceClient::LoadServerSuccess(const sptr<IRemoteObject>& remoteObject)
213c7afe287Sopenharmony_ci{
214c7afe287Sopenharmony_ci    std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
215c7afe287Sopenharmony_ci    if (remoteObject == nullptr) {
216c7afe287Sopenharmony_ci        OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service is null.");
217c7afe287Sopenharmony_ci        return;
218c7afe287Sopenharmony_ci    }
219c7afe287Sopenharmony_ci
220c7afe287Sopenharmony_ci    if (deathRecipient_ != nullptr) {
221c7afe287Sopenharmony_ci        remoteObject->AddDeathRecipient(deathRecipient_);
222c7afe287Sopenharmony_ci    }
223c7afe287Sopenharmony_ci    oaidServiceProxy_ = iface_cast<IOAIDService>(remoteObject);
224c7afe287Sopenharmony_ci    loadServiceReady_ = true;
225c7afe287Sopenharmony_ci    loadServiceCondition_.notify_one();
226c7afe287Sopenharmony_ci    OAID_HILOGI(OAID_MODULE_CLIENT, "Load OAID service success.");
227c7afe287Sopenharmony_ci}
228c7afe287Sopenharmony_ci
229c7afe287Sopenharmony_civoid OAIDServiceClient::LoadServerFail()
230c7afe287Sopenharmony_ci{
231c7afe287Sopenharmony_ci    std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
232c7afe287Sopenharmony_ci    loadServiceReady_ = false;
233c7afe287Sopenharmony_ci    OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service fail.");
234c7afe287Sopenharmony_ci}
235c7afe287Sopenharmony_ci
236c7afe287Sopenharmony_ciOAIDSaDeathRecipient::OAIDSaDeathRecipient() {}
237c7afe287Sopenharmony_ci
238c7afe287Sopenharmony_civoid OAIDSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
239c7afe287Sopenharmony_ci{
240c7afe287Sopenharmony_ci    OAID_HILOGW(OAID_MODULE_CLIENT, "Remote systemAbility died.");
241c7afe287Sopenharmony_ci    OAIDServiceClient::GetInstance()->OnRemoteSaDied(object);
242c7afe287Sopenharmony_ci}
243c7afe287Sopenharmony_ci} // namespace Cloud
244c7afe287Sopenharmony_ci} // namespace OHOS
245