未验证 提交 2bf73ced 编写于 作者: O openharmony_ci 提交者: Gitee

!306 动态拉起SA

Merge pull request !306 from wanghaoxu/master
......@@ -102,7 +102,7 @@ public:
static sptr<DBinderService> GetInstance();
bool StartDBinderService(std::shared_ptr<RpcSystemAbilityCallback> &callbackImpl);
sptr<DBinderServiceStub> MakeRemoteBinder(const std::u16string &serviceName,
const std::string &deviceID, binder_uintptr_t binderObject, uint64_t pid = 0);
const std::string &deviceID, binder_uintptr_t binderObject, uint32_t pid = 0, uint32_t uid = 0);
bool RegisterRemoteProxy(std::u16string serviceName, sptr<IRemoteObject> binderObject);
bool RegisterRemoteProxy(std::u16string serviceName, int32_t systemAbilityId);
bool OnRemoteMessageTask(const struct DHandleEntryTxRx *message);
......@@ -119,6 +119,8 @@ public:
std::string CreateDatabusName(int uid, int pid);
bool DetachProxyObject(binder_uintptr_t binderObject);
std::string QueryBusNameObject(IPCObjectProxy *proxy);
void LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId,
const sptr<IRemoteObject>& remoteObject);
private:
static std::shared_ptr<DBinderRemoteListener> GetRemoteListener();
......@@ -126,7 +128,7 @@ private:
static void StopRemoteListener();
static std::string ConvertToSecureDeviceID(const std::string &deviceID);
std::u16string GetRegisterService(binder_uintptr_t binderObject);
bool InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber);
bool InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid, uint32_t uid);
bool OnRemoteReplyMessage(const struct DHandleEntryTxRx *replyMessage);
void MakeSessionByReplyMessage(const struct DHandleEntryTxRx *replyMessage);
bool OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message);
......@@ -139,7 +141,7 @@ private:
bool DetachSessionObject(binder_uintptr_t stub);
bool AttachSessionObject(std::shared_ptr<struct SessionInfo> object, binder_uintptr_t stub);
sptr<IRemoteObject> FindOrNewProxy(binder_uintptr_t binderObject, int32_t systemAbilityId);
bool SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber);
bool SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid, uint32_t uid);
uint16_t AllocFreeSocketPort();
std::string GetLocalDeviceID();
bool CheckBinderObject(const sptr<DBinderServiceStub> &stub, binder_uintptr_t binderObject);
......@@ -167,11 +169,14 @@ private:
struct DHandleEntryTxRx *replyMessage);
bool ReStartRemoteListener();
bool ReGrantPermission(const std::string &sessionName);
bool IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId,
std::shared_ptr<DHandleEntryTxRx> loadSaItem);
std::shared_ptr<struct DHandleEntryTxRx> PopLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId);
private:
DISALLOW_COPY_AND_MOVE(DBinderService);
static std::mutex instanceMutex_;
static constexpr int WAIT_FOR_REPLY_MAX_SEC = 4;
static constexpr int WAIT_FOR_REPLY_MAX_SEC = 8;
static constexpr int RETRY_TIMES = 2;
static std::shared_ptr<DBinderRemoteListener> remoteListener_;
static bool mainThreadCreated_;
......@@ -182,6 +187,7 @@ private:
std::shared_mutex proxyMutex_;
std::shared_mutex deathRecipientMutex_;
std::shared_mutex sessionMutex_;
std::shared_mutex loadSaMutex_;
std::mutex handleEntryMutex_;
std::mutex threadLockMutex_;
......@@ -197,6 +203,7 @@ private:
std::map<sptr<IRemoteObject>, DBinderServiceStub *> noticeProxy_;
std::map<sptr<IRemoteObject>, sptr<IRemoteObject::DeathRecipient>> deathRecipients_;
std::map<IPCObjectProxy *, std::string> busNameObject_;
std::list<std::shared_ptr<struct DHandleEntryTxRx>> loadSaReply_;
static constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000001;
static constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff;
......
......@@ -21,12 +21,8 @@
namespace OHOS {
class RpcSystemAbilityCallback {
public:
using OnLoadSystemAbilityComplete = std::function<void(const std::string& srcNetworkId,
int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject)>;
virtual sptr<IRemoteObject> GetSystemAbilityFromRemote(int32_t systemAbilityId) = 0;
virtual bool LoadSystemAbilityFromRemote(const std::string& srcNetworkId, int32_t systemAbilityId,
OnLoadSystemAbilityComplete callback)
virtual bool LoadSystemAbilityFromRemote(const std::string& srcNetworkId, int32_t systemAbilityId)
{
return false;
};
......
......@@ -53,6 +53,7 @@ DBinderService::~DBinderService()
noticeProxy_.clear();
deathRecipients_.clear();
busNameObject_.clear();
loadSaReply_.clear();
dbinderCallback_ = nullptr;
DBINDER_LOGI("dbinder service died");
......@@ -156,7 +157,6 @@ sptr<DBinderService> DBinderService::GetInstance()
instance_ = temp;
}
}
return instance_;
}
......@@ -262,7 +262,7 @@ sptr<DBinderServiceStub> DBinderService::FindOrNewDBinderStub(const std::u16stri
}
sptr<DBinderServiceStub> DBinderService::MakeRemoteBinder(const std::u16string &serviceName,
const std::string &deviceID, binder_uintptr_t binderObject, uint64_t pid)
const std::string &deviceID, binder_uintptr_t binderObject, uint32_t pid, uint32_t uid)
{
if (IsDeviceIdIllegal(deviceID) || serviceName.length() == 0) {
DBINDER_LOGE("para is wrong device id length = %zu, service name length = %zu", deviceID.length(),
......@@ -284,7 +284,7 @@ sptr<DBinderServiceStub> DBinderService::MakeRemoteBinder(const std::u16string &
int retryTimes = 0;
bool ret = false;
do {
ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber());
ret = InvokerRemoteDBinder(dBinderServiceStub, GetSeqNumber(), pid, uid);
retryTimes++;
} while (!ret && (retryTimes < RETRY_TIMES));
......@@ -299,7 +299,8 @@ sptr<DBinderServiceStub> DBinderService::MakeRemoteBinder(const std::u16string &
return dBinderServiceStub;
}
bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber)
bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint32_t seqNumber, uint32_t pid,
uint32_t uid)
{
const std::string deviceID = stub->GetDeviceID();
const std::string localDevID = GetLocalDeviceID();
......@@ -319,8 +320,8 @@ bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint
message->binderObject = stub->GetBinderObject();
message->stub = reinterpret_cast<binder_uintptr_t>(stub.GetRefPtr());
message->deviceIdInfo.afType = DATABBUS_TYPE;
message->pid = static_cast<uint32_t>(IPCSkeleton::GetCallingPid());
message->uid = static_cast<uint32_t>(IPCSkeleton::GetCallingUid());
message->pid = pid;
message->uid = uid;
if (memcpy_s(message->deviceIdInfo.fromDeviceId, DEVICEID_LENGTH, localDevID.data(), localDevID.length()) != 0 ||
memcpy_s(message->deviceIdInfo.toDeviceId, DEVICEID_LENGTH, deviceID.data(), deviceID.length()) != 0) {
DBINDER_LOGE("fail to copy memory");
......@@ -342,13 +343,14 @@ bool DBinderService::SendEntryToRemote(const sptr<DBinderServiceStub> stub, uint
return true;
}
bool DBinderService::InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber)
bool DBinderService::InvokerRemoteDBinder(const sptr<DBinderServiceStub> stub, uint32_t seqNumber,
uint32_t pid, uint32_t uid)
{
if (stub == nullptr) {
DBINDER_LOGE("stub is nullptr");
return false;
}
bool result = SendEntryToRemote(stub, seqNumber);
bool result = SendEntryToRemote(stub, seqNumber, pid, uid);
if (!result) {
DBINDER_LOGE("send entry to remote dbinderService fail");
return false;
......@@ -384,88 +386,107 @@ bool DBinderService::CheckSystemAbilityId(int32_t systemAbilityId)
return systemAbilityId >= FIRST_SYS_ABILITY_ID && systemAbilityId <= LAST_SYS_ABILITY_ID;
}
sptr<IRemoteObject> DBinderService::FindOrNewProxy(binder_uintptr_t binderObject, int32_t systemAbilityId)
uint16_t DBinderService::AllocFreeSocketPort()
{
/* alloc port by system */
return 0;
}
bool DBinderService::IsSameLoadSaItem(const std::string& srcNetworkId, int32_t systemAbilityId,
std::shared_ptr<DHandleEntryTxRx> loadSaItem)
{
sptr<IRemoteObject> proxy = QueryProxyObject(binderObject);
if (proxy != nullptr) {
DBINDER_LOGI("already have proxy");
return proxy;
if (static_cast<int32_t>(loadSaItem->stubIndex) == systemAbilityId &&
loadSaItem->deviceIdInfo.fromDeviceId == srcNetworkId) {
DBINDER_LOGI("match succeed");
return true;
}
if (dbinderCallback_ == nullptr) {
DBINDER_LOGE("samgr not initialized get remote sa callback");
return false;
}
std::shared_ptr<DHandleEntryTxRx> DBinderService::PopLoadSaItem(const std::string& srcNetworkId,
int32_t systemAbilityId)
{
auto checkSaItem = [srcNetworkId, systemAbilityId, this](std::shared_ptr<DHandleEntryTxRx> loadSaItem) {
return IsSameLoadSaItem(srcNetworkId, systemAbilityId, loadSaItem);
};
auto it = std::find_if(loadSaReply_.begin(), loadSaReply_.end(), checkSaItem);
if (it == loadSaReply_.end()) {
DBINDER_LOGE("findSaItem failed");
return nullptr;
}
/* proxy is null, attempt to get a new proxy */
std::u16string serviceName = GetRegisterService(binderObject);
if (serviceName.empty() && !CheckSystemAbilityId(systemAbilityId)) {
DBINDER_LOGE("service is not registered in this device, saId:%{public}d", systemAbilityId);
return nullptr;
std::shared_ptr<DHandleEntryTxRx> replymsg = (*it);
it = loadSaReply_.erase(it);
return replymsg;
}
void DBinderService::LoadSystemAbilityComplete(const std::string& srcNetworkId, int32_t systemAbilityId,
const sptr<IRemoteObject>& remoteObject)
{
if (remoteObject == nullptr) {
DBINDER_LOGW("GetSystemAbility from samgr error, saId:%{public}d", systemAbilityId);
}
int32_t digitalName = !serviceName.empty() ? std::stoi(Str16ToStr8(serviceName).c_str()) : systemAbilityId;
proxy = dbinderCallback_->GetSystemAbilityFromRemote(digitalName);
if (proxy != nullptr) {
/* When the stub object dies, you need to delete the corresponding busName information */
IPCObjectProxy *saProxy = reinterpret_cast<IPCObjectProxy *>(proxy.GetRefPtr());
sptr<IRemoteObject::DeathRecipient> death(new DbinderSaDeathRecipient(binderObject));
if (!saProxy->AddDeathRecipient(death)) {
DBINDER_LOGE("fail to add death recipient");
return nullptr;
std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
while (true) {
std::shared_ptr<struct DHandleEntryTxRx> replyMessage = PopLoadSaItem(srcNetworkId, systemAbilityId);
if (replyMessage == nullptr) {
break;
}
bool ret = AttachProxyObject(proxy, binderObject);
if (!ret) {
DBINDER_LOGE("attach proxy object fail");
return nullptr;
if (remoteObject == nullptr) {
continue;
}
binder_uintptr_t binderObject = replyMessage->binderObject;
IPCObjectProxy *saProxy = reinterpret_cast<IPCObjectProxy *>(remoteObject.GetRefPtr());
if (QueryProxyObject(binderObject) == nullptr) {
/* When the stub object dies, you need to delete the corresponding busName information */
sptr<IRemoteObject::DeathRecipient> death(new DbinderSaDeathRecipient(binderObject));
if (!saProxy->AddDeathRecipient(death)) {
DBINDER_LOGE("fail to add death recipient");
continue;
}
if (!AttachProxyObject(remoteObject, binderObject)) {
DBINDER_LOGE("attach proxy object fail");
continue;
}
}
std::string deviceId = replyMessage->deviceIdInfo.fromDeviceId;
if (replyMessage->transType != IRemoteObject::DATABUS_TYPE) {
DBINDER_LOGE("Invalid Message Type");
} else {
if (!OnRemoteInvokerDataBusMessage(saProxy, replyMessage.get(), deviceId,
replyMessage->pid, replyMessage->uid)) {
continue;
}
}
std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
if (remoteListener == nullptr) {
DBINDER_LOGE("remoteListener is null");
continue;
}
if (!remoteListener->SendDataToRemote(deviceId, replyMessage.get())) {
DBINDER_LOGE("fail to send data from server DBS to client DBS");
continue;
}
} else {
DBINDER_LOGW("GetSystemAbility from samgr error, saId:%{public}d", digitalName);
}
return proxy;
}
uint16_t DBinderService::AllocFreeSocketPort()
{
/* alloc port by system */
return 0;
DBINDER_LOGI("complete");
}
bool DBinderService::OnRemoteInvokerMessage(const struct DHandleEntryTxRx *message)
{
sptr<IRemoteObject> proxy = FindOrNewProxy(message->binderObject, static_cast<int32_t>(message->stubIndex));
if (proxy == nullptr) {
DBINDER_LOGE("find and new proxy fail");
return false;
}
IPCObjectProxy *ipcProxy = reinterpret_cast<IPCObjectProxy *>(proxy.GetRefPtr());
std::shared_ptr<struct DHandleEntryTxRx> replyMessage = std::make_shared<struct DHandleEntryTxRx>();
if (memcpy_s(replyMessage.get(), sizeof(DHandleEntryTxRx), message, sizeof(DHandleEntryTxRx)) != 0) {
DBINDER_LOGE("fail to copy memory");
return false;
}
std::string deviceId = replyMessage->deviceIdInfo.fromDeviceId;
switch (replyMessage->transType) {
case IRemoteObject::DATABUS_TYPE: {
if (!OnRemoteInvokerDataBusMessage(ipcProxy, replyMessage.get(), deviceId, message->pid, message->uid)) {
DBINDER_LOGE("Invoker Databus Message fail");
return false;
}
break;
}
default: {
DBINDER_LOGE("Invalid Message Type");
return false;
}
}
std::shared_ptr<DBinderRemoteListener> remoteListener = GetRemoteListener();
if (remoteListener == nullptr) {
DBINDER_LOGE("remoteListener is null");
std::lock_guard<std::shared_mutex> lockGuard(loadSaMutex_);
bool isSaAvailable = dbinderCallback_->LoadSystemAbilityFromRemote(replyMessage->deviceIdInfo.fromDeviceId,
static_cast<int32_t>(replyMessage->stubIndex));
if (!isSaAvailable) {
DBINDER_LOGE("fail to call the system ability");
return false;
}
bool ret = remoteListener->SendDataToRemote(deviceId, replyMessage.get());
if (ret != true) {
DBINDER_LOGE("fail to send data from server DBS to client DBS");
return false;
}
loadSaReply_.push_back(replyMessage);
return true;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册