1bc2ed2b3Sopenharmony_ci/*
2bc2ed2b3Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3bc2ed2b3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bc2ed2b3Sopenharmony_ci * you may not use this file except in compliance with the License.
5bc2ed2b3Sopenharmony_ci * You may obtain a copy of the License at
6bc2ed2b3Sopenharmony_ci *
7bc2ed2b3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bc2ed2b3Sopenharmony_ci *
9bc2ed2b3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bc2ed2b3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bc2ed2b3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bc2ed2b3Sopenharmony_ci * See the License for the specific language governing permissions and
13bc2ed2b3Sopenharmony_ci * limitations under the License.
14bc2ed2b3Sopenharmony_ci */
15bc2ed2b3Sopenharmony_ci
16bc2ed2b3Sopenharmony_ci#include "nfc_sa_client.h"
17bc2ed2b3Sopenharmony_ci
18bc2ed2b3Sopenharmony_ci#include "iremote_broker.h"
19bc2ed2b3Sopenharmony_ci#include "iremote_object.h"
20bc2ed2b3Sopenharmony_ci#include "iservice_registry.h"
21bc2ed2b3Sopenharmony_ci#include "infc_controller_callback.h"
22bc2ed2b3Sopenharmony_ci#include "loghelper.h"
23bc2ed2b3Sopenharmony_ci
24bc2ed2b3Sopenharmony_cinamespace OHOS {
25bc2ed2b3Sopenharmony_cinamespace NFC {
26bc2ed2b3Sopenharmony_cistatic constexpr int32_t NFC_LOADSA_TIMEOUT_MS = 1000; // ms
27bc2ed2b3Sopenharmony_ci
28bc2ed2b3Sopenharmony_ciNfcSaClient &NfcSaClient::GetInstance()
29bc2ed2b3Sopenharmony_ci{
30bc2ed2b3Sopenharmony_ci    DebugLog("NfcSaClient::%{public}s enter", __func__);
31bc2ed2b3Sopenharmony_ci    static NfcSaClient nfcSaClient;
32bc2ed2b3Sopenharmony_ci    return nfcSaClient;
33bc2ed2b3Sopenharmony_ci}
34bc2ed2b3Sopenharmony_ci
35bc2ed2b3Sopenharmony_cibool NfcSaClient::CheckNfcSystemAbility()
36bc2ed2b3Sopenharmony_ci{
37bc2ed2b3Sopenharmony_ci    sptr<ISystemAbilityManager> samgr =
38bc2ed2b3Sopenharmony_ci        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
39bc2ed2b3Sopenharmony_ci    if (samgr == nullptr) {
40bc2ed2b3Sopenharmony_ci        ErrorLog("Get system ability manager failed!");
41bc2ed2b3Sopenharmony_ci        return false;
42bc2ed2b3Sopenharmony_ci    }
43bc2ed2b3Sopenharmony_ci    auto object = samgr->CheckSystemAbility(KITS::NFC_MANAGER_SYS_ABILITY_ID);
44bc2ed2b3Sopenharmony_ci    return (object != nullptr);
45bc2ed2b3Sopenharmony_ci}
46bc2ed2b3Sopenharmony_ci
47bc2ed2b3Sopenharmony_cisptr<IRemoteObject> NfcSaClient::LoadNfcSa(int32_t systemAbilityId)
48bc2ed2b3Sopenharmony_ci{
49bc2ed2b3Sopenharmony_ci    InfoLog("NfcSaClient::%{public}s enter, systemAbilityId [%{public}d] loading", __func__, systemAbilityId);
50bc2ed2b3Sopenharmony_ci    InitLoadState();
51bc2ed2b3Sopenharmony_ci    sptr<ISystemAbilityManager> samgr =
52bc2ed2b3Sopenharmony_ci        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
53bc2ed2b3Sopenharmony_ci    if (samgr == nullptr) {
54bc2ed2b3Sopenharmony_ci        ErrorLog("NfcSaClient::%{public}s get system ability manager failed!", __func__);
55bc2ed2b3Sopenharmony_ci        return nullptr;
56bc2ed2b3Sopenharmony_ci    }
57bc2ed2b3Sopenharmony_ci    auto object = samgr->CheckSystemAbility(systemAbilityId);
58bc2ed2b3Sopenharmony_ci    if (object != nullptr) {
59bc2ed2b3Sopenharmony_ci        InfoLog("NfcSaClient::%{public}s CheckSystemAbility systemAbilityId [%{public}d] SUCCESS",
60bc2ed2b3Sopenharmony_ci            __func__, systemAbilityId);
61bc2ed2b3Sopenharmony_ci        remoteObject_ = object;
62bc2ed2b3Sopenharmony_ci        return remoteObject_;
63bc2ed2b3Sopenharmony_ci    }
64bc2ed2b3Sopenharmony_ci
65bc2ed2b3Sopenharmony_ci    auto nfcSaLoadCallback = sptr<NfcSaLoadCallback>(new NfcSaLoadCallback());
66bc2ed2b3Sopenharmony_ci    int32_t ret = samgr->LoadSystemAbility(systemAbilityId, nfcSaLoadCallback);
67bc2ed2b3Sopenharmony_ci    if (ret != ERR_NONE) {
68bc2ed2b3Sopenharmony_ci        ErrorLog("NfcSaClient::%{public}s LoadSystemAbility systemAbilityId [%{public}d] FAILED, ret %{public}d",
69bc2ed2b3Sopenharmony_ci            __func__, systemAbilityId, ret);
70bc2ed2b3Sopenharmony_ci        return nullptr;
71bc2ed2b3Sopenharmony_ci    }
72bc2ed2b3Sopenharmony_ci    if (WaitLoadStateChange(systemAbilityId)) {
73bc2ed2b3Sopenharmony_ci        InfoLog("NfcSaClient::%{public}s LoadSystemAbility systemAbilityId [%{public}d] SUCCESS",
74bc2ed2b3Sopenharmony_ci            __func__, systemAbilityId);
75bc2ed2b3Sopenharmony_ci        return remoteObject_;
76bc2ed2b3Sopenharmony_ci    }
77bc2ed2b3Sopenharmony_ci    ErrorLog("NfcSaClient::%{public}s LoadSystemAbility systemAbilityId [%{public}d] FAILED",
78bc2ed2b3Sopenharmony_ci        __func__, systemAbilityId);
79bc2ed2b3Sopenharmony_ci    return nullptr;
80bc2ed2b3Sopenharmony_ci}
81bc2ed2b3Sopenharmony_ci
82bc2ed2b3Sopenharmony_civoid NfcSaClient::InitLoadState()
83bc2ed2b3Sopenharmony_ci{
84bc2ed2b3Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
85bc2ed2b3Sopenharmony_ci    loadState_ = false;
86bc2ed2b3Sopenharmony_ci}
87bc2ed2b3Sopenharmony_ci
88bc2ed2b3Sopenharmony_cibool NfcSaClient::WaitLoadStateChange(int32_t systemAbilityId)
89bc2ed2b3Sopenharmony_ci{
90bc2ed2b3Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
91bc2ed2b3Sopenharmony_ci    auto wait = locatorCond_.wait_for(lock, std::chrono::milliseconds(NFC_LOADSA_TIMEOUT_MS), [this] {
92bc2ed2b3Sopenharmony_ci        return loadState_ == true;
93bc2ed2b3Sopenharmony_ci    });
94bc2ed2b3Sopenharmony_ci    if (!wait) {
95bc2ed2b3Sopenharmony_ci        ErrorLog("NfcSaClient::%{public}s locator sa  [%{public}d] time out.", __func__, systemAbilityId);
96bc2ed2b3Sopenharmony_ci        return false;
97bc2ed2b3Sopenharmony_ci    }
98bc2ed2b3Sopenharmony_ci    return true;
99bc2ed2b3Sopenharmony_ci}
100bc2ed2b3Sopenharmony_ci
101bc2ed2b3Sopenharmony_civoid NfcSaClient::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
102bc2ed2b3Sopenharmony_ci{
103bc2ed2b3Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
104bc2ed2b3Sopenharmony_ci    loadState_ = true;
105bc2ed2b3Sopenharmony_ci    remoteObject_ = remoteObject;
106bc2ed2b3Sopenharmony_ci    locatorCond_.notify_one();
107bc2ed2b3Sopenharmony_ci}
108bc2ed2b3Sopenharmony_ci
109bc2ed2b3Sopenharmony_civoid NfcSaClient::LoadSystemAbilityFail()
110bc2ed2b3Sopenharmony_ci{
111bc2ed2b3Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
112bc2ed2b3Sopenharmony_ci    loadState_ = false;
113bc2ed2b3Sopenharmony_ci    locatorCond_.notify_one();
114bc2ed2b3Sopenharmony_ci}
115bc2ed2b3Sopenharmony_ci
116bc2ed2b3Sopenharmony_civoid NfcSaLoadCallback::OnLoadSystemAbilitySuccess(
117bc2ed2b3Sopenharmony_ci    int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
118bc2ed2b3Sopenharmony_ci{
119bc2ed2b3Sopenharmony_ci    InfoLog("NfcSaClient Load SA success, systemAbilityId = [%{public}d]", systemAbilityId);
120bc2ed2b3Sopenharmony_ci    NfcSaClient::GetInstance().LoadSystemAbilitySuccess(remoteObject);
121bc2ed2b3Sopenharmony_ci}
122bc2ed2b3Sopenharmony_ci
123bc2ed2b3Sopenharmony_civoid NfcSaLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
124bc2ed2b3Sopenharmony_ci{
125bc2ed2b3Sopenharmony_ci    InfoLog("NfcSaClient Load SA failed, systemAbilityId = [%{public}d]", systemAbilityId);
126bc2ed2b3Sopenharmony_ci    NfcSaClient::GetInstance().LoadSystemAbilityFail();
127bc2ed2b3Sopenharmony_ci}
128bc2ed2b3Sopenharmony_ci}  // namespace NFC
129bc2ed2b3Sopenharmony_ci}  // namespace OHOS