diff --git a/frameworks/native/source/system_ability_load_callback_stub.cpp b/frameworks/native/source/system_ability_load_callback_stub.cpp index a73807c..0034f50 100644 --- a/frameworks/native/source/system_ability_load_callback_stub.cpp +++ b/frameworks/native/source/system_ability_load_callback_stub.cpp @@ -37,6 +37,8 @@ int32_t SystemAbilityLoadCallbackStub::OnRemoteRequest(uint32_t code, return OnLoadSystemAbilitySuccessInner(data, reply); case ON_LOAD_SYSTEM_ABILITY_FAIL: return OnLoadSystemAbilityFailInner(data, reply); + case ON_LOAD_SYSTEM_ABILITY_COMPLETE_FOR_REMOTE: + return OnLoadSACompleteForRemoteInner(data, reply); default: HILOGW("SystemAbilityLoadCallbackStub::OnRemoteRequest unknown request code!"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -66,6 +68,21 @@ int32_t SystemAbilityLoadCallbackStub::OnLoadSystemAbilityFailInner(MessageParce return ERR_NONE; } +int32_t SystemAbilityLoadCallbackStub::OnLoadSACompleteForRemoteInner(MessageParcel& data, MessageParcel& reply) +{ + std::string deviceId = data.ReadString(); + int32_t systemAbilityId = data.ReadInt32(); + if (!CheckInputSystemAbilityId(systemAbilityId)) { + HILOGW("OnLoadSACompleteForRemoteInner invalid systemAbilityId:%{public}d !", systemAbilityId); + return ERR_INVALID_VALUE; + } + bool ret = data.ReadBool(); + HILOGI("OnLoadSACompleteForRemoteInner load : %{public}s", ret ? "succeed" : "failed"); + sptr remoteObject = ret ? data.ReadRemoteObject() : nullptr; + OnLoadSACompleteForRemote(deviceId, systemAbilityId, remoteObject); + return ERR_NONE; +} + bool SystemAbilityLoadCallbackStub::CheckInputSystemAbilityId(int32_t systemAbilityId) { return (systemAbilityId >= FIRST_SYS_ABILITY_ID) && (systemAbilityId <= LAST_SYS_ABILITY_ID); diff --git a/frameworks/native/source/system_ability_manager_proxy.cpp b/frameworks/native/source/system_ability_manager_proxy.cpp index 58928f2..4fb5869 100644 --- a/frameworks/native/source/system_ability_manager_proxy.cpp +++ b/frameworks/native/source/system_ability_manager_proxy.cpp @@ -474,6 +474,57 @@ int32_t SystemAbilityManagerProxy::LoadSystemAbility(int32_t systemAbilityId, return result; } +int32_t SystemAbilityManagerProxy::LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId, + const sptr& callback) +{ + if (!CheckInputSysAbilityId(systemAbilityId) || deviceId.empty() || callback == nullptr) { + HILOGE("LoadSystemAbility systemAbilityId:%{public}d ,deviceId or callback invalid!", systemAbilityId); + return ERR_INVALID_VALUE; + } + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("LoadSystemAbility remote is null!"); + return ERR_INVALID_OPERATION; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(SAMANAGER_INTERFACE_TOKEN)) { + HILOGW("LoadSystemAbility write interface token failed!"); + return ERR_FLATTEN_OBJECT; + } + bool ret = data.WriteInt32(systemAbilityId); + if (!ret) { + HILOGW("LoadSystemAbility write systemAbilityId failed!"); + return ERR_FLATTEN_OBJECT; + } + ret = data.WriteString(deviceId); + if (!ret) { + HILOGW("LoadSystemAbility write deviceId failed!"); + return ERR_FLATTEN_OBJECT; + } + ret = data.WriteRemoteObject(callback->AsObject()); + if (!ret) { + HILOGW("LoadSystemAbility Write callback failed!"); + return ERR_FLATTEN_OBJECT; + } + + MessageParcel reply; + MessageOption option; + int32_t err = remote->SendRequest(LOAD_REMOTE_SYSTEM_ABILITY_TRANSACTION, data, reply, option); + if (err != ERR_NONE) { + HILOGE("LoadSystemAbility systemAbilityId : %{public}d invalid error:%{public}d!", systemAbilityId, err); + return err; + } + HILOGD("LoadSystemAbility systemAbilityId : %{public}d for remote, SendRequest succeed!", systemAbilityId); + int32_t result = 0; + ret = reply.ReadInt32(result); + if (!ret) { + HILOGW("LoadSystemAbility read reply failed for remote!"); + return ERR_FLATTEN_OBJECT; + } + return result; +} + int32_t SystemAbilityManagerProxy::MarshalSAExtraProp(const SAExtraProp& extraProp, MessageParcel& data) const { if (!data.WriteBool(extraProp.isDistributed)) { diff --git a/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h b/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h index 827b992..da72360 100644 --- a/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h +++ b/interfaces/innerkits/samgr_proxy/include/if_system_ability_manager.h @@ -56,6 +56,7 @@ public: LIST_SYSTEM_ABILITY_TRANSACTION = 5, SUBSCRIBE_SYSTEM_ABILITY_TRANSACTION = 6, LOAD_SYSTEM_ABILITY_TRANSACTION = 7, + LOAD_REMOTE_SYSTEM_ABILITY_TRANSACTION = 8, CHECK_REMOTE_SYSTEM_ABILITY_TRANSACTION = 9, ADD_ONDEMAND_SYSTEM_ABILITY_TRANSACTION = 10, CHECK_SYSTEM_ABILITY_IMMEDIATELY_TRANSACTION = 12, @@ -113,6 +114,8 @@ public: virtual int32_t AddSystemProcess(const std::u16string& procName, const sptr& procObject) = 0; virtual int32_t LoadSystemAbility(int32_t systemAbilityId, const sptr& callback) = 0; + virtual int32_t LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId, + const sptr& callback) = 0; public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ISystemAbilityManager"); protected: diff --git a/interfaces/innerkits/samgr_proxy/include/isystem_ability_load_callback.h b/interfaces/innerkits/samgr_proxy/include/isystem_ability_load_callback.h index 01d55ca..088201d 100644 --- a/interfaces/innerkits/samgr_proxy/include/isystem_ability_load_callback.h +++ b/interfaces/innerkits/samgr_proxy/include/isystem_ability_load_callback.h @@ -24,13 +24,17 @@ namespace OHOS { class ISystemAbilityLoadCallback : public IRemoteBroker { public: virtual ~ISystemAbilityLoadCallback() = default; - virtual void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr& remoteObject) = 0; - virtual void OnLoadSystemAbilityFail(int32_t systemAbilityId) = 0; + virtual void OnLoadSystemAbilitySuccess([[maybe_unused]] int32_t systemAbilityId, + [[maybe_unused]] const sptr& remoteObject) {} + virtual void OnLoadSystemAbilityFail([[maybe_unused]] int32_t systemAbilityId) {} + virtual void OnLoadSACompleteForRemote([[maybe_unused]] const std::string& deviceId, + [[maybe_unused]] int32_t systemAbilityId, [[maybe_unused]] const sptr& remoteObject) {} DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ISystemAbilityLoadCallback"); protected: enum { ON_LOAD_SYSTEM_ABILITY_SUCCESS = 1, ON_LOAD_SYSTEM_ABILITY_FAIL = 2, + ON_LOAD_SYSTEM_ABILITY_COMPLETE_FOR_REMOTE = 3, }; }; } diff --git a/interfaces/innerkits/samgr_proxy/include/system_ability_load_callback_stub.h b/interfaces/innerkits/samgr_proxy/include/system_ability_load_callback_stub.h index 9bf201f..0d9a987 100644 --- a/interfaces/innerkits/samgr_proxy/include/system_ability_load_callback_stub.h +++ b/interfaces/innerkits/samgr_proxy/include/system_ability_load_callback_stub.h @@ -30,6 +30,7 @@ private: int32_t OnLoadSystemAbilitySuccessInner(MessageParcel& data, MessageParcel& reply); int32_t OnLoadSystemAbilityFailInner(MessageParcel& data, MessageParcel& reply); + int32_t OnLoadSACompleteForRemoteInner(MessageParcel& data, MessageParcel& reply); }; } #endif /* SAMGR_INTERFACES_INNERKITS_SAMGR_PROXY_INCLUDE_SYSTEM_ABILITY_LOAD_CALLBACK_STUB_H */ diff --git a/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h b/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h index 93304fa..2215dfc 100644 --- a/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h +++ b/interfaces/innerkits/samgr_proxy/include/system_ability_manager_proxy.h @@ -45,6 +45,8 @@ public: int32_t AddSystemProcess(const std::u16string& procName, const sptr& procObject) override; int32_t LoadSystemAbility(int32_t systemAbilityId, const sptr& callback) override; + int32_t LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId, + const sptr& callback) override; private: sptr GetSystemAbilityWrapper(int32_t systemAbilityId, const std::string& deviceId = ""); sptr CheckSystemAbilityWrapper(int32_t code, MessageParcel& data); diff --git a/services/samgr/native/BUILD.gn b/services/samgr/native/BUILD.gn index 4006f0e..b3565ed 100644 --- a/services/samgr/native/BUILD.gn +++ b/services/samgr/native/BUILD.gn @@ -35,6 +35,7 @@ config("sam_config") { ohos_executable("samgr") { install_enable = true sources = [ + "//foundation/distributedschedule/samgr/frameworks/native/source/system_ability_load_callback_stub.cpp", "//foundation/distributedschedule/samgr/services/dfx/source/hisysevent_adapter.cpp", "//foundation/distributedschedule/samgr/services/samgr/native/source/ability_death_recipient.cpp", "//foundation/distributedschedule/samgr/services/samgr/native/source/main.cpp", diff --git a/services/samgr/native/include/ability_death_recipient.h b/services/samgr/native/include/ability_death_recipient.h index 27fe3c9..9e88160 100644 --- a/services/samgr/native/include/ability_death_recipient.h +++ b/services/samgr/native/include/ability_death_recipient.h @@ -46,6 +46,13 @@ public: AbilityCallbackDeathRecipient() = default; ~AbilityCallbackDeathRecipient() override = default; }; + +class RemoteCallbackDeathRecipient : public IRemoteObject::DeathRecipient { +public: + void OnRemoteDied(const wptr& remote) override; + RemoteCallbackDeathRecipient() = default; + ~RemoteCallbackDeathRecipient() override = default; +}; } // namespace OHOS #endif // !defined(SERVICES_SAMGR_NATIVE_INCLUDE_ABILITY_DEATH_RECIPIENT_H_) diff --git a/services/samgr/native/include/rpc_callback_imp.h b/services/samgr/native/include/rpc_callback_imp.h index 86bb39b..faefcf4 100644 --- a/services/samgr/native/include/rpc_callback_imp.h +++ b/services/samgr/native/include/rpc_callback_imp.h @@ -17,13 +17,25 @@ #define SERVICES_SAMGR_NATIVE_INCLUDE_RPC_CALLBACK_IMP_H_ #include "rpc_system_ability_callback.h" +#include "system_ability_load_callback_stub.h" namespace OHOS { class RpcCallbackImp : public RpcSystemAbilityCallback { public: sptr GetSystemAbilityFromRemote(int32_t systemAbilityId) override; + bool LoadSystemAbilityFromRemote(const std::string& srcNetworkId, int32_t systemAbilityId) override; RpcCallbackImp() = default; ~RpcCallbackImp() override = default; +protected: + class LoadCallbackImp : public SystemAbilityLoadCallbackStub { + public: + void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr& remoteObject) override; + void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; + explicit LoadCallbackImp(const std::string& srcNetWorkId) : srcNetWorkId_(srcNetWorkId) {} + ~LoadCallbackImp() override = default; + private: + std::string srcNetWorkId_; + }; }; } // namespace OHOS diff --git a/services/samgr/native/include/system_ability_load_callback_proxy.h b/services/samgr/native/include/system_ability_load_callback_proxy.h index 2f52be4..926ef4a 100644 --- a/services/samgr/native/include/system_ability_load_callback_proxy.h +++ b/services/samgr/native/include/system_ability_load_callback_proxy.h @@ -27,6 +27,8 @@ public: void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr& remoteObject) override; void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; + void OnLoadSACompleteForRemote(const std::string& deviceId, + int32_t systemAbilityId, const sptr& remoteObject) override; private: static inline BrokerDelegator delegator_; }; diff --git a/services/samgr/native/include/system_ability_manager.h b/services/samgr/native/include/system_ability_manager.h index fb764fd..04a7953 100644 --- a/services/samgr/native/include/system_ability_manager.h +++ b/services/samgr/native/include/system_ability_manager.h @@ -24,9 +24,10 @@ #include #include "event_handler.h" -#include "rpc_callback_imp.h" #include "dbinder_service.h" #include "dbinder_service_stub.h" +#include "rpc_callback_imp.h" +#include "thread_pool.h" #include "sa_profiles.h" #include "system_ability_definition.h" #include "system_ability_manager_stub.h" @@ -90,17 +91,27 @@ public: int32_t RemoveSystemProcess(const sptr& procObject); int32_t LoadSystemAbility(int32_t systemAbilityId, const sptr& callback) override; + int32_t LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId, + const sptr& callback) override; void OnAbilityCallbackDied(const sptr& remoteObject); + void OnRemoteCallbackDied(const sptr& remoteObject); sptr GetSystemAbilityFromRemote(int32_t systemAbilityId); + bool LoadSystemAbilityFromRpc(const std::string& srcDeviceId, int32_t systemAbilityId, + const sptr& callback); + void NotifyRpcLoadCompleted(const std::string& srcDeviceId, int32_t systemAbilityId, + const sptr& remoteObject); private: enum class AbilityState { INIT, STARTING, STARTED, }; + + using CallbackList = std::list, int32_t>>; + struct AbilityItem { AbilityState state = AbilityState::INIT; - std::list, int32_t>> callbackList; + std::map callbackMap; // key : networkid }; SystemAbilityManager(); @@ -135,11 +146,22 @@ private: void StartOnDemandAbility(const std::u16string& name, int32_t systemAbilityId); void StartOnDemandAbilityInner(const std::u16string& name, int32_t systemAbilityId, AbilityItem& abilityItem); int32_t StartDynamicSystemProcess(const std::u16string& name, int32_t systemAbilityId); - void RemoveStartingAbilityCallback(AbilityItem& abilityItem, const sptr& remoteObject); + void RemoveStartingAbilityCallback(CallbackList& callbackList, const sptr& remoteObject); + void RemoveStartingAbilityCallbackForDevice(AbilityItem& abilityItem, const sptr& remoteObject); void RemoveStartingAbilityCallbackLocked(std::pair, int32_t>& itemPair); - void SendCheckLoadedMsg(int32_t systemAbilityId, const std::u16string& name, + void SendCheckLoadedMsg(int32_t systemAbilityId, const std::u16string& name, const std::string& srcDeviceId, const sptr& callback); void RemoveCheckLoadedMsg(int32_t systemAbilityId); + void SendLoadedSystemAblityMsg(int32_t systemAbilityId, const sptr& remoteObject, + const sptr& callback); + void DoLoadRemoteSystemAbility(int32_t systemAbilityId, int32_t callingPid, + int32_t callingUid, const std::string& deviceId, const sptr& callback); + sptr DoMakeRemoteBinder(int32_t systemAbilityId, int32_t callingPid, int32_t callingUid, + const std::string& deviceId); + void RemoveRemoteCallbackLocked(std::list>& callbacks, + const sptr& remoteObject); + void CleanCallbackForLoadFailed(int32_t systemAbilityId, const std::u16string& name, + const std::string& srcDeviceId, const sptr& callback); std::u16string deviceName_; static sptr instance; @@ -148,6 +170,7 @@ private: sptr systemProcessDeath_; sptr abilityStatusDeath_; sptr abilityCallbackDeath_; + sptr remoteCallbackDeath_; sptr dBinderService_; std::shared_ptr rpcCallbackImp_; @@ -171,6 +194,11 @@ private: std::map saProfileMap_; std::mutex saProfileMapLock_; + + std::mutex loadRemoteLock_; + std::map>> remoteCallbacks_; // key : said_deviceId + + ThreadPool loadPool_; }; } // namespace OHOS diff --git a/services/samgr/native/include/system_ability_manager_stub.h b/services/samgr/native/include/system_ability_manager_stub.h index 3f0a9cb..6df8119 100644 --- a/services/samgr/native/include/system_ability_manager_stub.h +++ b/services/samgr/native/include/system_ability_manager_stub.h @@ -45,6 +45,7 @@ private: int32_t AddSystemProcessInner(MessageParcel& data, MessageParcel& reply); int32_t RemoveSystemAbilityInner(MessageParcel& data, MessageParcel& reply); int32_t LoadSystemAbilityInner(MessageParcel& data, MessageParcel& reply); + int32_t LoadRemoteSystemAbilityInner(MessageParcel& data, MessageParcel& reply); int32_t UnmarshalingSaExtraProp(MessageParcel& data, SAExtraProp& extraProp); static int32_t GetHapIdMultiuser(int32_t uid); diff --git a/services/samgr/native/source/ability_death_recipient.cpp b/services/samgr/native/source/ability_death_recipient.cpp index 5a420b8..a73e5a2 100644 --- a/services/samgr/native/source/ability_death_recipient.cpp +++ b/services/samgr/native/source/ability_death_recipient.cpp @@ -47,4 +47,11 @@ void AbilityCallbackDeathRecipient::OnRemoteDied(const wptr& remo SystemAbilityManager::GetInstance()->OnAbilityCallbackDied(remote.promote()); HILOGD("AbilityCallbackDeathRecipient death notice success"); } + +void RemoteCallbackDeathRecipient::OnRemoteDied(const wptr& remote) +{ + HILOGI("RemoteCallbackDeathRecipient called!"); + SystemAbilityManager::GetInstance()->OnRemoteCallbackDied(remote.promote()); + HILOGD("RemoteCallbackDeathRecipient death notice success"); +} } // namespace OHOS diff --git a/services/samgr/native/source/rpc_callback_imp.cpp b/services/samgr/native/source/rpc_callback_imp.cpp index d28e770..ebcb61e 100644 --- a/services/samgr/native/source/rpc_callback_imp.cpp +++ b/services/samgr/native/source/rpc_callback_imp.cpp @@ -15,10 +15,36 @@ #include "rpc_callback_imp.h" #include "system_ability_manager.h" +#include "sam_log.h" +#include "tools.h" namespace OHOS { sptr RpcCallbackImp::GetSystemAbilityFromRemote(int32_t systemAbilityId) { return SystemAbilityManager::GetInstance()->GetSystemAbilityFromRemote(systemAbilityId); } -} \ No newline at end of file + +bool RpcCallbackImp::LoadSystemAbilityFromRemote(const std::string& srcNetworkId, int32_t systemAbilityId) +{ + HILOGI("LoadSystemAbilityFromRemote! deviceId : %{public}s, said : %{public}d", + AnonymizeDeviceId(srcNetworkId).c_str(), systemAbilityId); + sptr loadCallback = new LoadCallbackImp(srcNetworkId); + return SystemAbilityManager::GetInstance()->LoadSystemAbilityFromRpc(srcNetworkId, + systemAbilityId, loadCallback); +} + +void RpcCallbackImp::LoadCallbackImp::OnLoadSystemAbilitySuccess(int32_t systemAbilityId, + const sptr& remoteObject) +{ + HILOGI("LoadCallbackImp OnLoadSystemAbilitySuccess! deviceId : %{public}s, said : %{public}d", + AnonymizeDeviceId(srcNetWorkId_).c_str(), systemAbilityId); + SystemAbilityManager::GetInstance()->NotifyRpcLoadCompleted(srcNetWorkId_, systemAbilityId, remoteObject); +} + +void RpcCallbackImp::LoadCallbackImp::OnLoadSystemAbilityFail(int32_t systemAbilityId) +{ + HILOGW("LoadCallbackImp OnLoadSystemAbilityFail! deviceId : %{public}s, said : %{public}d", + AnonymizeDeviceId(srcNetWorkId_).c_str(), systemAbilityId); + SystemAbilityManager::GetInstance()->NotifyRpcLoadCompleted(srcNetWorkId_, systemAbilityId, nullptr); +} +} diff --git a/services/samgr/native/source/system_ability_load_callback_proxy.cpp b/services/samgr/native/source/system_ability_load_callback_proxy.cpp index 29142af..0a27940 100644 --- a/services/samgr/native/source/system_ability_load_callback_proxy.cpp +++ b/services/samgr/native/source/system_ability_load_callback_proxy.cpp @@ -96,4 +96,54 @@ void SystemAbilityLoadCallbackProxy::OnLoadSystemAbilityFail(int32_t systemAbili return; } } + +void SystemAbilityLoadCallbackProxy::OnLoadSACompleteForRemote(const std::string& deviceId, int32_t systemAbilityId, + const sptr& remoteObject) +{ + if (systemAbilityId <= 0) { + HILOGE("OnLoadSACompleteForRemote systemAbilityId:%{public}d invalid!", systemAbilityId); + return; + } + + sptr remote = Remote(); + if (remote == nullptr) { + HILOGE("OnLoadSACompleteForRemote remote is null!"); + return; + } + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + HILOGE("OnLoadSACompleteForRemote write interface token failed!"); + return; + } + bool ret = data.WriteString(deviceId); + if (!ret) { + HILOGE("OnLoadSACompleteForRemote write deviceId failed!"); + return; + } + ret = data.WriteInt32(systemAbilityId); + if (!ret) { + HILOGE("OnLoadSACompleteForRemote write systemAbilityId failed!"); + return; + } + if (remoteObject == nullptr) { + HILOGW("OnLoadSACompleteForRemote remoteObject null!"); + ret = data.WriteBool(false); + } else { + data.WriteBool(true); + ret = data.WriteRemoteObject(remoteObject); + } + + if (!ret) { + HILOGE("OnLoadSACompleteForRemote write failed!"); + return; + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + int32_t status = remote->SendRequest(ON_LOAD_SYSTEM_ABILITY_COMPLETE_FOR_REMOTE, data, reply, option); + if (status != NO_ERROR) { + HILOGE("OnLoadSACompleteForRemote SendRequest failed, return value:%{public}d !", status); + return; + } } +} \ No newline at end of file diff --git a/services/samgr/native/source/system_ability_manager.cpp b/services/samgr/native/source/system_ability_manager.cpp index 8b8fa62..ee7c6da 100644 --- a/services/samgr/native/source/system_ability_manager.cpp +++ b/services/samgr/native/source/system_ability_manager.cpp @@ -39,13 +39,15 @@ using namespace std; namespace OHOS { namespace { const string PREFIX = "/system/profile/"; +const string LOCAL_DEVICE = "local"; + constexpr int32_t MAX_NAME_SIZE = 200; constexpr int32_t SPLIT_NAME_VECTOR_SIZE = 2; constexpr int32_t UID_ROOT = 0; constexpr int32_t UID_SYSTEM = 1000; constexpr int32_t MAX_SUBSCRIBE_COUNT = 256; -constexpr int64_t CHECK_LOADED_DELAY_TIME = 60 * 1000; // ms +constexpr int64_t CHECK_LOADED_DELAY_TIME = 4 * 1000; // ms } std::mutex SystemAbilityManager::instanceLock; @@ -58,6 +60,7 @@ SystemAbilityManager::SystemAbilityManager() SystemAbilityManager::~SystemAbilityManager() { + loadPool_.Stop(); } void SystemAbilityManager::Init() @@ -66,12 +69,16 @@ void SystemAbilityManager::Init() systemProcessDeath_ = sptr(new SystemProcessDeathRecipient()); abilityStatusDeath_ = sptr(new AbilityStatusDeathRecipient()); abilityCallbackDeath_ = sptr(new AbilityCallbackDeathRecipient()); + remoteCallbackDeath_ = sptr(new RemoteCallbackDeathRecipient()); + rpcCallbackImp_ = make_shared(); if (workHandler_ == nullptr) { auto runner = AppExecFwk::EventRunner::Create("workHandler"); workHandler_ = make_shared(runner); } InitSaProfile(); + loadPool_.Start(std::thread::hardware_concurrency()); + loadPool_.SetMaxTaskNum(std::thread::hardware_concurrency()); } const sptr SystemAbilityManager::GetDBinder() const @@ -195,21 +202,7 @@ bool SystemAbilityManager::CheckDistributedPermission() sptr SystemAbilityManager::CheckSystemAbility(int32_t systemAbilityId, const std::string& deviceId) { - sptr remoteBinder = nullptr; - if (dBinderService_ != nullptr) { - string strName = to_string(systemAbilityId); - HILOGI("CheckSystemAbility, MakeRemoteBinder begin, systemAbilityId is %{public}d, deviceId is %s", - systemAbilityId, deviceId.c_str()); - remoteBinder = dBinderService_->MakeRemoteBinder(Str8ToStr16(strName), deviceId, systemAbilityId, 0); - if (remoteBinder == nullptr) { - HILOGE("MakeRemoteBinder error, remoteBinder is null, systemAbilityId is %{public}d, deviceId is %s", - systemAbilityId, deviceId.c_str()); - } else { - HILOGI("CheckSystemAbility, MakeRemoteBinder end, systemAbilityId is %{public}d, deviceId is %s", - systemAbilityId, deviceId.c_str()); - } - } - return remoteBinder; + return DoMakeRemoteBinder(systemAbilityId, IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid(), deviceId); } int32_t SystemAbilityManager::FindSystemAbilityNotify(int32_t systemAbilityId, int32_t code) @@ -719,45 +712,20 @@ void SystemAbilityManager::SendSystemAbilityRemovedMsg(int32_t systemAbilityId) } void SystemAbilityManager::SendCheckLoadedMsg(int32_t systemAbilityId, const std::u16string& name, - const sptr& callback) + const std::string& srcDeviceId, const sptr& callback) { if (workHandler_ == nullptr) { HILOGE("SendCheckLoadedMsg work handler not initialized!"); return; } - auto delayTask = [systemAbilityId, name, callback, this]() { + auto delayTask = [systemAbilityId, name, srcDeviceId, callback, this]() { HILOGI("SendCheckLoadedMsg handle for SA : %{public}d.", systemAbilityId); if (CheckSystemAbility(systemAbilityId) != nullptr) { HILOGI("SendCheckLoadedMsg SA : %{public}d loaded.", systemAbilityId); return; } - { - lock_guard autoLock(onDemandLock_); - auto iter = startingAbilityMap_.find(systemAbilityId); - if (iter == startingAbilityMap_.end()) { - HILOGI("SendCheckLoadedMsg SA : %{public}d not in startingAbilityMap.", systemAbilityId); - return; - } - auto& abilityItem = iter->second; - for (auto& callbackItem : abilityItem.callbackList) { - if (callback->AsObject() == callbackItem.first->AsObject()) { - NotifySystemAbilityLoadFail(systemAbilityId, callbackItem.first); - RemoveStartingAbilityCallbackLocked(callbackItem); - abilityItem.callbackList.remove(callbackItem); - break; - } - } - if (abilityItem.callbackList.empty()) { - HILOGI("SendCheckLoadedMsg startingAbilityMap remove SA : %{public}d.", systemAbilityId); - startingAbilityMap_.erase(iter); - } - auto iterStarting = startingProcessMap_.find(name); - if (iterStarting != startingProcessMap_.end()) { - HILOGI("SendCheckLoadedMsg clean process:%{public}s", Str16ToStr8(name).c_str()); - startingProcessMap_.erase(iterStarting); - } - } + CleanCallbackForLoadFailed(systemAbilityId, name, srcDeviceId, callback); (void)GetSystemProcess(name); }; bool ret = workHandler_->PostTask(delayTask, ToString(systemAbilityId), CHECK_LOADED_DELAY_TIME); @@ -765,6 +733,40 @@ void SystemAbilityManager::SendCheckLoadedMsg(int32_t systemAbilityId, const std systemAbilityId, ret ? "success" : "failed"); } +void SystemAbilityManager::CleanCallbackForLoadFailed(int32_t systemAbilityId, const std::u16string& name, + const std::string& srcDeviceId, const sptr& callback) +{ + lock_guard autoLock(onDemandLock_); + auto iterStarting = startingProcessMap_.find(name); + if (iterStarting != startingProcessMap_.end()) { + HILOGI("CleanCallback clean process:%{public}s", Str16ToStr8(name).c_str()); + startingProcessMap_.erase(iterStarting); + } + auto iter = startingAbilityMap_.find(systemAbilityId); + if (iter == startingAbilityMap_.end()) { + HILOGI("CleanCallback SA : %{public}d not in startingAbilityMap.", systemAbilityId); + return; + } + auto& abilityItem = iter->second; + for (auto& callbackItem : abilityItem.callbackMap[srcDeviceId]) { + if (callback->AsObject() == callbackItem.first->AsObject()) { + NotifySystemAbilityLoadFail(systemAbilityId, callbackItem.first); + RemoveStartingAbilityCallbackLocked(callbackItem); + abilityItem.callbackMap[srcDeviceId].remove(callbackItem); + break; + } + } + if (abilityItem.callbackMap[srcDeviceId].empty()) { + HILOGI("CleanCallback startingAbilityMap remove SA : %{public}d. with deviceId", systemAbilityId); + abilityItem.callbackMap.erase(srcDeviceId); + } + + if (abilityItem.callbackMap.empty()) { + HILOGI("CleanCallback startingAbilityMap remove SA : %{public}d.", systemAbilityId); + startingAbilityMap_.erase(iter); + } +} + void SystemAbilityManager::RemoveCheckLoadedMsg(int32_t systemAbilityId) { if (workHandler_ == nullptr) { @@ -774,6 +776,22 @@ void SystemAbilityManager::RemoveCheckLoadedMsg(int32_t systemAbilityId) workHandler_->RemoveTask(ToString(systemAbilityId)); } +void SystemAbilityManager::SendLoadedSystemAblityMsg(int32_t systemAbilityId, const sptr& remoteObject, + const sptr& callback) +{ + if (workHandler_ == nullptr) { + HILOGE("SendLoadedSystemAblityMsg work handler not initialized!"); + return; + } + auto notifyLoadedTask = [systemAbilityId, remoteObject, callback, this]() { + NotifySystemAbilityLoaded(systemAbilityId, remoteObject, callback); + }; + bool ret = workHandler_->PostTask(notifyLoadedTask); + if (!ret) { + HILOGW("SendLoadedSystemAblityMsg PostTask failed!"); + } +} + void SystemAbilityManager::NotifySystemAbilityLoaded(int32_t systemAbilityId, const sptr& remoteObject, const sptr& callback) { @@ -793,9 +811,11 @@ void SystemAbilityManager::NotifySystemAbilityLoaded(int32_t systemAbilityId, co return; } auto& abilityItem = iter->second; - for (auto& callbackItem : abilityItem.callbackList) { - NotifySystemAbilityLoaded(systemAbilityId, remoteObject, callbackItem.first); - RemoveStartingAbilityCallbackLocked(callbackItem); + for (auto& [deviceId, callbackList] : abilityItem.callbackMap) { + for (auto& callbackItem : callbackList) { + NotifySystemAbilityLoaded(systemAbilityId, remoteObject, callbackItem.first); + RemoveStartingAbilityCallbackLocked(callbackItem); + } } startingAbilityMap_.erase(iter); } @@ -841,6 +861,40 @@ int32_t SystemAbilityManager::StartingSystemProcess(const std::u16string& procNa return result; } +bool SystemAbilityManager::LoadSystemAbilityFromRpc(const std::string& srcDeviceId, int32_t systemAbilityId, + const sptr& callback) +{ + if (!CheckInputSysAbilityId(systemAbilityId) || callback == nullptr) { + HILOGW("LoadSystemAbility said or callback invalid!"); + return false; + } + SaProfile saProfile; + bool ret = GetSaProfile(systemAbilityId, saProfile); + if (!ret) { + HILOGE("LoadSystemAbilityFromRpc said:%{public}d not supported!", systemAbilityId); + return false; + } + + if (!saProfile.distributed) { + HILOGE("LoadSystemAbilityFromRpc said:%{public}d not distributed!", systemAbilityId); + return false; + } + + sptr targetObject = CheckSystemAbility(systemAbilityId); + if (targetObject != nullptr) { + SendLoadedSystemAblityMsg(systemAbilityId, targetObject, callback); + return true; + } + { + lock_guard autoLock(onDemandLock_); + auto& abilityItem = startingAbilityMap_[systemAbilityId]; + abilityItem.callbackMap[srcDeviceId].emplace_back(callback, 0); + StartingSystemProcess(saProfile.process, systemAbilityId); + } + SendCheckLoadedMsg(systemAbilityId, saProfile.process, srcDeviceId, callback); + return true; +} + int32_t SystemAbilityManager::LoadSystemAbility(int32_t systemAbilityId, const sptr& callback) { @@ -865,7 +919,7 @@ int32_t SystemAbilityManager::LoadSystemAbility(int32_t systemAbilityId, { lock_guard autoLock(onDemandLock_); auto& abilityItem = startingAbilityMap_[systemAbilityId]; - for (const auto& itemCallback : abilityItem.callbackList) { + for (const auto& itemCallback : abilityItem.callbackMap[LOCAL_DEVICE]) { if (callback->AsObject() == itemCallback.first->AsObject()) { HILOGI("LoadSystemAbility already existed callback object systemAbilityId:%{public}d", systemAbilityId); return ERR_OK; @@ -877,7 +931,7 @@ int32_t SystemAbilityManager::LoadSystemAbility(int32_t systemAbilityId, return ERR_PERMISSION_DENIED; } ++count; - abilityItem.callbackList.emplace_back(callback, callingPid); + abilityItem.callbackMap[LOCAL_DEVICE].emplace_back(callback, callingPid); if (abilityCallbackDeath_ != nullptr) { ret = callback->AsObject()->AddDeathRecipient(abilityCallbackDeath_); HILOGI("LoadSystemAbility systemAbilityId:%{public}d AddDeathRecipient %{public}s", @@ -885,12 +939,91 @@ int32_t SystemAbilityManager::LoadSystemAbility(int32_t systemAbilityId, } result = StartingSystemProcess(saProfile.process, systemAbilityId); HILOGI("LoadSystemAbility systemAbilityId:%{public}d size : %{public}zu", - systemAbilityId, abilityItem.callbackList.size()); + systemAbilityId, abilityItem.callbackMap[LOCAL_DEVICE].size()); } - SendCheckLoadedMsg(systemAbilityId, saProfile.process, callback); + SendCheckLoadedMsg(systemAbilityId, saProfile.process, LOCAL_DEVICE, callback); return result; } +int32_t SystemAbilityManager::LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId, + const sptr& callback) +{ + std::string key = ToString(systemAbilityId) + "_" + deviceId; + { + lock_guard autoLock(loadRemoteLock_); + auto& callbacks = remoteCallbacks_[key]; + auto iter = std::find_if(callbacks.begin(), callbacks.end(), [callback](auto itemCallback) { + return callback->AsObject() == itemCallback->AsObject(); + }); + if (iter != callbacks.end()) { + HILOGI("LoadSystemAbility already existed callback object systemAbilityId:%{public}d", systemAbilityId); + return ERR_OK; + } + if (remoteCallbackDeath_ != nullptr) { + bool ret = callback->AsObject()->AddDeathRecipient(remoteCallbackDeath_); + HILOGI("LoadSystemAbility systemAbilityId:%{public}d AddDeathRecipient %{public}s", + systemAbilityId, ret ? "succeed" : "failed"); + } + callbacks.emplace_back(callback); + } + auto callingPid = IPCSkeleton::GetCallingPid(); + auto callingUid = IPCSkeleton::GetCallingUid(); + auto task = std::bind(&SystemAbilityManager::DoLoadRemoteSystemAbility, this, + systemAbilityId, callingPid, callingUid, deviceId, callback); + loadPool_.AddTask(task); + return ERR_OK; +} + +void SystemAbilityManager::DoLoadRemoteSystemAbility(int32_t systemAbilityId, int32_t callingPid, + int32_t callingUid, const std::string& deviceId, const sptr& callback) +{ + sptr remoteBinder = DoMakeRemoteBinder(systemAbilityId, callingPid, callingUid, deviceId); + + if (callback == nullptr) { + HILOGI("DoLoadRemoteSystemAbility return, callback is nullptr, said : %{public}d", systemAbilityId); + return; + } + callback->OnLoadSACompleteForRemote(deviceId, systemAbilityId, remoteBinder); + std::string key = ToString(systemAbilityId) + "_" + deviceId; + { + lock_guard autoLock(loadRemoteLock_); + if (remoteCallbackDeath_ != nullptr) { + callback->AsObject()->RemoveDeathRecipient(remoteCallbackDeath_); + } + auto& callbacks = remoteCallbacks_[key]; + callbacks.remove(callback); + if (callbacks.empty()) { + remoteCallbacks_.erase(key); + } + } +} + +sptr SystemAbilityManager::DoMakeRemoteBinder(int32_t systemAbilityId, int32_t callingPid, + int32_t callingUid, const std::string& deviceId) +{ + HILOGI("MakeRemoteBinder begin, said : %{public}d", systemAbilityId); + sptr remoteBinder = nullptr; + if (dBinderService_ != nullptr) { + string strName = to_string(systemAbilityId); + remoteBinder = dBinderService_->MakeRemoteBinder(Str8ToStr16(strName), + deviceId, systemAbilityId, callingPid, callingUid); + } + HILOGI("MakeRemoteBinder end, result %{public}s, said : %{public}d, deviceId : %{public}s", + remoteBinder == nullptr ? " failed" : "succeed", systemAbilityId, AnonymizeDeviceId(deviceId).c_str()); + return remoteBinder; +} + +void SystemAbilityManager::NotifyRpcLoadCompleted(const std::string& srcDeviceId, int32_t systemAbilityId, + const sptr& remoteObject) +{ + if (dBinderService_ != nullptr) { + dBinderService_->LoadSystemAbilityComplete(srcDeviceId, systemAbilityId, remoteObject); + return; + } + HILOGW("NotifyRpcLoadCompleted failed, said: %{public}d, deviceId : %{public}s", + systemAbilityId, AnonymizeDeviceId(srcDeviceId).c_str()); +} + void SystemAbilityManager::RemoveStartingAbilityCallbackLocked( std::pair, int32_t>& itemPair) { @@ -906,16 +1039,31 @@ void SystemAbilityManager::RemoveStartingAbilityCallbackLocked( } } -void SystemAbilityManager::RemoveStartingAbilityCallback(AbilityItem& abilityItem, +void SystemAbilityManager::RemoveStartingAbilityCallbackForDevice(AbilityItem& abilityItem, const sptr& remoteObject) { - auto& callbacks = abilityItem.callbackList; - auto iterCallback = callbacks.begin(); - while (iterCallback != callbacks.end()) { + auto& callbacks = abilityItem.callbackMap; + auto iter = callbacks.begin(); + while (iter != callbacks.end()) { + CallbackList& callbackList = iter->second; + RemoveStartingAbilityCallback(callbackList, remoteObject); + if (callbackList.empty()) { + callbacks.erase(iter++); + } else { + ++iter; + } + } +} + +void SystemAbilityManager::RemoveStartingAbilityCallback(CallbackList& callbackList, + const sptr& remoteObject) +{ + auto iterCallback = callbackList.begin(); + while (iterCallback != callbackList.end()) { auto& callbackPair = *iterCallback; if (callbackPair.first->AsObject() == remoteObject) { RemoveStartingAbilityCallbackLocked(callbackPair); - iterCallback = callbacks.erase(iterCallback); + iterCallback = callbackList.erase(iterCallback); break; } else { ++iterCallback; @@ -930,15 +1078,45 @@ void SystemAbilityManager::OnAbilityCallbackDied(const sptr& remo auto iter = startingAbilityMap_.begin(); while (iter != startingAbilityMap_.end()) { AbilityItem& abilityItem = iter->second; - RemoveStartingAbilityCallback(abilityItem, remoteObject); - if (abilityItem.callbackList.empty()) { - iter = startingAbilityMap_.erase(iter); + RemoveStartingAbilityCallbackForDevice(abilityItem, remoteObject); + if (abilityItem.callbackMap.empty()) { + startingAbilityMap_.erase(iter++); } else { ++iter; } } } +void SystemAbilityManager::OnRemoteCallbackDied(const sptr& remoteObject) +{ + HILOGI("OnRemoteCallbackDied received remoteObject died message!"); + lock_guard autoLock(loadRemoteLock_); + auto iter = remoteCallbacks_.begin(); + while (iter != remoteCallbacks_.end()) { + auto& callbacks = iter->second; + RemoveRemoteCallbackLocked(callbacks, remoteObject); + if (callbacks.empty()) { + remoteCallbacks_.erase(iter++); + } else { + ++iter; + } + } +} + +void SystemAbilityManager::RemoveRemoteCallbackLocked(std::list>& callbacks, + const sptr& remoteObject) +{ + for (const auto& callback : callbacks) { + if (callback->AsObject() == remoteObject) { + if (remoteCallbackDeath_ != nullptr) { + callback->AsObject()->RemoveDeathRecipient(remoteCallbackDeath_); + } + callbacks.remove(callback); + break; + } + } +} + std::string SystemAbilityManager::TransformDeviceId(const std::string& deviceId, int32_t type, bool isPrivate) { return isPrivate ? std::string() : deviceId; diff --git a/services/samgr/native/source/system_ability_manager_stub.cpp b/services/samgr/native/source/system_ability_manager_stub.cpp index da73998..5b168dc 100644 --- a/services/samgr/native/source/system_ability_manager_stub.cpp +++ b/services/samgr/native/source/system_ability_manager_stub.cpp @@ -125,6 +125,8 @@ SystemAbilityManagerStub::SystemAbilityManagerStub() &SystemAbilityManagerStub::AddSystemProcessInner; memberFuncMap_[LOAD_SYSTEM_ABILITY_TRANSACTION] = &SystemAbilityManagerStub::LoadSystemAbilityInner; + memberFuncMap_[LOAD_REMOTE_SYSTEM_ABILITY_TRANSACTION] = + &SystemAbilityManagerStub::LoadRemoteSystemAbilityInner; } int32_t SystemAbilityManagerStub::OnRemoteRequest(uint32_t code, @@ -547,6 +549,44 @@ int32_t SystemAbilityManagerStub::LoadSystemAbilityInner(MessageParcel& data, Me return result; } +int32_t SystemAbilityManagerStub::LoadRemoteSystemAbilityInner(MessageParcel& data, MessageParcel& reply) +{ + int32_t systemAbilityId = data.ReadInt32(); + if (!CheckInputSysAbilityId(systemAbilityId)) { + HILOGW("SystemAbilityManagerStub::LoadRemoteSystemAbilityInner systemAbilityId invalid"); + return ERR_INVALID_VALUE; + } + + if (!CheckGetRemoteSAPermission(systemAbilityId)) { + HILOGE("LoadRemoteSystemAbilityInner selinux permission denied!SA : %{public}d", systemAbilityId); + return ERR_PERMISSION_DENIED; + } + + std::string deviceId = data.ReadString(); + if (deviceId.empty()) { + HILOGW("SystemAbilityManagerStub::LoadRemoteSystemAbilityInner read deviceId failed"); + return ERR_INVALID_VALUE; + } + sptr remoteObject = data.ReadRemoteObject(); + if (remoteObject == nullptr) { + HILOGW("SystemAbilityManagerStub::LoadRemoteSystemAbilityInner read callback failed!"); + return ERR_INVALID_VALUE; + } + sptr callback = iface_cast(remoteObject); + if (callback == nullptr) { + HILOGW("SystemAbilityManagerStub::LoadRemoteSystemAbilityInner iface_cast failed!"); + return ERR_INVALID_VALUE; + } + int32_t result = LoadSystemAbility(systemAbilityId, deviceId, callback); + HILOGD("SystemAbilityManagerStub::LoadRemoteSystemAbilityInner result is %{public}d", result); + bool ret = reply.WriteInt32(result); + if (!ret) { + HILOGW("SystemAbilityManagerStub::LoadRemoteSystemAbilityInner write reply failed."); + return ERR_FLATTEN_OBJECT; + } + return result; +} + bool SystemAbilityManagerStub::CanRequest() { auto accessTokenId = IPCSkeleton::GetCallingTokenID();