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