1518678f8Sopenharmony_ci/*
2518678f8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3518678f8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4518678f8Sopenharmony_ci * you may not use this file except in compliance with the License.
5518678f8Sopenharmony_ci * You may obtain a copy of the License at
6518678f8Sopenharmony_ci *
7518678f8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8518678f8Sopenharmony_ci *
9518678f8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10518678f8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11518678f8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12518678f8Sopenharmony_ci * See the License for the specific language governing permissions and
13518678f8Sopenharmony_ci * limitations under the License.
14518678f8Sopenharmony_ci */
15518678f8Sopenharmony_ci
16518678f8Sopenharmony_ci#include "dhcp_sa_manager.h"
17518678f8Sopenharmony_ci#include "dhcp_errcode.h"
18518678f8Sopenharmony_ci#include "iremote_broker.h"
19518678f8Sopenharmony_ci#include "iremote_object.h"
20518678f8Sopenharmony_ci#include "iservice_registry.h"
21518678f8Sopenharmony_ci#include "dhcp_logger.h"
22518678f8Sopenharmony_ci
23518678f8Sopenharmony_ciDEFINE_DHCPLOG_DHCP_LABEL("DhcpSaLoadManager");
24518678f8Sopenharmony_cinamespace OHOS {
25518678f8Sopenharmony_cinamespace DHCP {
26518678f8Sopenharmony_cistatic constexpr int32_t DHCP_LOADSA_TIMEOUT_MS = 1000;
27518678f8Sopenharmony_ciDhcpSaLoadManager& DhcpSaLoadManager::GetInstance()
28518678f8Sopenharmony_ci{
29518678f8Sopenharmony_ci    static auto instance = new DhcpSaLoadManager();
30518678f8Sopenharmony_ci    return *instance;
31518678f8Sopenharmony_ci}
32518678f8Sopenharmony_ci
33518678f8Sopenharmony_ciErrCode DhcpSaLoadManager::LoadWifiSa(int32_t systemAbilityId) __attribute__((no_sanitize("cfi")))
34518678f8Sopenharmony_ci{
35518678f8Sopenharmony_ci    DHCP_LOGD("%{public}s enter, systemAbilityId = [%{public}d] loading", __func__, systemAbilityId);
36518678f8Sopenharmony_ci    sptr<ISystemAbilityManager> samgr =
37518678f8Sopenharmony_ci        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
38518678f8Sopenharmony_ci    if (samgr == nullptr) {
39518678f8Sopenharmony_ci        DHCP_LOGE("%{public}s: get system ability manager failed!", __func__);
40518678f8Sopenharmony_ci        return DHCP_E_FAILED;
41518678f8Sopenharmony_ci    }
42518678f8Sopenharmony_ci    auto object = samgr->CheckSystemAbility(systemAbilityId);
43518678f8Sopenharmony_ci    if (object != nullptr) {
44518678f8Sopenharmony_ci        return DHCP_E_SUCCESS;
45518678f8Sopenharmony_ci    }
46518678f8Sopenharmony_ci    InitLoadState();
47518678f8Sopenharmony_ci    sptr<DhcpSaLoadCallback> loadCallback = new (std::nothrow)DhcpSaLoadCallback();
48518678f8Sopenharmony_ci    if (loadCallback == nullptr) {
49518678f8Sopenharmony_ci        DHCP_LOGE("%{public}s: dhcp sa load callback failed!", __func__);
50518678f8Sopenharmony_ci        return DHCP_E_FAILED;
51518678f8Sopenharmony_ci    }
52518678f8Sopenharmony_ci    int32_t ret = samgr->LoadSystemAbility(systemAbilityId, loadCallback);
53518678f8Sopenharmony_ci    if (ret != DHCP_E_SUCCESS) {
54518678f8Sopenharmony_ci        DHCP_LOGE("%{public}s: Failed to load system ability, SA Id = [%{public}d], ret = [%{public}d].",
55518678f8Sopenharmony_ci            __func__, systemAbilityId, ret);
56518678f8Sopenharmony_ci        return DHCP_E_FAILED;
57518678f8Sopenharmony_ci    }
58518678f8Sopenharmony_ci    DHCP_LOGI("DhcpSaLoadManager LoadWifiSa");
59518678f8Sopenharmony_ci    return WaitLoadStateChange(systemAbilityId);
60518678f8Sopenharmony_ci}
61518678f8Sopenharmony_ci
62518678f8Sopenharmony_civoid DhcpSaLoadManager::InitLoadState()
63518678f8Sopenharmony_ci{
64518678f8Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
65518678f8Sopenharmony_ci    state_ = false;
66518678f8Sopenharmony_ci}
67518678f8Sopenharmony_ci
68518678f8Sopenharmony_ciErrCode DhcpSaLoadManager::WaitLoadStateChange(int32_t systemAbilityId)
69518678f8Sopenharmony_ci{
70518678f8Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
71518678f8Sopenharmony_ci    auto wait = locatorCon_.wait_for(lock, std::chrono::milliseconds(DHCP_LOADSA_TIMEOUT_MS), [this] {
72518678f8Sopenharmony_ci        DHCP_LOGI("DhcpSaLoadManager wait_for");
73518678f8Sopenharmony_ci        return state_ == true;
74518678f8Sopenharmony_ci    });
75518678f8Sopenharmony_ci    if (!wait) {
76518678f8Sopenharmony_ci        DHCP_LOGE("locator sa [%{public}d] start time out.", systemAbilityId);
77518678f8Sopenharmony_ci        return DHCP_E_FAILED;
78518678f8Sopenharmony_ci    }
79518678f8Sopenharmony_ci    DHCP_LOGI("DhcpSaLoadManager WaitLoadStateChange ok");
80518678f8Sopenharmony_ci    return DHCP_E_SUCCESS;
81518678f8Sopenharmony_ci}
82518678f8Sopenharmony_ci
83518678f8Sopenharmony_ciErrCode DhcpSaLoadManager::UnloadWifiSa(int32_t systemAbilityId)
84518678f8Sopenharmony_ci{
85518678f8Sopenharmony_ci    DHCP_LOGI("%{public}s enter, systemAbilityId = [%{public}d] unloading", __func__, systemAbilityId);
86518678f8Sopenharmony_ci    sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
87518678f8Sopenharmony_ci    if (samgr == nullptr) {
88518678f8Sopenharmony_ci        DHCP_LOGE("%{public}s: get system ability manager failed!", __func__);
89518678f8Sopenharmony_ci        return DHCP_E_FAILED;
90518678f8Sopenharmony_ci    }
91518678f8Sopenharmony_ci    int32_t ret = samgr->UnloadSystemAbility(systemAbilityId);
92518678f8Sopenharmony_ci    if (ret != DHCP_E_SUCCESS) {
93518678f8Sopenharmony_ci        DHCP_LOGE("%{public}s: Failed to unload system ability, SA Id = [%{public}d], ret = [%{public}d].",
94518678f8Sopenharmony_ci            __func__, systemAbilityId, ret);
95518678f8Sopenharmony_ci        return DHCP_E_FAILED;
96518678f8Sopenharmony_ci    }
97518678f8Sopenharmony_ci    DHCP_LOGI("DhcpSaLoadManager UnloadWifiSa ok");
98518678f8Sopenharmony_ci    return DHCP_E_SUCCESS;
99518678f8Sopenharmony_ci}
100518678f8Sopenharmony_ci
101518678f8Sopenharmony_civoid DhcpSaLoadManager::LoadSystemAbilitySuccess()
102518678f8Sopenharmony_ci{
103518678f8Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
104518678f8Sopenharmony_ci    state_ = true;
105518678f8Sopenharmony_ci    DHCP_LOGI("DhcpSaLoadManager LoadSystemAbilitySuccess notify_one");
106518678f8Sopenharmony_ci    locatorCon_.notify_one();
107518678f8Sopenharmony_ci}
108518678f8Sopenharmony_ci
109518678f8Sopenharmony_civoid DhcpSaLoadManager::LoadSystemAbilityFail()
110518678f8Sopenharmony_ci{
111518678f8Sopenharmony_ci    std::unique_lock<std::mutex> lock(locatorMutex_);
112518678f8Sopenharmony_ci    state_ = false;
113518678f8Sopenharmony_ci    DHCP_LOGI("DhcpSaLoadManager LoadSystemAbilityFail notify_one");
114518678f8Sopenharmony_ci    locatorCon_.notify_one();
115518678f8Sopenharmony_ci}
116518678f8Sopenharmony_ci
117518678f8Sopenharmony_civoid DhcpSaLoadCallback::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject> &remoteObject)
118518678f8Sopenharmony_ci{
119518678f8Sopenharmony_ci    DHCP_LOGI("DhcpSaLoadManager Load SA success, systemAbilityId = [%{public}d]", systemAbilityId);
120518678f8Sopenharmony_ci    DhcpSaLoadManager::GetInstance().LoadSystemAbilitySuccess();
121518678f8Sopenharmony_ci}
122518678f8Sopenharmony_ci
123518678f8Sopenharmony_civoid DhcpSaLoadCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId)
124518678f8Sopenharmony_ci{
125518678f8Sopenharmony_ci    DHCP_LOGI("DhcpSaLoadManager Load SA failed, systemAbilityId = [%{public}d]", systemAbilityId);
126518678f8Sopenharmony_ci    DhcpSaLoadManager::GetInstance().LoadSystemAbilityFail();
127518678f8Sopenharmony_ci}
128518678f8Sopenharmony_ci}  // namespace DHCP
129518678f8Sopenharmony_ci}  // namespace OHOS
130