* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LOG_TAG
#define LOG_TAG "bt_fwk_profile_manager"
#endif
#include "bluetooth_profile_manager.h"
#include <atomic>
#include <mutex>
#include "i_bluetooth_host.h"
#include "bluetooth_def.h"
#include "bluetooth_host.h"
#include "bluetooth_log.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "bluetooth_no_destructor.h"
#include "ohos_bt_gatt.h"
#include "app_image_observer_manager.h"
namespace OHOS {
namespace Bluetooth {
class ApplicationUpdateCallbackImpl : public AbilityRuntime::AppImageLifeCycleCallback {
public:
ApplicationUpdateCallbackImpl() = default;
virtual ~ApplicationUpdateCallbackImpl() = default;
* Called back when the application update.
*/
void NotifyApplicationUpdate() override;
};
sptr<BluetoothProfileManager::BluetoothSystemAbility> BluetoothProfileManager::bluetoothSystemAbility_ = nullptr;
BluetoothProfileManager::BluetoothProfileManager()
{
bluetoothSystemAbility_ = new BluetoothSystemAbility();
SubScribeBluetoothSystemAbility();
applicationUpdateCallbackImpl_ = std::make_shared<ApplicationUpdateCallbackImpl>();
AppExecFwk::AppImageObserverManager::GetInstance().RegisterImageLifecycleCallback(applicationUpdateCallbackImpl_);
}
BluetoothProfileManager::~BluetoothProfileManager()
{
UnSubScribeBluetoothSystemAbility();
}
BluetoothProfileManager &BluetoothProfileManager::GetInstance()
{
static BluetoothNoDestructor<BluetoothProfileManager> instance;
return *instance;
}
void BluetoothProfileManager::ClearSystemAbility()
{
sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
CHECK_AND_RETURN_LOG(samgrProxy != nullptr, "[BLUETOOTH_PROFILE_MANAGER] failed to get samgrProxy");
CHECK_AND_RETURN_LOG(bluetoothSystemAbility_ != nullptr, "bluetoothSystemAbility_ is null");
int32_t ret = samgrProxy->UnSubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, bluetoothSystemAbility_);
CHECK_AND_RETURN_LOG(ret == ERR_OK,
"[BLUETOOTH_PROFILE_MANAGER] Unsubscribe systemAbilityId: bluetooth service failed!");
bluetoothSystemAbility_ = nullptr;
}
void BluetoothProfileManager::SubScribeBluetoothSystemAbility()
{
sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
CHECK_AND_RETURN_LOG(samgrProxy != nullptr, "[BLUETOOTH_PROFILE_MANAGER] failed to get samgrProxy");
int32_t ret = samgrProxy->SubscribeSystemAbilityInImage(BLUETOOTH_HOST_SYS_ABILITY_ID, bluetoothSystemAbility_);
CHECK_AND_RETURN_LOG(ret == ERR_OK,
"[BLUETOOTH_PROFILE_MANAGER] subscribe systemAbilityId: bluetooth service failed!");
}
void BluetoothProfileManager::UnSubScribeBluetoothSystemAbility()
{
sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
CHECK_AND_RETURN_LOG(samgrProxy != nullptr, "[BLUETOOTH_PROFILE_MANAGER] failed to get samgrProxy");
int32_t ret = samgrProxy->UnSubscribeSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, bluetoothSystemAbility_);
CHECK_AND_RETURN_LOG(ret == ERR_OK,
"[BLUETOOTH_PROFILE_MANAGER] Unsubscribe systemAbilityId: bluetooth service failed!");
}
sptr<IRemoteObject> BluetoothProfileManager::GetHostRemote()
{
sptr<IRemoteObject> value = nullptr;
if (profileRemoteMap_.Find(BLUETOOTH_HOST, value)) {
return value;
}
std::lock_guard<std::mutex> lock(needCheckBluetoothServiceOnMutex_);
if (!isNeedCheckBluetoothServiceOn_.load()) {
HILOGD("Bluetooth service is not start");
return value;
}
auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
CHECK_AND_RETURN_LOG_RET(samgrProxy != nullptr, nullptr, "samgrProxy is nullptr");
auto object = samgrProxy->CheckSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID);
if (object == nullptr) {
HILOGE("object is nullptr");
isNeedCheckBluetoothServiceOn_ = false;
return nullptr;
}
CHECK_AND_RETURN_LOG_RET(object != nullptr, nullptr, "object is nullptr");
return object;
}
sptr<IRemoteObject> BluetoothProfileManager::GetProfileRemote(const std::string &objectName)
{
std::lock_guard<std::mutex> lock(getProfileRemoteMutex_);
sptr<IRemoteObject> remote = nullptr;
if (profileRemoteMap_.Find(objectName, remote)) {
return remote;
}
auto hostRemote = GetHostRemote();
if (hostRemote == nullptr) {
HILOGD("hostRemote is nullptr");
return nullptr;
}
if (objectName == BLUETOOTH_HOST) {
remote = hostRemote;
} else {
sptr<IBluetoothHost> hostProxy = iface_cast<IBluetoothHost>(hostRemote);
CHECK_AND_RETURN_LOG_RET(hostProxy != nullptr, nullptr, "hostProxy is nullptr");
if (objectName == BLE_ADVERTISER_SERVER || objectName == BLE_CENTRAL_MANAGER_SERVER) {
remote = hostProxy->GetBleRemote(objectName);
} else {
remote = hostProxy->GetProfile(objectName);
}
}
if (remote == nullptr) {
HILOGD("remote is nullptr");
return nullptr;
}
profileRemoteMap_.Insert(objectName, remote);
return remote;
}
void BluetoothProfileManager::NotifyBluetoothStateChange(int32_t transport, int32_t status)
{
if (transport == ADAPTER_BLE && status == STATE_TURN_OFF) {
profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
if (property.functions.bluetoothTurnOffFunc) {
property.functions.bluetoothTurnOffFunc();
}
});
}
if (transport == ADAPTER_BLE && status == STATE_TURN_ON) {
profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
if (property.functions.bleTurnOnFunc) {
auto remote = GetProfileRemote(property.objectName);
property.functions.bleTurnOnFunc(remote);
}
});
}
return;
}
void BluetoothProfileManager::RunFuncWhenBluetoothServiceStarted()
{
profileIdFuncMap_.Iterate([this](const int32_t id, ProfileIdProperty &property) {
auto remote = GetProfileRemote(property.objectName);
if (property.functions.bluetoothLoadedfunc) {
property.functions.bluetoothLoadedfunc(remote);
}
});
}
void BluetoothProfileManager::BluetoothSystemAbility::OnAddSystemAbility(int32_t systemAbilityId,
const std::string &deviceId)
{
HILOGI("systemAbilityId:%{public}d", systemAbilityId);
switch (systemAbilityId) {
case BLUETOOTH_HOST_SYS_ABILITY_ID: {
BluetoothProfileManager::GetInstance().isBluetoothServiceOn_ = true;
{
std::lock_guard<std::mutex> lock(
BluetoothProfileManager::GetInstance().needCheckBluetoothServiceOnMutex_);
BluetoothProfileManager::GetInstance().isNeedCheckBluetoothServiceOn_ = true;
}
BluetoothHost::GetDefaultHost().LoadSystemAbilitySuccess(nullptr);
BluetoothProfileManager::GetInstance().RunFuncWhenBluetoothServiceStarted();
break;
}
default:
HILOGE("unhandled sysabilityId:%{public}d", systemAbilityId);
break;
}
return;
}
void BluetoothProfileManager::BluetoothSystemAbility::OnRemoveSystemAbility(int32_t systemAbilityId,
const std::string &deviceId)
{
HILOGI("systemAbilityId:%{public}d", systemAbilityId);
switch (systemAbilityId) {
case BLUETOOTH_HOST_SYS_ABILITY_ID: {
HILOGD("Clear global variables first");
ClearGlobalResource();
BluetoothProfileManager::GetInstance().profileRemoteMap_.Clear();
BluetoothProfileManager::GetInstance().isBluetoothServiceOn_ = false;
{
std::lock_guard<std::mutex> lock(
BluetoothProfileManager::GetInstance().needCheckBluetoothServiceOnMutex_);
BluetoothProfileManager::GetInstance().isNeedCheckBluetoothServiceOn_ = true;
}
BluetoothHost::GetDefaultHost().OnRemoveBluetoothSystemAbility();
break;
}
default:
HILOGE("unhandled sysabilityId:%{public}d", systemAbilityId);
break;
}
return;
}
int32_t BluetoothProfileManager::GetValidId()
{
std::lock_guard<std::mutex> lock(idMutex_);
registerValidId_++;
return registerValidId_;
}
int32_t BluetoothProfileManager::RegisterFunc(const std::string &objectName,
std::function<void (sptr<IRemoteObject>)> func)
{
int32_t id = GetValidId();
ProfileIdProperty value;
ProfileIdProperty idProperties;
idProperties.objectName = objectName;
idProperties.functions.bluetoothLoadedfunc = func;
HILOGD("objectname: %{public}s, id: %{public}d", objectName.c_str(), id);
profileIdFuncMap_.Insert(id, idProperties);
if (isBluetoothServiceOn_) {
sptr<IRemoteObject> remote = GetProfileRemote(objectName);
CHECK_AND_RETURN_LOG_RET(remote != nullptr, id, "remote is nullptr");
func(remote);
}
return id;
}
int32_t BluetoothProfileManager::RegisterFunc(const std::string &objectName, ProfileFunctions profileFunctions)
{
int32_t id = GetValidId();
ProfileIdProperty value;
ProfileIdProperty idProperties;
idProperties.objectName = objectName;
idProperties.functions = profileFunctions;
HILOGI("objectname: %{public}s, id: %{public}d", objectName.c_str(), id);
profileIdFuncMap_.Insert(id, idProperties);
if (isBluetoothServiceOn_) {
sptr<IRemoteObject> remote = GetProfileRemote(objectName);
CHECK_AND_RETURN_LOG_RET(remote != nullptr, id, "remote is nullptr");
if (profileFunctions.bluetoothLoadedfunc) {
profileFunctions.bluetoothLoadedfunc(remote);
}
if (profileFunctions.bleTurnOnFunc && IS_BLE_ENABLED()) {
profileFunctions.bleTurnOnFunc(remote);
}
}
return id;
}
void BluetoothProfileManager::DeregisterFunc(int32_t id)
{
HILOGI("id: %{public}d", id);
ProfileIdProperty value;
CHECK_AND_RETURN_LOG(profileIdFuncMap_.Find(id, value), "id is not exist");
profileIdFuncMap_.Erase(id);
}
bool BluetoothProfileManager::IsBluetoothServiceOn()
{
return isBluetoothServiceOn_.load();
}
void BluetoothProfileManager::BluetoothProfileManagerUpdate()
{
HILOGI("Clear the Binder cache when an app is loaded from an image.");
bluetoothSystemAbility_->OnRemoveSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, "");
bluetoothSystemAbility_->OnAddSystemAbility(BLUETOOTH_HOST_SYS_ABILITY_ID, "");
}
void ApplicationUpdateCallbackImpl::NotifyApplicationUpdate()
{
BluetoothProfileManager::GetInstance().BluetoothProfileManagerUpdate();
}
}
}