异包名应用接续

Signed-off-by: MisterE <smart_e@126.com>
This commit is contained in:
MisterE 2024-08-23 17:01:08 +08:00
commit b691763c8e
16 changed files with 286 additions and 24 deletions

View File

@ -17,6 +17,7 @@
#define OHOS_DISTRIBUTED_BUNDLE_MANANGER_INTERNAL_H
#include <string>
#include <vector>
#include "bundlemgr/bundle_mgr_interface.h"
#include "bundlemgr/bundle_mgr_proxy.h"
@ -42,6 +43,7 @@ public:
static void InitAbilityInfoFromExtension(const AppExecFwk::ExtensionAbilityInfo &extensionAbilityInfo,
AppExecFwk::AbilityInfo &abilityInfo);
static bool IsSameAppId(const std::string& callerAppId, const std::string& targetBundleName);
bool BundleManagerInternal::IsSameDeveloperId(const std::string& callerDeveloperId, const std::string& targetBundleName);
static int32_t GetLocalBundleInfo(const std::string& bundleName, AppExecFwk::BundleInfo &localBundleInfo);
static int32_t GetLocalBundleInfoV9(const std::string& bundleName, AppExecFwk::BundleInfo &bundleInfo);
static int32_t CheckRemoteBundleInfoForContinuation(const std::string& dstDeviceId,

View File

@ -36,6 +36,8 @@ struct CallerInfo {
std::string sourceDeviceId;
int32_t duid = -1;
std::string callerAppId;
std::string callerBundleName;
std::string callerDeveloperId;
std::vector<std::string> bundleNames;
int32_t dmsVersion = -1;
uint32_t accessToken = 0;

View File

@ -92,6 +92,7 @@ public:
std::string sinkDeviceId_;
std::string sinkBundleName_;
std::string continueType_;
std::string sourceAbilityName_;
std::string sinkAbilityName_;
int32_t missionId_ = 0;
};

View File

@ -77,6 +77,8 @@ public:
public:
int32_t direction_ = 0;
int32_t appVersion_ = 0;
std::string sourceAbilityName_;
std::string sinkAbilityName_;
DistributedWantParams wantParams_;
};

View File

@ -68,7 +68,7 @@ private:
void HandleContinueMission(const std::string& srcDeviceId, const std::string& dstDeviceId,
std::string bundleName, const std::string& continueType,
const sptr<IRemoteObject>& callback, const OHOS::AAFwk::WantParams& wantParams);
void HandleContinueMissionWithBundleName(const DSchedContinueInfo &info, const sptr<IRemoteObject>& callback,
void HandleContinueMissionWithBundleName(DSchedContinueInfo &info, const sptr<IRemoteObject>& callback,
const OHOS::AAFwk::WantParams& wantParams);
void HandleStartContinuation(const OHOS::AAFwk::Want& want, int32_t missionId, int32_t callerUid,
int32_t status, uint32_t accessToken);

View File

@ -59,6 +59,8 @@ public:
DmsBundleInfo &info);
bool GetDistributedBundleName(const std::string &networkId, const uint16_t& bundleNameId,
std::string& bundleName);
bool GetDistributedBundleInfo(const std::string &networkId, const uint16_t& bundleNameId,
DmsBundleInfo& distributeBundleInfo);
bool GetBundleNameId(const std::string& bundleName, uint16_t &bundleNameId);
std::string GetContinueType(const std::string &networkId, std::string &bundleName, uint8_t continueTypeId);
std::string GetAbilityName(const std::string &networkId, std::string &bundleName, std::string &continueType);
@ -80,7 +82,7 @@ private:
void AddBundleNameId(const uint16_t &bundleNameId, const std::string &bundleName);
void DelBundleNameId(const std::string &bundleName);
DmsBundleInfo ConvertToDistributedBundleInfo(const AppExecFwk::BundleInfo &bundleInfo,
bool isPackageChange = false);
AppExecFwk::AppProvisionInfo appProvisionInfo, bool isPackageChange = false);
bool InnerSaveStorageDistributeInfo(const DmsBundleInfo &distributedBundleInfo, const std::string &localUdid);
std::map<std::string, DmsBundleInfo> GetAllOldDistributionBundleInfo(
const std::vector<std::string> &bundleNames);

View File

@ -58,6 +58,8 @@ struct DmsBundleInfo : public Parcelable {
uint16_t bundleNameId = 0;
// bundle update time
int64_t updateTime = 0;
std::string developerId;
std::vector<std::string> continueBundle;
std::vector<DmsAbilityInfo> dmsAbilityInfos;
std::vector<uint8_t> userIdArr;

View File

@ -86,6 +86,7 @@ private:
const int32_t state, const int32_t retry = 0);
void NotifyRecvBroadcast(const sptr<IRemoteObject>& obj, const std::string& networkId,
const std::string& bundleName, const int32_t state, const std::string& continueType = "");
bool continueTypeCheck(const DmsBundleInfo& distributedBundleInfo, const std::string& continueType);
private:
currentIconInfo iconInfo_;
sptr<DistributedMissionDiedListener> missionDiedListener_;
@ -97,6 +98,8 @@ private:
std::mutex iconMutex_;
std::shared_ptr<OHOS::AppExecFwk::EventHandler> eventHandler_;
bool hasRegSoftbusEventListener_ = false;
public:
std::vector<DSchedContinueInfo> continueReady_;
};
} // namespace DistributedSchedule
} // namespace OHOS

View File

@ -184,6 +184,20 @@ bool BundleManagerInternal::IsSameAppId(const std::string& callerAppId, const st
return callerAppId == calleeAppId;
}
bool BundleManagerInternal::IsSameDeveloperId(const std::string& callerDeveloperId, const std::string& targetBundleName)
{
if (targetBundleName.empty() || callerDeveloperId.empty()) {
HILOGE("targetBundleName:%{public}s or callerDeveloperId:%s is empty",
targetBundleName.c_str(), GetAnonymStr(callerDeveloperId).c_str());
return false;
}
auto bundleMgr = GetBundleManager();
AppExecFwk::AppProvisionInfo targetAppProvisionInfo;
bundleMgr->GetAppProvisionInfo(targetBundleName, targetAppProvisionInfo);
return callerDeveloperId == targetAppProvisionInfo.developerId;
}
int32_t BundleManagerInternal::GetLocalBundleInfo(const std::string& bundleName,
AppExecFwk::BundleInfo &localBundleInfo)
{
@ -229,6 +243,19 @@ int32_t BundleManagerInternal::GetLocalBundleInfoV9(const std::string& bundleNam
return ret;
}
static bool GetContinueBundle4Src(const std::string srcBundleName,
std::vector<std::string> bundleNameList){
// todo: 打桩测试
if(srcBundleName == "com.hf.demo"){
bundleNameList.emplace_back("com.hf.demo1");
return true;
}else if(srcBundleName == "com.hf.demo1"){
bundleNameList.emplace_back("com.hf.demo");
return true;
}
return false;
}
int32_t BundleManagerInternal::CheckRemoteBundleInfoForContinuation(const std::string& dstDeviceId,
const std::string& bundleName, AppExecFwk::DistributedBundleInfo& remoteBundleInfo)
{

View File

@ -193,6 +193,9 @@ void DSchedContinue::SetEventData()
eventData_.destAbilityName_ = dstContinueInfo.abilityName;
eventData_.dSchedEventType_ = DMS_CONTINUE;
eventData_.state_ = DMS_DSCHED_EVENT_START;
continueInfo_.sourceAbilityName_ = srcContinueInfo.abilityName;
continueInfo_.sinkAbilityName_ = dstContinueInfo.abilityName;
}
int32_t DSchedContinue::Init()
@ -637,6 +640,8 @@ int32_t DSchedContinue::PackStartCmd(std::shared_ptr<DSchedContinueStartCmd>& cm
cmd->sourceMissionId_ = continueInfo_.missionId_;
cmd->continueByType_ = continueByType_;
cmd->dmsVersion_ = DMS_VERSION;
cmd->sourceAbilityName_ = eventData_.srcAbilityName_;
cmd->sinkAbilityName_ = eventData_.destAbilityName_;
cmd->direction_ = direction_;
if (subServiceType_ == CONTINUE_PULL && continueInfo_.missionId_ == 0) {
@ -768,11 +773,18 @@ int32_t DSchedContinue::ExecuteContinueSend(std::shared_ptr<ContinueAbilityData>
return INVALID_PARAMETERS_ERR;
}
AppExecFwk::AbilityInfo abilityInfo;
CallerInfo callerInfo;
callerInfo.sourceDeviceId = continueInfo_.sourceDeviceId_;
callerInfo.uid = data->callerUid;
callerInfo.accessToken = data->accessToken;
callerinfo.callerBundleName = continueInfo_.sinkBundleName_;
sptr<AppExecFwk::IBundleMgr> bundleMgr = BundleManagerInternal::GetBundleManager();
AppExecFwk::AppProvisionInfo appProvisionInfo;
bundleMgr->GetAppProvisionInfo(bundleNameItem, appProvisionInfo);
callerInfo.callerDeveloperId = appProvisionInfo.developerId;
if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
HILOGE("GetCallerAppIdFromBms failed");
return INVALID_PARAMETERS_ERR;
@ -826,6 +838,7 @@ int32_t DSchedContinue::SetWantForContinuation(AAFwk::Want& newWant)
{
newWant.SetParam("sessionId", continueInfo_.missionId_);
newWant.SetParam("deviceId", continueInfo_.sourceDeviceId_);
newWant.SetBundle(continueInfo_.sourceBundleName_);
AppExecFwk::BundleInfo localBundleInfo;
if (BundleManagerInternal::GetLocalBundleInfo(newWant.GetBundle(), localBundleInfo) != ERR_OK) {
@ -898,12 +911,14 @@ int32_t DSchedContinue::ExecuteContinueData(std::shared_ptr<DSchedContinueDataCm
std::string localDeviceId;
std::string deviceId = cmd->want_.GetElement().GetDeviceID();
cmd->want_.SetBundle(cmd->dstBundleName_);
if (!GetLocalDeviceId(localDeviceId) ||
!CheckDeviceIdFromRemote(localDeviceId, deviceId, cmd->callerInfo_.sourceDeviceId)) {
HILOGE("check deviceId failed");
return INVALID_REMOTE_PARAMETERS_ERR;
}
// todo 这里会校验appId是否相同不同则无法在sink端启动app
int32_t ret = DistributedSchedService::GetInstance().CheckTargetPermission(cmd->want_, cmd->callerInfo_,
cmd->accountInfo_, START_PERMISSION, true);
if (ret != ERR_OK) {

View File

@ -118,6 +118,8 @@ int32_t DSchedContinueStartCmd::Marshal(std::string &jsonStr)
cJSON_AddNumberToObject(rootValue, "Direction", direction_);
cJSON_AddNumberToObject(rootValue, "AppVersion", appVersion_);
cJSON_AddStringToObject(rootValue, "SourceAbilityName", sourceAbilityName_.c_str());
cJSON_AddStringToObject(rootValue, "SinkAbilityName", sinkAbilityName_.c_str());
Parcel parcel;
if (!wantParams_.Marshalling(parcel)) {
@ -170,6 +172,20 @@ int32_t DSchedContinueStartCmd::Unmarshal(const std::string &jsonStr)
}
appVersion_ = appVersion->valueint;
cJSON *sourceAbilityName = cJSON_GetObjectItemCaseSensitive(rootValue, "SourceAbilityName");
if (sourceAbilityName == nullptr || !cJSON_IsString(sourceAbilityName) || (sourceAbilityName->valuestring == nullptr)) {
cJSON_Delete(rootValue);
return INVALID_PARAMETERS_ERR;
}
sourceAbilityName_ = sourceAbilityName->valuestring;
cJSON *sinkAbilityName = cJSON_GetObjectItemCaseSensitive(rootValue, "SinkAbilityName");
if (sinkAbilityName == nullptr || !cJSON_IsString(sinkAbilityName) || (sinkAbilityName->valuestring == nullptr)) {
cJSON_Delete(rootValue);
return INVALID_PARAMETERS_ERR;
}
sinkAbilityName_ = sinkAbilityName->valuestring;
cJSON *wantParams = cJSON_GetObjectItemCaseSensitive(rootValue, "WantParams");
if (wantParams == nullptr || !cJSON_IsString(wantParams) || (wantParams->valuestring == nullptr)) {
cJSON_Delete(rootValue);

View File

@ -27,6 +27,8 @@
#include "dtbschedmgr_device_info_storage.h"
#include "dtbschedmgr_log.h"
#include "mission/dms_continue_send_manager.h"
#include "mission/dms_continue_recv_manager.h"
#include "mission/distributed_bm_storage.h"
namespace OHOS {
namespace DistributedSchedule {
@ -254,9 +256,49 @@ void DSchedContinueManager::HandleContinueMissionWithBundleName(const DSchedCont
int32_t subType = CONTINUE_PUSH;
if (direction == CONTINUE_SOURCE) {
cntSource_++;
uint16_t bundleNameId;
DmsBundleInfo distributedBundleInfo;
DmsBmStorage::GetInstance()->GetBundleNameId(info.sourceBundleName_, bundleNameId);
DmsBmStorage::GetInstance()->GetDistributedBundleInfo(info.sourceDeviceId_,
bundleNameId, distributedBundleInfo);
if(result && !distributedBundleInfo.continueBundle.emplace){
info.sinkBundleName_ = distributedBundleInfo.continueBundle[0];
}
} else {
cntSink_++;
subType = CONTINUE_PULL;
std::vector<DSchedContinueInfo> continueReady = DMSContinueRecvMgr::GetInstance().continueReady_;
std::string sourceBundleName;
for(const auto &item : continueReady){
if(item.sourceDeviceId_ == info.sourceDeviceId_ && item.sinkBundleName_ == info.sinkBundleName_){
sourceBundleName = item.sourceBundleName_;
break;
}
}
if(sourceBundleName.empty()){
uint16_t bundleNameId;
DmsBundleInfo distributedBundleInfo;
DmsBmStorage::GetInstance()->GetBundleNameId(info.sourceBundleName_, bundleNameId);
DmsBmStorage::GetInstance()->GetDistributedBundleInfo(info.sourceDeviceId_,
bundleNameId, distributedBundleInfo);
// 打桩测试
if(distributedBundleInfo.bundleName == "com.hf.demo"){
distributedBundleInfo.continueBundle.emplace_back("com.hf.demo1");
}else if(distributedBundleInfo.bundleName == "com.hf.demo1"){
distributedBundleInfo.continueBundle.emplace_back("com.hf.demo");
}
if(result && !distributedBundleInfo.continueBundle.emplace){
info.sinkBundleName_ = distributedBundleInfo.continueBundle[0];
}
}
if(!sourceBundleName.empty()){
info.sourceBundleName_ = sourceBundleName;
}
}
{
@ -389,12 +431,16 @@ std::shared_ptr<DSchedContinue> DSchedContinueManager::GetDSchedContinueByWant(
HILOGI("continue info: %{public}s.", info.toString().c_str());
{
std::lock_guard<std::mutex> continueLock(continueMutex_);
if (continues_.empty() || continues_.count(info) == 0) {
if (continues_.empty(){
HILOGE("continue info doesn't match an existing continuation.");
return nullptr;
}
if (continues_[info] != nullptr && missionId == continues_[info]->GetContinueInfo().missionId_) {
return continues_[info];
for(auto iter = continues_.begin(); iter != continues_.end(); iter++){
if(iter->second != nullptr && srcDeviceId == iter->second->GetContinueInfo().sourceDevideId_
&& bundleName == iter->second->GetContinueInfo().sourceBundleName_
&& dstDeviceId == iter->second->GetContinueInfo().sinkDeviceid_){
return iter->second;
}
}
}
HILOGE("missionId doesn't match the existing continuation, continueInfo: %{public}s.",

View File

@ -344,10 +344,14 @@ int32_t DistributedSchedPermission::CheckGetCallerPermission(const AAFwk::Want&
return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
}
// 2. check call with same appid
if (!BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
if(targetAbility.bundleName == callerInfo.callerBundleName && !BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)){
HILOGE("the appId is different, check permission denied!");
return CALL_PERMISSION_DENIED;
}else if(targetAbility.bundleName != callerInfo.callerBundleName && !BundleManagerInternal::IsSameDeveloperId(callerInfo.callerDeveloperId, targetAbility.bundleName)){
HILOGE("the DeveloperId is different, check permission denied!");
return CALL_PERMISSION_DENIED;
}
// 3. check background permission
if (!CheckBackgroundPermission(targetAbility, callerInfo, want, false)) {
HILOGE("Check background permission failed!");
@ -557,12 +561,15 @@ bool DistributedSchedPermission::CheckMigrateStartCtrlPer(const AppExecFwk::Abil
HILOGE("check device security level failed!");
return false;
}
if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
HILOGD("the appId is the same, check migration start control permission success!");
return true;
if(targetAbility.bundleName == callerInfo.callerBundleName && !BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)){
HILOGE("the appId is different in the migration scenario, permission denied!");
return false;
}else if(targetAbility.bundleName != callerInfo.callerBundleName && !BundleManagerInternal::IsSameDeveloperId(callerInfo.callerDeveloperId, targetAbility.bundleName)){
HILOGE("the DeveloperId is different in the migration scenario, permission denied!");
return false;
}
HILOGE("the appId is different in the migration scenario, permission denied!");
return false;
return true;
}
bool DistributedSchedPermission::CheckCollaborateStartCtrlPer(const AppExecFwk::AbilityInfo& targetAbility,
@ -581,8 +588,11 @@ bool DistributedSchedPermission::CheckCollaborateStartCtrlPer(const AppExecFwk::
return false;
}
// 3. check start or connect ability with same appid
if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
HILOGD("the appId is the same, check permission success!");
if(targetAbility.bundleName == callerInfo.callerBundleName && BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)){
HILOGE("the appId is the same, check permission success!");
return true;
}else if(targetAbility.bundleName != callerInfo.callerBundleName && BundleManagerInternal::IsSameDeveloperId(callerInfo.callerDeveloperId, targetAbility.bundleName)){
HILOGE("the DeveloperId is the same, check permission success!");
return true;
}
// 4. check if target ability is not visible and without PERMISSION_START_INVISIBLE_ABILITY

View File

@ -107,6 +107,15 @@ bool DmsBmStorage::SaveStorageDistributeInfo(const std::string &bundleName, bool
HILOGE("GetLocalUdid failed");
return false;
}
AppExecFwk::AppProvisionInfo appProvisionInfo;
ret = bundleMgr->GetAppProvisioninfo(bundleName, appProvisionInfo);
if(!ret){
HILOGW("GetBundleInfo of %{public}s failed:%{public}d or cannot be continued", bundleName.c_str(), ret);
DeleteStorageDistributeInfo(bundleName);
return false;
}
ret = InnerSaveStorageDistributeInfo(ConvertToDistributedBundleInfo(bundleInfo, isPackageChange), localUdid);
if (!ret) {
HILOGW("InnerSaveStorageDistributeInfo:%{public}s failed", bundleName.c_str());
@ -389,6 +398,51 @@ bool DmsBmStorage::GetDistributedBundleName(const std::string &networkId, const
return true;
}
bool DmsBmStorage::GetDistributedBundleInfo(const std::string &networkId,
const uint16_t& bundleNameId, DmsBundleInfo& distributeBundleInfo){
HILOGI("networkId: %{public}s bundleNameId: %{public}d", GetAnonymStr(networkId).c_str(), bundleNameId);
if (!CheckKvStore()) {
HILOGE("kvStore is nullptr");
return false;
}
std::string udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(networkId);
std::string uuid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUuidByNetworkId(networkId);
if (udid == "" || uuid == "") {
HILOGE("can not get udid or uuid");
return false;
}
HILOGI("uuid: %{public}s", GetAnonymStr(uuid).c_str());
std::vector<Entry> remoteEntries;
Status status = kvStorePtr_->GetDeviceEntries(uuid, remoteEntries);
if (remoteEntries.empty() || status != Status::SUCCESS) {
HILOGE("GetDeviceEntries error: %{public}d or remoteEntries is empty", status);
return false;
}
std::vector<Entry> reduRiskEntries;
std::string keyOfPublic = udid + AppExecFwk::Constants::FILE_UNDERLINE + PUBLIC_RECORDS;
for (auto entry : remoteEntries) {
std::string key = entry.key.ToString();
std::string value = entry.value.ToString();
if (key.find(keyOfPublic) != std::string::npos) {
continue;
}
DmsBundleInfo distributedBundleInfoTmp;
bool parseResult = distributedBundleInfoTmp.FromJsonString(value);
if (parseResult && distributedBundleInfoTmp.bundleNameId == bundleNameId) {
distributeBundleInfo = distributedBundleInfoTmp;
reduRiskEntries.push_back(entry);
}
}
if (reduRiskEntries.size() != 1) {
HILOGE("Redundant data needs to be deleted.");
DelReduData(networkId, reduRiskEntries);
return false;
}
HILOGI("end.");
return true;
}
Status DmsBmStorage::GetResultSatus(std::promise<OHOS::DistributedKv::Status> &resultStatusSignal)
{
auto future = resultStatusSignal.get_future();
@ -610,7 +664,7 @@ bool DmsBmStorage::RebuildLocalData()
}
DmsBundleInfo DmsBmStorage::ConvertToDistributedBundleInfo(const AppExecFwk::BundleInfo &bundleInfo,
bool isPackageChange)
AppExecFwk::AppProvisionInfo appProvisionInfo, bool isPackageChange)
{
DmsBundleInfo distributedBundleInfo;
if (bundleInfo.name == "") {
@ -627,6 +681,9 @@ DmsBundleInfo DmsBmStorage::ConvertToDistributedBundleInfo(const AppExecFwk::Bun
distributedBundleInfo.enabled = bundleInfo.applicationInfo.enabled;
distributedBundleInfo.bundleNameId = CreateBundleNameId(bundleInfo.name, isPackageChange);
distributedBundleInfo.updateTime = bundleInfo.updateTime;
// todo: 这里需要适配BMS的接口
distributedBundleInfo.developerId = appProvisionInfo.developerId;
distributedBundleInfo.continueBundle = bundleInfo.continueBundle;
uint8_t pos = 0;
for (const auto &abilityInfo : bundleInfo.abilityInfos) {
DmsAbilityInfo dmsAbilityInfo;
@ -704,15 +761,17 @@ void DmsBmStorage::UpdateDistributedData()
std::vector<DmsBundleInfo> dmsBundleInfos;
for (const auto &bundleInfo : bundleInfos) {
AppExecFwk::AppProvisionInfo appProvisionInfo;
bundleMgr->GetAppProvisionInfo(bundleInfo.name, appProvisionInfo);
if (oldDistributedBundleInfos.find(bundleInfo.name) != oldDistributedBundleInfos.end()) {
int64_t updateTime = oldDistributedBundleInfos[bundleInfo.name].updateTime;
if (updateTime != bundleInfo.updateTime) {
DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo, true);
DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo, appProvisionInfo, true);
dmsBundleInfos.push_back(dmsBundleInfo);
}
continue;
}
DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo);
DmsBundleInfo dmsBundleInfo = ConvertToDistributedBundleInfo(bundleInfo, appProvisionInfo);
if (dmsBundleInfo.bundleName == "") {
HILOGE("The package information is empty and does not need to be stored!");
continue;

View File

@ -35,6 +35,8 @@ const std::string JSON_KEY_APP_ID = "appId";
const std::string JSON_KEY_ENABLED = "enabled";
const std::string JSON_KEY_BUNDLE_NAME_ID = "bundleNameId";
const std::string JSON_KEY_UPDATE_TIME = "updateTime";
const std::string JSON_KEY_DEVELOPER_ID = "developerId";
const std::string JSON_KEY_CONTINUE_BUNDLE = "continueBundle";
const std::string JSON_KEY_DMS_ABILITY_INFOS = "dmsAbilityInfos";
const std::string JSON_KEY_DMS_ABILITY_NAME = "abilityName";
const std::string JSON_KEY_DMS_CONTINUETYPE = "continueType";
@ -291,6 +293,8 @@ std::string DmsBundleInfo::ToString() const
jsonObject[JSON_KEY_ENABLED] = enabled;
jsonObject[JSON_KEY_BUNDLE_NAME_ID] = bundleNameId;
jsonObject[JSON_KEY_UPDATE_TIME] = updateTime;
jsonObject[JSON_KEY_DEVELOPER_ID] = developerId;
jsonObject[JSON_KEY_CONTINUE_BUNDLE] = continueBundle;
jsonObject[JSON_KEY_DMS_ABILITY_INFOS] = dmsAbilityInfos;
jsonObject[JSON_KEY_DMS_USERID] = userIdArr;
return jsonObject.dump();
@ -327,6 +331,10 @@ bool DmsBundleInfo::FromJsonString(const std::string &jsonString)
JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
GetValueIfFindKey<int64_t>(jsonObject, jsonObjectEnd, JSON_KEY_UPDATE_TIME, updateTime,
JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_DEVELOPER_ID, developerId,
JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
GetValueIfFindKey<std::string>(jsonObject, jsonObjectEnd, JSON_KEY_CONTINUE_BUNDLE, continueBundle,
JsonType::STRING, false, parseResult, ArrayType::NOT_ARRAY);
GetValueIfFindKey<std::vector<DmsAbilityInfo>>(jsonObject, jsonObjectEnd, JSON_KEY_DMS_ABILITY_INFOS,
dmsAbilityInfos, JsonType::ARRAY, false, parseResult, ArrayType::OBJECT);
GetValueIfFindKey<std::vector<uint8_t>>(jsonObject, jsonObjectEnd, JSON_KEY_DMS_USERID, userIdArr,

View File

@ -30,6 +30,7 @@
#include "parcel_helper.h"
#include "softbus_adapter/softbus_adapter.h"
#include "switch_status_dependency.h"
#include "dsched_continue.h"
namespace OHOS {
namespace DistributedSchedule {
@ -221,6 +222,14 @@ int32_t DMSContinueRecvMgr::VerifyBroadcastSource(const std::string& senderNetwo
iconInfo_.senderNetworkId = "";
iconInfo_.bundleName = "";
iconInfo_.continueType = "";
auto ite = continueReady_.begin();
while(itr != continueReady_.end()){
if(itr->sourceDeviceId_ == senderNetworkId && itr->sinkBundleName_ == bundleName){
itr = continueReady_.erase(itr);
} else {
itr++;
}
}
}
return ERR_OK;
}
@ -256,13 +265,14 @@ int32_t DMSContinueRecvMgr::DealOnBroadcastBusiness(const std::string& senderNet
{
HILOGI("DealOnBroadcastBusiness start, senderNetworkId: %{public}s, bundleNameId: %{public}u, state: %{public}d.",
GetAnonymStr(senderNetworkId).c_str(), bundleNameId, state);
std::string bundleName;
int32_t ret = BundleManagerInternal::GetBundleNameById(senderNetworkId, bundleNameId, bundleName);
if (ret != ERR_OK) {
HILOGW("get bundleName failed, ret: %{public}d, try = %{public}d", ret, retry);
DmsBundleInfo distributedBundleInfo;
bool result = DmsBmStorage::GetInstance()->GetDistributedBundleInfo(senderNetworkId, bundleNameId, distributedBundleInfo);
if (!result) {
HILOGW("get bundleName failed, ret: %{public}d, try = %{public}d", result, retry);
return RetryPostBroadcast(senderNetworkId, bundleNameId, continueTypeId, state, retry);
}
std::string bundleName;
if (!CheckBundleContinueConfig(bundleName)) {
HILOGI("App does not allow continue in config file, bundle name %{public}s", bundleName.c_str());
return REMOTE_DEVICE_BIND_ABILITY_ERR;
@ -270,17 +280,52 @@ int32_t DMSContinueRecvMgr::DealOnBroadcastBusiness(const std::string& senderNet
HILOGI("get bundleName, bundleName: %{public}s", bundleName.c_str());
AppExecFwk::BundleInfo localBundleInfo;
if (BundleManagerInternal::GetLocalBundleInfoV9(bundleName, localBundleInfo) != ERR_OK) {
std::string continueType = BundleManagerInternal::GetContinueType(senderNetworkId, bundleName, continueTypeId);
std::string finalBundleName;
if(continueType.empty()){
if(BundleManagerInternal::GetLocalBundleInfoV9(bundleName, localBundleInfo) == ERR_OK){
finalBundleName = bundleName;
}
} else {
bool continueTypeGot = continueTypeCheck(distributedBundleInfo, continueType);
if(continueTypeGot && BundleManagerInternal::GetLocalBundleInfoV9(bundleName, localBundleInfo) == ERR_OK){
finalBundleName = bundleName;
} else {
std::vector<std::string> bundleNameList;
bool continueBundleGot = BundleManagerInternal::GetContinueBundle4Src(bundleName, bundleNameList);
if(continueBundleGot){
sptr<AppExecFwk::IBundleMgr> bundleMgr = BundleManagerInternal::GetBundleManager();
for(std::string& bundleNameItem : bundleNameList) {
continueType = BundleManagerInternal::GetContinueType(senderNetworkId, bundleNameItem, continueTypeId);
if(continueType.empty() || !continueTypeCheck(distributedBundleInfo, continueType)
|| BundleManagerInternal::GetLocalBundleInfoV9(bundleNameItem, localBundleInfo) != ERR_OK){
continue;
}
AppExecFwk::AppProvisionInfo appProvisionInfo;
if(bundleMgr->GetAppProvisionInfo(bundleNameItem, appProvisionInfo)
&& appProvisionInfo.developerId == distributedBundleInfo.developerId){
finalBundleName = bundleNameItem;
break;
}
}
}
}
}
if (finalBundleName.empty) {
HILOGE("The app is not installed on the local device.");
return INVALID_PARAMETERS_ERR;
}
continueReady_.emplace_back(senderNetworkId, bundleName, "", finalBundleName, continueType);
if (localBundleInfo.applicationInfo.bundleType != AppExecFwk::BundleType::APP) {
HILOGE("The bundleType must be app, but it is %{public}d", localBundleInfo.applicationInfo.bundleType);
return INVALID_PARAMETERS_ERR;
}
std::string continueType = BundleManagerInternal::GetContinueType(senderNetworkId, bundleName, continueTypeId);
ret = VerifyBroadcastSource(senderNetworkId, bundleName, continueType, state);
uint32_t ret = VerifyBroadcastSource(senderNetworkId, bundleName, continueType, state);
if (ret != ERR_OK) {
return ret;
}
@ -292,12 +337,25 @@ int32_t DMSContinueRecvMgr::DealOnBroadcastBusiness(const std::string& senderNet
}
std::vector<sptr<IRemoteObject>> objs = iterItem->second;
for (auto iter : objs) {
NotifyRecvBroadcast(iter, senderNetworkId, bundleName, state, continueType);
NotifyRecvBroadcast(iter, senderNetworkId, finalBundleName, state, continueType);
}
HILOGI("DealOnBroadcastBusiness end");
return ERR_OK;
}
bool DMSContinueRecvMgr::continueTypeCheck(const DmsBundleInfo& distributedBundleInfo,
const std::string& continueType){
std::vector<DmsAbilityInfo> dmsAbilityInfos = distributedBundleInfo.dmsAbilityInfos;
bool continueTyoeGot = false;
for(const auto& abilityInfo : dmsAbilityInfos){
std::vector<std::string> continueTypeConfig = abilityInfo.continueType;
for(const auto& continueTypeConfigItem : continueTypeConfig){
continueTyoeGot = continueTyoeGot || (continueType == continueTypeConfigItem);
}
}
return continueTyoeGot;
}
void DMSContinueRecvMgr::NotifyRecvBroadcast(const sptr<IRemoteObject>& obj,
const std::string& networkId, const std::string& bundleName, const int32_t state, const std::string& continueType)
{
@ -421,6 +479,7 @@ void DMSContinueRecvMgr::OnContinueSwitchOff()
iconInfo_.senderNetworkId = "";
iconInfo_.bundleName = "";
iconInfo_.continueType = "";
continueReady_.clear();
}
HILOGI("Saved iconInfo cleared, networkId: %{public}s, bundleName: %{public}s.",
GetAnonymStr(senderNetworkId).c_str(), bundleName.c_str());
@ -471,6 +530,14 @@ void DMSContinueRecvMgr::NotifyDeviceOffline(const std::string& networkId)
iconInfo_.senderNetworkId = "";
iconInfo_.bundleName = "";
iconInfo_.continueType = "";
auto ite = continueReady_.begin();
while(itr != continueReady_.end()){
if(itr->sourceDeviceId_ == senderNetworkId && itr->sinkBundleName_ == bundleName){
itr = continueReady_.erase(itr);
} else {
itr++;
}
}
}
HILOGI("Saved iconInfo cleared, networkId: %{public}s, bundleName: %{public}s.",
GetAnonymStr(senderNetworkId).c_str(), bundleName.c_str());