180922886Sopenharmony_ci/*
280922886Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
380922886Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
480922886Sopenharmony_ci * you may not use this file except in compliance with the License.
580922886Sopenharmony_ci * You may obtain a copy of the License at
680922886Sopenharmony_ci *
780922886Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
880922886Sopenharmony_ci *
980922886Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1080922886Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1180922886Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1280922886Sopenharmony_ci * See the License for the specific language governing permissions and
1380922886Sopenharmony_ci * limitations under the License.
1480922886Sopenharmony_ci */
1580922886Sopenharmony_ci
1680922886Sopenharmony_ci#include "ability_connect_helper.h"
1780922886Sopenharmony_ci
1880922886Sopenharmony_ci#include "ability_manager_interface.h"
1980922886Sopenharmony_ci#include "ability_manager_client.h"
2080922886Sopenharmony_ci#include "avsession_errors.h"
2180922886Sopenharmony_ci#include "avsession_log.h"
2280922886Sopenharmony_ci#include "iservice_registry.h"
2380922886Sopenharmony_ci#include "ipc_skeleton.h"
2480922886Sopenharmony_ci#include "message_parcel.h"
2580922886Sopenharmony_ci#include "system_ability_definition.h"
2680922886Sopenharmony_ci
2780922886Sopenharmony_cinamespace OHOS::AVSession {
2880922886Sopenharmony_ciAbilityConnectHelper& AbilityConnectHelper::GetInstance()
2980922886Sopenharmony_ci{
3080922886Sopenharmony_ci    static AbilityConnectHelper abilityConnectHelper;
3180922886Sopenharmony_ci    return abilityConnectHelper;
3280922886Sopenharmony_ci}
3380922886Sopenharmony_ci
3480922886Sopenharmony_ciint32_t AbilityConnectHelper::StartAbilityForegroundByCall(const std::string& bundleName,
3580922886Sopenharmony_ci    const std::string& abilityName)
3680922886Sopenharmony_ci{
3780922886Sopenharmony_ci    SLOGI("StartAbilityForegroundByCall bundleName=%{public}s abilityName=%{public}s",
3880922886Sopenharmony_ci        bundleName.c_str(), abilityName.c_str());
3980922886Sopenharmony_ci    MessageParcel data;
4080922886Sopenharmony_ci    MessageParcel reply;
4180922886Sopenharmony_ci    MessageOption option;
4280922886Sopenharmony_ci    if (!data.WriteInterfaceToken(ABILITY_MANAGER_INTERFACE_TOKEN)) {
4380922886Sopenharmony_ci        SLOGE("write interface token failed");
4480922886Sopenharmony_ci        return ERR_MARSHALLING;
4580922886Sopenharmony_ci    }
4680922886Sopenharmony_ci    AAFwk::Want want;
4780922886Sopenharmony_ci    AppExecFwk::ElementName element("", bundleName, abilityName);
4880922886Sopenharmony_ci    want.SetElement(element);
4980922886Sopenharmony_ci    want.SetParam("ohos.aafwk.param.callAbilityToForeground", true);
5080922886Sopenharmony_ci
5180922886Sopenharmony_ci    if (!data.WriteParcelable(&want)) {
5280922886Sopenharmony_ci        SLOGE("want write failed");
5380922886Sopenharmony_ci        return ERR_INVALID_PARAM;
5480922886Sopenharmony_ci    }
5580922886Sopenharmony_ci    sptr<AAFwk::IAbilityConnection> connect = new(std::nothrow) AbilityConnectCallback();
5680922886Sopenharmony_ci    if (connect == nullptr) {
5780922886Sopenharmony_ci        SLOGE("connect is nullptr");
5880922886Sopenharmony_ci        return ERR_NO_MEMORY;
5980922886Sopenharmony_ci    }
6080922886Sopenharmony_ci    if (!data.WriteRemoteObject(connect->AsObject())) {
6180922886Sopenharmony_ci        SLOGE("resolve write failed");
6280922886Sopenharmony_ci        return ERR_MARSHALLING;
6380922886Sopenharmony_ci    }
6480922886Sopenharmony_ci    if (!data.WriteBool(false)) {
6580922886Sopenharmony_ci        SLOGE("Failed to write flag");
6680922886Sopenharmony_ci        return ERR_MARSHALLING;
6780922886Sopenharmony_ci    }
6880922886Sopenharmony_ci    if (!data.WriteInt32(-1)) { // -1 is default connect id of ability manager
6980922886Sopenharmony_ci        SLOGE("Failed to write connect id");
7080922886Sopenharmony_ci        return ERR_MARSHALLING;
7180922886Sopenharmony_ci    }
7280922886Sopenharmony_ci
7380922886Sopenharmony_ci    sptr<IRemoteObject> remote = GetSystemAbility();
7480922886Sopenharmony_ci    if (remote == nullptr) {
7580922886Sopenharmony_ci        return ERR_SERVICE_NOT_EXIST;
7680922886Sopenharmony_ci    }
7780922886Sopenharmony_ci    if (remote->SendRequest(static_cast<uint32_t>(AAFwk::AbilityManagerInterfaceCode::START_CALL_ABILITY),
7880922886Sopenharmony_ci        data, reply, option) != 0) {
7980922886Sopenharmony_ci        SLOGE("Send request error");
8080922886Sopenharmony_ci        return ERR_IPC_SEND_REQUEST;
8180922886Sopenharmony_ci    }
8280922886Sopenharmony_ci    return reply.ReadInt32() == ERR_OK ? AVSESSION_SUCCESS : ERR_ABILITY_NOT_AVAILABLE;
8380922886Sopenharmony_ci}
8480922886Sopenharmony_ci
8580922886Sopenharmony_ciint32_t AbilityConnectHelper::StartAbilityByCall(const std::string& bundleName, const std::string& abilityName)
8680922886Sopenharmony_ci{
8780922886Sopenharmony_ci    SLOGI("bundleName=%{public}s abilityName=%{public}s", bundleName.c_str(), abilityName.c_str());
8880922886Sopenharmony_ci    MessageParcel data;
8980922886Sopenharmony_ci    MessageParcel reply;
9080922886Sopenharmony_ci    MessageOption option;
9180922886Sopenharmony_ci    if (!data.WriteInterfaceToken(ABILITY_MANAGER_INTERFACE_TOKEN)) {
9280922886Sopenharmony_ci        SLOGE("write interface token failed");
9380922886Sopenharmony_ci        return ERR_MARSHALLING;
9480922886Sopenharmony_ci    }
9580922886Sopenharmony_ci
9680922886Sopenharmony_ci    AAFwk::Want want;
9780922886Sopenharmony_ci    AppExecFwk::ElementName element("", bundleName, abilityName);
9880922886Sopenharmony_ci    want.SetElement(element);
9980922886Sopenharmony_ci    if (!data.WriteParcelable(&want)) {
10080922886Sopenharmony_ci        SLOGE("want write failed");
10180922886Sopenharmony_ci        return ERR_INVALID_PARAM;
10280922886Sopenharmony_ci    }
10380922886Sopenharmony_ci
10480922886Sopenharmony_ci    sptr<AAFwk::IAbilityConnection> connect = new(std::nothrow) AbilityConnectCallback();
10580922886Sopenharmony_ci    if (connect == nullptr) {
10680922886Sopenharmony_ci        SLOGE("connect is nullptr");
10780922886Sopenharmony_ci        return ERR_NO_MEMORY;
10880922886Sopenharmony_ci    }
10980922886Sopenharmony_ci    if (!data.WriteRemoteObject(connect->AsObject())) {
11080922886Sopenharmony_ci        SLOGE("resolve write failed");
11180922886Sopenharmony_ci        return ERR_MARSHALLING;
11280922886Sopenharmony_ci    }
11380922886Sopenharmony_ci    if (!data.WriteBool(false)) {
11480922886Sopenharmony_ci        SLOGE("Failed to write flag");
11580922886Sopenharmony_ci        return ERR_MARSHALLING;
11680922886Sopenharmony_ci    }
11780922886Sopenharmony_ci    if (!data.WriteInt32(-1)) { // -1 is default connect id of ability manager
11880922886Sopenharmony_ci        SLOGE("Failed to write connect id");
11980922886Sopenharmony_ci        return ERR_MARSHALLING;
12080922886Sopenharmony_ci    }
12180922886Sopenharmony_ci
12280922886Sopenharmony_ci    sptr<IRemoteObject> remote = GetSystemAbility();
12380922886Sopenharmony_ci    if (remote == nullptr) {
12480922886Sopenharmony_ci        return ERR_SERVICE_NOT_EXIST;
12580922886Sopenharmony_ci    }
12680922886Sopenharmony_ci    if (remote->SendRequest(static_cast<uint32_t>(AAFwk::AbilityManagerInterfaceCode::START_CALL_ABILITY),
12780922886Sopenharmony_ci        data, reply, option) != 0) {
12880922886Sopenharmony_ci        SLOGE("Send request error");
12980922886Sopenharmony_ci        return ERR_IPC_SEND_REQUEST;
13080922886Sopenharmony_ci    }
13180922886Sopenharmony_ci    return reply.ReadInt32() == ERR_OK ? AVSESSION_SUCCESS : ERR_ABILITY_NOT_AVAILABLE;
13280922886Sopenharmony_ci}
13380922886Sopenharmony_ci
13480922886Sopenharmony_cisptr<IRemoteObject> AbilityConnectHelper::GetSystemAbility()
13580922886Sopenharmony_ci{
13680922886Sopenharmony_ci    sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
13780922886Sopenharmony_ci    if (systemManager == nullptr) {
13880922886Sopenharmony_ci        SLOGE("Fail to get registry");
13980922886Sopenharmony_ci        return nullptr;
14080922886Sopenharmony_ci    }
14180922886Sopenharmony_ci    sptr<IRemoteObject> remote = systemManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
14280922886Sopenharmony_ci    if (remote == nullptr) {
14380922886Sopenharmony_ci        SLOGE("Fail to connect ability manager service");
14480922886Sopenharmony_ci        return nullptr;
14580922886Sopenharmony_ci    }
14680922886Sopenharmony_ci    SLOGI("Connect ability manager service success");
14780922886Sopenharmony_ci    return remote;
14880922886Sopenharmony_ci}
14980922886Sopenharmony_ci
15080922886Sopenharmony_ciAbilityConnectionStub::AbilityConnectionStub()
15180922886Sopenharmony_ci{}
15280922886Sopenharmony_ci
15380922886Sopenharmony_ciAbilityConnectionStub::~AbilityConnectionStub()
15480922886Sopenharmony_ci{}
15580922886Sopenharmony_ci
15680922886Sopenharmony_ciint AbilityConnectionStub::OnRemoteRequest(
15780922886Sopenharmony_ci    uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
15880922886Sopenharmony_ci{
15980922886Sopenharmony_ci    auto descriptor = AbilityConnectionStub::GetDescriptor();
16080922886Sopenharmony_ci    auto remoteDescriptor = data.ReadInterfaceToken();
16180922886Sopenharmony_ci    if (descriptor != remoteDescriptor) {
16280922886Sopenharmony_ci        SLOGE("Local descriptor is not equal to remote");
16380922886Sopenharmony_ci        return AVSESSION_ERROR;
16480922886Sopenharmony_ci    }
16580922886Sopenharmony_ci
16680922886Sopenharmony_ci    auto element = data.ReadParcelable<AppExecFwk::ElementName>();
16780922886Sopenharmony_ci    if (element == nullptr) {
16880922886Sopenharmony_ci        SLOGE("callback stub receive element is nullptr");
16980922886Sopenharmony_ci        return AVSESSION_ERROR;
17080922886Sopenharmony_ci    }
17180922886Sopenharmony_ci    if (code == AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE) {
17280922886Sopenharmony_ci        auto remoteObject = data.ReadRemoteObject();
17380922886Sopenharmony_ci        if (remoteObject == nullptr) {
17480922886Sopenharmony_ci            SLOGE("callback stub receive remoteObject is nullptr");
17580922886Sopenharmony_ci            delete element;
17680922886Sopenharmony_ci            element = nullptr;
17780922886Sopenharmony_ci            return AVSESSION_ERROR;
17880922886Sopenharmony_ci        }
17980922886Sopenharmony_ci        auto resultCode = data.ReadInt32();
18080922886Sopenharmony_ci        OnAbilityConnectDone(*element, remoteObject, resultCode);
18180922886Sopenharmony_ci        delete element;
18280922886Sopenharmony_ci        element = nullptr;
18380922886Sopenharmony_ci        return ERR_NONE;
18480922886Sopenharmony_ci    }
18580922886Sopenharmony_ci    if (code == AAFwk::IAbilityConnection::ON_ABILITY_DISCONNECT_DONE) {
18680922886Sopenharmony_ci        auto resultCode = data.ReadInt32();
18780922886Sopenharmony_ci        OnAbilityDisconnectDone(*element, resultCode);
18880922886Sopenharmony_ci        delete element;
18980922886Sopenharmony_ci        element = nullptr;
19080922886Sopenharmony_ci        return ERR_NONE;
19180922886Sopenharmony_ci    }
19280922886Sopenharmony_ci    delete element;
19380922886Sopenharmony_ci    element = nullptr;
19480922886Sopenharmony_ci    return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
19580922886Sopenharmony_ci}
19680922886Sopenharmony_ci
19780922886Sopenharmony_ciAbilityConnectCallback::~AbilityConnectCallback()
19880922886Sopenharmony_ci{}
19980922886Sopenharmony_ci
20080922886Sopenharmony_civoid AbilityConnectCallback::OnAbilityConnectDone(const AppExecFwk::ElementName& element,
20180922886Sopenharmony_ci    const sptr<IRemoteObject>& __attribute__((unused)) remoteObject, int resultCode)
20280922886Sopenharmony_ci{
20380922886Sopenharmony_ci    SLOGI("OnAbilityConnectDone callback, retcode:%{public}d, bundlename:%{public}s, abilityname:%{public}s",
20480922886Sopenharmony_ci        resultCode, element.GetBundleName().c_str(), element.GetAbilityName().c_str());
20580922886Sopenharmony_ci}
20680922886Sopenharmony_ci
20780922886Sopenharmony_civoid AbilityConnectCallback::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode)
20880922886Sopenharmony_ci{
20980922886Sopenharmony_ci    SLOGI("OnAbilityDisConnectDone callback, retcode:%{public}d, bundlename:%{public}s, abilityname:%{public}s",
21080922886Sopenharmony_ci        resultCode, element.GetBundleName().c_str(), element.GetAbilityName().c_str());
21180922886Sopenharmony_ci}
21280922886Sopenharmony_ci} // namespace OHOS::AVSession