12dc7c57fSopenharmony_ci/*
22dc7c57fSopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
32dc7c57fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42dc7c57fSopenharmony_ci * you may not use this file except in compliance with the License.
52dc7c57fSopenharmony_ci * You may obtain a copy of the License at
62dc7c57fSopenharmony_ci *
72dc7c57fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
82dc7c57fSopenharmony_ci *
92dc7c57fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102dc7c57fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112dc7c57fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122dc7c57fSopenharmony_ci * See the License for the specific language governing permissions and
132dc7c57fSopenharmony_ci * limitations under the License.
142dc7c57fSopenharmony_ci */
152dc7c57fSopenharmony_ci
162dc7c57fSopenharmony_ci#include "ability_manager_helper.h"
172dc7c57fSopenharmony_ci
182dc7c57fSopenharmony_ci#include "event_log_wrapper.h"
192dc7c57fSopenharmony_ci#include "hitrace_meter_adapter.h"
202dc7c57fSopenharmony_ci#include "in_process_call_wrapper.h"
212dc7c57fSopenharmony_ci#include "iservice_registry.h"
222dc7c57fSopenharmony_ci#include "static_subscriber_connection.h"
232dc7c57fSopenharmony_ci#include "system_ability_definition.h"
242dc7c57fSopenharmony_ci
252dc7c57fSopenharmony_cinamespace OHOS {
262dc7c57fSopenharmony_cinamespace EventFwk {
272dc7c57fSopenharmony_cinamespace {
282dc7c57fSopenharmony_ciconstexpr int32_t DISCONNECT_DELAY_TIME = 15000; // ms
292dc7c57fSopenharmony_ciconstexpr int32_t TIME_UNIT_SIZE = 1000;
302dc7c57fSopenharmony_ci}
312dc7c57fSopenharmony_ci
322dc7c57fSopenharmony_ciint AbilityManagerHelper::ConnectAbility(
332dc7c57fSopenharmony_ci    const Want &want, const CommonEventData &event, const sptr<IRemoteObject> &callerToken, const int32_t &userId)
342dc7c57fSopenharmony_ci{
352dc7c57fSopenharmony_ci    HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
362dc7c57fSopenharmony_ci    EVENT_LOGI("enter, target bundle = %{public}s", want.GetBundle().c_str());
372dc7c57fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
382dc7c57fSopenharmony_ci
392dc7c57fSopenharmony_ci    if (!GetAbilityMgrProxy()) {
402dc7c57fSopenharmony_ci        EVENT_LOGE("failed to get ability manager proxy!");
412dc7c57fSopenharmony_ci        return -1;
422dc7c57fSopenharmony_ci    }
432dc7c57fSopenharmony_ci
442dc7c57fSopenharmony_ci    sptr<StaticSubscriberConnection> connection = new (std::nothrow) StaticSubscriberConnection(event);
452dc7c57fSopenharmony_ci    if (connection == nullptr) {
462dc7c57fSopenharmony_ci        EVENT_LOGE("failed to create obj!");
472dc7c57fSopenharmony_ci        return -1;
482dc7c57fSopenharmony_ci    }
492dc7c57fSopenharmony_ci    int32_t result = abilityMgr_->ConnectAbility(want, connection, callerToken, userId);
502dc7c57fSopenharmony_ci    if (result == ERR_OK) {
512dc7c57fSopenharmony_ci        subscriberConnection_.emplace(connection);
522dc7c57fSopenharmony_ci    }
532dc7c57fSopenharmony_ci    return result;
542dc7c57fSopenharmony_ci}
552dc7c57fSopenharmony_ci
562dc7c57fSopenharmony_cibool AbilityManagerHelper::GetAbilityMgrProxy()
572dc7c57fSopenharmony_ci{
582dc7c57fSopenharmony_ci    EVENT_LOGI_LIMIT("GetAbilityMgrProxy enter");
592dc7c57fSopenharmony_ci    if (abilityMgr_ == nullptr) {
602dc7c57fSopenharmony_ci        sptr<ISystemAbilityManager> systemAbilityManager =
612dc7c57fSopenharmony_ci            SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
622dc7c57fSopenharmony_ci        if (systemAbilityManager == nullptr) {
632dc7c57fSopenharmony_ci            EVENT_LOGE("Failed to get system ability mgr.");
642dc7c57fSopenharmony_ci            return false;
652dc7c57fSopenharmony_ci        }
662dc7c57fSopenharmony_ci
672dc7c57fSopenharmony_ci        sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
682dc7c57fSopenharmony_ci        if (remoteObject == nullptr) {
692dc7c57fSopenharmony_ci            EVENT_LOGE("Failed to get ability manager service.");
702dc7c57fSopenharmony_ci            return false;
712dc7c57fSopenharmony_ci        }
722dc7c57fSopenharmony_ci
732dc7c57fSopenharmony_ci        abilityMgr_ = iface_cast<AAFwk::IAbilityManager>(remoteObject);
742dc7c57fSopenharmony_ci        if ((abilityMgr_ == nullptr) || (abilityMgr_->AsObject() == nullptr)) {
752dc7c57fSopenharmony_ci            EVENT_LOGE("Failed to get system ability manager services ability");
762dc7c57fSopenharmony_ci            return false;
772dc7c57fSopenharmony_ci        }
782dc7c57fSopenharmony_ci
792dc7c57fSopenharmony_ci        deathRecipient_ = new (std::nothrow) AbilityManagerDeathRecipient();
802dc7c57fSopenharmony_ci        if (deathRecipient_ == nullptr) {
812dc7c57fSopenharmony_ci            EVENT_LOGE("Failed to create AbilityManagerDeathRecipient");
822dc7c57fSopenharmony_ci            return false;
832dc7c57fSopenharmony_ci        }
842dc7c57fSopenharmony_ci        if (!abilityMgr_->AsObject()->AddDeathRecipient(deathRecipient_)) {
852dc7c57fSopenharmony_ci            EVENT_LOGW("Failed to add AbilityManagerDeathRecipient");
862dc7c57fSopenharmony_ci        }
872dc7c57fSopenharmony_ci    }
882dc7c57fSopenharmony_ci
892dc7c57fSopenharmony_ci    return true;
902dc7c57fSopenharmony_ci}
912dc7c57fSopenharmony_ci
922dc7c57fSopenharmony_civoid AbilityManagerHelper::Clear()
932dc7c57fSopenharmony_ci{
942dc7c57fSopenharmony_ci    EVENT_LOGI("enter");
952dc7c57fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
962dc7c57fSopenharmony_ci
972dc7c57fSopenharmony_ci    if ((abilityMgr_ != nullptr) && (abilityMgr_->AsObject() != nullptr)) {
982dc7c57fSopenharmony_ci        abilityMgr_->AsObject()->RemoveDeathRecipient(deathRecipient_);
992dc7c57fSopenharmony_ci    }
1002dc7c57fSopenharmony_ci    abilityMgr_ = nullptr;
1012dc7c57fSopenharmony_ci}
1022dc7c57fSopenharmony_ci
1032dc7c57fSopenharmony_civoid AbilityManagerHelper::DisconnectServiceAbilityDelay(const sptr<StaticSubscriberConnection> &connection)
1042dc7c57fSopenharmony_ci{
1052dc7c57fSopenharmony_ci    EVENT_LOGD("enter");
1062dc7c57fSopenharmony_ci    if (connection == nullptr) {
1072dc7c57fSopenharmony_ci        EVENT_LOGE("connection is nullptr");
1082dc7c57fSopenharmony_ci        return;
1092dc7c57fSopenharmony_ci    }
1102dc7c57fSopenharmony_ci
1112dc7c57fSopenharmony_ci    if (!ffrt_) {
1122dc7c57fSopenharmony_ci        EVENT_LOGD("ready to create ffrt");
1132dc7c57fSopenharmony_ci        ffrt_ = std::make_shared<ffrt::queue>("AbilityManagerHelper");
1142dc7c57fSopenharmony_ci    }
1152dc7c57fSopenharmony_ci
1162dc7c57fSopenharmony_ci    std::function<void()> task = [connection]() {
1172dc7c57fSopenharmony_ci        AbilityManagerHelper::GetInstance()->DisconnectAbility(connection);
1182dc7c57fSopenharmony_ci    };
1192dc7c57fSopenharmony_ci    ffrt_->submit(task, ffrt::task_attr().delay(DISCONNECT_DELAY_TIME * TIME_UNIT_SIZE));
1202dc7c57fSopenharmony_ci}
1212dc7c57fSopenharmony_ci
1222dc7c57fSopenharmony_civoid AbilityManagerHelper::DisconnectAbility(const sptr<StaticSubscriberConnection> &connection)
1232dc7c57fSopenharmony_ci{
1242dc7c57fSopenharmony_ci    EVENT_LOGD("enter");
1252dc7c57fSopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
1262dc7c57fSopenharmony_ci    if (connection == nullptr) {
1272dc7c57fSopenharmony_ci        EVENT_LOGE("connection is nullptr");
1282dc7c57fSopenharmony_ci        return;
1292dc7c57fSopenharmony_ci    }
1302dc7c57fSopenharmony_ci
1312dc7c57fSopenharmony_ci    if (subscriberConnection_.find(connection) == subscriberConnection_.end()) {
1322dc7c57fSopenharmony_ci        EVENT_LOGE("failed to find connection!");
1332dc7c57fSopenharmony_ci        return;
1342dc7c57fSopenharmony_ci    }
1352dc7c57fSopenharmony_ci
1362dc7c57fSopenharmony_ci    if (!GetAbilityMgrProxy()) {
1372dc7c57fSopenharmony_ci        EVENT_LOGE("failed to get ability manager proxy!");
1382dc7c57fSopenharmony_ci        return;
1392dc7c57fSopenharmony_ci    }
1402dc7c57fSopenharmony_ci    IN_PROCESS_CALL_WITHOUT_RET(abilityMgr_->DisconnectAbility(connection));
1412dc7c57fSopenharmony_ci    subscriberConnection_.erase(connection);
1422dc7c57fSopenharmony_ci}
1432dc7c57fSopenharmony_ci}  // namespace EventFwk
1442dc7c57fSopenharmony_ci}  // namespace OHOS
145