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#include "dataobs_mgr_inner.h" 16eace7efcSopenharmony_ci 17eace7efcSopenharmony_ci#include "data_ability_observer_stub.h" 18eace7efcSopenharmony_ci#include "dataobs_mgr_errors.h" 19eace7efcSopenharmony_ci#include "hilog_tag_wrapper.h" 20eace7efcSopenharmony_ci#include "common_utils.h" 21eace7efcSopenharmony_ci 22eace7efcSopenharmony_cinamespace OHOS { 23eace7efcSopenharmony_cinamespace AAFwk { 24eace7efcSopenharmony_ci 25eace7efcSopenharmony_ciDataObsMgrInner::DataObsMgrInner() {} 26eace7efcSopenharmony_ci 27eace7efcSopenharmony_ciDataObsMgrInner::~DataObsMgrInner() {} 28eace7efcSopenharmony_ci 29eace7efcSopenharmony_ciint DataObsMgrInner::HandleRegisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver) 30eace7efcSopenharmony_ci{ 31eace7efcSopenharmony_ci std::lock_guard<ffrt::mutex> lock(innerMutex_); 32eace7efcSopenharmony_ci 33eace7efcSopenharmony_ci auto [obsPair, flag] = observers_.try_emplace(uri.ToString(), std::list<sptr<IDataAbilityObserver>>()); 34eace7efcSopenharmony_ci if (!flag && obsPair->second.size() > OBS_NUM_MAX) { 35eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, 36eace7efcSopenharmony_ci "subscribers num:%{public}s maxed", 37eace7efcSopenharmony_ci CommonUtils::Anonymous(uri.ToString()).c_str()); 38eace7efcSopenharmony_ci return DATAOBS_SERVICE_OBS_LIMMIT; 39eace7efcSopenharmony_ci } 40eace7efcSopenharmony_ci 41eace7efcSopenharmony_ci for (auto obs = obsPair->second.begin(); obs != obsPair->second.end(); obs++) { 42eace7efcSopenharmony_ci if ((*obs)->AsObject() == dataObserver->AsObject()) { 43eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, "obs registered:%{public}s", 44eace7efcSopenharmony_ci CommonUtils::Anonymous(uri.ToString()).c_str()); 45eace7efcSopenharmony_ci return OBS_EXIST; 46eace7efcSopenharmony_ci } 47eace7efcSopenharmony_ci } 48eace7efcSopenharmony_ci 49eace7efcSopenharmony_ci obsPair->second.push_back(dataObserver); 50eace7efcSopenharmony_ci 51eace7efcSopenharmony_ci AddObsDeathRecipient(dataObserver); 52eace7efcSopenharmony_ci 53eace7efcSopenharmony_ci return NO_ERROR; 54eace7efcSopenharmony_ci} 55eace7efcSopenharmony_ci 56eace7efcSopenharmony_ciint DataObsMgrInner::HandleUnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver) 57eace7efcSopenharmony_ci{ 58eace7efcSopenharmony_ci std::lock_guard<ffrt::mutex> lock(innerMutex_); 59eace7efcSopenharmony_ci 60eace7efcSopenharmony_ci auto obsPair = observers_.find(uri.ToString()); 61eace7efcSopenharmony_ci if (obsPair == observers_.end()) { 62eace7efcSopenharmony_ci TAG_LOGW( 63eace7efcSopenharmony_ci AAFwkTag::DBOBSMGR, "uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); 64eace7efcSopenharmony_ci return NO_OBS_FOR_URI; 65eace7efcSopenharmony_ci } 66eace7efcSopenharmony_ci 67eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::DBOBSMGR, "obs num:%{public}zu:%{public}s", obsPair->second.size(), 68eace7efcSopenharmony_ci CommonUtils::Anonymous(uri.ToString()).c_str()); 69eace7efcSopenharmony_ci auto obs = obsPair->second.begin(); 70eace7efcSopenharmony_ci for (; obs != obsPair->second.end(); obs++) { 71eace7efcSopenharmony_ci if ((*obs)->AsObject() == dataObserver->AsObject()) { 72eace7efcSopenharmony_ci break; 73eace7efcSopenharmony_ci } 74eace7efcSopenharmony_ci } 75eace7efcSopenharmony_ci if (obs == obsPair->second.end()) { 76eace7efcSopenharmony_ci TAG_LOGW( 77eace7efcSopenharmony_ci AAFwkTag::DBOBSMGR, "uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str()); 78eace7efcSopenharmony_ci return NO_OBS_FOR_URI; 79eace7efcSopenharmony_ci } 80eace7efcSopenharmony_ci obsPair->second.remove(*obs); 81eace7efcSopenharmony_ci if (obsPair->second.empty()) { 82eace7efcSopenharmony_ci observers_.erase(obsPair); 83eace7efcSopenharmony_ci } 84eace7efcSopenharmony_ci 85eace7efcSopenharmony_ci if (!HaveRegistered(dataObserver)) { 86eace7efcSopenharmony_ci RemoveObsDeathRecipient(dataObserver->AsObject()); 87eace7efcSopenharmony_ci } 88eace7efcSopenharmony_ci 89eace7efcSopenharmony_ci return NO_ERROR; 90eace7efcSopenharmony_ci} 91eace7efcSopenharmony_ci 92eace7efcSopenharmony_ciint DataObsMgrInner::HandleNotifyChange(const Uri &uri) 93eace7efcSopenharmony_ci{ 94eace7efcSopenharmony_ci std::list<sptr<IDataAbilityObserver>> obsList; 95eace7efcSopenharmony_ci std::lock_guard<ffrt::mutex> lock(innerMutex_); 96eace7efcSopenharmony_ci { 97eace7efcSopenharmony_ci auto obsPair = observers_.find(uri.ToString()); 98eace7efcSopenharmony_ci if (obsPair == observers_.end()) { 99eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::DBOBSMGR, "uri no obs:%{public}s", 100eace7efcSopenharmony_ci CommonUtils::Anonymous(uri.ToString()).c_str()); 101eace7efcSopenharmony_ci return NO_OBS_FOR_URI; 102eace7efcSopenharmony_ci } 103eace7efcSopenharmony_ci obsList = obsPair->second; 104eace7efcSopenharmony_ci } 105eace7efcSopenharmony_ci 106eace7efcSopenharmony_ci for (auto &obs : obsList) { 107eace7efcSopenharmony_ci if (obs != nullptr) { 108eace7efcSopenharmony_ci obs->OnChange(); 109eace7efcSopenharmony_ci } 110eace7efcSopenharmony_ci } 111eace7efcSopenharmony_ci 112eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::DBOBSMGR, "uri end:%{public}s,obs num:%{public}zu", 113eace7efcSopenharmony_ci CommonUtils::Anonymous(uri.ToString()).c_str(), obsList.size()); 114eace7efcSopenharmony_ci return NO_ERROR; 115eace7efcSopenharmony_ci} 116eace7efcSopenharmony_ci 117eace7efcSopenharmony_civoid DataObsMgrInner::AddObsDeathRecipient(sptr<IDataAbilityObserver> dataObserver) 118eace7efcSopenharmony_ci{ 119eace7efcSopenharmony_ci if ((dataObserver == nullptr) || dataObserver->AsObject() == nullptr) { 120eace7efcSopenharmony_ci return; 121eace7efcSopenharmony_ci } 122eace7efcSopenharmony_ci 123eace7efcSopenharmony_ci auto it = obsRecipient_.find(dataObserver->AsObject()); 124eace7efcSopenharmony_ci if (it != obsRecipient_.end()) { 125eace7efcSopenharmony_ci TAG_LOGW(AAFwkTag::DBOBSMGR, "called"); 126eace7efcSopenharmony_ci return; 127eace7efcSopenharmony_ci } else { 128eace7efcSopenharmony_ci std::weak_ptr<DataObsMgrInner> thisWeakPtr(shared_from_this()); 129eace7efcSopenharmony_ci sptr<IRemoteObject::DeathRecipient> deathRecipient = 130eace7efcSopenharmony_ci new DataObsCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) { 131eace7efcSopenharmony_ci auto dataObsMgrInner = thisWeakPtr.lock(); 132eace7efcSopenharmony_ci if (dataObsMgrInner) { 133eace7efcSopenharmony_ci dataObsMgrInner->OnCallBackDied(remote); 134eace7efcSopenharmony_ci } 135eace7efcSopenharmony_ci }); 136eace7efcSopenharmony_ci if (!dataObserver->AsObject()->AddDeathRecipient(deathRecipient)) { 137eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, "failed"); 138eace7efcSopenharmony_ci } 139eace7efcSopenharmony_ci obsRecipient_.emplace(dataObserver->AsObject(), deathRecipient); 140eace7efcSopenharmony_ci } 141eace7efcSopenharmony_ci} 142eace7efcSopenharmony_ci 143eace7efcSopenharmony_civoid DataObsMgrInner::RemoveObsDeathRecipient(sptr<IRemoteObject> dataObserver) 144eace7efcSopenharmony_ci{ 145eace7efcSopenharmony_ci if (dataObserver == nullptr) { 146eace7efcSopenharmony_ci return; 147eace7efcSopenharmony_ci } 148eace7efcSopenharmony_ci 149eace7efcSopenharmony_ci auto it = obsRecipient_.find(dataObserver); 150eace7efcSopenharmony_ci if (it != obsRecipient_.end()) { 151eace7efcSopenharmony_ci it->first->RemoveDeathRecipient(it->second); 152eace7efcSopenharmony_ci obsRecipient_.erase(it); 153eace7efcSopenharmony_ci return; 154eace7efcSopenharmony_ci } 155eace7efcSopenharmony_ci} 156eace7efcSopenharmony_ci 157eace7efcSopenharmony_civoid DataObsMgrInner::OnCallBackDied(const wptr<IRemoteObject> &remote) 158eace7efcSopenharmony_ci{ 159eace7efcSopenharmony_ci auto dataObserver = remote.promote(); 160eace7efcSopenharmony_ci if (dataObserver == nullptr) { 161eace7efcSopenharmony_ci return; 162eace7efcSopenharmony_ci } 163eace7efcSopenharmony_ci std::lock_guard<ffrt::mutex> lock(innerMutex_); 164eace7efcSopenharmony_ci 165eace7efcSopenharmony_ci if (dataObserver == nullptr) { 166eace7efcSopenharmony_ci TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver"); 167eace7efcSopenharmony_ci return; 168eace7efcSopenharmony_ci } 169eace7efcSopenharmony_ci 170eace7efcSopenharmony_ci RemoveObs(dataObserver); 171eace7efcSopenharmony_ci} 172eace7efcSopenharmony_ci 173eace7efcSopenharmony_civoid DataObsMgrInner::RemoveObs(sptr<IRemoteObject> dataObserver) 174eace7efcSopenharmony_ci{ 175eace7efcSopenharmony_ci for (auto iter = observers_.begin(); iter != observers_.end();) { 176eace7efcSopenharmony_ci auto &obsList = iter->second; 177eace7efcSopenharmony_ci for (auto it = obsList.begin(); it != obsList.end(); it++) { 178eace7efcSopenharmony_ci if ((*it)->AsObject() == dataObserver) { 179eace7efcSopenharmony_ci TAG_LOGD(AAFwkTag::DBOBSMGR, "erase"); 180eace7efcSopenharmony_ci obsList.erase(it); 181eace7efcSopenharmony_ci break; 182eace7efcSopenharmony_ci } 183eace7efcSopenharmony_ci } 184eace7efcSopenharmony_ci if (obsList.size() == 0) { 185eace7efcSopenharmony_ci iter = observers_.erase(iter); 186eace7efcSopenharmony_ci } else { 187eace7efcSopenharmony_ci iter++; 188eace7efcSopenharmony_ci } 189eace7efcSopenharmony_ci } 190eace7efcSopenharmony_ci RemoveObsDeathRecipient(dataObserver); 191eace7efcSopenharmony_ci} 192eace7efcSopenharmony_ci 193eace7efcSopenharmony_cibool DataObsMgrInner::HaveRegistered(sptr<IDataAbilityObserver> dataObserver) 194eace7efcSopenharmony_ci{ 195eace7efcSopenharmony_ci for (auto &[key, value] : observers_) { 196eace7efcSopenharmony_ci auto obs = std::find(value.begin(), value.end(), dataObserver); 197eace7efcSopenharmony_ci if (obs != value.end()) { 198eace7efcSopenharmony_ci return true; 199eace7efcSopenharmony_ci } 200eace7efcSopenharmony_ci } 201eace7efcSopenharmony_ci return false; 202eace7efcSopenharmony_ci} 203eace7efcSopenharmony_ci} // namespace AAFwk 204eace7efcSopenharmony_ci} // namespace OHOS 205