1686862fbSopenharmony_ci/* 2686862fbSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3686862fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4686862fbSopenharmony_ci * you may not use this file except in compliance with the License. 5686862fbSopenharmony_ci * You may obtain a copy of the License at 6686862fbSopenharmony_ci * 7686862fbSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8686862fbSopenharmony_ci * 9686862fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10686862fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11686862fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12686862fbSopenharmony_ci * See the License for the specific language governing permissions and 13686862fbSopenharmony_ci * limitations under the License. 14686862fbSopenharmony_ci */ 15686862fbSopenharmony_ci 16686862fbSopenharmony_ci#include "distributed_ability_manager_service.h" 17686862fbSopenharmony_ci 18686862fbSopenharmony_ci#include <chrono> 19686862fbSopenharmony_ci#include <thread> 20686862fbSopenharmony_ci 21686862fbSopenharmony_ci#include "ability_manager_client.h" 22686862fbSopenharmony_ci#include "base/continuationmgr_log.h" 23686862fbSopenharmony_ci#include "base/parcel_helper.h" 24686862fbSopenharmony_ci#include "bundlemgr/bundle_mgr_interface.h" 25686862fbSopenharmony_ci#include "bundlemgr/bundle_mgr_proxy.h" 26686862fbSopenharmony_ci#include "continuation_manager/app_connection_stub.h" 27686862fbSopenharmony_ci#include "continuation_manager/app_device_callback_stub.h" 28686862fbSopenharmony_ci#include "continuation_manager/device_selection_notifier_proxy.h" 29686862fbSopenharmony_ci#include "continuation_manager/notifier_death_recipient.h" 30686862fbSopenharmony_ci#include "distributed_ability_manager_dumper.h" 31686862fbSopenharmony_ci#include "file_ex.h" 32686862fbSopenharmony_ci#include "ipc_skeleton.h" 33686862fbSopenharmony_ci#include "iservice_registry.h" 34686862fbSopenharmony_ci#include "os_account_manager.h" 35686862fbSopenharmony_ci#include "parameters.h" 36686862fbSopenharmony_ci#include "system_ability_definition.h" 37686862fbSopenharmony_ci 38686862fbSopenharmony_cinamespace OHOS { 39686862fbSopenharmony_cinamespace DistributedSchedule { 40686862fbSopenharmony_cinamespace { 41686862fbSopenharmony_ciconst std::string TAG = "ContinuationManagerService"; 42686862fbSopenharmony_ciconst std::u16string HIPLAY_PANEL_INTERFACE_TOKEN = u"ohos.hiplay.panel"; 43686862fbSopenharmony_ciconst std::string TOKEN_KEY = "distributedsched.continuationmanager.token"; 44686862fbSopenharmony_ciconst std::string DEFAULT_TOKEN_VALUE = "0"; 45686862fbSopenharmony_ciconst std::string DMS_HIPLAY_ACTION = "ohos.ability.action.deviceSelect"; 46686862fbSopenharmony_ciconstexpr int32_t MAX_TOKEN_NUM = 100000000; 47686862fbSopenharmony_ciconstexpr int32_t MAX_REGISTER_NUM = 600; 48686862fbSopenharmony_ciconstexpr int32_t START_DEVICE_MANAGER_CODE = 1; 49686862fbSopenharmony_ciconstexpr int32_t UPDATE_CONNECT_STATUS_CODE = 2; 50686862fbSopenharmony_ci} 51686862fbSopenharmony_ci 52686862fbSopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(DistributedAbilityManagerService); 53686862fbSopenharmony_ciconst bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&DistributedAbilityManagerService::GetInstance()); 54686862fbSopenharmony_ci 55686862fbSopenharmony_ciDistributedAbilityManagerService::DistributedAbilityManagerService() : SystemAbility(CONTINUATION_MANAGER_SA_ID, true) 56686862fbSopenharmony_ci{ 57686862fbSopenharmony_ci} 58686862fbSopenharmony_ci 59686862fbSopenharmony_civoid DistributedAbilityManagerService::OnStart() 60686862fbSopenharmony_ci{ 61686862fbSopenharmony_ci HILOGI("begin"); 62686862fbSopenharmony_ci { 63686862fbSopenharmony_ci std::lock_guard<std::mutex> tokenLock(tokenMutex_); 64686862fbSopenharmony_ci std::string tokenStr = system::GetParameter(TOKEN_KEY, DEFAULT_TOKEN_VALUE); 65686862fbSopenharmony_ci if (!tokenStr.empty()) { 66686862fbSopenharmony_ci token_.store(std::atoi(tokenStr.c_str())); 67686862fbSopenharmony_ci } 68686862fbSopenharmony_ci } 69686862fbSopenharmony_ci notifierDeathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new NotifierDeathRecipient()); 70686862fbSopenharmony_ci if (continuationHandler_ == nullptr) { 71686862fbSopenharmony_ci continuationHandler_ = std::make_shared<ffrt::queue>("ContinuationMgr"); 72686862fbSopenharmony_ci } 73686862fbSopenharmony_ci Publish(this); 74686862fbSopenharmony_ci} 75686862fbSopenharmony_ci 76686862fbSopenharmony_civoid DistributedAbilityManagerService::OnStop() 77686862fbSopenharmony_ci{ 78686862fbSopenharmony_ci HILOGI("begin"); 79686862fbSopenharmony_ci} 80686862fbSopenharmony_ci 81686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::Dump(int32_t fd, const std::vector<std::u16string>& args) 82686862fbSopenharmony_ci{ 83686862fbSopenharmony_ci std::vector<std::string> argsInStr8; 84686862fbSopenharmony_ci for (const auto& arg : args) { 85686862fbSopenharmony_ci argsInStr8.emplace_back(Str16ToStr8(arg)); 86686862fbSopenharmony_ci } 87686862fbSopenharmony_ci std::string result; 88686862fbSopenharmony_ci DistributedAbilityManagerDumper::Dump(argsInStr8, result); 89686862fbSopenharmony_ci if (!SaveStringToFd(fd, result)) { 90686862fbSopenharmony_ci HILOGE("save to fd failed"); 91686862fbSopenharmony_ci return DMS_WRITE_FILE_FAILED_ERR; 92686862fbSopenharmony_ci } 93686862fbSopenharmony_ci return ERR_OK; 94686862fbSopenharmony_ci} 95686862fbSopenharmony_ci 96686862fbSopenharmony_civoid DistributedAbilityManagerService::DumpAppRegisterInfo(std::string& info) 97686862fbSopenharmony_ci{ 98686862fbSopenharmony_ci std::lock_guard<std::mutex> autoLock(tokenMapMutex_); 99686862fbSopenharmony_ci info += "application register infos:\n"; 100686862fbSopenharmony_ci info += " "; 101686862fbSopenharmony_ci if (!tokenMap_.empty()) { 102686862fbSopenharmony_ci for (const auto& tokenMap : tokenMap_) { 103686862fbSopenharmony_ci info += "accessToken: "; 104686862fbSopenharmony_ci info += std::to_string(tokenMap.first); 105686862fbSopenharmony_ci std::vector<int32_t> tokenVec = tokenMap.second; 106686862fbSopenharmony_ci DumpNotifierLocked(tokenVec, info); 107686862fbSopenharmony_ci info += "\n"; 108686862fbSopenharmony_ci info += " "; 109686862fbSopenharmony_ci } 110686862fbSopenharmony_ci } else { 111686862fbSopenharmony_ci info += " <none info>\n"; 112686862fbSopenharmony_ci } 113686862fbSopenharmony_ci} 114686862fbSopenharmony_ci 115686862fbSopenharmony_civoid DistributedAbilityManagerService::DumpNotifierLocked(const std::vector<int32_t>& tokenVec, std::string& info) 116686862fbSopenharmony_ci{ 117686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 118686862fbSopenharmony_ci for (const auto& token : tokenVec) { 119686862fbSopenharmony_ci info += ", "; 120686862fbSopenharmony_ci info += "token: "; 121686862fbSopenharmony_ci info += std::to_string(token); 122686862fbSopenharmony_ci if (callbackMap_.find(token) == callbackMap_.end()) { 123686862fbSopenharmony_ci continue; 124686862fbSopenharmony_ci } 125686862fbSopenharmony_ci if (callbackMap_[token] == nullptr) { 126686862fbSopenharmony_ci HILOGE("this ptr is null"); 127686862fbSopenharmony_ci return; 128686862fbSopenharmony_ci } 129686862fbSopenharmony_ci if (!callbackMap_[token]->IsNotifierMapEmpty()) { 130686862fbSopenharmony_ci info += ", "; 131686862fbSopenharmony_ci info += "cbType: "; 132686862fbSopenharmony_ci if (callbackMap_[token]->GetNotifier(EVENT_CONNECT) != nullptr) { 133686862fbSopenharmony_ci info += " "; 134686862fbSopenharmony_ci info += EVENT_CONNECT; 135686862fbSopenharmony_ci } 136686862fbSopenharmony_ci if (callbackMap_[token]->GetNotifier(EVENT_DISCONNECT) != nullptr) { 137686862fbSopenharmony_ci info += " "; 138686862fbSopenharmony_ci info += EVENT_DISCONNECT; 139686862fbSopenharmony_ci } 140686862fbSopenharmony_ci } 141686862fbSopenharmony_ci } 142686862fbSopenharmony_ci} 143686862fbSopenharmony_ci 144686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::Register( 145686862fbSopenharmony_ci const std::shared_ptr<ContinuationExtraParams>& continuationExtraParams, int32_t& token) 146686862fbSopenharmony_ci{ 147686862fbSopenharmony_ci HILOGD("called"); 148686862fbSopenharmony_ci if (continuationExtraParams != nullptr) { 149686862fbSopenharmony_ci ContinuationMode continuationMode = continuationExtraParams->GetContinuationMode(); 150686862fbSopenharmony_ci if (!IsContinuationModeValid(continuationMode)) { 151686862fbSopenharmony_ci return INVALID_CONTINUATION_MODE; 152686862fbSopenharmony_ci } 153686862fbSopenharmony_ci } 154686862fbSopenharmony_ci uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 155686862fbSopenharmony_ci if (IsExceededRegisterMaxNum(accessToken)) { 156686862fbSopenharmony_ci return REGISTER_EXCEED_MAX_TIMES; 157686862fbSopenharmony_ci } 158686862fbSopenharmony_ci int32_t tToken = -1; 159686862fbSopenharmony_ci { 160686862fbSopenharmony_ci std::lock_guard<std::mutex> tokenLock(tokenMutex_); 161686862fbSopenharmony_ci tToken = token_.load(); 162686862fbSopenharmony_ci if (++tToken > MAX_TOKEN_NUM) { 163686862fbSopenharmony_ci tToken = 1; 164686862fbSopenharmony_ci } 165686862fbSopenharmony_ci token_.store(tToken); 166686862fbSopenharmony_ci // save at parameters 167686862fbSopenharmony_ci system::SetParameter(TOKEN_KEY, std::to_string(tToken)); 168686862fbSopenharmony_ci } 169686862fbSopenharmony_ci // update tokenMap_ 170686862fbSopenharmony_ci { 171686862fbSopenharmony_ci std::lock_guard<std::mutex> tokenMapLock(tokenMapMutex_); 172686862fbSopenharmony_ci tokenMap_[accessToken].emplace_back(tToken); 173686862fbSopenharmony_ci } 174686862fbSopenharmony_ci token = tToken; 175686862fbSopenharmony_ci return ERR_OK; 176686862fbSopenharmony_ci} 177686862fbSopenharmony_ci 178686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::Unregister(int32_t token) 179686862fbSopenharmony_ci{ 180686862fbSopenharmony_ci HILOGD("called"); 181686862fbSopenharmony_ci uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 182686862fbSopenharmony_ci if (!IsTokenRegistered(accessToken, token)) { 183686862fbSopenharmony_ci return TOKEN_HAS_NOT_REGISTERED; 184686862fbSopenharmony_ci } 185686862fbSopenharmony_ci // remove death recipient and update callbackMap_ by token 186686862fbSopenharmony_ci { 187686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 188686862fbSopenharmony_ci if (IsNotifierRegistered(token)) { 189686862fbSopenharmony_ci callbackMap_[token]->RemoveDeathRecipient(notifierDeathRecipient_); 190686862fbSopenharmony_ci callbackMap_.erase(token); 191686862fbSopenharmony_ci } 192686862fbSopenharmony_ci } 193686862fbSopenharmony_ci // update tokenMap_ by token 194686862fbSopenharmony_ci { 195686862fbSopenharmony_ci std::lock_guard<std::mutex> tokenMapLock(tokenMapMutex_); 196686862fbSopenharmony_ci for (auto iter = tokenMap_.begin(); iter != tokenMap_.end();) { 197686862fbSopenharmony_ci iter->second.erase(std::remove_if(iter->second.begin(), iter->second.end(), 198686862fbSopenharmony_ci [token](int32_t n) { return n == token; }), iter->second.end()); 199686862fbSopenharmony_ci if (iter->second.empty()) { 200686862fbSopenharmony_ci tokenMap_.erase(iter++); 201686862fbSopenharmony_ci break; 202686862fbSopenharmony_ci } else { 203686862fbSopenharmony_ci iter++; 204686862fbSopenharmony_ci } 205686862fbSopenharmony_ci } 206686862fbSopenharmony_ci } 207686862fbSopenharmony_ci // disconnect to app when third-party app called unregister 208686862fbSopenharmony_ci (void)HandleDisconnectAbility(); 209686862fbSopenharmony_ci return ERR_OK; 210686862fbSopenharmony_ci} 211686862fbSopenharmony_ci 212686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::RegisterDeviceSelectionCallback( 213686862fbSopenharmony_ci int32_t token, const std::string& cbType, const sptr<IRemoteObject>& notifier) 214686862fbSopenharmony_ci{ 215686862fbSopenharmony_ci HILOGD("called"); 216686862fbSopenharmony_ci if (cbType != EVENT_CONNECT && cbType != EVENT_DISCONNECT) { 217686862fbSopenharmony_ci HILOGE("type: %{public}s not support!", cbType.c_str()); 218686862fbSopenharmony_ci return UNKNOWN_CALLBACK_TYPE; 219686862fbSopenharmony_ci } 220686862fbSopenharmony_ci uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 221686862fbSopenharmony_ci if (!IsTokenRegistered(accessToken, token)) { 222686862fbSopenharmony_ci return TOKEN_HAS_NOT_REGISTERED; 223686862fbSopenharmony_ci } 224686862fbSopenharmony_ci if (IsNotifierRegisteredLocked(token, cbType)) { 225686862fbSopenharmony_ci return CALLBACK_HAS_REGISTERED; 226686862fbSopenharmony_ci } 227686862fbSopenharmony_ci { 228686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 229686862fbSopenharmony_ci auto iter = callbackMap_.find(token); 230686862fbSopenharmony_ci if (iter != callbackMap_.end()) { // registered at least once 231686862fbSopenharmony_ci if (iter->second == nullptr) { 232686862fbSopenharmony_ci return ERR_NULL_OBJECT; 233686862fbSopenharmony_ci } 234686862fbSopenharmony_ci iter->second->SetNotifier(cbType, notifier); 235686862fbSopenharmony_ci } else { // never registered 236686862fbSopenharmony_ci std::unique_ptr<NotifierInfo> notifierInfo = std::make_unique<NotifierInfo>(); 237686862fbSopenharmony_ci notifierInfo->SetNotifier(cbType, notifier); 238686862fbSopenharmony_ci callbackMap_[token] = std::move(notifierInfo); 239686862fbSopenharmony_ci notifier->AddDeathRecipient(notifierDeathRecipient_); 240686862fbSopenharmony_ci } 241686862fbSopenharmony_ci HILOGD("token register success"); 242686862fbSopenharmony_ci } 243686862fbSopenharmony_ci return ERR_OK; 244686862fbSopenharmony_ci} 245686862fbSopenharmony_ci 246686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::UnregisterDeviceSelectionCallback(int32_t token, const std::string& cbType) 247686862fbSopenharmony_ci{ 248686862fbSopenharmony_ci HILOGD("called"); 249686862fbSopenharmony_ci if (cbType != EVENT_CONNECT && cbType != EVENT_DISCONNECT) { 250686862fbSopenharmony_ci HILOGE("type: %{public}s not support!", cbType.c_str()); 251686862fbSopenharmony_ci return UNKNOWN_CALLBACK_TYPE; 252686862fbSopenharmony_ci } 253686862fbSopenharmony_ci uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 254686862fbSopenharmony_ci if (!IsTokenRegistered(accessToken, token)) { 255686862fbSopenharmony_ci return TOKEN_HAS_NOT_REGISTERED; 256686862fbSopenharmony_ci } 257686862fbSopenharmony_ci if (!IsNotifierRegisteredLocked(token, cbType)) { 258686862fbSopenharmony_ci return CALLBACK_HAS_NOT_REGISTERED; 259686862fbSopenharmony_ci } 260686862fbSopenharmony_ci { 261686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 262686862fbSopenharmony_ci auto iter = callbackMap_.find(token); 263686862fbSopenharmony_ci if (iter != callbackMap_.end()) { 264686862fbSopenharmony_ci iter->second->RemoveDeathRecipient(notifierDeathRecipient_, cbType); 265686862fbSopenharmony_ci iter->second->DeleteNotifier(cbType); 266686862fbSopenharmony_ci if (iter->second->IsNotifierMapEmpty()) { 267686862fbSopenharmony_ci callbackMap_.erase(iter); 268686862fbSopenharmony_ci } 269686862fbSopenharmony_ci } 270686862fbSopenharmony_ci } 271686862fbSopenharmony_ci HILOGD("token unregister success"); 272686862fbSopenharmony_ci return ERR_OK; 273686862fbSopenharmony_ci} 274686862fbSopenharmony_ci 275686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::UpdateConnectStatus(int32_t token, const std::string& deviceId, 276686862fbSopenharmony_ci const DeviceConnectStatus& deviceConnectStatus) 277686862fbSopenharmony_ci{ 278686862fbSopenharmony_ci HILOGD("called"); 279686862fbSopenharmony_ci if (deviceId.empty()) { 280686862fbSopenharmony_ci HILOGE("deviceId is empty"); 281686862fbSopenharmony_ci return ERR_NULL_OBJECT; 282686862fbSopenharmony_ci } 283686862fbSopenharmony_ci if (!IsConnectStatusValid(deviceConnectStatus)) { 284686862fbSopenharmony_ci return INVALID_CONNECT_STATUS; 285686862fbSopenharmony_ci } 286686862fbSopenharmony_ci uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 287686862fbSopenharmony_ci if (!IsTokenRegistered(accessToken, token)) { 288686862fbSopenharmony_ci return TOKEN_HAS_NOT_REGISTERED; 289686862fbSopenharmony_ci } 290686862fbSopenharmony_ci { 291686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 292686862fbSopenharmony_ci if (!IsNotifierRegistered(token)) { 293686862fbSopenharmony_ci return CALLBACK_HAS_NOT_REGISTERED; 294686862fbSopenharmony_ci } 295686862fbSopenharmony_ci std::shared_ptr<ConnectStatusInfo> connectStatusInfo = 296686862fbSopenharmony_ci std::make_shared<ConnectStatusInfo>(deviceId, deviceConnectStatus); 297686862fbSopenharmony_ci callbackMap_[token]->SetConnectStatusInfo(connectStatusInfo); 298686862fbSopenharmony_ci } 299686862fbSopenharmony_ci // sendRequest status(token, connectStatusInfo) to app by app proxy when appProxy_ is not null. 300686862fbSopenharmony_ci { 301686862fbSopenharmony_ci std::lock_guard<std::mutex> appProxyLock(appProxyMutex_); 302686862fbSopenharmony_ci if (appProxy_ != nullptr) { 303686862fbSopenharmony_ci HandleUpdateConnectStatus(token, deviceId, deviceConnectStatus); 304686862fbSopenharmony_ci } 305686862fbSopenharmony_ci } 306686862fbSopenharmony_ci return ERR_OK; 307686862fbSopenharmony_ci} 308686862fbSopenharmony_ci 309686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::StartDeviceManager( 310686862fbSopenharmony_ci int32_t token, const std::shared_ptr<ContinuationExtraParams>& continuationExtraParams) 311686862fbSopenharmony_ci{ 312686862fbSopenharmony_ci HILOGD("called"); 313686862fbSopenharmony_ci if (continuationExtraParams != nullptr) { 314686862fbSopenharmony_ci ContinuationMode continuationMode = continuationExtraParams->GetContinuationMode(); 315686862fbSopenharmony_ci if (!IsContinuationModeValid(continuationMode)) { 316686862fbSopenharmony_ci return INVALID_CONTINUATION_MODE; 317686862fbSopenharmony_ci } 318686862fbSopenharmony_ci } 319686862fbSopenharmony_ci uint32_t accessToken = IPCSkeleton::GetCallingTokenID(); 320686862fbSopenharmony_ci if (!IsTokenRegistered(accessToken, token)) { 321686862fbSopenharmony_ci return TOKEN_HAS_NOT_REGISTERED; 322686862fbSopenharmony_ci } 323686862fbSopenharmony_ci { 324686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 325686862fbSopenharmony_ci if (!IsNotifierRegistered(token)) { 326686862fbSopenharmony_ci return CALLBACK_HAS_NOT_REGISTERED; 327686862fbSopenharmony_ci } 328686862fbSopenharmony_ci } 329686862fbSopenharmony_ci // 1. connect to app and get the app proxy if appProxy_ is null, otherwise start device manager directly. 330686862fbSopenharmony_ci { 331686862fbSopenharmony_ci std::lock_guard<std::mutex> appProxyLock(appProxyMutex_); 332686862fbSopenharmony_ci if (appProxy_ != nullptr) { 333686862fbSopenharmony_ci HandleStartDeviceManager(token, continuationExtraParams); 334686862fbSopenharmony_ci return ERR_OK; 335686862fbSopenharmony_ci } 336686862fbSopenharmony_ci } 337686862fbSopenharmony_ci int32_t errCode = ConnectAbility(token, continuationExtraParams); 338686862fbSopenharmony_ci if (errCode != ERR_OK) { 339686862fbSopenharmony_ci HILOGE("token connect to app failed"); 340686862fbSopenharmony_ci return CONNECT_ABILITY_FAILED; 341686862fbSopenharmony_ci } 342686862fbSopenharmony_ci // 2. sendRequest data(token, filter, dmsStub, connectStatusInfo) to app by app proxy when connect callback. 343686862fbSopenharmony_ci return ERR_OK; 344686862fbSopenharmony_ci} 345686862fbSopenharmony_ci 346686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::ConnectAbility(int32_t token, 347686862fbSopenharmony_ci const std::shared_ptr<ContinuationExtraParams>& continuationExtraParams) 348686862fbSopenharmony_ci{ 349686862fbSopenharmony_ci AAFwk::Want want; 350686862fbSopenharmony_ci want.SetAction(DMS_HIPLAY_ACTION); 351686862fbSopenharmony_ci int32_t activeAccountId = -1; 352686862fbSopenharmony_ci#ifdef OS_ACCOUNT_PART 353686862fbSopenharmony_ci std::vector<int32_t> ids; 354686862fbSopenharmony_ci int32_t ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids); 355686862fbSopenharmony_ci if (ret != ERR_OK || ids.empty()) { 356686862fbSopenharmony_ci return INVALID_PARAMETERS_ERR; 357686862fbSopenharmony_ci } 358686862fbSopenharmony_ci activeAccountId = ids[0]; 359686862fbSopenharmony_ci#endif 360686862fbSopenharmony_ci AppExecFwk::ExtensionAbilityInfo extensionInfo; 361686862fbSopenharmony_ci if (!QueryExtensionAbilityInfo(activeAccountId, want, extensionInfo)) { 362686862fbSopenharmony_ci HILOGE("QueryExtensionAbilityInfo failed"); 363686862fbSopenharmony_ci return CONNECT_ABILITY_FAILED; 364686862fbSopenharmony_ci } 365686862fbSopenharmony_ci if (connect_ == nullptr) { 366686862fbSopenharmony_ci connect_ = new AppConnectionStub(token, continuationExtraParams); 367686862fbSopenharmony_ci } 368686862fbSopenharmony_ci int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect(); 369686862fbSopenharmony_ci if (errCode != ERR_OK) { 370686862fbSopenharmony_ci HILOGE("connect ability manager server failed, errCode=%{public}d", errCode); 371686862fbSopenharmony_ci return errCode; 372686862fbSopenharmony_ci } 373686862fbSopenharmony_ci errCode = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, 374686862fbSopenharmony_ci iface_cast<AAFwk::IAbilityConnection>(connect_), this, activeAccountId); 375686862fbSopenharmony_ci if (errCode != ERR_OK) { 376686862fbSopenharmony_ci HILOGE("ConnectAbility failed"); 377686862fbSopenharmony_ci connect_ = nullptr; 378686862fbSopenharmony_ci return CONNECT_ABILITY_FAILED; 379686862fbSopenharmony_ci } 380686862fbSopenharmony_ci return ERR_OK; 381686862fbSopenharmony_ci} 382686862fbSopenharmony_ci 383686862fbSopenharmony_cibool DistributedAbilityManagerService::QueryExtensionAbilityInfo(const int32_t& activeAccountId, 384686862fbSopenharmony_ci const AAFwk::Want& want, AppExecFwk::ExtensionAbilityInfo& extensionInfo) 385686862fbSopenharmony_ci{ 386686862fbSopenharmony_ci auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 387686862fbSopenharmony_ci if (samgrProxy == nullptr) { 388686862fbSopenharmony_ci HILOGE("get samgr failed"); 389686862fbSopenharmony_ci return false; 390686862fbSopenharmony_ci } 391686862fbSopenharmony_ci sptr<IRemoteObject> bmsProxy = samgrProxy->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 392686862fbSopenharmony_ci if (bmsProxy == nullptr) { 393686862fbSopenharmony_ci HILOGE("get bms from samgr failed"); 394686862fbSopenharmony_ci return false; 395686862fbSopenharmony_ci } 396686862fbSopenharmony_ci auto bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(bmsProxy); 397686862fbSopenharmony_ci if (bundleMgr == nullptr) { 398686862fbSopenharmony_ci HILOGE("bms iface_cast failed"); 399686862fbSopenharmony_ci return false; 400686862fbSopenharmony_ci } 401686862fbSopenharmony_ci std::vector<AppExecFwk::ExtensionAbilityInfo> extensionInfos; 402686862fbSopenharmony_ci std::string identity = IPCSkeleton::ResetCallingIdentity(); 403686862fbSopenharmony_ci bundleMgr->QueryExtensionAbilityInfos(want, AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT 404686862fbSopenharmony_ci | AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION, activeAccountId, extensionInfos); 405686862fbSopenharmony_ci IPCSkeleton::SetCallingIdentity(identity); 406686862fbSopenharmony_ci if (extensionInfos.empty()) { 407686862fbSopenharmony_ci HILOGE("QueryExtensionAbilityInfo failed"); 408686862fbSopenharmony_ci return false; 409686862fbSopenharmony_ci } 410686862fbSopenharmony_ci extensionInfo = extensionInfos.front(); 411686862fbSopenharmony_ci if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) { 412686862fbSopenharmony_ci HILOGE("ExtensionAbilityInfo is empty."); 413686862fbSopenharmony_ci return false; 414686862fbSopenharmony_ci } 415686862fbSopenharmony_ci HILOGD("ExtensionAbilityInfo found, name=%{public}s.", extensionInfo.name.c_str()); 416686862fbSopenharmony_ci return true; 417686862fbSopenharmony_ci} 418686862fbSopenharmony_ci 419686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::DisconnectAbility() 420686862fbSopenharmony_ci{ 421686862fbSopenharmony_ci if (connect_ == nullptr) { 422686862fbSopenharmony_ci return ERR_NULL_OBJECT; 423686862fbSopenharmony_ci } 424686862fbSopenharmony_ci int32_t errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect(); 425686862fbSopenharmony_ci if (errCode != ERR_OK) { 426686862fbSopenharmony_ci HILOGE("connect ability manager server failed, errCode=%{public}d", errCode); 427686862fbSopenharmony_ci return errCode; 428686862fbSopenharmony_ci } 429686862fbSopenharmony_ci errCode = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility( 430686862fbSopenharmony_ci iface_cast<AAFwk::IAbilityConnection>(connect_)); 431686862fbSopenharmony_ci connect_ = nullptr; 432686862fbSopenharmony_ci if (errCode != ERR_OK) { 433686862fbSopenharmony_ci HILOGE("DisconnectAbility failed"); 434686862fbSopenharmony_ci return DISCONNECT_ABILITY_FAILED; 435686862fbSopenharmony_ci } 436686862fbSopenharmony_ci return ERR_OK; 437686862fbSopenharmony_ci} 438686862fbSopenharmony_ci 439686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::OnDeviceConnect(int32_t token, 440686862fbSopenharmony_ci const std::vector<ContinuationResult>& continuationResults) 441686862fbSopenharmony_ci{ 442686862fbSopenharmony_ci // device connect callback to napi 443686862fbSopenharmony_ci if (!HandleDisconnectAbility()) { 444686862fbSopenharmony_ci return DISCONNECT_ABILITY_FAILED; 445686862fbSopenharmony_ci } 446686862fbSopenharmony_ci if (!IsNotifierRegisteredLocked(token, EVENT_CONNECT)) { 447686862fbSopenharmony_ci return CALLBACK_HAS_NOT_REGISTERED; 448686862fbSopenharmony_ci } 449686862fbSopenharmony_ci { 450686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 451686862fbSopenharmony_ci auto notifier = callbackMap_[token]->GetNotifier(EVENT_CONNECT); 452686862fbSopenharmony_ci if (!HandleDeviceConnect(notifier, continuationResults)) { 453686862fbSopenharmony_ci return INVALID_PARAMETERS_ERR; 454686862fbSopenharmony_ci } 455686862fbSopenharmony_ci } 456686862fbSopenharmony_ci return ERR_OK; 457686862fbSopenharmony_ci} 458686862fbSopenharmony_ci 459686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::OnDeviceDisconnect(int32_t token, 460686862fbSopenharmony_ci const std::vector<ContinuationResult>& continuationResults) 461686862fbSopenharmony_ci{ 462686862fbSopenharmony_ci // device disconnect callback to napi 463686862fbSopenharmony_ci if (!HandleDisconnectAbility()) { 464686862fbSopenharmony_ci return DISCONNECT_ABILITY_FAILED; 465686862fbSopenharmony_ci } 466686862fbSopenharmony_ci if (!IsNotifierRegisteredLocked(token, EVENT_DISCONNECT)) { 467686862fbSopenharmony_ci return CALLBACK_HAS_NOT_REGISTERED; 468686862fbSopenharmony_ci } 469686862fbSopenharmony_ci { 470686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 471686862fbSopenharmony_ci auto notifier = callbackMap_[token]->GetNotifier(EVENT_DISCONNECT); 472686862fbSopenharmony_ci if (!HandleDeviceDisconnect(notifier, continuationResults)) { 473686862fbSopenharmony_ci return INVALID_PARAMETERS_ERR; 474686862fbSopenharmony_ci } 475686862fbSopenharmony_ci } 476686862fbSopenharmony_ci return ERR_OK; 477686862fbSopenharmony_ci} 478686862fbSopenharmony_ci 479686862fbSopenharmony_ciint32_t DistributedAbilityManagerService::OnDeviceCancel() 480686862fbSopenharmony_ci{ 481686862fbSopenharmony_ci // disconnect to app when app close the window. 482686862fbSopenharmony_ci if (!HandleDisconnectAbility()) { 483686862fbSopenharmony_ci return DISCONNECT_ABILITY_FAILED; 484686862fbSopenharmony_ci } 485686862fbSopenharmony_ci return ERR_OK; 486686862fbSopenharmony_ci} 487686862fbSopenharmony_ci 488686862fbSopenharmony_cibool DistributedAbilityManagerService::HandleDisconnectAbility() 489686862fbSopenharmony_ci{ 490686862fbSopenharmony_ci if (continuationHandler_ == nullptr) { 491686862fbSopenharmony_ci HILOGE("continuationHandler is null."); 492686862fbSopenharmony_ci return false; 493686862fbSopenharmony_ci } 494686862fbSopenharmony_ci auto func = [this]() { 495686862fbSopenharmony_ci HILOGD("HandleDisconnectAbility called."); 496686862fbSopenharmony_ci int32_t errCode = DisconnectAbility(); 497686862fbSopenharmony_ci if (errCode != ERR_OK) { 498686862fbSopenharmony_ci HILOGE("DisconnectAbility errCode: %{public}d.", errCode); 499686862fbSopenharmony_ci return; 500686862fbSopenharmony_ci } 501686862fbSopenharmony_ci }; 502686862fbSopenharmony_ci continuationHandler_->submit(func); 503686862fbSopenharmony_ci return true; 504686862fbSopenharmony_ci} 505686862fbSopenharmony_ci 506686862fbSopenharmony_cibool DistributedAbilityManagerService::IsExceededRegisterMaxNum(uint32_t accessToken) 507686862fbSopenharmony_ci{ 508686862fbSopenharmony_ci std::lock_guard<std::mutex> tokenMapLock(tokenMapMutex_); 509686862fbSopenharmony_ci auto iter = tokenMap_.find(accessToken); 510686862fbSopenharmony_ci if (iter != tokenMap_.end() && iter->second.size() >= MAX_REGISTER_NUM) { 511686862fbSopenharmony_ci HILOGE("accessToken registered too much times"); 512686862fbSopenharmony_ci return true; 513686862fbSopenharmony_ci } 514686862fbSopenharmony_ci return false; 515686862fbSopenharmony_ci} 516686862fbSopenharmony_ci 517686862fbSopenharmony_cibool DistributedAbilityManagerService::IsContinuationModeValid(ContinuationMode continuationMode) 518686862fbSopenharmony_ci{ 519686862fbSopenharmony_ci if (static_cast<int32_t>(continuationMode) < static_cast<int32_t>(ContinuationMode::COLLABORATION_SINGLE) || 520686862fbSopenharmony_ci static_cast<int32_t>(continuationMode) > static_cast<int32_t>(ContinuationMode::COLLABORATION_MUTIPLE)) { 521686862fbSopenharmony_ci HILOGE("continuationMode is invalid"); 522686862fbSopenharmony_ci return false; 523686862fbSopenharmony_ci } 524686862fbSopenharmony_ci return true; 525686862fbSopenharmony_ci} 526686862fbSopenharmony_ci 527686862fbSopenharmony_cibool DistributedAbilityManagerService::IsConnectStatusValid(DeviceConnectStatus deviceConnectStatus) 528686862fbSopenharmony_ci{ 529686862fbSopenharmony_ci if (static_cast<int32_t>(deviceConnectStatus) < static_cast<int32_t>(DeviceConnectStatus::IDLE) || 530686862fbSopenharmony_ci static_cast<int32_t>(deviceConnectStatus) > static_cast<int32_t>(DeviceConnectStatus::DISCONNECTING)) { 531686862fbSopenharmony_ci HILOGE("deviceConnectStatus is invalid"); 532686862fbSopenharmony_ci return false; 533686862fbSopenharmony_ci } 534686862fbSopenharmony_ci return true; 535686862fbSopenharmony_ci} 536686862fbSopenharmony_ci 537686862fbSopenharmony_cibool DistributedAbilityManagerService::IsTokenRegistered(uint32_t accessToken, int32_t token) 538686862fbSopenharmony_ci{ 539686862fbSopenharmony_ci std::lock_guard<std::mutex> tokenMapLock(tokenMapMutex_); 540686862fbSopenharmony_ci auto iter = tokenMap_.find(accessToken); 541686862fbSopenharmony_ci if (iter == tokenMap_.end()) { 542686862fbSopenharmony_ci HILOGE("accessToken has not registered in token map."); 543686862fbSopenharmony_ci return false; 544686862fbSopenharmony_ci } 545686862fbSopenharmony_ci for (auto it = iter->second.begin(); it != iter->second.end(); it++) { 546686862fbSopenharmony_ci if (*it == token) { 547686862fbSopenharmony_ci return true; 548686862fbSopenharmony_ci } 549686862fbSopenharmony_ci } 550686862fbSopenharmony_ci HILOGE("token has not registered"); 551686862fbSopenharmony_ci return false; 552686862fbSopenharmony_ci} 553686862fbSopenharmony_ci 554686862fbSopenharmony_cibool DistributedAbilityManagerService::IsNotifierRegistered(int32_t token) 555686862fbSopenharmony_ci{ 556686862fbSopenharmony_ci // must be in callbackMapLock scope 557686862fbSopenharmony_ci auto iter = callbackMap_.find(token); 558686862fbSopenharmony_ci if (iter == callbackMap_.end()) { 559686862fbSopenharmony_ci HILOGE("accessToken has not registered in callback map."); 560686862fbSopenharmony_ci return false; 561686862fbSopenharmony_ci } 562686862fbSopenharmony_ci if (iter->second == nullptr) { 563686862fbSopenharmony_ci HILOGE("notifierInfo is nullptr"); 564686862fbSopenharmony_ci return false; 565686862fbSopenharmony_ci } 566686862fbSopenharmony_ci return true; 567686862fbSopenharmony_ci} 568686862fbSopenharmony_ci 569686862fbSopenharmony_cibool DistributedAbilityManagerService::IsNotifierRegisteredLocked(int32_t token, const std::string& cbType) 570686862fbSopenharmony_ci{ 571686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 572686862fbSopenharmony_ci if (!IsNotifierRegistered(token)) { 573686862fbSopenharmony_ci return false; 574686862fbSopenharmony_ci } 575686862fbSopenharmony_ci if (callbackMap_[token]->GetNotifier(cbType) != nullptr) { 576686862fbSopenharmony_ci HILOGD("token and cbType:%{public}s has already registered", cbType.c_str()); 577686862fbSopenharmony_ci return true; 578686862fbSopenharmony_ci } 579686862fbSopenharmony_ci HILOGE("token and cbType:%{public}s has not registered", cbType.c_str()); 580686862fbSopenharmony_ci return false; 581686862fbSopenharmony_ci} 582686862fbSopenharmony_ci 583686862fbSopenharmony_cibool DistributedAbilityManagerService::HandleDeviceConnect(const sptr<IRemoteObject>& notifier, 584686862fbSopenharmony_ci const std::vector<ContinuationResult>& continuationResults) 585686862fbSopenharmony_ci{ 586686862fbSopenharmony_ci if (continuationHandler_ == nullptr) { 587686862fbSopenharmony_ci HILOGE("continuationHandler_ is nullptr"); 588686862fbSopenharmony_ci return false; 589686862fbSopenharmony_ci } 590686862fbSopenharmony_ci if (notifier == nullptr) { 591686862fbSopenharmony_ci HILOGE("notifier is nullptr"); 592686862fbSopenharmony_ci return false; 593686862fbSopenharmony_ci } 594686862fbSopenharmony_ci auto func = [notifier, continuationResults]() { 595686862fbSopenharmony_ci HILOGD("HandleDeviceConnect called."); 596686862fbSopenharmony_ci auto proxy = std::make_unique<DeviceSelectionNotifierProxy>(notifier); 597686862fbSopenharmony_ci proxy->OnDeviceConnect(continuationResults); 598686862fbSopenharmony_ci }; 599686862fbSopenharmony_ci continuationHandler_->submit(func); 600686862fbSopenharmony_ci return true; 601686862fbSopenharmony_ci} 602686862fbSopenharmony_ci 603686862fbSopenharmony_cibool DistributedAbilityManagerService::HandleDeviceDisconnect(const sptr<IRemoteObject>& notifier, 604686862fbSopenharmony_ci const std::vector<ContinuationResult>& continuationResults) 605686862fbSopenharmony_ci{ 606686862fbSopenharmony_ci if (continuationHandler_ == nullptr) { 607686862fbSopenharmony_ci HILOGE("continuationHandler_ is nullptr"); 608686862fbSopenharmony_ci return false; 609686862fbSopenharmony_ci } 610686862fbSopenharmony_ci if (notifier == nullptr) { 611686862fbSopenharmony_ci HILOGE("notifier is nullptr"); 612686862fbSopenharmony_ci return false; 613686862fbSopenharmony_ci } 614686862fbSopenharmony_ci auto func = [notifier, continuationResults]() { 615686862fbSopenharmony_ci HILOGD("HandleDeviceDisconnect called."); 616686862fbSopenharmony_ci auto proxy = std::make_unique<DeviceSelectionNotifierProxy>(notifier); 617686862fbSopenharmony_ci proxy->OnDeviceDisconnect(continuationResults); 618686862fbSopenharmony_ci }; 619686862fbSopenharmony_ci continuationHandler_->submit(func); 620686862fbSopenharmony_ci return true; 621686862fbSopenharmony_ci} 622686862fbSopenharmony_ci 623686862fbSopenharmony_civoid DistributedAbilityManagerService::ScheduleStartDeviceManager(const sptr<IRemoteObject>& appProxy, int32_t token, 624686862fbSopenharmony_ci const std::shared_ptr<ContinuationExtraParams>& continuationExtraParams) 625686862fbSopenharmony_ci{ 626686862fbSopenharmony_ci std::lock_guard<std::mutex> appProxyLock(appProxyMutex_); 627686862fbSopenharmony_ci appProxy_ = appProxy; 628686862fbSopenharmony_ci if (appProxy_ == nullptr) { 629686862fbSopenharmony_ci return; 630686862fbSopenharmony_ci } 631686862fbSopenharmony_ci HandleStartDeviceManager(token, continuationExtraParams); 632686862fbSopenharmony_ci} 633686862fbSopenharmony_ci 634686862fbSopenharmony_civoid DistributedAbilityManagerService::HandleStartDeviceManager(int32_t token, 635686862fbSopenharmony_ci const std::shared_ptr<ContinuationExtraParams>& continuationExtraParams) 636686862fbSopenharmony_ci{ 637686862fbSopenharmony_ci if (continuationHandler_ == nullptr) { 638686862fbSopenharmony_ci HILOGE("continuationHandler_ is nullptr"); 639686862fbSopenharmony_ci return; 640686862fbSopenharmony_ci } 641686862fbSopenharmony_ci auto func = [this, token, continuationExtraParams, appProxy = appProxy_]() { 642686862fbSopenharmony_ci HILOGD("HandleStartDeviceManager called."); 643686862fbSopenharmony_ci MessageParcel data; 644686862fbSopenharmony_ci if (!data.WriteInterfaceToken(HIPLAY_PANEL_INTERFACE_TOKEN)) { 645686862fbSopenharmony_ci HILOGE("WriteInterfaceToken failed"); 646686862fbSopenharmony_ci return; 647686862fbSopenharmony_ci } 648686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, token); 649686862fbSopenharmony_ci if (continuationExtraParams == nullptr) { 650686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, VALUE_NULL); 651686862fbSopenharmony_ci } else { 652686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, VALUE_OBJECT); 653686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Parcelable, continuationExtraParams.get()); 654686862fbSopenharmony_ci } 655686862fbSopenharmony_ci sptr<AppDeviceCallbackStub> callback(new AppDeviceCallbackStub()); 656686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, RemoteObject, callback); 657686862fbSopenharmony_ci // query whether the connect status needs to be send 658686862fbSopenharmony_ci { 659686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 660686862fbSopenharmony_ci if (IsNotifierRegistered(token)) { 661686862fbSopenharmony_ci std::shared_ptr<ConnectStatusInfo> connectStatusInfo = callbackMap_[token]->GetConnectStatusInfo(); 662686862fbSopenharmony_ci if (connectStatusInfo == nullptr) { 663686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, VALUE_NULL); 664686862fbSopenharmony_ci } else { 665686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, VALUE_OBJECT); 666686862fbSopenharmony_ci // use u16string, because send to app 667686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, String16, Str8ToStr16(connectStatusInfo->GetDeviceId())); 668686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, 669686862fbSopenharmony_ci static_cast<int32_t>(connectStatusInfo->GetDeviceConnectStatus())); 670686862fbSopenharmony_ci } 671686862fbSopenharmony_ci } else { 672686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, VALUE_NULL); 673686862fbSopenharmony_ci } 674686862fbSopenharmony_ci } 675686862fbSopenharmony_ci MessageParcel reply; 676686862fbSopenharmony_ci MessageOption option; 677686862fbSopenharmony_ci if (appProxy == nullptr) { 678686862fbSopenharmony_ci HILOGE("appProxy is nullptr"); 679686862fbSopenharmony_ci return; 680686862fbSopenharmony_ci } 681686862fbSopenharmony_ci int32_t result = appProxy->SendRequest(START_DEVICE_MANAGER_CODE, data, reply, option); 682686862fbSopenharmony_ci HILOGD("result is %{public}d", result); 683686862fbSopenharmony_ci }; 684686862fbSopenharmony_ci continuationHandler_->submit(func); 685686862fbSopenharmony_ci} 686686862fbSopenharmony_ci 687686862fbSopenharmony_civoid DistributedAbilityManagerService::HandleUpdateConnectStatus(int32_t token, std::string deviceId, 688686862fbSopenharmony_ci const DeviceConnectStatus& deviceConnectStatus) 689686862fbSopenharmony_ci{ 690686862fbSopenharmony_ci if (continuationHandler_ == nullptr) { 691686862fbSopenharmony_ci HILOGE("continuationHandler_ is nullptr"); 692686862fbSopenharmony_ci return; 693686862fbSopenharmony_ci } 694686862fbSopenharmony_ci auto func = [this, token, deviceId, deviceConnectStatus, appProxy = appProxy_]() { 695686862fbSopenharmony_ci HILOGD("HandleUpdateConnectStatus called."); 696686862fbSopenharmony_ci MessageParcel data; 697686862fbSopenharmony_ci if (!data.WriteInterfaceToken(HIPLAY_PANEL_INTERFACE_TOKEN)) { 698686862fbSopenharmony_ci HILOGE("WriteInterfaceToken failed"); 699686862fbSopenharmony_ci return; 700686862fbSopenharmony_ci } 701686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, token); 702686862fbSopenharmony_ci // use u16string, because send to app 703686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, String16, Str8ToStr16(deviceId)); 704686862fbSopenharmony_ci PARCEL_WRITE_HELPER_NORET(data, Int32, static_cast<int32_t>(deviceConnectStatus)); 705686862fbSopenharmony_ci MessageParcel reply; 706686862fbSopenharmony_ci MessageOption option; 707686862fbSopenharmony_ci int32_t result = appProxy->SendRequest(UPDATE_CONNECT_STATUS_CODE, data, reply, option); 708686862fbSopenharmony_ci HILOGD("result is %{public}d", result); 709686862fbSopenharmony_ci }; 710686862fbSopenharmony_ci continuationHandler_->submit(func); 711686862fbSopenharmony_ci} 712686862fbSopenharmony_ci 713686862fbSopenharmony_cibool DistributedAbilityManagerService::QueryTokenByNotifier(const sptr<IRemoteObject>& notifier, int32_t& token) 714686862fbSopenharmony_ci{ 715686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 716686862fbSopenharmony_ci for (auto iter = callbackMap_.begin(); iter != callbackMap_.end(); iter++) { 717686862fbSopenharmony_ci if (iter->second == nullptr) { 718686862fbSopenharmony_ci return false; 719686862fbSopenharmony_ci } 720686862fbSopenharmony_ci if (iter->second->QueryNotifier(notifier)) { 721686862fbSopenharmony_ci token = iter->first; 722686862fbSopenharmony_ci return true; 723686862fbSopenharmony_ci } 724686862fbSopenharmony_ci } 725686862fbSopenharmony_ci return false; 726686862fbSopenharmony_ci} 727686862fbSopenharmony_ci 728686862fbSopenharmony_civoid DistributedAbilityManagerService::ProcessNotifierDied(const sptr<IRemoteObject>& notifier) 729686862fbSopenharmony_ci{ 730686862fbSopenharmony_ci // update cache when third-party app died 731686862fbSopenharmony_ci if (notifier == nullptr) { 732686862fbSopenharmony_ci return; 733686862fbSopenharmony_ci } 734686862fbSopenharmony_ci HandleNotifierDied(notifier); 735686862fbSopenharmony_ci} 736686862fbSopenharmony_ci 737686862fbSopenharmony_civoid DistributedAbilityManagerService::HandleNotifierDied(const sptr<IRemoteObject>& notifier) 738686862fbSopenharmony_ci{ 739686862fbSopenharmony_ci if (continuationHandler_ == nullptr) { 740686862fbSopenharmony_ci HILOGE("continuationHandler_ is nullptr"); 741686862fbSopenharmony_ci return; 742686862fbSopenharmony_ci } 743686862fbSopenharmony_ci auto func = [this, notifier] () { 744686862fbSopenharmony_ci HILOGD("HandleNotifierDied called."); 745686862fbSopenharmony_ci // query token in callbackMap_ by notifier 746686862fbSopenharmony_ci int32_t token = -1; 747686862fbSopenharmony_ci if (!QueryTokenByNotifier(notifier, token)) { 748686862fbSopenharmony_ci HILOGE("QueryTokenByNotifier failed"); 749686862fbSopenharmony_ci return; 750686862fbSopenharmony_ci } 751686862fbSopenharmony_ci // remove death recipient and update callbackMap_ by token 752686862fbSopenharmony_ci { 753686862fbSopenharmony_ci std::lock_guard<std::mutex> callbackMapLock(callbackMapMutex_); 754686862fbSopenharmony_ci if (IsNotifierRegistered(token)) { 755686862fbSopenharmony_ci callbackMap_[token]->RemoveDeathRecipient(notifierDeathRecipient_); 756686862fbSopenharmony_ci callbackMap_.erase(token); 757686862fbSopenharmony_ci } 758686862fbSopenharmony_ci } 759686862fbSopenharmony_ci // update tokenMap_ by token 760686862fbSopenharmony_ci { 761686862fbSopenharmony_ci std::lock_guard<std::mutex> tokenMapLock(tokenMapMutex_); 762686862fbSopenharmony_ci for (auto iter = tokenMap_.begin(); iter != tokenMap_.end();) { 763686862fbSopenharmony_ci iter->second.erase(std::remove_if(iter->second.begin(), iter->second.end(), 764686862fbSopenharmony_ci [token](int32_t n) { return n == token; }), iter->second.end()); 765686862fbSopenharmony_ci if (iter->second.empty()) { 766686862fbSopenharmony_ci tokenMap_.erase(iter++); 767686862fbSopenharmony_ci break; 768686862fbSopenharmony_ci } else { 769686862fbSopenharmony_ci iter++; 770686862fbSopenharmony_ci } 771686862fbSopenharmony_ci } 772686862fbSopenharmony_ci } 773686862fbSopenharmony_ci // disconnect to app when third-party app died 774686862fbSopenharmony_ci (void)HandleDisconnectAbility(); 775686862fbSopenharmony_ci }; 776686862fbSopenharmony_ci continuationHandler_->submit(func); 777686862fbSopenharmony_ci} 778686862fbSopenharmony_ci} // namespace DistributedSchedule 779686862fbSopenharmony_ci} // namespace OHOS