1eace7efcSopenharmony_ci/* 2eace7efcSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3eace7efcSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4eace7efcSopenharmony_ci * you may not use this file except in compliance with the License. 5eace7efcSopenharmony_ci * You may obtain a copy of the License at 6eace7efcSopenharmony_ci * 7eace7efcSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8eace7efcSopenharmony_ci * 9eace7efcSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10eace7efcSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11eace7efcSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12eace7efcSopenharmony_ci * See the License for the specific language governing permissions and 13eace7efcSopenharmony_ci * limitations under the License. 14eace7efcSopenharmony_ci */ 15eace7efcSopenharmony_ci 16eace7efcSopenharmony_ci#include <thread> 17eace7efcSopenharmony_ci#include "dataobs_mgr_client.h" 18eace7efcSopenharmony_ci 19eace7efcSopenharmony_ci#include "hilog_tag_wrapper.h" 20eace7efcSopenharmony_ci#include "if_system_ability_manager.h" 21eace7efcSopenharmony_ci#include "iservice_registry.h" 22eace7efcSopenharmony_ci#include "system_ability_definition.h" 23eace7efcSopenharmony_ci#include "system_ability_status_change_stub.h" 24eace7efcSopenharmony_ci 25eace7efcSopenharmony_cinamespace OHOS { 26eace7efcSopenharmony_cinamespace AAFwk { 27eace7efcSopenharmony_cistd::mutex DataObsMgrClient::mutex_; 28eace7efcSopenharmony_ci 29eace7efcSopenharmony_ciclass DataObsMgrClient::SystemAbilityStatusChangeListener 30eace7efcSopenharmony_ci : public SystemAbilityStatusChangeStub { 31eace7efcSopenharmony_cipublic: 32eace7efcSopenharmony_ci SystemAbilityStatusChangeListener() 33eace7efcSopenharmony_ci { 34eace7efcSopenharmony_ci } 35eace7efcSopenharmony_ci ~SystemAbilityStatusChangeListener() = default; 36eace7efcSopenharmony_ci void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; 37eace7efcSopenharmony_ci void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override 38eace7efcSopenharmony_ci { 39eace7efcSopenharmony_ci } 40eace7efcSopenharmony_ci}; 41eace7efcSopenharmony_ci 42eace7efcSopenharmony_civoid DataObsMgrClient::SystemAbilityStatusChangeListener::OnAddSystemAbility( 43eace7efcSopenharmony_ci int32_t systemAbilityId, const std::string &deviceId) 44eace7efcSopenharmony_ci{ 45eace7efcSopenharmony_ci TAG_LOGI(AAFwkTag::DBOBSMGR, "called"); 46eace7efcSopenharmony_ci if (systemAbilityId != DATAOBS_MGR_SERVICE_SA_ID) { 47eace7efcSopenharmony_ci return; 48eace7efcSopenharmony_ci } 49eace7efcSopenharmony_ci GetInstance()->ReRegister(); 50eace7efcSopenharmony_ci} 51eace7efcSopenharmony_ci 52eace7efcSopenharmony_cistd::shared_ptr<DataObsMgrClient> DataObsMgrClient::GetInstance() 53eace7efcSopenharmony_ci{ 54eace7efcSopenharmony_ci static std::shared_ptr<DataObsMgrClient> proxy = std::make_shared<DataObsMgrClient>(); 55eace7efcSopenharmony_ci return proxy; 56eace7efcSopenharmony_ci} 57eace7efcSopenharmony_ci 58eace7efcSopenharmony_ciDataObsMgrClient::DataObsMgrClient() 59eace7efcSopenharmony_ci{ 60eace7efcSopenharmony_ci callback_ = new SystemAbilityStatusChangeListener(); 61eace7efcSopenharmony_ci} 62eace7efcSopenharmony_ci 63eace7efcSopenharmony_ciDataObsMgrClient::~DataObsMgrClient() 64eace7efcSopenharmony_ci{} 65eace7efcSopenharmony_ci 66eace7efcSopenharmony_ci/** 67eace7efcSopenharmony_ci * Registers an observer to DataObsMgr specified by the given Uri. 68eace7efcSopenharmony_ci * 69eace7efcSopenharmony_ci * @param uri, Indicates the path of the data to operate. 70eace7efcSopenharmony_ci * @param dataObserver, Indicates the IDataAbilityObserver object. 71eace7efcSopenharmony_ci * 72eace7efcSopenharmony_ci * @return Returns ERR_OK on success, others on failure. 73eace7efcSopenharmony_ci */ 74eace7efcSopenharmony_ciErrCode DataObsMgrClient::RegisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver) 75eace7efcSopenharmony_ci{ 76eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 77eace7efcSopenharmony_ci if (errCode != SUCCESS) { 78eace7efcSopenharmony_ci return DATAOBS_SERVICE_NOT_CONNECTED; 79eace7efcSopenharmony_ci } 80eace7efcSopenharmony_ci auto status = dataObsManger->RegisterObserver(uri, dataObserver); 81eace7efcSopenharmony_ci if (status != NO_ERROR) { 82eace7efcSopenharmony_ci return status; 83eace7efcSopenharmony_ci } 84eace7efcSopenharmony_ci observers_.Compute(dataObserver, [&uri](const auto &key, auto &value) { 85eace7efcSopenharmony_ci value.emplace_back(uri); 86eace7efcSopenharmony_ci return true; 87eace7efcSopenharmony_ci }); 88eace7efcSopenharmony_ci return status; 89eace7efcSopenharmony_ci} 90eace7efcSopenharmony_ci 91eace7efcSopenharmony_ci/** 92eace7efcSopenharmony_ci * Deregisters an observer used for DataObsMgr specified by the given Uri. 93eace7efcSopenharmony_ci * 94eace7efcSopenharmony_ci * @param uri, Indicates the path of the data to operate. 95eace7efcSopenharmony_ci * @param dataObserver, Indicates the IDataAbilityObserver object. 96eace7efcSopenharmony_ci * 97eace7efcSopenharmony_ci * @return Returns ERR_OK on success, others on failure. 98eace7efcSopenharmony_ci */ 99eace7efcSopenharmony_ciErrCode DataObsMgrClient::UnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver) 100eace7efcSopenharmony_ci{ 101eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 102eace7efcSopenharmony_ci if (errCode != SUCCESS) { 103eace7efcSopenharmony_ci return DATAOBS_SERVICE_NOT_CONNECTED; 104eace7efcSopenharmony_ci } 105eace7efcSopenharmony_ci auto status = dataObsManger->UnregisterObserver(uri, dataObserver); 106eace7efcSopenharmony_ci if (status != NO_ERROR) { 107eace7efcSopenharmony_ci return status; 108eace7efcSopenharmony_ci } 109eace7efcSopenharmony_ci observers_.Compute(dataObserver, [&uri](const auto &key, auto &value) { 110eace7efcSopenharmony_ci value.remove_if([&uri](const auto &val) { 111eace7efcSopenharmony_ci return uri == val; 112eace7efcSopenharmony_ci }); 113eace7efcSopenharmony_ci return !value.empty(); 114eace7efcSopenharmony_ci }); 115eace7efcSopenharmony_ci return status; 116eace7efcSopenharmony_ci} 117eace7efcSopenharmony_ci 118eace7efcSopenharmony_ci/** 119eace7efcSopenharmony_ci * Notifies the registered observers of a change to the data resource specified by Uri. 120eace7efcSopenharmony_ci * 121eace7efcSopenharmony_ci * @param uri, Indicates the path of the data to operate. 122eace7efcSopenharmony_ci * 123eace7efcSopenharmony_ci * @return Returns ERR_OK on success, others on failure. 124eace7efcSopenharmony_ci */ 125eace7efcSopenharmony_ciErrCode DataObsMgrClient::NotifyChange(const Uri &uri) 126eace7efcSopenharmony_ci{ 127eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 128eace7efcSopenharmony_ci if (errCode != SUCCESS) { 129eace7efcSopenharmony_ci return DATAOBS_SERVICE_NOT_CONNECTED; 130eace7efcSopenharmony_ci } 131eace7efcSopenharmony_ci return dataObsManger->NotifyChange(uri); 132eace7efcSopenharmony_ci} 133eace7efcSopenharmony_ci 134eace7efcSopenharmony_ci/** 135eace7efcSopenharmony_ci * Connect dataobs manager service. 136eace7efcSopenharmony_ci * 137eace7efcSopenharmony_ci * @return Returns SUCCESS on success, others on failure. 138eace7efcSopenharmony_ci */ 139eace7efcSopenharmony_ci__attribute__ ((no_sanitize("cfi"))) std::pair<Status, sptr<IDataObsMgr>> DataObsMgrClient::GetObsMgr() 140eace7efcSopenharmony_ci{ 141eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 142eace7efcSopenharmony_ci 143eace7efcSopenharmony_ci if (dataObsManger_ != nullptr) { 144eace7efcSopenharmony_ci return std::make_pair(SUCCESS, dataObsManger_); 145eace7efcSopenharmony_ci } 146eace7efcSopenharmony_ci 147eace7efcSopenharmony_ci sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 148eace7efcSopenharmony_ci if (systemManager == nullptr) { 149eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, "registry failed"); 150eace7efcSopenharmony_ci return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr); 151eace7efcSopenharmony_ci } 152eace7efcSopenharmony_ci 153eace7efcSopenharmony_ci auto remoteObject = systemManager->CheckSystemAbility(DATAOBS_MGR_SERVICE_SA_ID); 154eace7efcSopenharmony_ci if (remoteObject == nullptr) { 155eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, "systemAbility failed"); 156eace7efcSopenharmony_ci return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr); 157eace7efcSopenharmony_ci } 158eace7efcSopenharmony_ci 159eace7efcSopenharmony_ci dataObsManger_ = iface_cast<IDataObsMgr>(remoteObject); 160eace7efcSopenharmony_ci if (dataObsManger_ == nullptr) { 161eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, "iDataObsMgr failed"); 162eace7efcSopenharmony_ci return std::make_pair(GET_DATAOBS_SERVICE_FAILED, nullptr); 163eace7efcSopenharmony_ci } 164eace7efcSopenharmony_ci sptr<ServiceDeathRecipient> serviceDeathRecipient(new (std::nothrow) ServiceDeathRecipient(GetInstance())); 165eace7efcSopenharmony_ci dataObsManger_->AsObject()->AddDeathRecipient(serviceDeathRecipient); 166eace7efcSopenharmony_ci return std::make_pair(SUCCESS, dataObsManger_); 167eace7efcSopenharmony_ci} 168eace7efcSopenharmony_ci 169eace7efcSopenharmony_ciStatus DataObsMgrClient::RegisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver, 170eace7efcSopenharmony_ci bool isDescendants) 171eace7efcSopenharmony_ci{ 172eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 173eace7efcSopenharmony_ci if (errCode != SUCCESS) { 174eace7efcSopenharmony_ci return DATAOBS_SERVICE_NOT_CONNECTED; 175eace7efcSopenharmony_ci } 176eace7efcSopenharmony_ci auto status = dataObsManger->RegisterObserverExt(uri, dataObserver, isDescendants); 177eace7efcSopenharmony_ci if (status != SUCCESS) { 178eace7efcSopenharmony_ci return status; 179eace7efcSopenharmony_ci } 180eace7efcSopenharmony_ci observerExts_.Compute(dataObserver, [&uri, isDescendants](const auto &key, auto &value) { 181eace7efcSopenharmony_ci value.emplace_back(uri, isDescendants); 182eace7efcSopenharmony_ci return true; 183eace7efcSopenharmony_ci }); 184eace7efcSopenharmony_ci return status; 185eace7efcSopenharmony_ci} 186eace7efcSopenharmony_ci 187eace7efcSopenharmony_ciStatus DataObsMgrClient::UnregisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver) 188eace7efcSopenharmony_ci{ 189eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 190eace7efcSopenharmony_ci if (errCode != SUCCESS) { 191eace7efcSopenharmony_ci return DATAOBS_SERVICE_NOT_CONNECTED; 192eace7efcSopenharmony_ci } 193eace7efcSopenharmony_ci auto status = dataObsManger->UnregisterObserverExt(uri, dataObserver); 194eace7efcSopenharmony_ci if (status != SUCCESS) { 195eace7efcSopenharmony_ci return status; 196eace7efcSopenharmony_ci } 197eace7efcSopenharmony_ci observerExts_.Compute(dataObserver, [&uri](const auto &key, auto &value) { 198eace7efcSopenharmony_ci value.remove_if([&uri](const auto ¶m) { 199eace7efcSopenharmony_ci return uri == param.uri; 200eace7efcSopenharmony_ci }); 201eace7efcSopenharmony_ci return !value.empty(); 202eace7efcSopenharmony_ci }); 203eace7efcSopenharmony_ci return status; 204eace7efcSopenharmony_ci} 205eace7efcSopenharmony_ci 206eace7efcSopenharmony_ciStatus DataObsMgrClient::UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver) 207eace7efcSopenharmony_ci{ 208eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 209eace7efcSopenharmony_ci if (errCode != SUCCESS) { 210eace7efcSopenharmony_ci return DATAOBS_SERVICE_NOT_CONNECTED; 211eace7efcSopenharmony_ci } 212eace7efcSopenharmony_ci auto status = dataObsManger->UnregisterObserverExt(dataObserver); 213eace7efcSopenharmony_ci if (status != SUCCESS) { 214eace7efcSopenharmony_ci return status; 215eace7efcSopenharmony_ci } 216eace7efcSopenharmony_ci observerExts_.Erase(dataObserver); 217eace7efcSopenharmony_ci return status; 218eace7efcSopenharmony_ci} 219eace7efcSopenharmony_ci 220eace7efcSopenharmony_ciStatus DataObsMgrClient::NotifyChangeExt(const ChangeInfo &changeInfo) 221eace7efcSopenharmony_ci{ 222eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 223eace7efcSopenharmony_ci if (errCode != SUCCESS) { 224eace7efcSopenharmony_ci return DATAOBS_SERVICE_NOT_CONNECTED; 225eace7efcSopenharmony_ci } 226eace7efcSopenharmony_ci return dataObsManger->NotifyChangeExt(changeInfo); 227eace7efcSopenharmony_ci} 228eace7efcSopenharmony_ci 229eace7efcSopenharmony_civoid DataObsMgrClient::ResetService() 230eace7efcSopenharmony_ci{ 231eace7efcSopenharmony_ci std::lock_guard<std::mutex> lock(mutex_); 232eace7efcSopenharmony_ci dataObsManger_ = nullptr; 233eace7efcSopenharmony_ci} 234eace7efcSopenharmony_ci 235eace7efcSopenharmony_civoid DataObsMgrClient::OnRemoteDied() 236eace7efcSopenharmony_ci{ 237eace7efcSopenharmony_ci std::this_thread::sleep_for(std::chrono::seconds(RESUB_INTERVAL)); 238eace7efcSopenharmony_ci ResetService(); 239eace7efcSopenharmony_ci auto [errCode, dataObsManger] = GetObsMgr(); 240eace7efcSopenharmony_ci if (errCode != SUCCESS) { 241eace7efcSopenharmony_ci sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 242eace7efcSopenharmony_ci if (systemManager == nullptr) { 243eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, "null systemmgr"); 244eace7efcSopenharmony_ci return; 245eace7efcSopenharmony_ci } 246eace7efcSopenharmony_ci systemManager->SubscribeSystemAbility(DATAOBS_MGR_SERVICE_SA_ID, callback_); 247eace7efcSopenharmony_ci return; 248eace7efcSopenharmony_ci } 249eace7efcSopenharmony_ci ReRegister(); 250eace7efcSopenharmony_ci} 251eace7efcSopenharmony_ci 252eace7efcSopenharmony_civoid DataObsMgrClient::ReRegister() 253eace7efcSopenharmony_ci{ 254eace7efcSopenharmony_ci decltype(observers_) observers(std::move(observers_)); 255eace7efcSopenharmony_ci observers_.Clear(); 256eace7efcSopenharmony_ci observers.ForEach([this](const auto &key, const auto &value) { 257eace7efcSopenharmony_ci for (const auto &uri : value) { 258eace7efcSopenharmony_ci RegisterObserver(uri, key); 259eace7efcSopenharmony_ci } 260eace7efcSopenharmony_ci return false; 261eace7efcSopenharmony_ci }); 262eace7efcSopenharmony_ci 263eace7efcSopenharmony_ci decltype(observerExts_) observerExts(std::move(observerExts_)); 264eace7efcSopenharmony_ci observerExts_.Clear(); 265eace7efcSopenharmony_ci observerExts.ForEach([this](const auto &key, const auto &value) { 266eace7efcSopenharmony_ci for (const auto ¶m : value) { 267eace7efcSopenharmony_ci RegisterObserverExt(param.uri, key, param.isDescendants); 268eace7efcSopenharmony_ci } 269eace7efcSopenharmony_ci return false; 270eace7efcSopenharmony_ci }); 271eace7efcSopenharmony_ci} 272eace7efcSopenharmony_ci} // namespace AAFwk 273eace7efcSopenharmony_ci} // namespace OHOS 274