OpenHarmony应用开发进阶 - 隐式Want的匹配规则源码解析(二)
Want对象用于在应用组件之间传递信息,常见的使用场景为startAbility方法的参数。本文将向大家详细介绍隐式Want的匹配规则。
概述
文档环境
DevEco Studio 版本:DevEco Studio 5.0.2 Release(5.0.7.200)
SDK 版本:5.0.2 (API14)
开发板型号:DAYU 200
系统版本:OpenHarmony-5.0.2-Release
涉及仓库:bundlemanager_bundle_framework
功能简介
- Want对象用于在应用组件之间传递信息,常见的使用场景为startAbility方法的参数。例如,当UIAbility-A需要启动UIAbility-B并向UIAbility-B传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbility-B。
- 在启动目标应用组件时,通过显式Want或者隐式Want进行目标应用组件的匹配:
显式Want:在启动目标应用组件时,调用方传入的want参数中指定了abilityName和bundleName,称为显式Want。
隐式Want:在启动目标应用组件时,调用方传入的want参数中未指定abilityName,称为隐式Want。
- 在隐式Want的匹配规则源码解析(一)中向大家介绍了隐式Want和基础匹配规则,本文将向大家详细介绍隐式Want的匹配规则。
隐式Want匹配规则
规则1:如果parameters中的linkFeature字段取值不为空,进行linkFeature匹配,返回linkFeature匹配的结果。
将调用方传入的want参数的parameters与待匹配应用组件的skills配置中的uris进行匹配。
为了简化描述, 称调用方传入的want参数中的linkFeature参数为w_linkFeature;待匹配应用组件的skills配置中uris为s_uris,其中每个元素为s_uri。
- 规则1.1:如果want参数的uri和type均为空, 当w_linkFeature和s_uri的linkFeature相同时匹配成功,否则匹配失败。
注:如果want参数的uri和type有一个参数为空,进行下一条规则匹配。
- 规则1.2:如果want参数的uri或type不为空, 依次匹配linkFeature、uri、type,当三个字段均匹配成功时,则匹配成功,否则匹配失败。
// interfaces/inner_api/appexecfwk_base/src/skill.cpp
bool Skill::MatchLinkFeature(const std::string &linkFeature, const OHOS::AAFwk::Want &want, size_t &matchUriIndex) const
{
// 规则1.1:如果want参数的uri和type均为空, 当w_linkFeature和s_uri的linkFeature相同时匹配成功,否则匹配失败。
std::string paramUriString = GetOptParamUri(want.GetUriString());
std::string paramType = want.GetType();
if (paramUriString.empty() && paramType.empty()) {
for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
const SkillUri &skillUri = uris[uriIndex];
if (linkFeature == skillUri.linkFeature) {
matchUriIndex = uriIndex;
return true;
}
}
return false;
}
// 规则1.2:如果want参数的uri或type不为空, 依次匹配linkFeature、uri、type,当三个字段均匹配成功时,则匹配成功,否则匹配失败。
bool onlyUri = !paramUriString.empty() && paramType.empty();
for (size_t uriIndex = 0; uriIndex < uris.size(); ++uriIndex) {
const SkillUri &skillUri = uris[uriIndex];
// 当w_linkFeature和s_uri的linkFeature不相同时,匹配不成功,继续匹配下一条s_uri。
if (linkFeature != skillUri.linkFeature) {
continue;
}
// 当URI和Type均匹配成功时,匹配成功,否则继续匹配。
if (MatchUri(paramUriString, skillUri) && MatchType(paramType, skillUri.type)) {
matchUriIndex = uriIndex;
return true;
}
// 当w_uri为空或w_type不为空时,继续匹配下一条s_uri。
if (!onlyUri) {
continue;
}
// 根据w_uri后缀匹配UTD,如果未匹配到系统中的UTD,则继续匹配下一条s_uri。
std::vector<std::string> paramUtdVector;
if (!MimeTypeMgr::GetUtdVectorByUri(paramUriString, paramUtdVector)) {
continue;
}
// 当URI和使用w_UTD进行Type匹配,同时匹配成功时,匹配成功,否则匹配失败。
for (const std::string ¶mUtd : paramUtdVector) {
if ((MatchUri(paramUriString, skillUri) ||
(skillUri.scheme.empty() && paramUriString.find(SCHEME_SEPARATOR) == std::string::npos)) &&
MatchType(paramUtd, skillUri.type)) {
matchUriIndex = uriIndex;
return true;
}
}
}
return false;
}
规则2:如果parameters中的linkFeature未配置时,只有当action、entities、uri和type四个属性均匹配成功则隐式匹配成功。
规则2.1:当want参数的action匹配失败时,隐式匹配失败,否则继续匹配。
将调用方传入的want参数的action与待匹配应用组件的skills配置中的actions进行匹配。
为了简化描述,称调用方传入的want参数中的action参数为w_action;待匹配应用组件的skills配置中actions为s_actions。
- 规则2.1.1:当s_actions为空时,匹配失败。
- 规则2.1.2:当w_action为空时,匹配成功。
- 规则2.1.3:当w_action不为空,s_actions中包含w_action时匹配成功,否则匹配失败。
// interfaces/inner_api/appexecfwk_base/src/skill.cpp
bool Skill::MatchActionAndEntities(const OHOS::AAFwk::Want &want) const
{
bool matchAction = MatchAction(want.GetAction());
if (!matchAction) {
APP_LOGD("Action does not match");
return false;
}
bool matchEntities = MatchEntities(want.GetEntities());
if (!matchEntities) {
APP_LOGD("Entities does not match");
return false;
}
return true;
}
bool Skill::MatchAction(const std::string &action) const
{
// 规则2.1.1:当s_actions为空时,匹配失败。
if (actions.empty()) {
return false;
}
// 规则2.1.2:当w_action为空时,匹配成功。
if (action.empty()) {
return true;
}
auto actionMatcher = [action] (const std::string &configAction) {
// 规则2.1.3:当w_action不为空,s_actions中包含w_action时匹配成功,否则匹配失败。
if (action == configAction) {
return true;
}
// ACTION_HOME = "action.system.home";WANT_ACTION_HOME = "ohos.want.action.home";
if (action == Constants::ACTION_HOME && configAction == Constants::WANT_ACTION_HOME) {
return true;
}
if (action == Constants::WANT_ACTION_HOME && configAction == Constants::ACTION_HOME) {
return true;
}
return false;
};
return std::find_if(actions.cbegin(), actions.cend(), actionMatcher) != actions.cend();
}
规则2.2:当want参数的entities匹配失败时,隐式匹配失败,否则继续匹配。
将调用方传入的want参数的entities与待匹配应用组件的skills配置中的entities进行匹配。
为了简化描述,称调用方传入的want参数中的entities参数为w_entities;待匹配应用组件的skills配置中entities为s_entities。
- 规则2.2.1:当w_entities为空时,匹配成功,否则进行下一条规则匹配。
- 规则2.2.2:当s_entities为空时,匹配失败,否则进行下一条规则匹配。
- 规则2.2.3:当w_entities不为空,s_entities中包含w_entities中任一项时匹配成功,否则匹配失败。
// interfaces/inner_api/appexecfwk_base/src/skill.cpp
bool Skill::MatchActionAndEntities(const OHOS::AAFwk::Want &want) const
{
bool matchAction = MatchAction(want.GetAction());
if (!matchAction) {
APP_LOGD("Action does not match");
return false;
}
bool matchEntities = MatchEntities(want.GetEntities());
if (!matchEntities) {
APP_LOGD("Entities does not match");
return false;
}
return true;
}
bool Skill::MatchEntities(const std::vector<std::string> ¶mEntities) const
{
// 规则2.2.1:当w_entities为空时,匹配成功,否则进行下一条规则匹配。
if (paramEntities.empty()) {
return true;
}
// 规则2.2.2:当s_entities为空时,匹配失败,否则进行下一条规则匹配。
if (entities.empty()) {
return false;
}
// 规则2.2.3:当w_entities不为空,s_entities中包含w_entities中任一项时匹配成功,否则匹配失败。
std::vector<std::string>::size_type size = paramEntities.size();
for (std::vector<std::string>::size_type i = 0; i < size; i++) {
bool ret = std::find(entities.cbegin(), entities.cend(), paramEntities[i]) == entities.cend();
if (ret) {
return false;
}
}
return true;
}
规则2.3:当want参数的uri和type匹配失败时,隐式匹配失败。
调用方传入的want参数中设置uri和type参数发起启动应用组件的请求,系统会遍历当前系统已安装的组件列表,并逐个匹配待匹配应用组件的skills配置中的uris数组,如果待匹配应用组件的skills配置中的uris数组中只要有一个可以匹配调用方传入的want参数中设置的uri和type即为匹配成功。
为了简化描述,称调用方传入的want参数中的uri参数为w_uri,type参数为w_type;待匹配应用组件的skills配置中uris为s_uris,其中每个元素为s_uri。
- 规则2.3.1:如果w_uri和w_type都为空,当s_uris为空时,匹配成功,否则进行下一条规则匹配。
- 规则2.3.2:如果w_uri和w_type都为空,当s_uri中的scheme和type均为空时,匹配成功,否则进行下一条规则匹配。
- 规则2.3.3:如果w_uri和w_type都为空,当以上两条均未匹配成功时,匹配失败。
注:如果w_uri和w_type有一个参数不为空,跳过规则2.3.1、规则2.3.2和规则2.3.3,进行下一条规则匹配。
- 规则2.3.4:当s_uris为空时,匹配失败,否则进行下一条规则匹配。
- 规则2.3.5:如果w_uri不为空,w_type为空,当URI匹配成功,且s_uri中的type为空时,匹配成功,否则进行下一条规则匹配。
- 规则2.3.6:如果w_uri不为空,w_type为空,返回MimeType匹配结果。
注:如果w_uri为空或w_type不为空,跳过规则2.3.5和规则2.3.6,进行下一条规则匹配。
- 规则2.3.7:如果w_uri为空,w_type不为空,当Type匹配成功,且s_uri中的scheme为空时,匹配成功,否则匹配失败。
注:如果w_uri不为空或w_type为空,跳过规则2.3.7,进行下一条规则匹配。
- 规则2.3.8:如果w_uri和w_type均不为空,当Type匹配和URI匹配均成功时,匹配成功,否则匹配失败。
bool Skill::MatchUriAndType(const std::string &rawUriString, const std::string &type) const
{
const std::string uriString = GetOptParamUri(rawUriString);
if (uriString.empty() && type.empty()) {
// 规则2.3.1:如果w_uri和w_type都为空,当s_uris为空时,匹配成功,否则进行下一条规则匹配。
if (uris.empty()) {
return true;
}
// 规则2.3.2:如果w_uri和w_type都为空,当s_uri中的scheme和type均为空时,匹配成功,否则进行下一条规则匹配。
for (const SkillUri &skillUri : uris) {
if (skillUri.scheme.empty() && skillUri.type.empty()) {
return true;
}
}
// 规则2.3.3:如果w_uri和w_type都为空,当以上两条均未匹配成功时,匹配失败。
return false;
}
// 规则2.3.4:当s_uris为空时,匹配失败,否则进行下一条规则匹配。
if (uris.empty()) {
return false;
}
if (!uriString.empty() && type.empty()) {
// 规则2.3.5:如果w_uri不为空,w_type为空,当URI匹配成功,且s_uri中的type为空时,匹配成功,否则进行下一条规则匹配。
for (const SkillUri &skillUri : uris) {
if (MatchUri(uriString, skillUri) && skillUri.type.empty()) {
return true;
}
}
// 规则2.3.6:如果w_uri不为空,w_type为空,返回MimeType匹配结果。
return MatchMimeType(uriString);
} else if (uriString.empty() && !type.empty()) {
// 规则2.3.7:如果w_uri为空,w_type不为空,当Type匹配成功,且s_uri中的scheme为空时,匹配成功,否则匹配失败。
for (const SkillUri &skillUri : uris) {
if (skillUri.scheme.empty() && MatchType(type, skillUri.type)) {
return true;
}
}
return false;
} else {
// 规则2.3.8:如果w_uri和w_type均不为空,当Type匹配和URI匹配均成功时,匹配成功,否则匹配失败。
for (const SkillUri &skillUri : uris) {
if (MatchUri(uriString, skillUri) && MatchType(type, skillUri.type)) {
return true;
}
}
return false;
}
}
更多推荐
所有评论(0)