From 13a1a5f0b677aee5f404fbddbdab12cf2637be63 Mon Sep 17 00:00:00 2001 From: Gymee Date: Fri, 10 Sep 2021 10:36:40 +0800 Subject: [PATCH] add connect ability Signed-off-by: Gymee Change-Id: I301b305fd200cf3c37112f190aba35f482f8800e --- services/dtbschedmgr/BUILD.gn | 4 + .../ability_connection_wrapper_proxy.h | 41 ++ .../include/ability_connection_wrapper_stub.h | 45 ++ .../include/connect_death_recipient.h | 32 + .../include/distributed_sched_adapter.h | 7 +- .../include/distributed_sched_dumper.h | 40 ++ .../include/distributed_sched_interface.h | 9 + .../include/distributed_sched_proxy.h | 8 + .../include/distributed_sched_service.h | 91 ++- .../include/distributed_sched_stub.h | 6 + .../src/ability_connection_wrapper_proxy.cpp | 60 ++ .../src/ability_connection_wrapper_stub.cpp | 83 +++ .../src/connect_death_recipient.cpp | 30 + .../src/distributed_sched_adapter.cpp | 54 ++ .../src/distributed_sched_dumper.cpp | 95 +++ .../src/distributed_sched_proxy.cpp | 119 ++++ .../src/distributed_sched_service.cpp | 590 +++++++++++++++++- .../src/distributed_sched_stub.cpp | 120 +++- .../src/dtbschedmgr_device_info_storage.cpp | 2 +- services/dtbschedmgr/test/BUILD.gn | 151 +++-- .../distributed_sched_connect_test.cpp | 80 +++ 21 files changed, 1599 insertions(+), 68 deletions(-) create mode 100755 services/dtbschedmgr/include/ability_connection_wrapper_proxy.h create mode 100755 services/dtbschedmgr/include/ability_connection_wrapper_stub.h create mode 100755 services/dtbschedmgr/include/connect_death_recipient.h create mode 100755 services/dtbschedmgr/include/distributed_sched_dumper.h create mode 100755 services/dtbschedmgr/src/ability_connection_wrapper_proxy.cpp create mode 100755 services/dtbschedmgr/src/ability_connection_wrapper_stub.cpp create mode 100755 services/dtbschedmgr/src/connect_death_recipient.cpp create mode 100755 services/dtbschedmgr/src/distributed_sched_dumper.cpp create mode 100755 services/dtbschedmgr/test/unittest/distributed_sched_connect_test.cpp diff --git a/services/dtbschedmgr/BUILD.gn b/services/dtbschedmgr/BUILD.gn index 0a554343..cbee6e47 100644 --- a/services/dtbschedmgr/BUILD.gn +++ b/services/dtbschedmgr/BUILD.gn @@ -29,14 +29,18 @@ config("distributed_sched_config") { ohos_shared_library("distributedschedsvr") { install_enable = true sources = [ + "src/ability_connection_wrapper_proxy.cpp", + "src/ability_connection_wrapper_stub.cpp", "src/adapter/dnetwork_adapter.cpp", "src/bundle/bundle_manager_internal.cpp", + "src/connect_death_recipient.cpp", "src/continuation_callback_death_recipient.cpp", "src/deviceManager/dms_device_info.cpp", "src/distributed_device_node_listener.cpp", "src/distributed_sched_ability_shell.cpp", "src/distributed_sched_adapter.cpp", "src/distributed_sched_continuation.cpp", + "src/distributed_sched_dumper.cpp", "src/distributed_sched_permission.cpp", "src/distributed_sched_proxy.cpp", "src/distributed_sched_service.cpp", diff --git a/services/dtbschedmgr/include/ability_connection_wrapper_proxy.h b/services/dtbschedmgr/include/ability_connection_wrapper_proxy.h new file mode 100755 index 00000000..75c27985 --- /dev/null +++ b/services/dtbschedmgr/include/ability_connection_wrapper_proxy.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_ABILITY_CONNECTION_WRAPPER_PROXY_H +#define OHOS_DISTRIBUTED_ABILITY_CONNECTION_WRAPPER_PROXY_H + +#include "ability_connect_callback_interface.h" + +#include "iremote_object.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace DistributedSchedule { +class AbilityConnectionWrapperProxy : public IRemoteProxy { +public: + explicit AbilityConnectionWrapperProxy(const sptr& impl) + : IRemoteProxy(impl) {} + virtual ~AbilityConnectionWrapperProxy() = default; + + void OnAbilityConnectDone(const AppExecFwk::ElementName& element, const sptr& remoteObject, + int32_t resultCode) override; + void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int32_t resultCode) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DistributedSchedule +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_ABILITY_CONNECTION_WRAPPER_PROXY_H \ No newline at end of file diff --git a/services/dtbschedmgr/include/ability_connection_wrapper_stub.h b/services/dtbschedmgr/include/ability_connection_wrapper_stub.h new file mode 100755 index 00000000..23f1a075 --- /dev/null +++ b/services/dtbschedmgr/include/ability_connection_wrapper_stub.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_ABILITY_CONNECTION_WRAPPER_STUB_H +#define OHOS_DISTRIBUTED_ABILITY_CONNECTION_WRAPPER_STUB_H + +#include "ability_connect_callback_interface.h" + +#include "nocopyable.h" +#include "iremote_object.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace DistributedSchedule { +class AbilityConnectionWrapperStub : public IRemoteStub { +public: + explicit AbilityConnectionWrapperStub(sptr connection); + virtual ~AbilityConnectionWrapperStub() = default; + + void OnAbilityConnectDone(const AppExecFwk::ElementName& element, const sptr& remoteObject, + int32_t resultCode) override; + void OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int32_t resultCode) override; + + virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, + MessageOption& option) override; + +private: + DISALLOW_COPY_AND_MOVE(AbilityConnectionWrapperStub); + sptr distributedConnection_; +}; +} // namespace DistributedSchedule +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_ABILITY_CONNECTION_WRAPPER_STUB_H \ No newline at end of file diff --git a/services/dtbschedmgr/include/connect_death_recipient.h b/services/dtbschedmgr/include/connect_death_recipient.h new file mode 100755 index 00000000..3541f648 --- /dev/null +++ b/services/dtbschedmgr/include/connect_death_recipient.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_CONNECT_DEATH_RECIPIENT_H +#define OHOS_DISTRIBUTED_CONNECT_DEATH_RECIPIENT_H + +#include "iremote_object.h" + +namespace OHOS { +namespace DistributedSchedule { +class ConnectDeathRecipient : public IRemoteObject::DeathRecipient { +public: + ConnectDeathRecipient() = default; + ~ConnectDeathRecipient() override = default; + + void OnRemoteDied(const wptr& remote) override; +}; +} // namespace DistributedSchedule +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_CONNECT_DEATH_RECIPIENT_H \ No newline at end of file diff --git a/services/dtbschedmgr/include/distributed_sched_adapter.h b/services/dtbschedmgr/include/distributed_sched_adapter.h index ced5937a..43ae6b97 100755 --- a/services/dtbschedmgr/include/distributed_sched_adapter.h +++ b/services/dtbschedmgr/include/distributed_sched_adapter.h @@ -18,7 +18,6 @@ #include "ability_info.h" #include "ability_manager_client.h" - #include "caller_info.h" #include "event_handler.h" #include "if_system_ability_manager.h" @@ -35,13 +34,19 @@ public: void Init(); void UnInit(); + int32_t ConnectAbility(const OHOS::AAFwk::Want& want, const sptr& connect, + const sptr& callerToken); + int32_t DisconnectAbility(const sptr& connect); void DeviceOnline(const std::string& deviceId); void DeviceOffline(const std::string& deviceId); bool QueryAbilityInfo(const OHOS::AAFwk::Want& want, AppExecFwk::AbilityInfo& abilityInfo); + void ProcessConnectDied(const sptr& connect); int32_t GetBundleNameListFromBms(int32_t uid, std::vector& u16BundleNameList); int32_t GetBundleNameListFromBms(int32_t uid, std::vector& bundleNameList); private: + void ProcessDeviceOffline(const std::string& deviceId); + std::shared_ptr dmsAdapterHandler_; friend class BundleManagerInternal; }; diff --git a/services/dtbschedmgr/include/distributed_sched_dumper.h b/services/dtbschedmgr/include/distributed_sched_dumper.h new file mode 100755 index 00000000..6850be2c --- /dev/null +++ b/services/dtbschedmgr/include/distributed_sched_dumper.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_DISTRIBUTED_SCHED_DUMPER_H +#define OHOS_DISTRIBUTED_SCHED_DUMPER_H + +#include +#include + +namespace OHOS { +namespace DistributedSchedule { +class DistributedSchedDumper { +public: + static bool Dump(const std::vector& args, std::string& result); + +private: + DistributedSchedDumper() = default; + ~DistributedSchedDumper() = default; + + static void ShowHelp(std::string& result); + static void IllegalInput(std::string& result); + static void ShowConnectRemoteAbility(std::string& result); + static bool CanDump(); + static bool DumpDefault(std::string& result); +}; +} // namespace DistributedSchedule +} // namespace OHOS +#endif // OHOS_DISTRIBUTED_SCHED_DUMPER_H \ No newline at end of file diff --git a/services/dtbschedmgr/include/distributed_sched_interface.h b/services/dtbschedmgr/include/distributed_sched_interface.h index 9cac7008..50eca016 100644 --- a/services/dtbschedmgr/include/distributed_sched_interface.h +++ b/services/dtbschedmgr/include/distributed_sched_interface.h @@ -34,6 +34,7 @@ public: int32_t accountType = SAME_ACCOUNT_TYPE; std::vector groupIdList; }; + virtual int32_t StartRemoteAbility(const OHOS::AAFwk::Want& want, const OHOS::AppExecFwk::AbilityInfo& abilityInfo, int32_t requestCode) = 0; virtual int32_t StartAbilityFromRemote(const OHOS::AAFwk::Want& want, @@ -47,6 +48,14 @@ public: const sptr& continuationCallback) = 0; virtual int32_t UnregisterAbilityToken(const sptr& abilityToken, const sptr& continuationCallback) = 0; + virtual int32_t ConnectRemoteAbility(const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const sptr& connect) = 0; + virtual int32_t DisconnectRemoteAbility(const sptr& connect) = 0; + virtual int32_t ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const sptr& connect, const CallerInfo& callerInfo, const AccountInfo& accountInfo) = 0; + virtual int32_t DisconnectAbilityFromRemote(const sptr& connect, + int32_t uid, const std::string& sourceDeviceId) = 0; + virtual int32_t NotifyProcessDiedFromRemote(const CallerInfo& callerInfo) = 0; enum { START_REMOTE_ABILITY = 1, diff --git a/services/dtbschedmgr/include/distributed_sched_proxy.h b/services/dtbschedmgr/include/distributed_sched_proxy.h index 952bff48..bd00ae09 100644 --- a/services/dtbschedmgr/include/distributed_sched_proxy.h +++ b/services/dtbschedmgr/include/distributed_sched_proxy.h @@ -39,6 +39,14 @@ public: const sptr& continuationCallback) override; int32_t UnregisterAbilityToken(const sptr& abilityToken, const sptr& continuationCallback) override; + int32_t ConnectRemoteAbility(const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const sptr& connect) override; + int32_t DisconnectRemoteAbility(const sptr& connect) override; + int32_t ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const sptr& connect, const CallerInfo& callerInfo, const AccountInfo& accountInfo) override; + int32_t DisconnectAbilityFromRemote(const sptr& connect, + int32_t uid, const std::string& sourceDeviceId) override; + int32_t NotifyProcessDiedFromRemote(const CallerInfo& callerInfo) override; private: static inline BrokerDelegator delegator_; diff --git a/services/dtbschedmgr/include/distributed_sched_service.h b/services/dtbschedmgr/include/distributed_sched_service.h index 5820ac3b..3091b6fc 100644 --- a/services/dtbschedmgr/include/distributed_sched_service.h +++ b/services/dtbschedmgr/include/distributed_sched_service.h @@ -31,6 +31,8 @@ namespace OHOS { namespace DistributedSchedule { +class ConnectAbilitySession; + enum class ServiceRunningState { STATE_NO_START, STATE_RUNNING @@ -40,6 +42,11 @@ enum class TargetComponent { HARMONY_COMPONENT, }; +struct ConnectInfo { + CallerInfo callerInfo; + sptr callbackWrapper; +}; + class DistributedSchedService : public SystemAbility, public DistributedSchedStub { DECLARE_SYSTEM_ABILITY(DistributedSchedService); @@ -62,13 +69,93 @@ public: const sptr& continuationCallback) override; int32_t UnregisterAbilityToken(const sptr& abilityToken, const sptr& continuationCallback) override; + int32_t ConnectRemoteAbility(const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const sptr& connect) override; + int32_t DisconnectRemoteAbility(const sptr& connect) override; + int32_t ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const sptr& connect, const CallerInfo& callerInfo, const AccountInfo& accountInfo) override; + int32_t DisconnectAbilityFromRemote(const sptr& connect, + int32_t uid, const std::string& sourceDeviceId) override; + int32_t NotifyProcessDiedFromRemote(const CallerInfo& callerInfo) override; + void ProcessConnectDied(const sptr& connect); + void ProcessDeviceOffline(const std::string& deviceId); + int32_t Dump(int32_t fd, const std::vector& args) override; + void DumpConnectInfo(std::string& info); + void DumpSessionsLocked(const std::list& sessionsList, std::string& info); + void DumpElementLocked(const std::list& elementsList, std::string& info); + private: DistributedSchedService(); bool Init(); - bool GetLocalDeviceId(std::string& localDeviceId); - sptr GetRemoteDms(const std::string& remoteDeviceId); void NotifyContinuationCallbackResult(const sptr& abilityToken, int32_t isSuccess); + void RemoteConnectAbilityMappingLocked(const sptr& connect, const std::string& localDeviceId, + const std::string& remoteDeviceId, const AppExecFwk::ElementName& element, const CallerInfo& callerInfo, + TargetComponent targetComponent); + int32_t DisconnectEachRemoteAbilityLocked(const std::string& localDeviceId, + const std::string& remoteDeviceId, const sptr& connect); + sptr GetRemoteDms(const std::string& remoteDeviceId); + static bool GetLocalDeviceId(std::string& localDeviceId); + bool CheckDeviceId(const std::string& localDeviceId, const std::string& remoteDeviceId); + bool CheckDeviceIdFromRemote(const std::string& localDeviceId, + const std::string& remoteDeviceId, const std::string& sourceDeviceId); + void NotifyDeviceOfflineToAppLocked(const sptr& connect, const ConnectAbilitySession& session); + int32_t NotifyApp(const sptr& connect, const AppExecFwk::ElementName& element, int32_t errCode); + void NotifyProcessDiedLocked(const std::string& remoteDeviceId, const CallerInfo& callerInfo, + TargetComponent targetComponent); + int32_t CheckDistributedConnectLocked(const CallerInfo& callerInfo) const; + void DecreaseConnectLocked(int32_t uid); + static int32_t GetUidLocked(const std::list& sessionList); + int32_t TryConnectRemoteAbility(const OHOS::AAFwk::Want& want, const AppExecFwk::AbilityInfo& abilityInfo, + const sptr& connect, const CallerInfo& callerInfo); + std::shared_ptr dschedContinuation_; + std::map, std::list> distributedConnectAbilityMap_; + std::map, ConnectInfo> connectAbilityMap_; + std::unordered_map trackingUidMap_; + std::mutex distributedLock_; + sptr connectDeathRecipient_; +}; + +class ConnectAbilitySession { +public: + ConnectAbilitySession(const std::string& sourceDeviceId, const std::string& destinationDeviceId, + const CallerInfo& callerInfo, TargetComponent targetComponent = TargetComponent::HARMONY_COMPONENT); + ~ConnectAbilitySession() = default; + + const std::string& GetSourceDeviceId() const + { + return sourceDeviceId_; + } + + const std::string& GetDestinationDeviceId() const + { + return destinationDeviceId_; + } + + std::list GetElementsList() const + { + return elementsList_; + } + + CallerInfo GetCallerInfo() const + { + return callerInfo_; + } + + TargetComponent GetTargetComponent() const + { + return targetComponent_; + } + + bool IsSameCaller(const CallerInfo& callerInfo); + void AddElement(const AppExecFwk::ElementName& element); + +private: + std::string sourceDeviceId_; + std::string destinationDeviceId_; + std::list elementsList_; + CallerInfo callerInfo_; + TargetComponent targetComponent_; }; } // namespace DistributedSchedule } // namespace OHOS diff --git a/services/dtbschedmgr/include/distributed_sched_stub.h b/services/dtbschedmgr/include/distributed_sched_stub.h index 35a2fdaa..823dc5c0 100644 --- a/services/dtbschedmgr/include/distributed_sched_stub.h +++ b/services/dtbschedmgr/include/distributed_sched_stub.h @@ -37,6 +37,12 @@ private: int32_t RegisterAbilityTokenInner(MessageParcel& data, MessageParcel& reply); int32_t UnregisterAbilityTokenInner(MessageParcel& data, MessageParcel& reply); bool CheckDmsRequestPermission(); + int32_t ConnectRemoteAbilityInner(MessageParcel& data, MessageParcel& reply); + int32_t DisconnectRemoteAbilityInner(MessageParcel& data, MessageParcel& reply); + int32_t ConnectAbilityFromRemoteInner(MessageParcel& data, MessageParcel& reply); + int32_t DisconnectAbilityFromRemoteInner(MessageParcel& data, MessageParcel& reply); + int32_t NotifyProcessDiedFromRemoteInner(MessageParcel& data, MessageParcel& reply); + bool CheckCallingUid(); bool EnforceInterfaceToken(MessageParcel& data); using DistributedSchedFunc = int32_t(DistributedSchedStub::*)(MessageParcel& data, MessageParcel& reply); diff --git a/services/dtbschedmgr/src/ability_connection_wrapper_proxy.cpp b/services/dtbschedmgr/src/ability_connection_wrapper_proxy.cpp new file mode 100755 index 00000000..2d856666 --- /dev/null +++ b/services/dtbschedmgr/src/ability_connection_wrapper_proxy.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ability_connection_wrapper_proxy.h" + +#include "dtbschedmgr_log.h" +#include "ipc_object_proxy.h" +#include "ipc_types.h" +#include "parcel_helper.h" + +namespace OHOS { +namespace DistributedSchedule { +void AbilityConnectionWrapperProxy::OnAbilityConnectDone(const AppExecFwk::ElementName& element, + const sptr& remoteObject, int32_t resultCode) +{ + HILOGD("AbilityConnectionWrapperProxy::OnAbilityConnectDone called"); + MessageParcel data; + if (!data.WriteInterfaceToken(IAbilityConnection::GetDescriptor())) { + return; + } + + MessageParcel reply; + MessageOption option; + PARCEL_WRITE_HELPER_NORET(data, Parcelable, &element); + PARCEL_WRITE_HELPER_NORET(data, RemoteObject, remoteObject); + PARCEL_WRITE_HELPER_NORET(data, Int32, resultCode); + HILOGD("ConnectAbilityFromRemote Remote() is %{public}p", Remote().GetRefPtr()); + int32_t errCode = Remote()->SendRequest(IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option); + HILOGD("AbilityConnectionWrapperProxy::OnAbilityConnectDone result %{public}d", errCode); +} + +void AbilityConnectionWrapperProxy::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int32_t resultCode) +{ + HILOGD("AbilityConnectionWrapperProxy::OnAbilityDisconnectDone called"); + MessageParcel data; + if (!data.WriteInterfaceToken(IAbilityConnection::GetDescriptor())) { + return; + } + + MessageParcel reply; + MessageOption option; + PARCEL_WRITE_HELPER_NORET(data, Parcelable, &element); + PARCEL_WRITE_HELPER_NORET(data, Int32, resultCode); + int32_t errCode = Remote()->SendRequest(IAbilityConnection::ON_ABILITY_DISCONNECT_DONE, data, reply, option); + HILOGD("AbilityConnectionWrapperProxy::OnAbilityDisconnectDone result %{public}d", errCode); +} +} // namespace DistributedSchedule +} // namespace OHOS \ No newline at end of file diff --git a/services/dtbschedmgr/src/ability_connection_wrapper_stub.cpp b/services/dtbschedmgr/src/ability_connection_wrapper_stub.cpp new file mode 100755 index 00000000..d55d2cde --- /dev/null +++ b/services/dtbschedmgr/src/ability_connection_wrapper_stub.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ability_connection_wrapper_stub.h" + +#include "ability_connection_wrapper_proxy.h" +#include "dtbschedmgr_log.h" +#include "ipc_types.h" + +namespace OHOS { +namespace DistributedSchedule { +using namespace AAFwk; + +AbilityConnectionWrapperStub::AbilityConnectionWrapperStub(sptr connection) +{ + distributedConnection_ = connection; +} + +int32_t AbilityConnectionWrapperStub::OnRemoteRequest(uint32_t code, MessageParcel& data, + MessageParcel& reply, MessageOption& option) +{ + HILOGD("AbilityConnectionWrapperStub::OnRemoteRequest code = %{public}d", code); + std::u16string descriptor = IAbilityConnection::GetDescriptor(); + std::u16string remoteDescriptor = data.ReadInterfaceToken(); + if (descriptor != remoteDescriptor) { + HILOGE("AbilityConnectionWrapperStub local descriptor is not equal to remote"); + return ERR_INVALID_STATE; + } + + sptr element(data.ReadParcelable()); + if (element == nullptr) { + HILOGE("AbilityConnectionWrapperStub element is null"); + return ERR_INVALID_VALUE; + } + switch (code) { + case IAbilityConnection::ON_ABILITY_CONNECT_DONE: { + if (auto remoteObject = data.ReadParcelable()) { + auto resultCode = data.ReadInt32(); + OnAbilityConnectDone(*element, remoteObject, resultCode); + return ERR_NONE; + } + HILOGE("AbilityConnectionWrapperStub remoteObject is null"); + return ERR_INVALID_DATA; + } + case IAbilityConnection::ON_ABILITY_DISCONNECT_DONE: { + auto resultCode = data.ReadInt32(); + OnAbilityDisconnectDone(*element, resultCode); + return ERR_NONE; + } + default: { + HILOGE("AbilityConnectionWrapperStub unknown code"); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + } +} + +void AbilityConnectionWrapperStub::OnAbilityConnectDone(const AppExecFwk::ElementName& element, + const sptr& remoteObject, int32_t resultCode) +{ + auto proxy = std::make_unique(distributedConnection_); + proxy->OnAbilityConnectDone(element, remoteObject, resultCode); +} + +void AbilityConnectionWrapperStub::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, + int32_t resultCode) +{ + auto proxy = std::make_unique(distributedConnection_); + proxy->OnAbilityDisconnectDone(element, resultCode); +} +} // namespace DistributedSchedule +} // namespace OHOS \ No newline at end of file diff --git a/services/dtbschedmgr/src/connect_death_recipient.cpp b/services/dtbschedmgr/src/connect_death_recipient.cpp new file mode 100755 index 00000000..d3789ed6 --- /dev/null +++ b/services/dtbschedmgr/src/connect_death_recipient.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "connect_death_recipient.h" + +#include "distributed_sched_adapter.h" +#include "dtbschedmgr_log.h" +#include "iremote_proxy.h" + +namespace OHOS { +namespace DistributedSchedule { +void ConnectDeathRecipient::OnRemoteDied(const wptr& remote) +{ + HILOGI("ConnectDeathRecipient::OnRemoteDied called"); + DistributedSchedAdapter::GetInstance().ProcessConnectDied(remote.promote()); +} +} // namespace DistributedSchedule +} // namespace OHOS \ No newline at end of file diff --git a/services/dtbschedmgr/src/distributed_sched_adapter.cpp b/services/dtbschedmgr/src/distributed_sched_adapter.cpp index 4afdba95..0017efc8 100755 --- a/services/dtbschedmgr/src/distributed_sched_adapter.cpp +++ b/services/dtbschedmgr/src/distributed_sched_adapter.cpp @@ -55,6 +55,33 @@ void DistributedSchedAdapter::UnInit() dmsAdapterHandler_ = nullptr; } +int32_t DistributedSchedAdapter::ConnectAbility(const OHOS::AAFwk::Want& want, + const sptr& connect, const sptr& callerToken) +{ + HILOGD("DistributedSchedAdapter ConnectAbility"); + ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect(); + if (errCode != ERR_OK) { + HILOGE("DistributedSchedAdapter connect ability server failed, errCode=%{public}d", errCode); + return errCode; + } + ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, + iface_cast(connect), callerToken); + return ret; +} + +int32_t DistributedSchedAdapter::DisconnectAbility(const sptr& connect) +{ + HILOGD("DistributedSchedAdapter DisconnectAbility"); + ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect(); + if (errCode != ERR_OK) { + HILOGE("DistributedSchedAdapter connect ability server failed, errCode=%{public}d", errCode); + return errCode; + } + ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility( + iface_cast(connect)); + return ret; +} + void DistributedSchedAdapter::DeviceOnline(const std::string& deviceId) { if (dmsAdapterHandler_ == nullptr) { @@ -83,6 +110,7 @@ void DistributedSchedAdapter::DeviceOffline(const std::string& deviceId) } HILOGD("process DeviceOffline deviceId is %s", deviceId.c_str()); auto callback = [deviceId, this] () { + ProcessDeviceOffline(deviceId); }; if (!dmsAdapterHandler_->PostTask(callback, deviceId, DEVICE_OFFLINE_DELAY_TIME)) { HILOGW("DeviceOffline PostTask failed"); @@ -104,6 +132,32 @@ bool DistributedSchedAdapter::QueryAbilityInfo(const OHOS::AAFwk::Want& want, Ap return true; } +void DistributedSchedAdapter::ProcessDeviceOffline(const std::string& deviceId) +{ + HILOGD("ProcessDeviceOffline"); + DistributedSchedService::GetInstance().ProcessDeviceOffline(deviceId); +} + +void DistributedSchedAdapter::ProcessConnectDied(const sptr& connect) +{ + if (dmsAdapterHandler_ == nullptr) { + HILOGE("ProcessConnectDied dmsAdapterHandler is null"); + return; + } + + if (connect == nullptr) { + HILOGE("ProcessConnectDied connect is null"); + return; + } + HILOGD("process connect died"); + auto callback = [connect] () { + DistributedSchedService::GetInstance().ProcessConnectDied(connect); + }; + if (!dmsAdapterHandler_->PostTask(callback)) { + HILOGW("ProcessConnectDied PostTask failed"); + } +} + int32_t DistributedSchedAdapter::GetBundleNameListFromBms(int32_t uid, std::vector& u16BundleNameList) { diff --git a/services/dtbschedmgr/src/distributed_sched_dumper.cpp b/services/dtbschedmgr/src/distributed_sched_dumper.cpp new file mode 100755 index 00000000..9ff85236 --- /dev/null +++ b/services/dtbschedmgr/src/distributed_sched_dumper.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "distributed_sched_dumper.h" + +#include "distributed_sched_service.h" +#include "dtbschedmgr_log.h" +#include "ipc_skeleton.h" + +namespace OHOS { +namespace DistributedSchedule { +namespace { +constexpr size_t MIN_ARGS_SIZE = 1; +const std::string ARGS_HELP = "-h"; +const std::string ARGS_CONNECT_REMOTE_ABILITY = "-connect"; +constexpr int32_t UID_ROOT = 0; +} + +bool DistributedSchedDumper::DumpDefault(std::string& result) +{ + result.append("DistributedSched Dump\n"); + result.append("\n"); + ShowConnectRemoteAbility(result); + return true; +} + +bool DistributedSchedDumper::Dump(const std::vector& args, std::string& result) +{ + result.clear(); + if (!CanDump()) { + result.append("Dump failed, not allowed"); + return false; + } + + if (args.size() < MIN_ARGS_SIZE) { + return DumpDefault(result); + } + + if (args.size() == MIN_ARGS_SIZE) { + // -h + if (args[0] == ARGS_HELP) { + ShowHelp(result); + return true; + } + // -connect + if (args[0] == ARGS_CONNECT_REMOTE_ABILITY) { + ShowConnectRemoteAbility(result); + return true; + } + } + IllegalInput(result); + return false; +} + +void DistributedSchedDumper::ShowHelp(std::string& result) +{ + result.append("DistributedSched Dump options:\n") + .append(" [-h] [cmd]...\n") + .append("cmd maybe one of:\n") + .append(" -connect: show all connected remote abilities.\n"); +} + +void DistributedSchedDumper::IllegalInput(std::string& result) +{ + result.append("The arguments are illegal and you can enter '-h' for help.\n"); +} + +void DistributedSchedDumper::ShowConnectRemoteAbility(std::string& result) +{ + DistributedSchedService::GetInstance().DumpConnectInfo(result); +} + +bool DistributedSchedDumper::CanDump() +{ + auto callingUid = IPCSkeleton::GetCallingUid(); + HILOGI("calling uid = %u", callingUid); + if (callingUid != UID_ROOT) { + return false; + } + return true; +} +} // namespace DistributedSchedule +} // namespace OHOS \ No newline at end of file diff --git a/services/dtbschedmgr/src/distributed_sched_proxy.cpp b/services/dtbschedmgr/src/distributed_sched_proxy.cpp index 1b102096..8da4f9b4 100644 --- a/services/dtbschedmgr/src/distributed_sched_proxy.cpp +++ b/services/dtbschedmgr/src/distributed_sched_proxy.cpp @@ -168,6 +168,125 @@ int32_t DistributedSchedProxy::UnregisterAbilityToken(const sptr& MessageParcel reply; PARCEL_TRANSACT_SYNC_RET_INT(remote, UNREGISTER_ABILITY_TOKEN, data, reply); } + +int32_t DistributedSchedProxy::ConnectRemoteAbility(const OHOS::AAFwk::Want& want, + const AppExecFwk::AbilityInfo& abilityInfo, const sptr& connect) +{ + if (connect == nullptr) { + HILOGE("ConnectRemoteAbility connect is null"); + return ERR_NULL_OBJECT; + } + + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("ConnectRemoteAbility remote is null"); + return ERR_NULL_OBJECT; + } + MessageParcel data; + if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { + return ERR_FLATTEN_OBJECT; + } + PARCEL_WRITE_HELPER(data, Parcelable, &want); + PARCEL_WRITE_HELPER(data, Parcelable, &abilityInfo); + PARCEL_WRITE_HELPER(data, RemoteObject, connect); + MessageParcel reply; + PARCEL_TRANSACT_SYNC_RET_INT(remote, CONNECT_REMOTE_ABILITY, data, reply); +} + +int32_t DistributedSchedProxy::DisconnectRemoteAbility(const sptr& connect) +{ + if (connect == nullptr) { + HILOGE("DisconnectRemoteAbility connect is null"); + return ERR_NULL_OBJECT; + } + + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("DisconnectRemoteAbility remote is null"); + return ERR_NULL_OBJECT; + } + MessageParcel data; + if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { + return ERR_FLATTEN_OBJECT; + } + PARCEL_WRITE_HELPER(data, RemoteObject, connect); + MessageParcel reply; + PARCEL_TRANSACT_SYNC_RET_INT(remote, DISCONNECT_REMOTE_ABILITY, data, reply); +} + +int32_t DistributedSchedProxy::ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want, + const AppExecFwk::AbilityInfo& abilityInfo, const sptr& connect, + const CallerInfo& callerInfo, const AccountInfo& accountInfo) +{ + if (connect == nullptr) { + HILOGE("ConnectAbilityFromRemote connect is null"); + return ERR_NULL_OBJECT; + } + + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("ConnectAbilityFromRemote remote is null"); + return ERR_NULL_OBJECT; + } + MessageParcel data; + if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { + return ERR_FLATTEN_OBJECT; + } + PARCEL_WRITE_HELPER(data, Parcelable, &want); + PARCEL_WRITE_HELPER(data, Parcelable, &abilityInfo); + PARCEL_WRITE_HELPER(data, RemoteObject, connect); + PARCEL_WRITE_HELPER(data, Int32, callerInfo.uid); + PARCEL_WRITE_HELPER(data, Int32, callerInfo.pid); + PARCEL_WRITE_HELPER(data, String, callerInfo.sourceDeviceId); + PARCEL_WRITE_HELPER(data, Int32, accountInfo.accountType); + PARCEL_WRITE_HELPER(data, StringVector, accountInfo.groupIdList); + PARCEL_WRITE_HELPER(data, String, callerInfo.callerAppId); + MessageParcel reply; + PARCEL_TRANSACT_SYNC_RET_INT(remote, CONNECT_ABILITY_FROM_REMOTE, data, reply); +} + +int32_t DistributedSchedProxy::DisconnectAbilityFromRemote(const sptr& connect, + int32_t uid, const std::string& sourceDeviceId) +{ + if (connect == nullptr) { + HILOGE("DisconnectAbilityFromRemote connect is null"); + return ERR_NULL_OBJECT; + } + + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("DisconnectAbilityFromRemote remote is null"); + return ERR_NULL_OBJECT; + } + MessageParcel data; + if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { + return ERR_FLATTEN_OBJECT; + } + PARCEL_WRITE_HELPER(data, RemoteObject, connect); + PARCEL_WRITE_HELPER(data, Int32, uid); + PARCEL_WRITE_HELPER(data, String, sourceDeviceId); + MessageParcel reply; + PARCEL_TRANSACT_SYNC_RET_INT(remote, DISCONNECT_ABILITY_FROM_REMOTE, data, reply); +} + +int32_t DistributedSchedProxy::NotifyProcessDiedFromRemote(const CallerInfo& callerInfo) +{ + HILOGD("DistributedSchedProxy::NotifyProcessDiedFromRemote called"); + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("NotifyProcessDiedFromRemote remote is null"); + return ERR_NULL_OBJECT; + } + MessageParcel data; + if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) { + return ERR_FLATTEN_OBJECT; + } + PARCEL_WRITE_HELPER(data, Int32, callerInfo.uid); + PARCEL_WRITE_HELPER(data, Int32, callerInfo.pid); + PARCEL_WRITE_HELPER(data, String, callerInfo.sourceDeviceId); + MessageParcel reply; + PARCEL_TRANSACT_SYNC_RET_INT(remote, NOTIFY_PROCESS_DIED_FROM_REMOTE, data, reply); +} } // namespace DistributedSchedule } // namespace OHOS diff --git a/services/dtbschedmgr/src/distributed_sched_service.cpp b/services/dtbschedmgr/src/distributed_sched_service.cpp index fc66f6e0..9911d61a 100644 --- a/services/dtbschedmgr/src/distributed_sched_service.cpp +++ b/services/dtbschedmgr/src/distributed_sched_service.cpp @@ -18,12 +18,16 @@ #include #include +#include "ability_connection_wrapper_stub.h" #include "adapter/dnetwork_adapter.h" +#include "bundle/bundle_manager_internal.h" +#include "connect_death_recipient.h" #include "distributed_sched_adapter.h" #include "distributed_sched_ability_shell.h" #include "distributed_sched_permission.h" #include "dtbschedmgr_device_info_storage.h" #include "dtbschedmgr_log.h" +#include "distributed_sched_dumper.h" #include "ability_manager_client.h" #include "datetime_ex.h" @@ -32,20 +36,20 @@ #include "iservice_registry.h" #include "parcel_helper.h" #include "string_ex.h" +#include "file_ex.h" #include "system_ability_definition.h" -#include "distributed_sched_adapter.h" -#include "dtbschedmgr_device_info_storage.h" - namespace OHOS { namespace DistributedSchedule { using namespace AAFwk; using namespace AppExecFwk; namespace { -const std::string PARAM_CALLING_UID = "dms.extra.param.key.callingUid"; -const std::string PARAM_CALLING_PID = "dms.extra.param.key.callingPid"; -const std::string PARAM_CALLING_NETWORK_ID = "dms.extra.param.key.srcNetworkId"; +constexpr int32_t BIND_CONNECT_RETRY_TIMES = 3; +constexpr int32_t BIND_CONNECT_TIMEOUT = 500; // 500ms +constexpr int32_t MAX_DISTRIBUTED_CONNECT_NUM = 600; +constexpr int32_t SYSTEM_UID = 1000; +constexpr int32_t INVALID_CALLER_UID = -1; } IMPLEMENT_SINGLE_INSTANCE(DistributedSchedService); @@ -87,6 +91,7 @@ bool DistributedSchedService::Init() HILOGD("DistributedSchedService::Init init success."); DistributedSchedAdapter::GetInstance().Init(); DnetworkAdapter::GetInstance()->Init(); + connectDeathRecipient_ = sptr(new ConnectDeathRecipient()); return true; } @@ -255,13 +260,155 @@ int32_t DistributedSchedService::UnregisterAbilityToken(const sptr& connect, + const std::string& localDeviceId, const std::string& remoteDeviceId, const AppExecFwk::ElementName& element, + const CallerInfo& callerInfo, TargetComponent targetComponent) { - if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localDeviceId)) { - HILOGE("GetLocalDeviceId fail"); - return false; + if (connect == nullptr) { + return; } - return true; + auto itConnect = distributedConnectAbilityMap_.find(connect); + if (itConnect == distributedConnectAbilityMap_.end()) { + // add uid's connect number + uint32_t number = ++trackingUidMap_[callerInfo.uid]; + HILOGD("uid %d has %u connection(s), targetComponent:%d", callerInfo.uid, number, targetComponent); + // new connect, add death recipient + connect->AddDeathRecipient(connectDeathRecipient_); + } + auto& sessionsList = distributedConnectAbilityMap_[connect]; + for (auto& session : sessionsList) { + if (remoteDeviceId == session.GetDestinationDeviceId()) { + session.AddElement(element); + // already added session for remote device + return; + } + } + // connect to another remote device, add a new session to list + auto& session = sessionsList.emplace_back(localDeviceId, remoteDeviceId, callerInfo, targetComponent); + session.AddElement(element); + HILOGD("add connection success"); +} + +int32_t DistributedSchedService::CheckDistributedConnectLocked(const CallerInfo& callerInfo) const +{ + if (callerInfo.uid < 0) { + HILOGE("uid %d is invalid", callerInfo.uid); + return BIND_ABILITY_UID_INVALID_ERR; + } + + if (callerInfo.uid == SYSTEM_UID) { + return ERR_OK; + } + auto it = trackingUidMap_.find(callerInfo.uid); + if (it != trackingUidMap_.end() && it->second >= MAX_DISTRIBUTED_CONNECT_NUM) { + HILOGE("uid %{public}d connected too much abilities, it maybe leak", callerInfo.uid); + return BIND_ABILITY_LEAK_ERR; + } + return ERR_OK; +} + +void DistributedSchedService::DecreaseConnectLocked(int32_t uid) +{ + if (uid < 0) { + HILOGE("DecreaseConnectLocked invalid uid %{public}d", uid); + return; + } + auto it = trackingUidMap_.find(uid); + if (it != trackingUidMap_.end()) { + auto& conns = it->second; + if (conns > 0) { + conns--; + } + if (conns == 0) { + HILOGD("DecreaseConnectLocked uid %{public}d connection(s) is 0", uid); + trackingUidMap_.erase(it); + } + } +} + +int32_t DistributedSchedService::GetUidLocked(const std::list& sessionsList) +{ + if (!sessionsList.empty()) { + return sessionsList.front().GetCallerInfo().uid; + } + return INVALID_CALLER_UID; +} + +int32_t DistributedSchedService::ConnectRemoteAbility(const OHOS::AAFwk::Want& want, + const AppExecFwk::AbilityInfo& abilityInfo, const sptr& connect) +{ + std::string localDeviceId; + if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, abilityInfo.deviceId)) { + HILOGE("ConnectRemoteAbility check deviceId failed"); + return INVALID_PARAMETERS_ERR; + } + + std::lock_guard autoLock(distributedLock_); + CallerInfo callerInfo = { + IPCSkeleton::GetCallingUid(), IPCSkeleton::GetCallingPid(), CALLER_TYPE_HARMONY, localDeviceId + }; + int32_t checkResult = CheckDistributedConnectLocked(callerInfo); + if (checkResult != ERR_OK) { + return checkResult; + } + + if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) { + HILOGE("ConnectRemoteAbility GetCallerAppIdFromBms failed"); + return INVALID_PARAMETERS_ERR; + } + int32_t ret = DistributedSchedAdapter::GetInstance().GetBundleNameListFromBms( + callerInfo.uid, callerInfo.bundleNames); + if (ret != ERR_OK) { + HILOGE("ConnectRemoteAbility GetBundleNameListFromBms failed"); + return INVALID_PARAMETERS_ERR; + } + + if (abilityInfo.type == AppExecFwk::AbilityType::UNKNOWN) { + HILOGE("ConnectRemoteAbility AbilityType error"); + return INVALID_PARAMETERS_ERR; + } + + HILOGD("[PerformanceTest] DistributedSchedService::ConnectRemoteAbility begin"); + int32_t result = TryConnectRemoteAbility(want, abilityInfo, connect, callerInfo); + if (result != ERR_OK) { + HILOGE("ConnectRemoteAbility result is %{public}d", result); + } + HILOGD("[PerformanceTest] DistributedSchedService::ConnectRemoteAbility end"); + return result; +} + +int32_t DistributedSchedService::TryConnectRemoteAbility(const OHOS::AAFwk::Want& want, + const AppExecFwk::AbilityInfo& abilityInfo, const sptr& connect, const CallerInfo& callerInfo) +{ + AccountInfo accountInfo; + sptr remoteDms = GetRemoteDms(abilityInfo.deviceId); + if (remoteDms == nullptr || connect == nullptr) { + HILOGE("TryConnectRemoteAbility invalid parameters"); + return INVALID_PARAMETERS_ERR; + } + + int32_t retryTimes = BIND_CONNECT_RETRY_TIMES; + int32_t result = REMOTE_DEVICE_BIND_ABILITY_ERR; + while (retryTimes--) { + int64_t start = GetTickCount(); + HILOGD("[PerformanceTest] ConnectRemoteAbility begin"); + result = remoteDms->ConnectAbilityFromRemote(want, abilityInfo, connect, callerInfo, accountInfo); + HILOGD("[PerformanceTest] ConnectRemoteAbility end"); + if (result == ERR_OK) { + RemoteConnectAbilityMappingLocked(connect, callerInfo.sourceDeviceId, abilityInfo.deviceId, + want.GetElement(), callerInfo, TargetComponent::HARMONY_COMPONENT); + break; + } + if (result == INVALID_REMOTE_PARAMETERS_ERR || result == REMOTE_DEVICE_BIND_ABILITY_ERR) { + break; + } + int64_t elapsedTime = GetTickCount() - start; + if (elapsedTime > BIND_CONNECT_TIMEOUT) { + HILOGW("ConnectRemoteAbility timeout, elapsedTime is %{public}" PRId64 " ms", elapsedTime); + break; + } + } + return result; } sptr DistributedSchedService::GetRemoteDms(const std::string& remoteDeviceId) @@ -285,5 +432,426 @@ sptr DistributedSchedService::GetRemoteDms(const std::string& } return iface_cast(object); } + +bool DistributedSchedService::GetLocalDeviceId(std::string& localDeviceId) +{ + if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localDeviceId)) { + HILOGE("GetLocalDeviceId failed"); + return false; + } + return true; +} + +bool DistributedSchedService::CheckDeviceId(const std::string& localDeviceId, const std::string& remoteDeviceId) +{ + // remoteDeviceId must not same with localDeviceId + if (localDeviceId.empty() || remoteDeviceId.empty() || localDeviceId == remoteDeviceId) { + HILOGE("check deviceId failed"); + return false; + } + return true; +} + +bool DistributedSchedService::CheckDeviceIdFromRemote(const std::string& localDeviceId, + const std::string& remoteDeviceId, const std::string& sourceDeviceId) +{ + if (localDeviceId.empty() || remoteDeviceId.empty() || sourceDeviceId.empty()) { + HILOGE("CheckDeviceIdFromRemote failed"); + return false; + } + // remoteDeviceId set by remote must be same with localDeviceId + if (localDeviceId != remoteDeviceId) { + HILOGE("remoteDeviceId is not same with localDeviceId"); + return false; + } + HILOGD("CheckDeviceIdFromRemote sourceDeviceId %s", sourceDeviceId.c_str()); + HILOGD("CheckDeviceIdFromRemote localDeviceId %s", localDeviceId.c_str()); + HILOGD("CheckDeviceIdFromRemote remoteDeviceId %s", remoteDeviceId.c_str()); + + if (sourceDeviceId == remoteDeviceId || sourceDeviceId == localDeviceId) { + HILOGE("sourceDeviceId is different with localDeviceId and remoteDeviceId"); + return false; + } + return true; +} + +int32_t DistributedSchedService::ConnectAbilityFromRemote(const OHOS::AAFwk::Want& want, + const AppExecFwk::AbilityInfo& abilityInfo, const sptr& connect, + const CallerInfo& callerInfo, const AccountInfo& accountInfo) +{ + HILOGD("[PerformanceTest] DistributedSchedService ConnectAbilityFromRemote begin"); + if (connect == nullptr) { + HILOGE("ConnectAbilityFromRemote connect is null"); + return INVALID_REMOTE_PARAMETERS_ERR; + } + HILOGD("ConnectAbilityFromRemote uid is %d, pid is %d", callerInfo.uid, callerInfo.pid); + std::string localDeviceId; + if (!GetLocalDeviceId(localDeviceId) || + !CheckDeviceIdFromRemote(localDeviceId, abilityInfo.deviceId, callerInfo.sourceDeviceId)) { + HILOGE("ConnectAbilityFromRemote check deviceId failed"); + return INVALID_REMOTE_PARAMETERS_ERR; + } + + DistributedSchedPermission& permissionInstance = DistributedSchedPermission::GetInstance(); + int32_t result = permissionInstance.CheckDPermission(want, callerInfo, accountInfo, abilityInfo, localDeviceId); + if (result != ERR_OK) { + HILOGE("ConnectAbilityFromRemote CheckDPermission denied!!"); + return result; + } + + HILOGD("ConnectAbilityFromRemote callerType is %{public}d", callerInfo.callerType); + sptr callbackWrapper = connect; + if (callerInfo.callerType == CALLER_TYPE_HARMONY) { + std::lock_guard autoLock(distributedLock_); + auto itConnect = connectAbilityMap_.find(connect); + if (itConnect != connectAbilityMap_.end()) { + callbackWrapper = itConnect->second.callbackWrapper; + } else { + callbackWrapper = new AbilityConnectionWrapperStub(connect); + ConnectInfo connectInfo {callerInfo, callbackWrapper}; + connectAbilityMap_.emplace(connect, connectInfo); + } + } + int32_t errCode = DistributedSchedAdapter::GetInstance().ConnectAbility(want, callbackWrapper, this); + HILOGD("[PerformanceTest] DistributedSchedService ConnectAbilityFromRemote end"); + return errCode; +} + +int32_t DistributedSchedService::DisconnectEachRemoteAbilityLocked(const std::string& localDeviceId, + const std::string& remoteDeviceId, const sptr& connect) +{ + sptr remoteDms = GetRemoteDms(remoteDeviceId); + if (remoteDms == nullptr) { + HILOGE("DisconnectRemoteAbility get remote dms failed"); + return INVALID_PARAMETERS_ERR; + } + int32_t result = remoteDms->DisconnectAbilityFromRemote(connect, IPCSkeleton::GetCallingUid(), localDeviceId); + if (result != ERR_OK) { + HILOGE("DisconnectEachRemoteAbilityLocked result is %{public}d", result); + } + return result; +} + +int32_t DistributedSchedService::DisconnectRemoteAbility(const sptr& connect) +{ + if (connect == nullptr) { + HILOGE("DisconnectRemoteAbility connect is null"); + return INVALID_PARAMETERS_ERR; + } + + std::lock_guard autoLock(distributedLock_); + auto it = distributedConnectAbilityMap_.find(connect); + if (it != distributedConnectAbilityMap_.end()) { + std::list& sessionsList = it->second; + int32_t uid = GetUidLocked(sessionsList); + for (const auto& session : sessionsList) { + if (session.GetTargetComponent() == TargetComponent::HARMONY_COMPONENT) { + DisconnectEachRemoteAbilityLocked(session.GetSourceDeviceId(), + session.GetDestinationDeviceId(), connect); + } else { + HILOGW("DisconnectRemoteAbility non-harmony component"); + } + } + // also decrease number when erase connect + DecreaseConnectLocked(uid); + connect->RemoveDeathRecipient(connectDeathRecipient_); + distributedConnectAbilityMap_.erase(it); + HILOGI("remove connect sucess"); + return ERR_OK; + } + return NO_CONNECT_CALLBACK_ERR; +} + +int32_t DistributedSchedService::DisconnectAbilityFromRemote(const sptr& connect, + int32_t uid, const std::string& sourceDeviceId) +{ + if (connect == nullptr) { + HILOGE("DisconnectAbilityFromRemote connect is null"); + return INVALID_REMOTE_PARAMETERS_ERR; + } + + HILOGD("[PerformanceTest] DistributedSchedService::DisconnectAbilityFromRemote begin"); + std::string localDeviceId; + AppExecFwk::AbilityInfo abilityInfo; + if (!GetLocalDeviceId(localDeviceId) || localDeviceId.empty() || + sourceDeviceId.empty() || localDeviceId == sourceDeviceId) { + HILOGE("DisconnectAbilityFromRemote check deviceId failed"); + return INVALID_REMOTE_PARAMETERS_ERR; + } + + sptr callbackWrapper = connect; + { + std::lock_guard autoLock(distributedLock_); + auto itConnect = connectAbilityMap_.find(connect); + if (itConnect != connectAbilityMap_.end()) { + callbackWrapper = itConnect->second.callbackWrapper; + connectAbilityMap_.erase(itConnect); + } else { + if (!IPCSkeleton::IsLocalCalling()) { + HILOGE("DisconnectAbilityFromRemote connect not found"); + return INVALID_REMOTE_PARAMETERS_ERR; + } + } + } + int32_t result = DistributedSchedAdapter::GetInstance().DisconnectAbility(callbackWrapper); + HILOGD("[PerformanceTest] DistributedSchedService::DisconnectAbilityFromRemote end"); + return result; +} + +int32_t DistributedSchedService::NotifyProcessDiedFromRemote(const CallerInfo& callerInfo) +{ + HILOGI("DistributedSchedService::NotifyProcessDiedFromRemote called"); + int32_t errCode = ERR_OK; + { + std::lock_guard autoLock(distributedLock_); + for (auto iter = connectAbilityMap_.begin(); iter != connectAbilityMap_.end();) { + ConnectInfo& connectInfo = iter->second; + if (callerInfo.sourceDeviceId == connectInfo.callerInfo.sourceDeviceId + && callerInfo.uid == connectInfo.callerInfo.uid + && callerInfo.pid == connectInfo.callerInfo.pid + && callerInfo.callerType == connectInfo.callerInfo.callerType) { + HILOGI("NotifyProcessDiedFromRemote erase connection success"); + int32_t ret = DistributedSchedAdapter::GetInstance().DisconnectAbility(connectInfo.callbackWrapper); + if (ret != ERR_OK) { + errCode = ret; + } + connectAbilityMap_.erase(iter++); + } else { + iter++; + } + } + } + return errCode; +} + +void DistributedSchedService::ProcessDeviceOffline(const std::string& deviceId) +{ + HILOGI("DistributedSchedService::ProcessDeviceOffline called"); + std::string localDeviceId; + if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) { + HILOGE("ProcessDeviceOffline check deviceId failed"); + return; + } + + std::lock_guard autoLock(distributedLock_); + for (auto itConnect = distributedConnectAbilityMap_.begin(); itConnect != distributedConnectAbilityMap_.end();) { + std::list& sessionsList = itConnect->second; + int32_t uid = GetUidLocked(sessionsList); + auto itSession = std::find_if(sessionsList.begin(), sessionsList.end(), [&deviceId](const auto& session) { + return session.GetDestinationDeviceId() == deviceId; + }); + if (itSession != sessionsList.end()) { + NotifyDeviceOfflineToAppLocked(itConnect->first, *itSession); + CallerInfo callerInfo = itSession->GetCallerInfo(); + sessionsList.erase(itSession); + } + + if (sessionsList.empty()) { + if (itConnect->first != nullptr) { + itConnect->first->RemoveDeathRecipient(connectDeathRecipient_); + } + DecreaseConnectLocked(uid); + distributedConnectAbilityMap_.erase(itConnect++); + } else { + itConnect++; + } + } + + for (auto iter = connectAbilityMap_.begin(); iter != connectAbilityMap_.end();) { + ConnectInfo& connectInfo = iter->second; + if (deviceId == connectInfo.callerInfo.sourceDeviceId) { + DistributedSchedAdapter::GetInstance().DisconnectAbility(connectInfo.callbackWrapper); + connectAbilityMap_.erase(iter++); + HILOGI("ProcessDeviceOffline erase connection success"); + } else { + iter++; + } + } +} + +void DistributedSchedService::NotifyDeviceOfflineToAppLocked(const sptr& connect, + const ConnectAbilitySession& session) +{ + std::list elementsList = session.GetElementsList(); + for (const auto& element : elementsList) { + int32_t errCode = NotifyApp(connect, element, DEVICE_OFFLINE_ERR); + if (errCode != ERR_NONE) { + HILOGW("ProcessDeviceOffline notify failed, errCode = %{public}d", errCode); + } + } +} + +int32_t DistributedSchedService::NotifyApp(const sptr& connect, + const AppExecFwk::ElementName& element, int32_t errCode) +{ + if (connect == nullptr) { + return OBJECT_NULL; + } + MessageParcel data; + if (!data.WriteInterfaceToken(IAbilityConnection::GetDescriptor())) { + return ERR_FLATTEN_OBJECT; + } + PARCEL_WRITE_HELPER(data, Parcelable, &element); + PARCEL_WRITE_HELPER(data, Int32, errCode); + MessageParcel reply; + MessageOption option; + return connect->SendRequest(IAbilityConnection::ON_ABILITY_DISCONNECT_DONE, data, reply, option); +} + +void DistributedSchedService::ProcessConnectDied(const sptr& connect) +{ + if (connect == nullptr) { + HILOGE("ProcessConnectDied connect is null"); + return; + } + + std::lock_guard autoLock(distributedLock_); + auto it = distributedConnectAbilityMap_.find(connect); + if (it == distributedConnectAbilityMap_.end()) { + return; + } + std::list& connectSessionsList = it->second; + if (connectSessionsList.empty()) { + return; + } + CallerInfo callerInfo = connectSessionsList.front().GetCallerInfo(); + std::set processedDeviceSet; + // to reduce the number of communications between devices, clean all the died process's connections + for (auto itConnect = distributedConnectAbilityMap_.begin(); itConnect != distributedConnectAbilityMap_.end();) { + std::list& sessionsList = itConnect->second; + if (!sessionsList.empty() && sessionsList.front().IsSameCaller(callerInfo)) { + for (const auto& session : sessionsList) { + std::string remoteDeviceId = session.GetDestinationDeviceId(); + TargetComponent targetComponent = session.GetTargetComponent(); + // the same session can connect different types component on the same device + std::string key = remoteDeviceId + std::to_string(static_cast(targetComponent)); + // just notify one time for same remote device + auto [_, isSuccess] = processedDeviceSet.emplace(key); + if (isSuccess) { + NotifyProcessDiedLocked(remoteDeviceId, callerInfo, targetComponent); + } + } + DecreaseConnectLocked(callerInfo.uid); + if (itConnect->first != nullptr) { + itConnect->first ->RemoveDeathRecipient(connectDeathRecipient_); + } + distributedConnectAbilityMap_.erase(itConnect++); + } else { + itConnect++; + } + } +} + +void DistributedSchedService::NotifyProcessDiedLocked(const std::string& remoteDeviceId, + const CallerInfo& callerInfo, TargetComponent targetComponent) +{ + if (targetComponent != TargetComponent::HARMONY_COMPONENT) { + HILOGD("NotifyProcessDiedLocked not harmony component, no need to notify"); + return; + } + + sptr remoteDms = GetRemoteDms(remoteDeviceId); + if (remoteDms == nullptr) { + HILOGE("NotifyProcessDiedLocked get remote dms failed"); + return; + } + int32_t result = remoteDms->NotifyProcessDiedFromRemote(callerInfo); + HILOGI("NotifyProcessDiedLocked result is %{public}d", result); +} + +ConnectAbilitySession::ConnectAbilitySession(const std::string& sourceDeviceId, const std::string& destinationDeviceId, + const CallerInfo& callerInfo, TargetComponent targetComponent) + : sourceDeviceId_(sourceDeviceId), + destinationDeviceId_(destinationDeviceId), + callerInfo_(callerInfo), + targetComponent_(targetComponent) +{ +} + +void ConnectAbilitySession::AddElement(const AppExecFwk::ElementName& element) +{ + for (const auto& elementName : elementsList_) { + if (elementName == element) { + return; + } + } + elementsList_.emplace_back(element); +} + +bool ConnectAbilitySession::IsSameCaller(const CallerInfo& callerInfo) +{ + return (callerInfo.uid == callerInfo_.uid && + callerInfo.pid == callerInfo_.pid && + callerInfo.sourceDeviceId == callerInfo_.sourceDeviceId && + callerInfo.callerType == callerInfo_.callerType); +} + +int32_t DistributedSchedService::Dump(int32_t fd, const std::vector& args) +{ + std::vector argsInStr8; + for (const auto& arg : args) { + argsInStr8.emplace_back(Str16ToStr8(arg)); + } + + std::string result; + DistributedSchedDumper::Dump(argsInStr8, result); + + if (!SaveStringToFd(fd, result)) { + HILOGE("save to fd failed"); + return DMS_WRITE_FILE_FAILED_ERR; + } + return ERR_OK; +} + +void DistributedSchedService::DumpConnectInfo(std::string& info) +{ + std::lock_guard autoLock(distributedLock_); + info += "connected remote abilities:\n"; + if (!distributedConnectAbilityMap_.empty()) { + for (const auto& distributedConnect : distributedConnectAbilityMap_) { + const std::list sessionsList = distributedConnect.second; + DumpSessionsLocked(sessionsList, info); + } + } else { + info += " \n"; + } +} + +void DistributedSchedService::DumpSessionsLocked(const std::list& sessionsList, + std::string& info) +{ + for (const auto& session : sessionsList) { + info += " "; + info += "SourceDeviceId: "; + info += session.GetSourceDeviceId(); + info += ", "; + info += "DestinationDeviceId: "; + info += session.GetDestinationDeviceId(); + info += ", "; + info += "CallerUid: "; + info += std::to_string(session.GetCallerInfo().uid); + info += ", "; + info += "CallerPid: "; + info += std::to_string(session.GetCallerInfo().pid); + info += ", "; + info += "CallerType: "; + info += std::to_string(session.GetCallerInfo().callerType); + DumpElementLocked(session.GetElementsList(), info); + info += "\n"; + } +} + +void DistributedSchedService::DumpElementLocked(const std::list& elementsList, + std::string& info) +{ + for (const auto& element : elementsList) { + info += ", "; + info += "BundleName: "; + info += element.GetBundleName(); + info += ", "; + info += "AbilityName: "; + info += element.GetAbilityName(); + } +} } // namespace DistributedSchedule } // namespace OHOS \ No newline at end of file diff --git a/services/dtbschedmgr/src/distributed_sched_stub.cpp b/services/dtbschedmgr/src/distributed_sched_stub.cpp index 81860af6..7d5fdf8d 100644 --- a/services/dtbschedmgr/src/distributed_sched_stub.cpp +++ b/services/dtbschedmgr/src/distributed_sched_stub.cpp @@ -43,9 +43,15 @@ DistributedSchedStub::DistributedSchedStub() localFuncsMap_[NOTIFY_COMPLETE_CONTINUATION] = &DistributedSchedStub::NotifyCompleteContinuationInner; localFuncsMap_[REGISTER_ABILITY_TOKEN] = &DistributedSchedStub::RegisterAbilityTokenInner; localFuncsMap_[UNREGISTER_ABILITY_TOKEN] = &DistributedSchedStub::UnregisterAbilityTokenInner; + localFuncsMap_[CONNECT_REMOTE_ABILITY] = &DistributedSchedStub::ConnectRemoteAbilityInner; + localFuncsMap_[DISCONNECT_REMOTE_ABILITY] = &DistributedSchedStub::DisconnectRemoteAbilityInner; + remoteFuncsMap_[START_ABILITY_FROM_REMOTE] = &DistributedSchedStub::StartAbilityFromRemoteInner; remoteFuncsMap_[NOTIFY_CONTINUATION_RESULT_FROM_REMOTE] = &DistributedSchedStub::NotifyContinuationResultFromRemoteInner; + remoteFuncsMap_[CONNECT_ABILITY_FROM_REMOTE] = &DistributedSchedStub::ConnectAbilityFromRemoteInner; + remoteFuncsMap_[DISCONNECT_ABILITY_FROM_REMOTE] = &DistributedSchedStub::DisconnectAbilityFromRemoteInner; + remoteFuncsMap_[NOTIFY_PROCESS_DIED_FROM_REMOTE] = &DistributedSchedStub::NotifyProcessDiedFromRemoteInner; } DistributedSchedStub::~DistributedSchedStub() @@ -155,7 +161,7 @@ int32_t DistributedSchedStub::NotifyCompleteContinuationInner(MessageParcel& dat int32_t DistributedSchedStub::NotifyContinuationResultFromRemoteInner(MessageParcel& data, [[maybe_unused]] MessageParcel& reply) { - if (!CheckDmsRequestPermission()) { + if (!CheckCallingUid()) { HILOGW("DistributedSchedStub: NotifyContinuationResultFromRemoteInner request DENIED!"); return DMS_PERMISSION_DENIED; } @@ -185,11 +191,117 @@ int32_t DistributedSchedStub::UnregisterAbilityTokenInner(MessageParcel& data, M PARCEL_WRITE_REPLY_NOERROR(reply, Int32, result); } -bool DistributedSchedStub::CheckDmsRequestPermission() +int32_t DistributedSchedStub::ConnectRemoteAbilityInner(MessageParcel& data, MessageParcel& reply) { - // never allow non-system uid distributed request + shared_ptr want(data.ReadParcelable()); + if (want == nullptr) { + HILOGW("DistributedSchedStub::ConnectRemoteAbilityInner want readParcelable failed!"); + return ERR_NULL_OBJECT; + } + unique_ptr abilityInfo(data.ReadParcelable()); + if (abilityInfo == nullptr) { + HILOGW("DistributedSchedStub::ConnectRemoteAbilityInner abilityInfo readParcelable failed!"); + return ERR_NULL_OBJECT; + } + sptr connect = data.ReadRemoteObject(); + int32_t result = ConnectRemoteAbility(*want, *abilityInfo, connect); + HILOGI("DistributedSchedStub::ConnectRemoteAbilityInner result = %{public}d", result); + PARCEL_WRITE_REPLY_NOERROR(reply, Int32, result); +} + +int32_t DistributedSchedStub::DisconnectRemoteAbilityInner(MessageParcel& data, MessageParcel& reply) +{ + sptr connect = data.ReadRemoteObject(); + int32_t result = DisconnectRemoteAbility(connect); + HILOGI("DistributedSchedStub::DisconnectRemoteAbilityInner result = %{public}d", result); + PARCEL_WRITE_REPLY_NOERROR(reply, Int32, result); +} + +int32_t DistributedSchedStub::ConnectAbilityFromRemoteInner(MessageParcel& data, MessageParcel& reply) +{ + if (!CheckCallingUid()) { + HILOGW("DistributedSchedStub::ConnectAbilityFromRemoteInner request DENIED!"); + return DMS_PERMISSION_DENIED; + } + + shared_ptr want(data.ReadParcelable()); + if (want == nullptr) { + HILOGW("DistributedSchedStub::ConnectAbilityFromRemoteInner want readParcelable failed!"); + return ERR_NULL_OBJECT; + } + unique_ptr abilityInfo(data.ReadParcelable()); + if (abilityInfo == nullptr) { + HILOGW("DistributedSchedStub::ConnectAbilityFromRemoteInner abilityInfo readParcelable failed!"); + return ERR_NULL_OBJECT; + } + sptr connect = data.ReadRemoteObject(); + CallerInfo callerInfo; + PARCEL_READ_HELPER(data, Int32, callerInfo.uid); + PARCEL_READ_HELPER(data, Int32, callerInfo.pid); + PARCEL_READ_HELPER(data, String, callerInfo.sourceDeviceId); + callerInfo.callerType = CALLER_TYPE_HARMONY; + AccountInfo accountInfo; + accountInfo.accountType = data.ReadInt32(); + PARCEL_READ_HELPER(data, StringVector, &accountInfo.groupIdList); + callerInfo.callerAppId = data.ReadString(); + std::string package = abilityInfo->bundleName; + std::string deviceId = abilityInfo->deviceId; + int64_t begin = GetTickCount(); + int32_t result = ConnectAbilityFromRemote(*want, *abilityInfo, connect, callerInfo, accountInfo); + HILOGW("DistributedSchedStub::ConnectAbilityFromRemoteInner result = %{public}d", result); + int64_t end = GetTickCount(); + PARCEL_WRITE_HELPER(reply, Int32, result); + PARCEL_WRITE_HELPER(reply, Int64, end - begin); + PARCEL_WRITE_HELPER(reply, String, package); + PARCEL_WRITE_HELPER(reply, String, deviceId); + return ERR_NONE; +} + +int32_t DistributedSchedStub::DisconnectAbilityFromRemoteInner(MessageParcel& data, MessageParcel& reply) +{ + if (!CheckCallingUid()) { + HILOGW("DistributedSchedStub::DisconnectAbilityFromRemoteInner request DENIED!"); + return DMS_PERMISSION_DENIED; + } + + sptr connect = data.ReadRemoteObject(); + int32_t uid = 0; + PARCEL_READ_HELPER(data, Int32, uid); + string sourceDeviceId; + PARCEL_READ_HELPER(data, String, sourceDeviceId); + int32_t result = DisconnectAbilityFromRemote(connect, uid, sourceDeviceId); + HILOGI("DistributedSchedStub::DisconnectAbilityFromRemoteInner result %{public}d", result); + PARCEL_WRITE_REPLY_NOERROR(reply, Int32, result); +} + +int32_t DistributedSchedStub::NotifyProcessDiedFromRemoteInner(MessageParcel& data, MessageParcel& reply) +{ + if (!CheckCallingUid()) { + HILOGW("DistributedSchedStub::NotifyProcessDiedFromRemoteInner request DENIED!"); + return DMS_PERMISSION_DENIED; + } + + int32_t uid = 0; + PARCEL_READ_HELPER(data, Int32, uid); + int32_t pid = 0; + PARCEL_READ_HELPER(data, Int32, pid); + string sourceDeviceId; + PARCEL_READ_HELPER(data, String, sourceDeviceId); + CallerInfo callerInfo; + callerInfo.uid = uid; + callerInfo.pid = pid; + callerInfo.sourceDeviceId = sourceDeviceId; + callerInfo.callerType = CALLER_TYPE_HARMONY; + int32_t result = NotifyProcessDiedFromRemote(callerInfo); + HILOGI("DistributedSchedStub::NotifyProcessDiedFromRemoteInner result %{public}d", result); + PARCEL_WRITE_REPLY_NOERROR(reply, Int32, result); +} + +bool DistributedSchedStub::CheckCallingUid() +{ + // never allow non-system uid for distributed request auto callingUid = IPCSkeleton::GetCallingUid(); - return (callingUid < HID_HAP); + return callingUid < HID_HAP; } bool DistributedSchedStub::EnforceInterfaceToken(MessageParcel& data) diff --git a/services/dtbschedmgr/src/dtbschedmgr_device_info_storage.cpp b/services/dtbschedmgr/src/dtbschedmgr_device_info_storage.cpp index dcc54817..efa275ea 100755 --- a/services/dtbschedmgr/src/dtbschedmgr_device_info_storage.cpp +++ b/services/dtbschedmgr/src/dtbschedmgr_device_info_storage.cpp @@ -219,7 +219,7 @@ void DtbschedmgrDeviceInfoStorage::OnDeviceInfoChanged(const std::string& device void DnetServiceDeathRecipient::OnRemoteDied(const wptr& remote) { - HILOGE("DnetServiceDeathRecipient::OnRemoteDied dnetwork service died"); + HILOGI("DnetServiceDeathRecipient::OnRemoteDied dnetwork service died"); DtbschedmgrDeviceInfoStorage::GetInstance().Init(); } } diff --git a/services/dtbschedmgr/test/BUILD.gn b/services/dtbschedmgr/test/BUILD.gn index 81b67b20..05aa036c 100644 --- a/services/dtbschedmgr/test/BUILD.gn +++ b/services/dtbschedmgr/test/BUILD.gn @@ -17,62 +17,115 @@ import("//build/test.gni") module_output_path = "dmsfwk/distributedschedsvrtest" +distributed_service = "//foundation/distributedschedule/dmsfwk/services" + +dsched_configs = + [ "${distributed_service}/dtbschedmgr:distributed_sched_config" ] + +dsched_deps = [ + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager", + "//foundation/aafwk/standard/interfaces/innerkits/base:base", + "//foundation/aafwk/standard/interfaces/innerkits/want:want", + "//foundation/appexecfwk/standard/common:libappexecfwk_common", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base:appexecfwk_base", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core", + "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//utils/native/base:utils", +] + +dsched_external_deps = [ + "dsoftbus_standard:softbus_client", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "permission_standard:libpermissionsdk_standard", +] + +dsched_public_deps = [ + "//third_party/googletest:gtest_main", + "//third_party/libxml2:libxml2", +] + +dtbschedmgr_sources = [ + "${distributed_service}/dtbschedmgr/src/ability_connection_wrapper_proxy.cpp", + "${distributed_service}/dtbschedmgr/src/ability_connection_wrapper_stub.cpp", + "${distributed_service}/dtbschedmgr/src/adapter/dnetwork_adapter.cpp", + "${distributed_service}/dtbschedmgr/src/bundle/bundle_manager_internal.cpp", + "${distributed_service}/dtbschedmgr/src/connect_death_recipient.cpp", + "${distributed_service}/dtbschedmgr/src/continuation_callback_death_recipient.cpp", + "${distributed_service}/dtbschedmgr/src/deviceManager/dms_device_info.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_device_node_listener.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_ability_shell.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_adapter.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_continuation.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_dumper.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_permission.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_proxy.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_service.cpp", + "${distributed_service}/dtbschedmgr/src/distributed_sched_stub.cpp", + "${distributed_service}/dtbschedmgr/src/dtbschedmgr_device_info_storage.cpp", +] + ohos_unittest("distributedschedsvrtest") { module_out_path = module_output_path - sources = [ - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/adapter/dnetwork_adapter.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/bundle/bundle_manager_internal.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/continuation_callback_death_recipient.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/deviceManager/dms_device_info.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_device_node_listener.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_ability_shell.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_adapter.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_continuation.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_permission.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_proxy.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_service.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/distributed_sched_stub.cpp", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/src/dtbschedmgr_device_info_storage.cpp", - "unittest/distributed_sched_continuation_test.cpp", - "unittest/distributed_sched_permission_test.cpp", - "unittest/distributed_sched_service_test.cpp", - ] - - include_dirs = [ - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/include", - "//foundation/distributedschedule/dmsfwk/interfaces", - ] - - configs = [ "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr:distributed_sched_config" ] - - deps = [ - "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", - "//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager", - "//foundation/aafwk/standard/interfaces/innerkits/base:base", - "//foundation/aafwk/standard/interfaces/innerkits/want:want", - "//foundation/appexecfwk/standard/common:libappexecfwk_common", - "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base:appexecfwk_base", - "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core", - "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", - "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", - "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", - "//third_party/googletest:gtest_main", - "//utils/native/base:utils", - ] - + sources = [ "unittest/distributed_sched_service_test.cpp" ] + sources += dtbschedmgr_sources + configs = dsched_configs + deps = dsched_deps if (is_standard_system) { - external_deps = [ - "dsoftbus_standard:softbus_client", - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", - "permission_standard:libpermissionsdk_standard", - ] - public_deps = [ "//third_party/libxml2:libxml2" ] + external_deps = dsched_external_deps + public_deps = dsched_public_deps + } +} + +ohos_unittest("dschedcontinuetest") { + module_out_path = module_output_path + + sources = [ "unittest/distributed_sched_continuation_test.cpp" ] + sources += dtbschedmgr_sources + configs = dsched_configs + deps = dsched_deps + if (is_standard_system) { + external_deps = dsched_external_deps + public_deps = dsched_public_deps + } +} + +ohos_unittest("dschedconnecttest") { + module_out_path = module_output_path + + sources = [ "unittest/distributed_sched_connect_test.cpp" ] + sources += dtbschedmgr_sources + configs = dsched_configs + deps = dsched_deps + if (is_standard_system) { + external_deps = dsched_external_deps + public_deps = dsched_public_deps + } +} + +ohos_unittest("dschedpermissiontest") { + module_out_path = module_output_path + + sources = [ "unittest/distributed_sched_permission_test.cpp" ] + sources += dtbschedmgr_sources + configs = dsched_configs + deps = dsched_deps + if (is_standard_system) { + external_deps = dsched_external_deps + public_deps = dsched_public_deps } } group("unittest") { testonly = true - deps = [ ":distributedschedsvrtest" ] + deps = [ + ":distributedschedsvrtest", + ":dschedconnecttest", + ":dschedcontinuetest", + ":dschedpermissiontest", + ] } diff --git a/services/dtbschedmgr/test/unittest/distributed_sched_connect_test.cpp b/services/dtbschedmgr/test/unittest/distributed_sched_connect_test.cpp new file mode 100755 index 00000000..1eb9c745 --- /dev/null +++ b/services/dtbschedmgr/test/unittest/distributed_sched_connect_test.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "distributed_sched_proxy.h" +#include "distributed_sched_service.h" + +#include "gtest/gtest.h" +#include "if_system_ability_manager.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "test_log.h" + +namespace OHOS { +namespace DistributedSchedule { +using namespace testing; +using namespace testing::ext; + +namespace { +constexpr int32_t STDOUT_FD = 1; +} + +class DistributedSchedConnectTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void DistributedSchedConnectTest::SetUpTestCase() +{ +} + +void DistributedSchedConnectTest::TearDownTestCase() +{ +} + +void DistributedSchedConnectTest::SetUp() +{ +} + +void DistributedSchedConnectTest::TearDown() +{ +} + +/** + * @tc.name: DumpConnectInfo_001 + * @tc.desc: dump connect ability info + * @tc.type: FUNC + */ +HWTEST_F(DistributedSchedConnectTest, DumpConnectInfo_001, TestSize.Level1) +{ + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (samgr == nullptr) { + DTEST_LOG << "DistributedSchedServiceTest DumpConnectInfo_001 samgr null" << std::endl; + } else { + DTEST_LOG << "DistributedSchedServiceTest DumpConnectInfo_001 avaiable" << std::endl; + } + + auto dms = samgr->GetSystemAbility(DISTRIBUTED_SCHED_SA_ID); + std::vector args; + args.push_back(u"-connect"); + int32_t result = dms->Dump(STDOUT_FD, args); + DTEST_LOG << "DistributedSchedServiceTest DumpConnectInfo_001 dump result: " << result << std::endl; +} +} +} \ No newline at end of file