!225 添加动态加载

Merge pull request !225 from chen/730
This commit is contained in:
openharmony_ci
2022-08-05 11:10:20 +00:00
committed by Gitee
17 changed files with 496 additions and 66 deletions
@@ -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<IRemoteObject> 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);
@@ -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<ISystemAbilityLoadCallback>& callback)
{
if (!CheckInputSysAbilityId(systemAbilityId) || deviceId.empty() || callback == nullptr) {
HILOGE("LoadSystemAbility systemAbilityId:%{public}d ,deviceId or callback invalid!", systemAbilityId);
return ERR_INVALID_VALUE;
}
sptr<IRemoteObject> 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)) {
@@ -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<IRemoteObject>& procObject) = 0;
virtual int32_t LoadSystemAbility(int32_t systemAbilityId, const sptr<ISystemAbilityLoadCallback>& callback) = 0;
virtual int32_t LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId,
const sptr<ISystemAbilityLoadCallback>& callback) = 0;
public:
DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ISystemAbilityManager");
protected:
@@ -24,13 +24,17 @@ namespace OHOS {
class ISystemAbilityLoadCallback : public IRemoteBroker {
public:
virtual ~ISystemAbilityLoadCallback() = default;
virtual void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject) = 0;
virtual void OnLoadSystemAbilityFail(int32_t systemAbilityId) = 0;
virtual void OnLoadSystemAbilitySuccess([[maybe_unused]] int32_t systemAbilityId,
[[maybe_unused]] const sptr<IRemoteObject>& 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<IRemoteObject>& 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,
};
};
}
@@ -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 */
@@ -45,6 +45,8 @@ public:
int32_t AddSystemProcess(const std::u16string& procName, const sptr<IRemoteObject>& procObject) override;
int32_t LoadSystemAbility(int32_t systemAbilityId, const sptr<ISystemAbilityLoadCallback>& callback) override;
int32_t LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId,
const sptr<ISystemAbilityLoadCallback>& callback) override;
private:
sptr<IRemoteObject> GetSystemAbilityWrapper(int32_t systemAbilityId, const std::string& deviceId = "");
sptr<IRemoteObject> CheckSystemAbilityWrapper(int32_t code, MessageParcel& data);
+1
View File
@@ -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",
@@ -46,6 +46,13 @@ public:
AbilityCallbackDeathRecipient() = default;
~AbilityCallbackDeathRecipient() override = default;
};
class RemoteCallbackDeathRecipient : public IRemoteObject::DeathRecipient {
public:
void OnRemoteDied(const wptr<IRemoteObject>& remote) override;
RemoteCallbackDeathRecipient() = default;
~RemoteCallbackDeathRecipient() override = default;
};
} // namespace OHOS
#endif // !defined(SERVICES_SAMGR_NATIVE_INCLUDE_ABILITY_DEATH_RECIPIENT_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<IRemoteObject> 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<IRemoteObject>& 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
@@ -27,6 +27,8 @@ public:
void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject) override;
void OnLoadSystemAbilityFail(int32_t systemAbilityId) override;
void OnLoadSACompleteForRemote(const std::string& deviceId,
int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject) override;
private:
static inline BrokerDelegator<SystemAbilityLoadCallbackProxy> delegator_;
};
@@ -24,9 +24,10 @@
#include <utility>
#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<IRemoteObject>& procObject);
int32_t LoadSystemAbility(int32_t systemAbilityId, const sptr<ISystemAbilityLoadCallback>& callback) override;
int32_t LoadSystemAbility(int32_t systemAbilityId, const std::string& deviceId,
const sptr<ISystemAbilityLoadCallback>& callback) override;
void OnAbilityCallbackDied(const sptr<IRemoteObject>& remoteObject);
void OnRemoteCallbackDied(const sptr<IRemoteObject>& remoteObject);
sptr<IRemoteObject> GetSystemAbilityFromRemote(int32_t systemAbilityId);
bool LoadSystemAbilityFromRpc(const std::string& srcDeviceId, int32_t systemAbilityId,
const sptr<ISystemAbilityLoadCallback>& callback);
void NotifyRpcLoadCompleted(const std::string& srcDeviceId, int32_t systemAbilityId,
const sptr<IRemoteObject>& remoteObject);
private:
enum class AbilityState {
INIT,
STARTING,
STARTED,
};
using CallbackList = std::list<std::pair<sptr<ISystemAbilityLoadCallback>, int32_t>>;
struct AbilityItem {
AbilityState state = AbilityState::INIT;
std::list<std::pair<sptr<ISystemAbilityLoadCallback>, int32_t>> callbackList;
std::map<std::string, CallbackList> 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<IRemoteObject>& remoteObject);
void RemoveStartingAbilityCallback(CallbackList& callbackList, const sptr<IRemoteObject>& remoteObject);
void RemoveStartingAbilityCallbackForDevice(AbilityItem& abilityItem, const sptr<IRemoteObject>& remoteObject);
void RemoveStartingAbilityCallbackLocked(std::pair<sptr<ISystemAbilityLoadCallback>, 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<ISystemAbilityLoadCallback>& callback);
void RemoveCheckLoadedMsg(int32_t systemAbilityId);
void SendLoadedSystemAblityMsg(int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject,
const sptr<ISystemAbilityLoadCallback>& callback);
void DoLoadRemoteSystemAbility(int32_t systemAbilityId, int32_t callingPid,
int32_t callingUid, const std::string& deviceId, const sptr<ISystemAbilityLoadCallback>& callback);
sptr<DBinderServiceStub> DoMakeRemoteBinder(int32_t systemAbilityId, int32_t callingPid, int32_t callingUid,
const std::string& deviceId);
void RemoveRemoteCallbackLocked(std::list<sptr<ISystemAbilityLoadCallback>>& callbacks,
const sptr<IRemoteObject>& remoteObject);
void CleanCallbackForLoadFailed(int32_t systemAbilityId, const std::u16string& name,
const std::string& srcDeviceId, const sptr<ISystemAbilityLoadCallback>& callback);
std::u16string deviceName_;
static sptr<SystemAbilityManager> instance;
@@ -148,6 +170,7 @@ private:
sptr<IRemoteObject::DeathRecipient> systemProcessDeath_;
sptr<IRemoteObject::DeathRecipient> abilityStatusDeath_;
sptr<IRemoteObject::DeathRecipient> abilityCallbackDeath_;
sptr<IRemoteObject::DeathRecipient> remoteCallbackDeath_;
sptr<DBinderService> dBinderService_;
std::shared_ptr<RpcSystemAbilityCallback> rpcCallbackImp_;
@@ -171,6 +194,11 @@ private:
std::map<int32_t, SaProfile> saProfileMap_;
std::mutex saProfileMapLock_;
std::mutex loadRemoteLock_;
std::map<std::string, std::list<sptr<ISystemAbilityLoadCallback>>> remoteCallbacks_; // key : said_deviceId
ThreadPool loadPool_;
};
} // namespace OHOS
@@ -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);
@@ -47,4 +47,11 @@ void AbilityCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remo
SystemAbilityManager::GetInstance()->OnAbilityCallbackDied(remote.promote());
HILOGD("AbilityCallbackDeathRecipient death notice success");
}
void RemoteCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
{
HILOGI("RemoteCallbackDeathRecipient called!");
SystemAbilityManager::GetInstance()->OnRemoteCallbackDied(remote.promote());
HILOGD("RemoteCallbackDeathRecipient death notice success");
}
} // namespace OHOS
@@ -15,10 +15,36 @@
#include "rpc_callback_imp.h"
#include "system_ability_manager.h"
#include "sam_log.h"
#include "tools.h"
namespace OHOS {
sptr<IRemoteObject> RpcCallbackImp::GetSystemAbilityFromRemote(int32_t systemAbilityId)
{
return SystemAbilityManager::GetInstance()->GetSystemAbilityFromRemote(systemAbilityId);
}
}
bool RpcCallbackImp::LoadSystemAbilityFromRemote(const std::string& srcNetworkId, int32_t systemAbilityId)
{
HILOGI("LoadSystemAbilityFromRemote! deviceId : %{public}s, said : %{public}d",
AnonymizeDeviceId(srcNetworkId).c_str(), systemAbilityId);
sptr<LoadCallbackImp> loadCallback = new LoadCallbackImp(srcNetworkId);
return SystemAbilityManager::GetInstance()->LoadSystemAbilityFromRpc(srcNetworkId,
systemAbilityId, loadCallback);
}
void RpcCallbackImp::LoadCallbackImp::OnLoadSystemAbilitySuccess(int32_t systemAbilityId,
const sptr<IRemoteObject>& 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);
}
}
@@ -96,4 +96,54 @@ void SystemAbilityLoadCallbackProxy::OnLoadSystemAbilityFail(int32_t systemAbili
return;
}
}
void SystemAbilityLoadCallbackProxy::OnLoadSACompleteForRemote(const std::string& deviceId, int32_t systemAbilityId,
const sptr<IRemoteObject>& remoteObject)
{
if (systemAbilityId <= 0) {
HILOGE("OnLoadSACompleteForRemote systemAbilityId:%{public}d invalid!", systemAbilityId);
return;
}
sptr<IRemoteObject> 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;
}
}
}
@@ -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<IRemoteObject::DeathRecipient>(new SystemProcessDeathRecipient());
abilityStatusDeath_ = sptr<IRemoteObject::DeathRecipient>(new AbilityStatusDeathRecipient());
abilityCallbackDeath_ = sptr<IRemoteObject::DeathRecipient>(new AbilityCallbackDeathRecipient());
remoteCallbackDeath_ = sptr<IRemoteObject::DeathRecipient>(new RemoteCallbackDeathRecipient());
rpcCallbackImp_ = make_shared<RpcCallbackImp>();
if (workHandler_ == nullptr) {
auto runner = AppExecFwk::EventRunner::Create("workHandler");
workHandler_ = make_shared<AppExecFwk::EventHandler>(runner);
}
InitSaProfile();
loadPool_.Start(std::thread::hardware_concurrency());
loadPool_.SetMaxTaskNum(std::thread::hardware_concurrency());
}
const sptr<DBinderService> SystemAbilityManager::GetDBinder() const
@@ -195,21 +202,7 @@ bool SystemAbilityManager::CheckDistributedPermission()
sptr<IRemoteObject> SystemAbilityManager::CheckSystemAbility(int32_t systemAbilityId,
const std::string& deviceId)
{
sptr<DBinderServiceStub> 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<ISystemAbilityLoadCallback>& callback)
const std::string& srcDeviceId, const sptr<ISystemAbilityLoadCallback>& 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<recursive_mutex> 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<ISystemAbilityLoadCallback>& callback)
{
lock_guard<recursive_mutex> 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<IRemoteObject>& remoteObject,
const sptr<ISystemAbilityLoadCallback>& 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<IRemoteObject>& remoteObject,
const sptr<ISystemAbilityLoadCallback>& 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<ISystemAbilityLoadCallback>& 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<IRemoteObject> targetObject = CheckSystemAbility(systemAbilityId);
if (targetObject != nullptr) {
SendLoadedSystemAblityMsg(systemAbilityId, targetObject, callback);
return true;
}
{
lock_guard<recursive_mutex> 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<ISystemAbilityLoadCallback>& callback)
{
@@ -865,7 +919,7 @@ int32_t SystemAbilityManager::LoadSystemAbility(int32_t systemAbilityId,
{
lock_guard<recursive_mutex> 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<ISystemAbilityLoadCallback>& callback)
{
std::string key = ToString(systemAbilityId) + "_" + deviceId;
{
lock_guard<mutex> 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<ISystemAbilityLoadCallback>& callback)
{
sptr<DBinderServiceStub> 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<mutex> autoLock(loadRemoteLock_);
if (remoteCallbackDeath_ != nullptr) {
callback->AsObject()->RemoveDeathRecipient(remoteCallbackDeath_);
}
auto& callbacks = remoteCallbacks_[key];
callbacks.remove(callback);
if (callbacks.empty()) {
remoteCallbacks_.erase(key);
}
}
}
sptr<DBinderServiceStub> SystemAbilityManager::DoMakeRemoteBinder(int32_t systemAbilityId, int32_t callingPid,
int32_t callingUid, const std::string& deviceId)
{
HILOGI("MakeRemoteBinder begin, said : %{public}d", systemAbilityId);
sptr<DBinderServiceStub> 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<IRemoteObject>& 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<sptr<ISystemAbilityLoadCallback>, int32_t>& itemPair)
{
@@ -906,16 +1039,31 @@ void SystemAbilityManager::RemoveStartingAbilityCallbackLocked(
}
}
void SystemAbilityManager::RemoveStartingAbilityCallback(AbilityItem& abilityItem,
void SystemAbilityManager::RemoveStartingAbilityCallbackForDevice(AbilityItem& abilityItem,
const sptr<IRemoteObject>& 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<IRemoteObject>& 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<IRemoteObject>& 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<IRemoteObject>& remoteObject)
{
HILOGI("OnRemoteCallbackDied received remoteObject died message!");
lock_guard<mutex> 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<sptr<ISystemAbilityLoadCallback>>& callbacks,
const sptr<IRemoteObject>& 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;
@@ -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<IRemoteObject> remoteObject = data.ReadRemoteObject();
if (remoteObject == nullptr) {
HILOGW("SystemAbilityManagerStub::LoadRemoteSystemAbilityInner read callback failed!");
return ERR_INVALID_VALUE;
}
sptr<ISystemAbilityLoadCallback> callback = iface_cast<ISystemAbilityLoadCallback>(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();