195489c19Sopenharmony_ci/*
295489c19Sopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
395489c19Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
495489c19Sopenharmony_ci * you may not use this file except in compliance with the License.
595489c19Sopenharmony_ci * You may obtain a copy of the License at
695489c19Sopenharmony_ci *
795489c19Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
895489c19Sopenharmony_ci *
995489c19Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1095489c19Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1195489c19Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1295489c19Sopenharmony_ci * See the License for the specific language governing permissions and
1395489c19Sopenharmony_ci * limitations under the License.
1495489c19Sopenharmony_ci */
1595489c19Sopenharmony_ci
1695489c19Sopenharmony_ci#include "bluetooth_profile_manager.h"
1795489c19Sopenharmony_ci
1895489c19Sopenharmony_ci#include <atomic>
1995489c19Sopenharmony_ci#include <mutex>
2095489c19Sopenharmony_ci
2195489c19Sopenharmony_ci#include "i_bluetooth_host.h"
2295489c19Sopenharmony_ci#include "bluetooth_def.h"
2395489c19Sopenharmony_ci#include "bluetooth_host.h"
2495489c19Sopenharmony_ci#include "bluetooth_log.h"
2595489c19Sopenharmony_ci#include "iservice_registry.h"
2695489c19Sopenharmony_ci#include "system_ability_definition.h"
2795489c19Sopenharmony_ci#include "bluetooth_no_destructor.h"
2895489c19Sopenharmony_ci#include "ohos_bt_gatt.h"
2995489c19Sopenharmony_ci
3095489c19Sopenharmony_cinamespace OHOS {
3195489c19Sopenharmony_cinamespace Bluetooth {
3295489c19Sopenharmony_ci
3395489c19Sopenharmony_ciBluetoothProfileManager::BluetoothProfileManager()
3495489c19Sopenharmony_ci{
3595489c19Sopenharmony_ci    bluetoothSystemAbility_ = new BluetoothSystemAbility();
3695489c19Sopenharmony_ci    SubScribeBluetoothSystemAbility();
3795489c19Sopenharmony_ci}
3895489c19Sopenharmony_ci
3995489c19Sopenharmony_ciBluetoothProfileManager::~BluetoothProfileManager()
4095489c19Sopenharmony_ci{
4195489c19Sopenharmony_ci    UnSubScribeBluetoothSystemAbility();
4295489c19Sopenharmony_ci}
4395489c19Sopenharmony_ci
4495489c19Sopenharmony_ciBluetoothProfileManager &BluetoothProfileManager::GetInstance()
4595489c19Sopenharmony_ci{
4695489c19Sopenharmony_ci    static BluetoothNoDestructor<BluetoothProfileManager> instance;
4795489c19Sopenharmony_ci    return *instance;
4895489c19Sopenharmony_ci}
4995489c19Sopenharmony_ci
5095489c19Sopenharmony_civoid BluetoothProfileManager::SubScribeBluetoothSystemAbility()
5195489c19Sopenharmony_ci{
5295489c19Sopenharmony_ci    sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
5395489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(samgrProxy != nullptr, "[BLUETOOTH_PROFILE_MANAGER] failed to get samgrProxy");
5495489c19Sopenharmony_ci    int32_t ret = samgrProxy->SubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, bluetoothSystemAbility_);
5595489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(ret == ERR_OK,
5695489c19Sopenharmony_ci        "[BLUETOOTH_PROFILE_MANAGER] subscribe systemAbilityId: bluetooth service failed!");
5795489c19Sopenharmony_ci}
5895489c19Sopenharmony_ci
5995489c19Sopenharmony_civoid BluetoothProfileManager::UnSubScribeBluetoothSystemAbility()
6095489c19Sopenharmony_ci{
6195489c19Sopenharmony_ci    sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
6295489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(samgrProxy != nullptr, "[BLUETOOTH_PROFILE_MANAGER] failed to get samgrProxy");
6395489c19Sopenharmony_ci    int32_t ret = samgrProxy->UnSubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, bluetoothSystemAbility_);
6495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(ret == ERR_OK,
6595489c19Sopenharmony_ci        "[BLUETOOTH_PROFILE_MANAGER] Unsubscribe systemAbilityId: bluetooth service failed!");
6695489c19Sopenharmony_ci}
6795489c19Sopenharmony_ci
6895489c19Sopenharmony_cisptr<IRemoteObject> BluetoothProfileManager::GetHostRemote()
6995489c19Sopenharmony_ci{
7095489c19Sopenharmony_ci    sptr<IRemoteObject> value = nullptr;
7195489c19Sopenharmony_ci    if (profileRemoteMap_.Find(BLUETOOTH_HOST, value)) {
7295489c19Sopenharmony_ci        return value;
7395489c19Sopenharmony_ci    }
7495489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(needCheckBluetoothServiceOnMutex_);
7595489c19Sopenharmony_ci    if (!isNeedCheckBluetoothServiceOn_.load()) {
7695489c19Sopenharmony_ci        HILOGD("Bluetooth service is not start");
7795489c19Sopenharmony_ci        return value;
7895489c19Sopenharmony_ci    }
7995489c19Sopenharmony_ci    auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
8095489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(samgrProxy != nullptr, nullptr, "samgrProxy is nullptr");
8195489c19Sopenharmony_ci    auto object = samgrProxy->CheckSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
8295489c19Sopenharmony_ci    if (object == nullptr) {
8395489c19Sopenharmony_ci        HILOGE("object is nullptr");
8495489c19Sopenharmony_ci        isNeedCheckBluetoothServiceOn_ = false;
8595489c19Sopenharmony_ci        return nullptr;
8695489c19Sopenharmony_ci    }
8795489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG_RET(object != nullptr, nullptr, "object is nullptr");
8895489c19Sopenharmony_ci    return object;
8995489c19Sopenharmony_ci}
9095489c19Sopenharmony_ci
9195489c19Sopenharmony_cisptr<IRemoteObject> BluetoothProfileManager::GetProfileRemote(const std::string &objectName)
9295489c19Sopenharmony_ci{
9395489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(getProfileRemoteMutex_);
9495489c19Sopenharmony_ci    sptr<IRemoteObject> remote = nullptr;
9595489c19Sopenharmony_ci    if (profileRemoteMap_.Find(objectName, remote)) {
9695489c19Sopenharmony_ci        return remote;
9795489c19Sopenharmony_ci    } // SafeMap
9895489c19Sopenharmony_ci    auto hostRemote = GetHostRemote();
9995489c19Sopenharmony_ci    if (hostRemote == nullptr) {
10095489c19Sopenharmony_ci        HILOGD("hostRemote is nullptr");
10195489c19Sopenharmony_ci        return nullptr;
10295489c19Sopenharmony_ci    }
10395489c19Sopenharmony_ci    if (objectName == BLUETOOTH_HOST) {
10495489c19Sopenharmony_ci        remote = hostRemote;
10595489c19Sopenharmony_ci    } else {
10695489c19Sopenharmony_ci        sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
10795489c19Sopenharmony_ci        CHECK_AND_RETURN_LOG_RET(hostProxy != nullptr, nullptr, "hostProxy is nullptr");
10895489c19Sopenharmony_ci        if (objectName == BLE_ADVERTISER_SERVER || objectName == BLE_CENTRAL_MANAGER_SERVER) {
10995489c19Sopenharmony_ci            remote = hostProxy->GetBleRemote(objectName);
11095489c19Sopenharmony_ci        } else {
11195489c19Sopenharmony_ci            remote = hostProxy->GetProfile(objectName);
11295489c19Sopenharmony_ci        }
11395489c19Sopenharmony_ci    }
11495489c19Sopenharmony_ci    if (remote == nullptr) {
11595489c19Sopenharmony_ci        HILOGD("remote is nullptr");
11695489c19Sopenharmony_ci        return nullptr;
11795489c19Sopenharmony_ci    }
11895489c19Sopenharmony_ci    profileRemoteMap_.Insert(objectName, remote);
11995489c19Sopenharmony_ci    return remote;
12095489c19Sopenharmony_ci}
12195489c19Sopenharmony_ci
12295489c19Sopenharmony_civoid BluetoothProfileManager::NotifyBluetoothStateChange(int32_t transport, int32_t status)
12395489c19Sopenharmony_ci{
12495489c19Sopenharmony_ci    if (transport == ADAPTER_BLE && status == STATE_TURN_OFF) {
12595489c19Sopenharmony_ci        profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
12695489c19Sopenharmony_ci            // true if *this stores a callcack function target.flase otherwise
12795489c19Sopenharmony_ci            if (property.functions.bluetoothTurnOffFunc) {
12895489c19Sopenharmony_ci                property.functions.bluetoothTurnOffFunc();
12995489c19Sopenharmony_ci            }
13095489c19Sopenharmony_ci        });
13195489c19Sopenharmony_ci    }
13295489c19Sopenharmony_ci    if (transport == ADAPTER_BLE && status == STATE_TURN_ON) {
13395489c19Sopenharmony_ci        HILOGD("Clear global variables, return to initial state");
13495489c19Sopenharmony_ci        ClearGlobalResource();
13595489c19Sopenharmony_ci        profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
13695489c19Sopenharmony_ci            if (property.functions.bleTurnOnFunc) {
13795489c19Sopenharmony_ci                auto remote = GetProfileRemote(property.objectName);
13895489c19Sopenharmony_ci                property.functions.bleTurnOnFunc(remote);
13995489c19Sopenharmony_ci            }
14095489c19Sopenharmony_ci        });
14195489c19Sopenharmony_ci    }
14295489c19Sopenharmony_ci    return;
14395489c19Sopenharmony_ci}
14495489c19Sopenharmony_ci
14595489c19Sopenharmony_civoid BluetoothProfileManager::RunFuncWhenBluetoothServiceStarted()
14695489c19Sopenharmony_ci{
14795489c19Sopenharmony_ci    profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
14895489c19Sopenharmony_ci        auto remote = GetProfileRemote(property.objectName);
14995489c19Sopenharmony_ci        if (property.functions.bluetoothLoadedfunc) {
15095489c19Sopenharmony_ci            property.functions.bluetoothLoadedfunc(remote);
15195489c19Sopenharmony_ci        }
15295489c19Sopenharmony_ci    });
15395489c19Sopenharmony_ci}
15495489c19Sopenharmony_ci
15595489c19Sopenharmony_civoid BluetoothProfileManager::BluetoothSystemAbility::OnAddSystemAbility(int32_t systemAbilityId,
15695489c19Sopenharmony_ci    const std::string &deviceId)
15795489c19Sopenharmony_ci{
15895489c19Sopenharmony_ci    HILOGD("systemAbilityId:%{public}d", systemAbilityId);
15995489c19Sopenharmony_ci    switch (systemAbilityId) {
16095489c19Sopenharmony_ci        case BLUETOOTH_HOST_SYS_ABILITY_ID: {
16195489c19Sopenharmony_ci            BluetoothProfileManager::GetInstance().isBluetoothServiceOn_ = true;
16295489c19Sopenharmony_ci            {
16395489c19Sopenharmony_ci                std::lock_guard<std::mutex> lock(
16495489c19Sopenharmony_ci                    BluetoothProfileManager::GetInstance().needCheckBluetoothServiceOnMutex_);
16595489c19Sopenharmony_ci                BluetoothProfileManager::GetInstance().isNeedCheckBluetoothServiceOn_ = true;
16695489c19Sopenharmony_ci            }
16795489c19Sopenharmony_ci            BluetoothHost::GetDefaultHost().LoadSystemAbilitySuccess(nullptr);
16895489c19Sopenharmony_ci            BluetoothProfileManager::GetInstance().RunFuncWhenBluetoothServiceStarted();
16995489c19Sopenharmony_ci            break;
17095489c19Sopenharmony_ci        }
17195489c19Sopenharmony_ci        default:
17295489c19Sopenharmony_ci            HILOGE("unhandled sysabilityId:%{public}d", systemAbilityId);
17395489c19Sopenharmony_ci            break;
17495489c19Sopenharmony_ci    }
17595489c19Sopenharmony_ci    return;
17695489c19Sopenharmony_ci}
17795489c19Sopenharmony_ci
17895489c19Sopenharmony_civoid BluetoothProfileManager::BluetoothSystemAbility::OnRemoveSystemAbility(int32_t systemAbilityId,
17995489c19Sopenharmony_ci    const std::string &deviceId)
18095489c19Sopenharmony_ci{
18195489c19Sopenharmony_ci    HILOGD("systemAbilityId:%{public}d", systemAbilityId);
18295489c19Sopenharmony_ci    switch (systemAbilityId) {
18395489c19Sopenharmony_ci        case BLUETOOTH_HOST_SYS_ABILITY_ID: {
18495489c19Sopenharmony_ci            HILOGD("Clear global variables first");
18595489c19Sopenharmony_ci            ClearGlobalResource();
18695489c19Sopenharmony_ci            BluetoothProfileManager::GetInstance().profileRemoteMap_.Clear();
18795489c19Sopenharmony_ci            BluetoothProfileManager::GetInstance().isBluetoothServiceOn_ = false;
18895489c19Sopenharmony_ci            {
18995489c19Sopenharmony_ci                std::lock_guard<std::mutex> lock(
19095489c19Sopenharmony_ci                    BluetoothProfileManager::GetInstance().needCheckBluetoothServiceOnMutex_);
19195489c19Sopenharmony_ci                BluetoothProfileManager::GetInstance().isNeedCheckBluetoothServiceOn_ = true;
19295489c19Sopenharmony_ci            }
19395489c19Sopenharmony_ci            BluetoothHost::GetDefaultHost().OnRemoveBluetoothSystemAbility();
19495489c19Sopenharmony_ci            break;
19595489c19Sopenharmony_ci        }
19695489c19Sopenharmony_ci        default:
19795489c19Sopenharmony_ci            HILOGE("unhandled sysabilityId:%{public}d", systemAbilityId);
19895489c19Sopenharmony_ci            break;
19995489c19Sopenharmony_ci    }
20095489c19Sopenharmony_ci    return;
20195489c19Sopenharmony_ci}
20295489c19Sopenharmony_ci
20395489c19Sopenharmony_ciint32_t BluetoothProfileManager::GetValidId()
20495489c19Sopenharmony_ci{
20595489c19Sopenharmony_ci    std::lock_guard<std::mutex> lock(idMutex_);
20695489c19Sopenharmony_ci    registerValidId_++;
20795489c19Sopenharmony_ci    return registerValidId_;
20895489c19Sopenharmony_ci}
20995489c19Sopenharmony_ci
21095489c19Sopenharmony_ciint32_t BluetoothProfileManager::RegisterFunc(const std::string &objectName,
21195489c19Sopenharmony_ci    std::function<void (sptr<IRemoteObject>)> func)
21295489c19Sopenharmony_ci{
21395489c19Sopenharmony_ci    int32_t id = GetValidId();
21495489c19Sopenharmony_ci    ProfileIdProperty value;
21595489c19Sopenharmony_ci    ProfileIdProperty idProperties;
21695489c19Sopenharmony_ci    idProperties.objectName = objectName;
21795489c19Sopenharmony_ci    idProperties.functions.bluetoothLoadedfunc = func;
21895489c19Sopenharmony_ci    HILOGD("objectname: %{public}s, id: %{public}d", objectName.c_str(), id);
21995489c19Sopenharmony_ci    profileIdFuncMap_.Insert(id, idProperties);
22095489c19Sopenharmony_ci    if (isBluetoothServiceOn_) {
22195489c19Sopenharmony_ci        sptr<IRemoteObject> remote = GetProfileRemote(objectName);
22295489c19Sopenharmony_ci        CHECK_AND_RETURN_LOG_RET(remote != nullptr, id, "remote is nullptr"); // 蓝牙已开启,但getremote失败。
22395489c19Sopenharmony_ci        func(remote);
22495489c19Sopenharmony_ci    }
22595489c19Sopenharmony_ci    return id;
22695489c19Sopenharmony_ci}
22795489c19Sopenharmony_ci
22895489c19Sopenharmony_ciint32_t BluetoothProfileManager::RegisterFunc(const std::string &objectName, ProfileFunctions profileFunctions)
22995489c19Sopenharmony_ci{
23095489c19Sopenharmony_ci    int32_t id = GetValidId();
23195489c19Sopenharmony_ci    ProfileIdProperty value;
23295489c19Sopenharmony_ci    ProfileIdProperty idProperties;
23395489c19Sopenharmony_ci    idProperties.objectName = objectName;
23495489c19Sopenharmony_ci    idProperties.functions = profileFunctions;
23595489c19Sopenharmony_ci    HILOGI("objectname: %{public}s, id: %{public}d", objectName.c_str(), id);
23695489c19Sopenharmony_ci    profileIdFuncMap_.Insert(id, idProperties);
23795489c19Sopenharmony_ci    if (isBluetoothServiceOn_) {
23895489c19Sopenharmony_ci        sptr<IRemoteObject> remote = GetProfileRemote(objectName);
23995489c19Sopenharmony_ci        CHECK_AND_RETURN_LOG_RET(remote != nullptr, id, "remote is nullptr"); // 蓝牙已开启,但getremote失败。
24095489c19Sopenharmony_ci        if (profileFunctions.bluetoothLoadedfunc) {
24195489c19Sopenharmony_ci            profileFunctions.bluetoothLoadedfunc(remote);
24295489c19Sopenharmony_ci        }
24395489c19Sopenharmony_ci        if (profileFunctions.bleTurnOnFunc && IS_BLE_ENABLED()) {
24495489c19Sopenharmony_ci            profileFunctions.bleTurnOnFunc(remote);
24595489c19Sopenharmony_ci        }
24695489c19Sopenharmony_ci    }
24795489c19Sopenharmony_ci    return id;
24895489c19Sopenharmony_ci}
24995489c19Sopenharmony_ci
25095489c19Sopenharmony_civoid BluetoothProfileManager::DeregisterFunc(int32_t id)
25195489c19Sopenharmony_ci{
25295489c19Sopenharmony_ci    HILOGI("id: %{public}d", id);
25395489c19Sopenharmony_ci    ProfileIdProperty value;
25495489c19Sopenharmony_ci    CHECK_AND_RETURN_LOG(profileIdFuncMap_.Find(id, value), "id is not exist");
25595489c19Sopenharmony_ci    profileIdFuncMap_.Erase(id);
25695489c19Sopenharmony_ci}
25795489c19Sopenharmony_ci
25895489c19Sopenharmony_cibool BluetoothProfileManager::IsBluetoothServiceOn()
25995489c19Sopenharmony_ci{
26095489c19Sopenharmony_ci    return isBluetoothServiceOn_.load();
26195489c19Sopenharmony_ci}
26295489c19Sopenharmony_ci} // namespace bluetooth
26395489c19Sopenharmony_ci} // namespace OHOS