!9311 分身适配选择框

Merge pull request !9311 from 夏良伟/分身适配选择框
This commit is contained in:
openharmony_ci
2024-07-19 13:04:23 +00:00
committed by Gitee
34 changed files with 539 additions and 110 deletions
@@ -67,6 +67,10 @@ napi_value WrapDialogAbilityInfo(napi_env env, const AAFwk::DialogAbilityInfo &d
SetPropertyValueByPropertyName(env, jsObject, "abilityLabelId", jsValue);
jsValue = WrapBoolToJS(env, dialogAbilityInfo.visible);
SetPropertyValueByPropertyName(env, jsObject, "visible", jsValue);
jsValue = WrapInt32ToJS(env, dialogAbilityInfo.appIndex);
SetPropertyValueByPropertyName(env, jsObject, "appIndex", jsValue);
jsValue = WrapMultiAppModeData(env, dialogAbilityInfo.multiAppMode);
SetPropertyValueByPropertyName(env, jsObject, "multiAppMode", jsValue);
return jsObject;
}
@@ -89,5 +93,20 @@ napi_value WrapDialogSessionInfo(napi_env env, const AAFwk::DialogSessionInfo &d
return jsObject;
}
napi_value WrapMultiAppModeData(napi_env env, const AppExecFwk::MultiAppModeData &multiAppMode)
{
napi_value jsObject = nullptr;
napi_value jsValue = nullptr;
NAPI_CALL(env, napi_create_object(env, &jsObject));
jsValue = WrapInt32ToJS(env, static_cast<int32_t>(multiAppMode.multiAppModeType));
SetPropertyValueByPropertyName(env, jsObject, "multiAppModeType", jsValue);
jsValue = WrapInt32ToJS(env, static_cast<int32_t>(multiAppMode.maxCount));
SetPropertyValueByPropertyName(env, jsObject, "maxCount", jsValue);
return jsObject;
}
} // namespace AbilityRuntime
} // nampspace OHOS
@@ -30,6 +30,7 @@ namespace AppExecFwk {
napi_value WrapArrayDialogAbilityInfoToJS(napi_env env, const std::vector<DialogAbilityInfo> &value);
napi_value WrapDialogSessionInfo(napi_env env, const AAFwk::DialogSessionInfo &dialogSessionInfo);
napi_value WrapDialogAbilityInfo(napi_env env, const AAFwk::DialogAbilityInfo &dialogAbilityInfo);
napi_value WrapMultiAppModeData(napi_env env, const AppExecFwk::MultiAppModeData &multiAppMode);
} // namespace AppExecFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_JS_DIALOG_SESSION_UTILS_H
@@ -866,5 +866,19 @@ ErrCode BundleMgrHelper::QueryCloneExtensionAbilityInfoWithAppIndex(const Elemen
return bundleMgr->QueryCloneExtensionAbilityInfoWithAppIndex(element, flags, appCloneIndex, extensionInfo, userId);
}
ErrCode BundleMgrHelper::GetCloneAppIndexes(const std::string &bundleName, std::vector<int32_t> &appIndexes,
int32_t userId)
{
TAG_LOGD(AAFwkTag::BUNDLEMGRHELPER, "Called.");
auto bundleMgr = Connect();
if (bundleMgr == nullptr) {
TAG_LOGE(AAFwkTag::BUNDLEMGRHELPER, "Failed to connect.");
return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR;
}
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
return bundleMgr->GetCloneAppIndexes(bundleName, appIndexes, userId);
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -1034,7 +1034,7 @@ public:
void UpdateMissionSnapShot(sptr<IRemoteObject> token,
std::shared_ptr<OHOS::Media::PixelMap> pixelMap);
ErrCode GetDialogSessionInfo(const std::string dialogSessionId, sptr<DialogSessionInfo> &info);
ErrCode GetDialogSessionInfo(const std::string &dialogSessionId, sptr<DialogSessionInfo> &info);
ErrCode SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllow);
#endif
@@ -936,7 +936,7 @@ public:
return 0;
}
virtual int GetDialogSessionInfo(const std::string dialogSessionId, sptr<DialogSessionInfo> &dialogSessionInfo)
virtual int GetDialogSessionInfo(const std::string &dialogSessionId, sptr<DialogSessionInfo> &dialogSessionInfo)
{
return 0;
}
@@ -19,6 +19,7 @@
#include <string>
#include <vector>
#include "application_info.h"
#include "json_serializer.h"
#include "parcel.h"
#include "refbase.h"
@@ -35,6 +36,8 @@ struct DialogAbilityInfo {
int32_t abilityIconId = 0;
int32_t abilityLabelId = 0;
bool visible = true;
int32_t appIndex = 0;
AppExecFwk::MultiAppModeData multiAppMode;
std::string GetURI() const;
bool ParseURI(const std::string &uri);
@@ -99,6 +99,7 @@ public:
BundleInfo &bundleInfo, int32_t userId);
ErrCode QueryCloneExtensionAbilityInfoWithAppIndex(const ElementName &element, int32_t flags, int32_t appCloneIndex,
ExtensionAbilityInfo &extensionInfo, int32_t userId);
ErrCode GetCloneAppIndexes(const std::string &bundleName, std::vector<int32_t> &appIndexes, int32_t userId);
private:
sptr<IBundleMgr> Connect();
@@ -728,7 +728,7 @@ public:
virtual int PrepareTerminateAbility(
const sptr<IRemoteObject> &token, sptr<IPrepareTerminateCallback> &callback) override;
virtual int GetDialogSessionInfo(const std::string dialogSessionId, sptr<DialogSessionInfo> &info) override;
virtual int GetDialogSessionInfo(const std::string &dialogSessionId, sptr<DialogSessionInfo> &info) override;
virtual int SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllow) override;
@@ -1136,11 +1136,13 @@ public:
void HandleUnfocused(const sptr<OHOS::Rosen::FocusChangeInfo> &focusChangeInfo);
virtual int GetDialogSessionInfo(const std::string dialogSessionId,
virtual int GetDialogSessionInfo(const std::string &dialogSessionId,
sptr<DialogSessionInfo> &dialogSessionInfo) override;
virtual int SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllowed) override;
int CreateCloneSelectorDialog(AbilityRequest &request, int32_t userId, const std::string &replaceWantString = "");
virtual int RegisterAbilityFirstFrameStateObserver(const sptr<IAbilityFirstFrameStateObserver> &observer,
const std::string &bundleName) override;
@@ -38,37 +38,61 @@ struct DialogCallerInfo {
bool isSelector = false;
};
enum class SelectorType {
IMPLICIT_START_SELECTOR = 0,
APP_CLONR_SELECTOR = 1
};
class DialogSessionManager {
public:
static DialogSessionManager &GetInstance();
~DialogSessionManager() = default;
sptr<DialogSessionInfo> GetDialogSessionInfo(const std::string dialogSessionId) const;
sptr<DialogSessionInfo> GetDialogSessionInfo(const std::string &dialogSessionId) const;
std::shared_ptr<DialogCallerInfo> GetDialogCallerInfo(const std::string dialogSessionId) const;
std::shared_ptr<DialogCallerInfo> GetDialogCallerInfo(const std::string &dialogSessionId) const;
int SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllowed);
int CreateJumpModalDialog(AbilityRequest &abilityRequest, int32_t userId, const Want &replaceWant);
int CreateSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId,
int CreateImplicitSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId,
std::vector<DialogAppInfo> &dialogAppInfos);
int CreateCloneSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId,
std::vector<DialogAppInfo> &dialogAppInfos, const std::string &replaceWant);
int HandleErmsResult(AbilityRequest &abilityRequest, int32_t userId, const Want &replaceWant);
bool IsCreateCloneSelectorDialog(const std::string &bundleName, int32_t userId);
private:
DialogSessionManager() = default;
std::string GenerateDialogSessionId();
void SetDialogSessionInfo(const std::string dialogSessionId, sptr<DialogSessionInfo> &dilogSessionInfo,
void SetDialogSessionInfo(const std::string &dialogSessionId, sptr<DialogSessionInfo> &dilogSessionInfo,
std::shared_ptr<DialogCallerInfo> &dialogCallerInfo);
void ClearDialogContext(const std::string dialogSessionId);
void ClearDialogContext(const std::string &dialogSessionId);
void ClearAllDialogContexts();
bool GenerateDialogSessionRecord(AbilityRequest &abilityRequest, int32_t userId,
std::string &dialogSessionId, std::vector<DialogAppInfo> &dialogAppInfos, bool isSelector);
std::string GenerateDialogSessionRecordCommon(AbilityRequest &abilityRequest, int32_t userId,
const AAFwk::WantParams &parameters, std::vector<DialogAppInfo> &dialogAppInfos, bool isSelector);
int CreateModalDialogCommon(const Want &replaceWant, sptr<IRemoteObject> callerToken, std::string dialogSessionId);
void GenerateCallerAbilityInfo(AbilityRequest &abilityRequest, DialogAbilityInfo &callerAbilityInfo);
void GenerateSelectorTargetAbilityInfos(std::vector<DialogAppInfo> &dialogAppInfos,
std::vector<DialogAbilityInfo> &targetAbilityInfos);
void GenerateJumpTargetAbilityInfos(AbilityRequest &abilityRequest,
std::vector<DialogAbilityInfo> &targetAbilityInfos);
void GenerateDialogCallerInfo(AbilityRequest &abilityRequest, int32_t userId,
std::shared_ptr<DialogCallerInfo> dialogCallerInfo, bool isSelector);
int CreateModalDialogCommon(const Want &replaceWant, sptr<IRemoteObject> callerToken,
const std::string &dialogSessionId);
mutable ffrt::mutex dialogSessionRecordLock_;
std::unordered_map<std::string, sptr<DialogSessionInfo>> dialogSessionInfoMap_;
@@ -28,7 +28,7 @@ namespace EcologicalRuleMgrService {
using Want = OHOS::AAFwk::Want;
struct AbilityExperienceRule : public Parcelable {
bool isAllow = true;
int32_t resultCode = 10;
std::string sceneCode = "";
sptr<Want> replaceWant = nullptr;
@@ -58,7 +58,8 @@ public:
static bool IsImplicitStartAction(const Want &want);
int ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode = 0);
int ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode = 0,
const std::string &replaceWantString = "", bool isAppCloneSelector = false);
void ResetCallingIdentityAsCaller(int32_t tokenId);
@@ -69,6 +70,13 @@ public:
private:
int GenerateAbilityRequestByAction(int32_t userId, AbilityRequest &request,
std::vector<DialogAppInfo> &dialogAppInfos, bool isMoreHapList, bool &findDefaultApp);
int GenerateAbilityRequestByAppIndexes(int32_t userId, AbilityRequest &request,
std::vector<DialogAppInfo> &dialogAppInfos);
int FindExtensionInfo(const Want &want, int32_t flags, int32_t userId, int32_t appIndex,
AppExecFwk::AbilityInfo &abilityInfo);
std::string MatchTypeAndUri(const AAFwk::Want &want);
std::shared_ptr<AppExecFwk::BundleMgrHelper> GetBundleManagerHelper();
std::vector<std::string> SplitStr(const std::string& str, char delimiter);
@@ -53,6 +53,7 @@ struct StartAbilityUtils {
static bool GetCallerAbilityInfo(const sptr<IRemoteObject> &callerToken,
AppExecFwk::AbilityInfo &abilityInfo);
static int32_t CheckAppProvisionMode(const Want& want, int32_t userId);
static std::vector<int32_t> GetCloneAppIndexes(const std::string &bundleName, int32_t userId);
static bool IsCallFromAncoShellOrBroker(const sptr<IRemoteObject> &callerToken);
@@ -61,6 +62,8 @@ struct StartAbilityUtils {
static thread_local bool skipCrowTest;
static thread_local bool skipStartOther;
static thread_local bool skipErms;
static thread_local int32_t ermsResultCode;
static thread_local bool isWantWithAppCloneIndex;
};
struct StartAbilityInfoWrap {
@@ -17,6 +17,7 @@
#include <functional>
#include "application_info.h"
#include "bundle_mgr_interface.h"
#include "singleton.h"
@@ -59,6 +60,8 @@ struct DialogAppInfo {
std::string abilityName = {};
std::string moduleName = {};
bool visible = true;
int32_t appIndex = 0;
AppExecFwk::MultiAppModeData multiAppMode;
};
/**
* @class SystemDialogScheduler
@@ -1330,7 +1330,7 @@ ErrCode AbilityManagerClient::PrepareTerminateAbility(sptr<IRemoteObject> token,
return abms->PrepareTerminateAbility(token, callback);
}
ErrCode AbilityManagerClient::GetDialogSessionInfo(const std::string dialogSessionId, sptr<DialogSessionInfo> &info)
ErrCode AbilityManagerClient::GetDialogSessionInfo(const std::string &dialogSessionId, sptr<DialogSessionInfo> &info)
{
auto abms = GetAbilityManager();
CHECK_POINTER_RETURN_NOT_CONNECTED(abms);
@@ -3056,7 +3056,7 @@ int AbilityManagerProxy::PrepareTerminateAbility(const sptr<IRemoteObject> &toke
return reply.ReadInt32();
}
int AbilityManagerProxy::GetDialogSessionInfo(const std::string dialogSessionId, sptr<DialogSessionInfo> &info)
int AbilityManagerProxy::GetDialogSessionInfo(const std::string &dialogSessionId, sptr<DialogSessionInfo> &info)
{
MessageParcel data;
MessageParcel reply;
@@ -1152,7 +1152,12 @@ int AbilityManagerService::StartAbilityInner(const Want &want, const sptr<IRemot
#ifdef SUPPORT_SCREEN
if (result != ERR_OK && isReplaceWantExist && !isSendDialogResult &&
callerBundleName != BUNDLE_NAME_DIALOG) {
return DialogSessionManager::GetInstance().CreateJumpModalDialog(abilityRequest, GetUserId(), newWant);
return DialogSessionManager::GetInstance().HandleErmsResult(abilityRequest, GetUserId(), newWant);
}
if (result == ERR_OK &&
DialogSessionManager::GetInstance().IsCreateCloneSelectorDialog(abilityInfo.bundleName, GetUserId())) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "create clone selector dialog");
return CreateCloneSelectorDialog(abilityRequest, GetUserId());
}
#endif // SUPPORT_SCREEN
@@ -1757,7 +1762,12 @@ int AbilityManagerService::StartAbilityForOptionInner(const Want &want, const St
}
#ifdef SUPPORT_SCREEN
if (result != ERR_OK && isReplaceWantExist) {
return DialogSessionManager::GetInstance().CreateJumpModalDialog(abilityRequest, GetUserId(), newWant);
return DialogSessionManager::GetInstance().HandleErmsResult(abilityRequest, GetUserId(), newWant);
}
if (result == ERR_OK &&
DialogSessionManager::GetInstance().IsCreateCloneSelectorDialog(abilityInfo.bundleName, GetUserId())) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "create clone selector dialog");
return CreateCloneSelectorDialog(abilityRequest, GetUserId());
}
#endif // SUPPORT_GRAPHICS
abilityRequest.want.RemoveParam(SPECIFY_TOKEN_ID);
@@ -6914,6 +6924,10 @@ int AbilityManagerService::StartAbilityByCall(const Want &want, const sptr<IAbil
false, callerToken, std::make_shared<AppExecFwk::AbilityInfo>(abilityRequest.abilityInfo));
result = afterCheckExecuter_ == nullptr ? ERR_INVALID_VALUE :
afterCheckExecuter_->DoProcess(afterCheckParam);
if (result != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "afterCheckExecuter_ is nullptr or DoProcess return error.");
return result;
}
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
ReportEventToRSS(abilityRequest.abilityInfo, callerToken);
abilityRequest.want.SetParam(IS_CALL_BY_SCB, false);
@@ -6929,11 +6943,6 @@ int AbilityManagerService::StartAbilityByCall(const Want &want, const sptr<IAbil
}
ReportEventToRSS(abilityRequest.abilityInfo, callerToken);
if (result != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "afterCheckExecuter_ is nullptr or DoProcess return error.");
return result;
}
return missionListMgr->ResolveLocked(abilityRequest);
}
@@ -10263,7 +10272,7 @@ int32_t AbilityManagerService::OpenFile(const Uri& uri, uint32_t flag)
return collaborator->OpenFile(uri, flag);
}
#ifdef SUPPORT_SCREEN
int AbilityManagerService::GetDialogSessionInfo(const std::string dialogSessionId,
int AbilityManagerService::GetDialogSessionInfo(const std::string &dialogSessionId,
sptr<DialogSessionInfo> &dialogSessionInfo)
{
CHECK_CALLER_IS_SYSTEM_APP;
@@ -10281,6 +10290,13 @@ int AbilityManagerService::SendDialogResult(const Want &want, const std::string
CHECK_CALLER_IS_SYSTEM_APP;
return DialogSessionManager::GetInstance().SendDialogResult(want, dialogSessionId, isAllowed);
}
int AbilityManagerService::CreateCloneSelectorDialog(AbilityRequest &request, int32_t userId,
const std::string &replaceWantString)
{
CHECK_POINTER_AND_RETURN(implicitStartProcessor_, ERR_IMPLICIT_START_ABILITY_FAIL);
return implicitStartProcessor_->ImplicitStartAbility(request, userId, 0, replaceWantString, true);
}
#endif // SUPPORT_SCREEN
void AbilityManagerService::RemoveLauncherDeathRecipient(int32_t userId)
{
@@ -11238,9 +11254,13 @@ int AbilityManagerService::StartUIAbilityByPreInstallInner(sptr<SessionInfo> ses
return result;
}
#ifdef SUPPORT_SCREEN
if (result != ERR_OK && isReplaceWantExist &&
callerBundleName != BUNDLE_NAME_DIALOG) {
return DialogSessionManager::GetInstance().CreateJumpModalDialog(abilityRequest, GetUserId(), newWant);
if (result != ERR_OK && isReplaceWantExist && callerBundleName != BUNDLE_NAME_DIALOG) {
return DialogSessionManager::GetInstance().HandleErmsResult(abilityRequest, GetUserId(), newWant);
}
if (result == ERR_OK &&
DialogSessionManager::GetInstance().IsCreateCloneSelectorDialog(abilityInfo.bundleName, GetUserId())) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "create clone selector dialog");
return CreateCloneSelectorDialog(abilityRequest, GetUserId());
}
#endif // SUPPORT_SCREEN
@@ -24,14 +24,16 @@
namespace OHOS {
namespace AAFwk {
constexpr int32_t CYCLE_LIMIT = 1000;
constexpr size_t MEMBER_NUM = 8;
constexpr size_t MEMBER_NUM = 11;
std::string DialogAbilityInfo::GetURI() const
{
return bundleName + "/" + moduleName + "/" + abilityName + "/" +
std::to_string(bundleIconId) + "/" + std::to_string(bundleLabelId) + "/" +
std::to_string(abilityIconId) + "/" + std::to_string(abilityLabelId) + "/" +
std::to_string(visible);
std::to_string(visible) + "/" + std::to_string(appIndex) + "/" +
std::to_string(static_cast<int32_t>(multiAppMode.multiAppModeType)) + "/" +
std::to_string(multiAppMode.maxCount);
}
bool DialogAbilityInfo::ParseURI(const std::string &uri)
@@ -54,6 +56,9 @@ bool DialogAbilityInfo::ParseURI(const std::string &uri)
abilityIconId = static_cast<int32_t>(std::stoi(uriVec[index++]));
abilityLabelId = static_cast<int32_t>(std::stoi(uriVec[index++]));
visible = std::stoi(uriVec[index++]);
appIndex = static_cast<int32_t>(std::stoi(uriVec[index++]));
multiAppMode.multiAppModeType = static_cast<AppExecFwk::MultiAppModeType>(std::stoi(uriVec[index++]));
multiAppMode.maxCount = static_cast<int32_t>(std::stoi(uriVec[index++]));
return true;
}
@@ -26,7 +26,9 @@
#include "int_wrapper.h"
#include "modal_system_ui_extension.h"
#include "parameters.h"
#include "start_ability_utils.h"
#include "string_wrapper.h"
#include "want.h"
#include "want_params_wrapper.h"
namespace OHOS {
@@ -34,6 +36,7 @@ namespace AAFwk {
using OHOS::AppExecFwk::BundleInfo;
namespace {
constexpr const char* UIEXTENSION_MODAL_TYPE = "ability.want.params.modalType";
constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10;
constexpr const char* SUPPORT_CLOSE_ON_BLUR = "supportCloseOnBlur";
}
@@ -63,7 +66,7 @@ std::string DialogSessionManager::GenerateDialogSessionId()
return dialogSessionId;
}
void DialogSessionManager::SetDialogSessionInfo(const std::string dialogSessionId,
void DialogSessionManager::SetDialogSessionInfo(const std::string &dialogSessionId,
sptr<DialogSessionInfo> &dilogSessionInfo, std::shared_ptr<DialogCallerInfo> &dialogCallerInfo)
{
std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
@@ -71,7 +74,7 @@ void DialogSessionManager::SetDialogSessionInfo(const std::string dialogSessionI
dialogCallerInfoMap_[dialogSessionId] = dialogCallerInfo;
}
sptr<DialogSessionInfo> DialogSessionManager::GetDialogSessionInfo(const std::string dialogSessionId) const
sptr<DialogSessionInfo> DialogSessionManager::GetDialogSessionInfo(const std::string &dialogSessionId) const
{
std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
auto it = dialogSessionInfoMap_.find(dialogSessionId);
@@ -82,7 +85,7 @@ sptr<DialogSessionInfo> DialogSessionManager::GetDialogSessionInfo(const std::st
return nullptr;
}
std::shared_ptr<DialogCallerInfo> DialogSessionManager::GetDialogCallerInfo(const std::string dialogSessionId) const
std::shared_ptr<DialogCallerInfo> DialogSessionManager::GetDialogCallerInfo(const std::string &dialogSessionId) const
{
std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
auto it = dialogCallerInfoMap_.find(dialogSessionId);
@@ -93,7 +96,7 @@ std::shared_ptr<DialogCallerInfo> DialogSessionManager::GetDialogCallerInfo(cons
return nullptr;
}
void DialogSessionManager::ClearDialogContext(const std::string dialogSessionId)
void DialogSessionManager::ClearDialogContext(const std::string &dialogSessionId)
{
std::lock_guard<ffrt::mutex> guard(dialogSessionRecordLock_);
auto it = dialogSessionInfoMap_.find(dialogSessionId);
@@ -114,26 +117,29 @@ void DialogSessionManager::ClearAllDialogContexts()
dialogCallerInfoMap_.clear();
}
bool DialogSessionManager::GenerateDialogSessionRecord(AbilityRequest &abilityRequest, int32_t userId,
std::string &dialogSessionId, std::vector<DialogAppInfo> &dialogAppInfos, bool isSelector)
void DialogSessionManager::GenerateCallerAbilityInfo(AbilityRequest &abilityRequest,
DialogAbilityInfo &callerAbilityInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
auto dialogSessionInfo = sptr<DialogSessionInfo>::MakeSptr();
CHECK_POINTER_AND_RETURN(dialogSessionInfo, ERR_INVALID_VALUE);
sptr<IRemoteObject> callerToken = abilityRequest.callerToken;
if (callerToken != nullptr) {
auto callerRecord = Token::GetAbilityRecordByToken(callerToken);
CHECK_POINTER_AND_RETURN(callerRecord, ERR_INVALID_VALUE);
dialogSessionInfo->callerAbilityInfo.bundleName = callerRecord->GetAbilityInfo().bundleName;
dialogSessionInfo->callerAbilityInfo.moduleName = callerRecord->GetAbilityInfo().moduleName;
dialogSessionInfo->callerAbilityInfo.abilityName = callerRecord->GetAbilityInfo().name;
dialogSessionInfo->callerAbilityInfo.abilityIconId = callerRecord->GetAbilityInfo().iconId;
dialogSessionInfo->callerAbilityInfo.abilityLabelId = callerRecord->GetAbilityInfo().labelId;
dialogSessionInfo->callerAbilityInfo.bundleIconId = callerRecord->GetApplicationInfo().iconId;
dialogSessionInfo->callerAbilityInfo.bundleLabelId = callerRecord->GetApplicationInfo().labelId;
CHECK_POINTER(callerRecord);
callerAbilityInfo.bundleName = callerRecord->GetAbilityInfo().bundleName;
callerAbilityInfo.moduleName = callerRecord->GetAbilityInfo().moduleName;
callerAbilityInfo.abilityName = callerRecord->GetAbilityInfo().name;
callerAbilityInfo.abilityIconId = callerRecord->GetAbilityInfo().iconId;
callerAbilityInfo.abilityLabelId = callerRecord->GetAbilityInfo().labelId;
callerAbilityInfo.bundleIconId = callerRecord->GetApplicationInfo().iconId;
callerAbilityInfo.bundleLabelId = callerRecord->GetApplicationInfo().labelId;
callerAbilityInfo.visible = callerRecord->GetAbilityInfo().visible;
callerAbilityInfo.appIndex = callerRecord->GetApplicationInfo().appIndex;
callerAbilityInfo.multiAppMode = callerRecord->GetApplicationInfo().multiAppMode;
}
dialogSessionInfo->parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType()));
dialogSessionInfo->parameters.SetParam("userId", AAFwk::Integer::Box(userId));
}
void DialogSessionManager::GenerateSelectorTargetAbilityInfos(std::vector<DialogAppInfo> &dialogAppInfos,
std::vector<DialogAbilityInfo> &targetAbilityInfos)
{
for (auto &dialogAppInfo : dialogAppInfos) {
DialogAbilityInfo targetDialogAbilityInfo;
targetDialogAbilityInfo.bundleName = dialogAppInfo.bundleName;
@@ -144,22 +150,39 @@ bool DialogSessionManager::GenerateDialogSessionRecord(AbilityRequest &abilityRe
targetDialogAbilityInfo.bundleIconId = dialogAppInfo.bundleIconId;
targetDialogAbilityInfo.bundleLabelId = dialogAppInfo.bundleLabelId;
targetDialogAbilityInfo.visible = dialogAppInfo.visible;
dialogSessionInfo->targetAbilityInfos.emplace_back(targetDialogAbilityInfo);
targetDialogAbilityInfo.appIndex = dialogAppInfo.appIndex;
targetDialogAbilityInfo.multiAppMode = dialogAppInfo.multiAppMode;
targetAbilityInfos.emplace_back(targetDialogAbilityInfo);
}
std::shared_ptr<DialogCallerInfo> dialogCallerInfo = std::make_shared<DialogCallerInfo>();
if (isSelector) {
dialogSessionInfo->parameters.SetParam("action", AAFwk::String::Box(abilityRequest.want.GetAction()));
dialogSessionInfo->parameters.SetParam("wantType", AAFwk::String::Box(abilityRequest.want.GetType()));
dialogSessionInfo->parameters.SetParam("uri", AAFwk::String::Box(abilityRequest.want.GetUriString()));
dialogCallerInfo->isSelector = true;
}
dialogCallerInfo->callerToken = callerToken;
}
void DialogSessionManager::GenerateJumpTargetAbilityInfos(AbilityRequest &abilityRequest,
std::vector<DialogAbilityInfo> &targetAbilityInfos)
{
DialogAbilityInfo targetDialogAbilityInfo;
targetDialogAbilityInfo.bundleName = abilityRequest.abilityInfo.bundleName;
targetDialogAbilityInfo.moduleName = abilityRequest.abilityInfo.moduleName;
targetDialogAbilityInfo.abilityName = abilityRequest.abilityInfo.name;
targetDialogAbilityInfo.abilityIconId = abilityRequest.abilityInfo.iconId;
targetDialogAbilityInfo.abilityLabelId = abilityRequest.abilityInfo.labelId;
targetDialogAbilityInfo.bundleIconId = abilityRequest.abilityInfo.applicationInfo.iconId;
targetDialogAbilityInfo.bundleLabelId = abilityRequest.abilityInfo.applicationInfo.labelId;
targetDialogAbilityInfo.visible = abilityRequest.abilityInfo.visible;
targetDialogAbilityInfo.appIndex = abilityRequest.abilityInfo.applicationInfo.appIndex;
targetDialogAbilityInfo.multiAppMode = abilityRequest.abilityInfo.applicationInfo.multiAppMode;
targetAbilityInfos.emplace_back(targetDialogAbilityInfo);
}
void DialogSessionManager::GenerateDialogCallerInfo(AbilityRequest &abilityRequest, int32_t userId,
std::shared_ptr<DialogCallerInfo> dialogCallerInfo, bool isSelector)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
CHECK_POINTER(dialogCallerInfo);
dialogCallerInfo->isSelector = isSelector;
dialogCallerInfo->callerToken = abilityRequest.callerToken;
dialogCallerInfo->requestCode = abilityRequest.requestCode;
dialogCallerInfo->targetWant = abilityRequest.want;
dialogCallerInfo->userId = userId;
dialogSessionId = GenerateDialogSessionId();
SetDialogSessionInfo(dialogSessionId, dialogSessionInfo, dialogCallerInfo);
return true;
}
int DialogSessionManager::SendDialogResult(const Want &want, const std::string &dialogSessionId, bool isAllowed)
@@ -179,6 +202,10 @@ int DialogSessionManager::SendDialogResult(const Want &want, const std::string &
targetWant.SetElement(want.GetElement());
targetWant.SetParam("isSelector", dialogCallerInfo->isSelector);
targetWant.SetParam("dialogSessionId", dialogSessionId);
if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY)) {
int32_t appIndex = want.GetIntParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, 0);
targetWant.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, appIndex);
}
sptr<IRemoteObject> callerToken = dialogCallerInfo->callerToken;
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
if (!abilityMgr) {
@@ -193,39 +220,105 @@ int DialogSessionManager::SendDialogResult(const Want &want, const std::string &
return ret;
}
std::string DialogSessionManager::GenerateDialogSessionRecordCommon(AbilityRequest &abilityRequest, int32_t userId,
const AAFwk::WantParams &parameters, std::vector<DialogAppInfo> &dialogAppInfos, bool isSelector)
{
auto dialogSessionInfo = sptr<DialogSessionInfo>::MakeSptr();
CHECK_POINTER_AND_RETURN(dialogSessionInfo, "");
GenerateCallerAbilityInfo(abilityRequest, dialogSessionInfo->callerAbilityInfo);
if (isSelector) {
GenerateSelectorTargetAbilityInfos(dialogAppInfos, dialogSessionInfo->targetAbilityInfos);
} else {
GenerateJumpTargetAbilityInfos(abilityRequest, dialogSessionInfo->targetAbilityInfos);
}
dialogSessionInfo->parameters = parameters;
std::shared_ptr<DialogCallerInfo> dialogCallerInfo = std::make_shared<DialogCallerInfo>();
GenerateDialogCallerInfo(abilityRequest, userId, dialogCallerInfo, isSelector);
std::string dialogSessionId = GenerateDialogSessionId();
SetDialogSessionInfo(dialogSessionId, dialogSessionInfo, dialogCallerInfo);
return dialogSessionId;
}
int DialogSessionManager::CreateJumpModalDialog(AbilityRequest &abilityRequest, int32_t userId,
const Want &replaceWant)
{
std::string dialogSessionId;
std::vector<DialogAppInfo> dialogAppInfos(1);
dialogAppInfos.front().bundleName = abilityRequest.abilityInfo.bundleName;
dialogAppInfos.front().moduleName = abilityRequest.abilityInfo.moduleName;
dialogAppInfos.front().abilityName = abilityRequest.abilityInfo.name;
dialogAppInfos.front().abilityIconId = abilityRequest.abilityInfo.iconId;
dialogAppInfos.front().abilityLabelId = abilityRequest.abilityInfo.labelId;
dialogAppInfos.front().bundleIconId = abilityRequest.abilityInfo.applicationInfo.iconId;
dialogAppInfos.front().bundleLabelId = abilityRequest.abilityInfo.applicationInfo.labelId;
if (!GenerateDialogSessionRecord(abilityRequest, userId, dialogSessionId, dialogAppInfos, false)) {
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
AAFwk::WantParams parameters;
parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType()));
parameters.SetParam("userId", AAFwk::Integer::Box(userId));
std::vector<DialogAppInfo> dialogAppInfos;
std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, parameters,
dialogAppInfos, false);
if (dialogSessionId == "") {
TAG_LOGE(AAFwkTag::ABILITYMGR, "generate dialog session record failed");
return INNER_ERR;
return ERR_INVALID_VALUE;
}
return CreateModalDialogCommon(replaceWant, abilityRequest.callerToken, dialogSessionId);
}
int DialogSessionManager::CreateSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want, int32_t userId,
std::vector<DialogAppInfo> &dialogAppInfos)
int DialogSessionManager::CreateImplicitSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want,
int32_t userId, std::vector<DialogAppInfo> &dialogAppInfos)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
std::string dialogSessionId;
if (!GenerateDialogSessionRecord(abilityRequest, userId, dialogSessionId, dialogAppInfos, true)) {
AAFwk::Want sessionWant;
sessionWant.SetParam("deviceType", OHOS::system::GetDeviceType());
sessionWant.SetParam("userId", userId);
sessionWant.SetParam("action", abilityRequest.want.GetAction());
sessionWant.SetParam("wantType", abilityRequest.want.GetType());
sessionWant.SetParam("uri", abilityRequest.want.GetUriString());
sessionWant.SetParam("entities", abilityRequest.want.GetEntities());
sessionWant.SetParam("appselector.selectorType", static_cast<int>(SelectorType::IMPLICIT_START_SELECTOR));
bool showCaller = abilityRequest.want.GetBoolParam("showcaller", false);
sessionWant.SetParam("showCaller", showCaller);
std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, sessionWant.GetParams(),
dialogAppInfos, true);
if (dialogSessionId == "") {
TAG_LOGE(AAFwkTag::ABILITYMGR, "generate dialog session record failed");
return INNER_ERR;
return ERR_INVALID_VALUE;
}
return CreateModalDialogCommon(want, abilityRequest.callerToken, dialogSessionId);
}
int DialogSessionManager::CreateCloneSelectorModalDialog(AbilityRequest &abilityRequest, const Want &want,
int32_t userId, std::vector<DialogAppInfo> &dialogAppInfos, const std::string &replaceWant)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
AAFwk::WantParams parameters;
parameters.SetParam("deviceType", AAFwk::String::Box(OHOS::system::GetDeviceType()));
parameters.SetParam("userId", AAFwk::Integer::Box(userId));
parameters.SetParam("appselector.selectorType",
AAFwk::Integer::Box(static_cast<int>(SelectorType::APP_CLONR_SELECTOR)));
if (replaceWant != "") {
parameters.SetParam("replaceWant", AAFwk::String::Box(replaceWant));
}
std::string dialogSessionId = GenerateDialogSessionRecordCommon(abilityRequest, userId, parameters,
dialogAppInfos, true);
if (dialogSessionId == "") {
TAG_LOGE(AAFwkTag::ABILITYMGR, "generate dialog session record failed");
return ERR_INVALID_VALUE;
}
return CreateModalDialogCommon(want, abilityRequest.callerToken, dialogSessionId);
}
int DialogSessionManager::CreateModalDialogCommon(const Want &replaceWant, sptr<IRemoteObject> callerToken,
std::string dialogSessionId)
const std::string &dialogSessionId)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
(const_cast<Want &>(replaceWant)).SetParam("dialogSessionId", dialogSessionId);
@@ -265,5 +358,36 @@ int DialogSessionManager::CreateModalDialogCommon(const Want &replaceWant, sptr<
(const_cast<Want &>(replaceWant)).SetParam(SUPPORT_CLOSE_ON_BLUR, true);
return connection->CreateModalUIExtension(replaceWant) ? ERR_OK : INNER_ERR;
}
int DialogSessionManager::HandleErmsResult(AbilityRequest &abilityRequest, int32_t userId,
const Want &replaceWant)
{
std::string bundleName = abilityRequest.abilityInfo.bundleName;
if (StartAbilityUtils::ermsResultCode < ERMS_ISALLOW_RESULTCODE ||
!IsCreateCloneSelectorDialog(bundleName, userId)) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "create jump modal dialog");
return CreateJumpModalDialog(abilityRequest, userId, replaceWant);
}
auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
if (!abilityMgr) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "abilityMgr is nullptr.");
return INNER_ERR;
}
return abilityMgr->CreateCloneSelectorDialog(abilityRequest, userId, replaceWant.ToString());
}
bool DialogSessionManager::IsCreateCloneSelectorDialog(const std::string &bundleName, int32_t userId)
{
if (StartAbilityUtils::isWantWithAppCloneIndex) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "want with app clone index.");
return false;
}
auto appIndexes = StartAbilityUtils::GetCloneAppIndexes(bundleName, userId);
if (appIndexes.empty()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "The application do not create clone index.");
return false;
}
return true;
}
} // namespace AAFwk
} // namespace OHOS
@@ -144,8 +144,8 @@ int32_t AbilityEcologicalRuleMgrServiceClient::QueryStartExperience(const OHOS::
if (rule.replaceWant != nullptr) {
rule.replaceWant->SetParam(ERMS_ORIGINAL_TARGET, want.ToString());
TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE,
"queryStart finish: isAllow = %{public}d, sceneCode = %{public}s, replaceWant = %{public}s", rule.isAllow,
rule.sceneCode.c_str(), (*(rule.replaceWant)).ToString().c_str());
"queryStart finish: resultCode = %{public}d, sceneCode = %{public}s, replaceWant = %{public}s",
rule.resultCode, rule.sceneCode.c_str(), (*(rule.replaceWant)).ToString().c_str());
}
int64_t cost = GetCurrentTimeMicro() - start;
TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE,
@@ -34,7 +34,7 @@ AbilityExperienceRule *AbilityExperienceRule::Unmarshalling(Parcel &in)
return nullptr;
}
if (!in.ReadBool(rule->isAllow)) {
if (!in.ReadInt32(rule->resultCode)) {
delete rule;
return nullptr;
}
@@ -51,8 +51,8 @@ AbilityExperienceRule *AbilityExperienceRule::Unmarshalling(Parcel &in)
bool AbilityExperienceRule::Marshalling(Parcel &parcel) const
{
if (!parcel.WriteBool(isAllow)) {
TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write isAllow failed");
if (!parcel.WriteInt32(resultCode)) {
TAG_LOGE(AAFwkTag::ECOLOGICAL_RULE, "write resultCode failed");
return false;
}
@@ -25,12 +25,14 @@
#include "errors.h"
#include "ecological_rule/ability_ecological_rule_mgr_service.h"
#include "event_report.h"
#include "global_constant.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
#include "in_process_call_wrapper.h"
#include "parameters.h"
#include "scene_board_judgement.h"
#include "start_ability_utils.h"
#include "startup_util.h"
#include "want.h"
namespace OHOS {
@@ -86,7 +88,8 @@ bool ImplicitStartProcessor::IsImplicitStartAction(const Want &want)
return false;
}
int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode)
int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_t userId, int32_t windowMode,
const std::string &replaceWantString, bool isAppCloneSelector)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
TAG_LOGI(AAFwkTag::ABILITYMGR, "implicit start ability by type: %{public}d", request.callType);
@@ -96,9 +99,14 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_
std::vector<DialogAppInfo> dialogAppInfos;
request.want.RemoveParam(APP_CLONE_INDEX);
bool findDefaultApp = false;
auto ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos, false, findDefaultApp);
int32_t ret = ERR_OK;
if (isAppCloneSelector) {
ret = GenerateAbilityRequestByAppIndexes(userId, request, dialogAppInfos);
} else {
ret = GenerateAbilityRequestByAction(userId, request, dialogAppInfos, false, findDefaultApp);
}
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "generate ability request by action failed.");
TAG_LOGE(AAFwkTag::ABILITYMGR, "generate ability request failed.");
return ret;
}
AbilityUtil::WantSetParameterWindowMode(request.want, windowMode);
@@ -136,7 +144,8 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_
}
if (want.GetBoolParam("isCreateAppGallerySelector", false)) {
want.RemoveParam("isCreateAppGallerySelector");
DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos);
DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request, want, userId,
dialogAppInfos);
return ERR_IMPLICIT_START_ABILITY_FAIL;
}
TAG_LOGE(AAFwkTag::ABILITYMGR, "implicit query ability infos failed, show tips dialog.");
@@ -153,7 +162,8 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_
}
if (want.GetBoolParam("isCreateAppGallerySelector", false)) {
want.RemoveParam("isCreateAppGallerySelector");
DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos);
DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request, want, userId,
dialogAppInfos);
return ERR_IMPLICIT_START_ABILITY_FAIL;
}
std::vector<DialogAppInfo> dialogAllAppInfos;
@@ -206,7 +216,12 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_
}
if (want.GetBoolParam("isCreateAppGallerySelector", false)) {
want.RemoveParam("isCreateAppGallerySelector");
return DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos);
if (isAppCloneSelector) {
return DialogSessionManager::GetInstance().CreateCloneSelectorModalDialog(request, want,
userId, dialogAppInfos, replaceWantString);
}
return DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request,
want, userId, dialogAppInfos);
}
ret = abilityMgr->ImplicitStartAbilityAsCaller(request.want, request.callerToken, nullptr);
// reset calling indentity
@@ -225,7 +240,12 @@ int ImplicitStartProcessor::ImplicitStartAbility(AbilityRequest &request, int32_
}
if (want.GetBoolParam("isCreateAppGallerySelector", false)) {
want.RemoveParam("isCreateAppGallerySelector");
return DialogSessionManager::GetInstance().CreateSelectorModalDialog(request, want, userId, dialogAppInfos);
if (isAppCloneSelector) {
return DialogSessionManager::GetInstance().CreateCloneSelectorModalDialog(request, want, userId,
dialogAppInfos, replaceWantString);
}
return DialogSessionManager::GetInstance().CreateImplicitSelectorModalDialog(request, want, userId,
dialogAppInfos);
}
ret = abilityMgr->ImplicitStartAbilityAsCaller(request.want, request.callerToken, nullptr);
// reset calling indentity
@@ -446,12 +466,78 @@ int ImplicitStartProcessor::GenerateAbilityRequestByAction(int32_t userId,
dialogAppInfo.bundleIconId = info.applicationInfo.iconId;
dialogAppInfo.bundleLabelId = info.applicationInfo.labelId;
dialogAppInfo.visible = info.visible;
dialogAppInfo.appIndex = info.applicationInfo.appIndex;
dialogAppInfo.multiAppMode = info.applicationInfo.multiAppMode;
dialogAppInfos.emplace_back(dialogAppInfo);
}
return ERR_OK;
}
int ImplicitStartProcessor::GenerateAbilityRequestByAppIndexes(int32_t userId, AbilityRequest &request,
std::vector<DialogAppInfo> &dialogAppInfos)
{
auto appIndexes = StartAbilityUtils::GetCloneAppIndexes(request.want.GetBundle(), userId);
if (appIndexes.size() > AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "The size of appIndexes is too large.");
return ERR_INVALID_VALUE;
}
auto bms = GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED);
auto abilityInfoFlag = static_cast<uint32_t>(AbilityRuntime::StartupUtil::BuildAbilityInfoFlag()) |
static_cast<uint32_t>(AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_SKILL);
std::vector<AppExecFwk::AbilityInfo> abilityInfos;
abilityInfos.emplace_back(request.abilityInfo);
for (auto &appIndex: appIndexes) {
AppExecFwk::AbilityInfo abilityInfo;
IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneAbilityInfo(request.want.GetElement(), abilityInfoFlag, appIndex,
abilityInfo, userId));
if (abilityInfo.name.empty() || abilityInfo.bundleName.empty()) {
int32_t ret = FindExtensionInfo(request.want, abilityInfoFlag, userId, appIndex, abilityInfo);
if (ret != ERR_OK) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "query clone extension info failed.");
return ret;
}
}
abilityInfos.emplace_back(abilityInfo);
}
for (const auto &info : abilityInfos) {
DialogAppInfo dialogAppInfo;
dialogAppInfo.abilityName = info.name;
dialogAppInfo.bundleName = info.bundleName;
dialogAppInfo.moduleName = info.moduleName;
dialogAppInfo.abilityIconId = info.iconId;
dialogAppInfo.abilityLabelId = info.labelId;
dialogAppInfo.bundleIconId = info.applicationInfo.iconId;
dialogAppInfo.bundleLabelId = info.applicationInfo.labelId;
dialogAppInfo.visible = info.visible;
dialogAppInfo.appIndex = info.applicationInfo.appIndex;
dialogAppInfo.multiAppMode = info.applicationInfo.multiAppMode;
dialogAppInfos.emplace_back(dialogAppInfo);
}
return ERR_OK;
}
int ImplicitStartProcessor::FindExtensionInfo(const Want &want, int32_t flags, int32_t userId,
int32_t appIndex, AppExecFwk::AbilityInfo &abilityInfo)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
auto bms = GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED);
AppExecFwk::ExtensionAbilityInfo extensionInfo;
IN_PROCESS_CALL_WITHOUT_RET(bms->QueryCloneExtensionAbilityInfoWithAppIndex(want.GetElement(),
flags, appIndex, extensionInfo, userId));
if (extensionInfo.bundleName.empty() || extensionInfo.name.empty()) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "extensionInfo empty.");
return RESOLVE_ABILITY_ERR;
}
if (AbilityRuntime::StartupUtil::IsSupportAppClone(extensionInfo.type)) {
AbilityRuntime::StartupUtil::InitAbilityInfoFromExtension(extensionInfo, abilityInfo);
return ERR_OK;
}
return ERR_APP_CLONE_INDEX_INVALID;
}
int ImplicitStartProcessor::QueryBmsAppInfos(AbilityRequest &request, int32_t userId,
std::vector<DialogAppInfo> &dialogAppInfos)
{
@@ -489,6 +575,9 @@ int ImplicitStartProcessor::QueryBmsAppInfos(AbilityRequest &request, int32_t us
dialogAppInfo.abilityLabelId = abilityInfo.labelId;
dialogAppInfo.bundleIconId = abilityInfo.applicationInfo.iconId;
dialogAppInfo.bundleLabelId = abilityInfo.applicationInfo.labelId;
dialogAppInfo.visible = abilityInfo.visible;
dialogAppInfo.appIndex = abilityInfo.applicationInfo.appIndex;
dialogAppInfo.multiAppMode = abilityInfo.applicationInfo.multiAppMode;
dialogAppInfos.emplace_back(dialogAppInfo);
}
}
@@ -720,6 +809,8 @@ void ImplicitStartProcessor::AddAbilityInfoToDialogInfos(const AddInfoParam &par
dialogAppInfo.bundleIconId = param.info.applicationInfo.iconId;
dialogAppInfo.bundleLabelId = param.info.applicationInfo.labelId;
dialogAppInfo.visible = param.info.visible;
dialogAppInfo.appIndex = param.info.applicationInfo.appIndex;
dialogAppInfo.multiAppMode = param.info.applicationInfo.multiAppMode;
dialogAppInfos.emplace_back(dialogAppInfo);
}
@@ -31,6 +31,7 @@ namespace {
constexpr const char* ABILITY_SUPPORT_ECOLOGICAL_RULEMGRSERVICE =
"persist.sys.abilityms.support.ecologicalrulemgrservice";
constexpr const char* BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard";
constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10;
}
ErrCode EcologicalRuleInterceptor::DoProcess(AbilityInterceptorParam param)
{
@@ -63,7 +64,8 @@ ErrCode EcologicalRuleInterceptor::DoProcess(AbilityInterceptorParam param)
return ERR_OK;
}
TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "check ecological rule success");
if (rule.isAllow) {
StartAbilityUtils::ermsResultCode = rule.resultCode;
if (rule.resultCode == ERMS_ISALLOW_RESULTCODE) {
TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "ecological rule is allow, keep going.");
return ERR_OK;
}
@@ -125,7 +127,7 @@ bool EcologicalRuleInterceptor::DoProcess(Want &want, int32_t userId)
TAG_LOGD(AAFwkTag::ECOLOGICAL_RULE, "check ecological rule failed, keep going.");
return true;
}
return rule.isAllow;
return rule.resultCode == ERMS_ISALLOW_RESULTCODE;
}
void EcologicalRuleInterceptor::GetEcologicalTargetInfo(const Want &want,
@@ -30,6 +30,7 @@ namespace AAFwk {
namespace {
constexpr const char* SCREENSHOT_BUNDLE_NAME = "com.huawei.ohos.screenshot";
constexpr const char* SCREENSHOT_ABILITY_NAME = "com.huawei.ohos.screenshot.ServiceExtAbility";
constexpr int32_t ERMS_ISALLOW_RESULTCODE = 10;
constexpr const char* SHELL_ASSISTANT_BUNDLENAME = "com.huawei.shell_assistant";
constexpr int32_t BROKER_UID = 5557;
}
@@ -38,6 +39,8 @@ thread_local std::shared_ptr<StartAbilityInfo> StartAbilityUtils::callerAbilityI
thread_local bool StartAbilityUtils::skipCrowTest = false;
thread_local bool StartAbilityUtils::skipStartOther = false;
thread_local bool StartAbilityUtils::skipErms = false;
thread_local int32_t StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
thread_local bool StartAbilityUtils::isWantWithAppCloneIndex = false;
bool StartAbilityUtils::GetAppIndex(const Want &want, sptr<IRemoteObject> callerToken, int32_t &appIndex)
{
@@ -116,6 +119,15 @@ int32_t StartAbilityUtils::CheckAppProvisionMode(const Want& want, int32_t userI
return ERR_OK;
}
std::vector<int32_t> StartAbilityUtils::GetCloneAppIndexes(const std::string &bundleName, int32_t userId)
{
std::vector<int32_t> appIndexes;
auto bms = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER_AND_RETURN(bms, appIndexes);
IN_PROCESS_CALL_WITHOUT_RET(bms->GetCloneAppIndexes(bundleName, appIndexes, userId));
return appIndexes;
}
StartAbilityInfoWrap::StartAbilityInfoWrap(const Want &want, int32_t validUserId, int32_t appIndex,
const sptr<IRemoteObject> &callerToken, bool isExtension)
{
@@ -154,6 +166,13 @@ StartAbilityInfoWrap::StartAbilityInfoWrap(const Want &want, int32_t validUserId
TAG_LOGW(AAFwkTag::ABILITYMGR, "callerAbilityInfo has been created");
}
StartAbilityUtils::callerAbilityInfo = StartAbilityInfo::CreateCallerAbilityInfo(callerToken);
StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
StartAbilityUtils::isWantWithAppCloneIndex = false;
if (want.HasParameter(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY) && appIndex >= 0 &&
appIndex < AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
StartAbilityUtils::isWantWithAppCloneIndex = true;
}
}
StartAbilityInfoWrap::~StartAbilityInfoWrap()
@@ -163,6 +182,8 @@ StartAbilityInfoWrap::~StartAbilityInfoWrap()
StartAbilityUtils::skipCrowTest = false;
StartAbilityUtils::skipStartOther = false;
StartAbilityUtils::skipErms = false;
StartAbilityUtils::ermsResultCode = ERMS_ISALLOW_RESULTCODE;
StartAbilityUtils::isWantWithAppCloneIndex = false;
}
std::shared_ptr<StartAbilityInfo> StartAbilityInfo::CreateStartAbilityInfo(const Want &want, int32_t userId,
@@ -351,6 +351,9 @@ const std::string SystemDialogScheduler::GetSelectorParams(const std::vector<Dia
aObj["bundle"] = aInfo.bundleName;
aObj["ability"] = aInfo.abilityName;
aObj["module"] = aInfo.moduleName;
aObj["appIndex"] = std::to_string(aInfo.appIndex);
aObj["bundleLabel"] = std::to_string(aInfo.bundleLabelId);
aObj["bundleIcon"] = std::to_string(aInfo.bundleIconId);
hapListObj.emplace_back(aObj);
}
jsonObject["hapList"] = hapListObj;
@@ -401,6 +404,9 @@ const std::string SystemDialogScheduler::GetPcSelectorParams(const std::vector<D
aObj["module"] = info.moduleName;
aObj["type"] = type;
aObj["userId"] = std::to_string(userId);
aObj["appIndex"] = std::to_string(info.appIndex);
aObj["bundleLabel"] = std::to_string(info.bundleLabelId);
aObj["bundleIcon"] = std::to_string(info.bundleIconId);
hapListObj.emplace_back(aObj);
}
jsonObject["hapList"] = hapListObj;
@@ -2,8 +2,8 @@
"app": {
"bundleName": "com.ohos.amsdialog",
"vendor": "example",
"versionCode": 1000006,
"versionName": "1.3.0",
"versionCode": 1000007,
"versionName": "1.4.0",
"icon": "$media:app_icon",
"label": "$string:app_name",
"distributedNotificationEnabled": true,
@@ -48,7 +48,7 @@ export default class SelectorServiceExtensionAbility extends extension {
let phoneShowHapList = [];
let jsonIconMap: Map<string, image.PixelMap> = new Map();
for (let i = 1; i <= globalThis.params.hapList.length; i++) {
console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i]));
console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i - 1]));
await this.getHapResource(globalThis.params.hapList[i - 1], showHapList, jsonIconMap);
if (i % lineNums === 0) {
phoneShowHapList.push(showHapList);
@@ -65,7 +65,7 @@ export default class SelectorServiceExtensionAbility extends extension {
let signalRowShowHapList = [];
let signalRowPhoneShowHapList = [];
for (let i = 1; i <= globalThis.params.hapList.length; i++) {
console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i]));
console.info(TAG, 'hapList[' + (i - 1).toString() + ']: ' + JSON.stringify(globalThis.params.hapList[i - 1]));
await this.getHapResource(globalThis.params.hapList[i - 1], signalRowShowHapList, jsonIconMap);
if (i % signalRowlineNums === 0) {
signalRowPhoneShowHapList.push(signalRowShowHapList);
@@ -99,19 +99,30 @@ export default class SelectorServiceExtensionAbility extends extension {
let appIcon = '';
let type = '';
let userId = Number('0');
let appIndex = Number(hap.appIndex);
if (!globalThis.params.isDefaultSelector) {
type = hap.type;
userId = Number(hap.userId);
}
let lableId = Number(hap.label);
if (lableId === 0) {
lableId = Number(hap.bundleLabel);
}
let moduleContext = globalThis.selectExtensionContext.createModuleContext(bundleName, moduleName);
await moduleContext.resourceManager.getString(lableId).then(value => {
appName = value;
if (appIndex === 0) {
appName = value;
} else {
appName = value + hap.appIndex;
}
}).catch(error => {
console.error(TAG, 'getString error:' + JSON.stringify(error));
});
let iconId = Number(hap.icon);
if (iconId === 0) {
iconId = Number(hap.bundleIcon);
}
await moduleContext.resourceManager.getMediaBase64(iconId).then(value => {
appIcon = value;
if (appIcon.indexOf('image/json') > -1) {
@@ -123,7 +134,8 @@ export default class SelectorServiceExtensionAbility extends extension {
<drawableDescriptor.LayeredDrawableDescriptor> imageDescriptor;
let foregroundDescriptor: drawableDescriptor.DrawableDescriptor = layeredDrawableDescriptor.getForeground();
if (foregroundDescriptor !== null && foregroundDescriptor !== undefined) {
jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName, foregroundDescriptor.getPixelMap());
jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName + ':' + hap.appIndex,
foregroundDescriptor.getPixelMap());
} else {
console.error(TAG, 'get foregroundDescriptor is null');
}
@@ -136,7 +148,7 @@ export default class SelectorServiceExtensionAbility extends extension {
console.error(TAG, 'getMediaBase64 error:' + JSON.stringify(error));
});
showHapList.push(bundleName + '#' + abilityName + '#' + appName +
'#' + appIcon + '#' + moduleName + '#' + type + '#' + userId);
'#' + appIcon + '#' + moduleName + '#' + type + '#' + userId + '#' + appIndex);
}
async onRequest(want, startId) {
@@ -79,6 +79,7 @@ struct SelectorPcDialog {
globalThis.abilityWant.bundleName = item.split('#')[0];
globalThis.abilityWant.abilityName = item.split('#')[1];
globalThis.abilityWant.moduleName = item.split('#')[4];
globalThis.abilityWant.parameters['ohos.extra.param.key.appCloneIndex'] = Number(item.split('#')[7]);
globalThis.selectExtensionContext.startAbilityAsCaller(globalThis.abilityWant, (data, error) => {
if (error) {
console.error(this.TAG + ' startAbility finish, error: ' + JSON.stringify(error));
@@ -148,7 +149,7 @@ struct SelectorPcDialog {
let foregroundDescriptor: drawableDescriptor.DrawableDescriptor =
layeredDrawableDescriptor.getForeground();
if (foregroundDescriptor !== null && foregroundDescriptor !== undefined) {
globalThis.jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName,
globalThis.jsonIconMap.set(bundleName + ':' + moduleName + ':' + abilityName + ':' + hap.appIndex,
foregroundDescriptor.getPixelMap());
} else {
console.error(this.TAG, 'get foregroundDescriptor is null');
@@ -276,7 +277,7 @@ struct SelectorPcDialog {
if (item.split('#')[3] != '') {
if (item.split('#')[3].indexOf('image/json') > -1) {
Image(globalThis.jsonIconMap.get(item.split('#')[0] + ':' + item.split('#')[4] +
':' + item.split('#')[1]))
':' + item.split('#')[1] + ':' + item.split('#')[7]))
.height(48)
.width(48)
.alignSelf(ItemAlign.Center)
@@ -372,7 +373,7 @@ struct SelectorPcDialog {
if (item.split('#')[3] != '') {
if (item.split('#')[3].indexOf('image/json') > -1) {
Image(globalThis.jsonIconMap.get(item.split('#')[0] + ':' + item.split('#')[4] +
':' + item.split('#')[1]))
':' + item.split('#')[1] + ':' + item.split('#')[7]))
.height(48)
.width(48)
.alignSelf(ItemAlign.Center)
@@ -83,6 +83,29 @@ struct SelectorPhoneDialog {
@State private hapList: HapInfo[] = [];
private TAG = 'SelectorDialog_Phone_Page';
@Builder
elementIconCombine(iconSrc: string, appIndex: string) {
RelativeContainer() {
Image(iconSrc)
.id('iconLab')
.height(60)
.width(60)
.alignSelf(ItemAlign.Center);
if (appIndex !== '0') {
Image($r('app.media.app_icon_clone_index_' + appIndex))
.height(18)
.width(18)
.alignRules({
end: { anchor: 'iconLab', align: HorizontalAlign.End },
bottom: { anchor: 'iconLab', align: VerticalAlign.Bottom }
})
}
}
.height(60)
.width(60)
.alignSelf(ItemAlign.Center);
}
aboutToAppear(): void {
console.log(this.TAG, 'dialog page appears');
this.hapList = globalThis.params.hapList;
@@ -99,6 +122,7 @@ struct SelectorPhoneDialog {
globalThis.abilityWant.bundleName = item.split('#')[0];
globalThis.abilityWant.abilityName = item.split('#')[1];
globalThis.abilityWant.moduleName = item.split('#')[4];
globalThis.abilityWant.parameters['ohos.extra.param.key.appCloneIndex'] = Number(item.split('#')[7]);
globalThis.selectExtensionContext.startAbilityAsCaller(globalThis.abilityWant, (data, error) => {
if (error) {
console.error(this.TAG + ' startAbility finish, error: ' + JSON.stringify(error));
@@ -158,16 +182,11 @@ struct SelectorPhoneDialog {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
if (item.split('#')[3] != '') {
if (item.split('#')[3].indexOf('image/json') > -1) {
Image(globalThis.jsonIconMap.get(item.split('#')[0] + ':' + item.split('#')[4] +
':' + item.split('#')[1]))
.height(60)
.width(60)
.alignSelf(ItemAlign.Center);
this.elementIconCombine(globalThis.jsonIconMap.get(item.split('#')[0] + ':' +
item.split('#')[4] + ':' + item.split('#')[1] + ':' + item.split('#')[7]),
item.split('#')[7]);
} else {
Image(item.split('#')[3])
.height(60)
.width(60)
.alignSelf(ItemAlign.Center);
this.elementIconCombine(item.split('#')[3], item.split('#')[7]);
}
} else {
Image($r('app.media.app_icon'))
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>画板</title>
<g id="画板" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="椭圆形-2">
<circle id="椭圆形" fill="#0A59F7" cx="9" cy="9" r="9"></circle>
<path d="M10.2360985,5.76107106 C10.8402386,5.76107106 11.3299909,6.27979367 11.3299909,6.91967044 L11.3299909,12.8414006 C11.3299909,13.4812774 10.8402386,14 10.2360985,14 L6.09389243,14 C5.48975233,14 5,13.4812774 5,12.8414006 L5,6.91967044 C5,6.27979367 5.48975233,5.76107106 6.09389243,5.76107106 L10.2360985,5.76107106 Z M8.747,7.806 L8.069,7.806 L6.725,8.568 L6.725,9.402 L7.865,8.766 L7.865,12.204 L8.747,12.204 L8.747,7.806 Z M11.1039198,4 C12.151096,4 13,4.89911919 13,6.00823893 L13,10.4881565 C13,11.1802455 12.6694588,11.7905657 12.1664598,12.1516828 L12.1663954,6.34809475 C12.1663954,5.55643325 11.5745605,4.91117893 10.8339464,4.88159526 L10.7807983,4.88053553 L6.3989544,4.88053887 C6.74008934,4.34908286 7.3156025,4 7.9680948,4 L11.1039198,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>画板备份 6</title>
<g id="画板备份-6" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组">
<circle id="椭圆形" fill="#0A59F7" cx="9" cy="9" r="9"></circle>
<path d="M10.2360985,5.76107106 C10.8402386,5.76107106 11.3299909,6.27979367 11.3299909,6.91967044 L11.3299909,12.8414006 C11.3299909,13.4812774 10.8402386,14 10.2360985,14 L6.09389243,14 C5.48975233,14 5,13.4812774 5,12.8414006 L5,6.91967044 C5,6.27979367 5.48975233,5.76107106 6.09389243,5.76107106 L10.2360985,5.76107106 Z M7.979,7.728 C7.623,7.728 7.309,7.823 7.037,8.013 C6.765,8.203 6.577,8.476 6.473,8.832 L7.157,9.228 C7.225,9.004 7.323,8.831 7.451,8.709 C7.579,8.587 7.727,8.526 7.895,8.526 C8.059,8.526 8.189,8.578 8.285,8.682 C8.381,8.786 8.429,8.924 8.429,9.096 C8.429,9.252 8.384,9.403 8.294,9.549 C8.204,9.695 8.045,9.896 7.817,10.152 L6.491,11.64 L6.491,12.204 L9.521,12.204 L9.521,11.442 L7.763,11.442 L8.513,10.608 C8.825,10.26 9.042,9.977 9.164,9.759 C9.286,9.541 9.347,9.306 9.347,9.054 C9.347,8.798 9.292,8.57 9.182,8.37 C9.072,8.17 8.914,8.013 8.708,7.899 C8.502,7.785 8.259,7.728 7.979,7.728 Z M11.1039198,4 C12.151096,4 13,4.89911919 13,6.00823893 L13,10.4881565 C13,11.1802455 12.6694588,11.7905657 12.1664598,12.1516828 L12.1663954,6.34809475 C12.1663954,5.55643325 11.5745605,4.91117893 10.8339464,4.88159526 L10.7807983,4.88053553 L6.3989544,4.88053887 C6.74008934,4.34908286 7.3156025,4 7.9680948,4 L11.1039198,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>画板备份 7</title>
<g id="画板备份-7" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组">
<circle id="椭圆形" fill="#0A59F7" cx="9" cy="9" r="9"></circle>
<path d="M10.2360985,5.76107106 C10.8402386,5.76107106 11.3299909,6.27979367 11.3299909,6.91967044 L11.3299909,12.8414006 C11.3299909,13.4812774 10.8402386,14 10.2360985,14 L6.09389243,14 C5.48975233,14 5,13.4812774 5,12.8414006 L5,6.91967044 C5,6.27979367 5.48975233,5.76107106 6.09389243,5.76107106 L10.2360985,5.76107106 Z M7.949,7.728 C7.593,7.728 7.285,7.817 7.025,7.995 C6.765,8.173 6.583,8.43 6.479,8.766 L7.139,9.144 C7.207,8.94 7.304,8.783 7.43,8.673 C7.556,8.563 7.705,8.508 7.877,8.508 C8.037,8.508 8.167,8.554 8.267,8.646 C8.367,8.738 8.417,8.86 8.417,9.012 C8.417,9.176 8.356,9.313 8.234,9.423 C8.112,9.533 7.937,9.588 7.709,9.588 L7.475,9.588 L7.475,10.308 L7.637,10.308 C8.253,10.308 8.561,10.51 8.561,10.914 C8.561,11.098 8.5,11.242 8.378,11.346 C8.256,11.45 8.105,11.502 7.925,11.502 C7.741,11.502 7.575,11.449 7.427,11.343 C7.279,11.237 7.173,11.08 7.109,10.872 L6.419,11.268 C6.531,11.596 6.722,11.846 6.992,12.018 C7.262,12.19 7.579,12.276 7.943,12.276 C8.227,12.276 8.486,12.225 8.72,12.123 C8.954,12.021 9.14,11.873 9.278,11.679 C9.416,11.485 9.485,11.252 9.485,10.98 C9.485,10.716 9.421,10.495 9.293,10.317 C9.165,10.139 8.979,10.004 8.735,9.912 C8.935,9.82 9.086,9.692 9.188,9.528 C9.29,9.364 9.341,9.17 9.341,8.946 C9.341,8.706 9.283,8.494 9.167,8.31 C9.051,8.126 8.888,7.983 8.678,7.881 C8.468,7.779 8.225,7.728 7.949,7.728 Z M11.1039198,4 C12.151096,4 13,4.89911919 13,6.00823893 L13,10.4881565 C13,11.1802455 12.6694588,11.7905657 12.1664598,12.1516828 L12.1663954,6.34809475 C12.1663954,5.55643325 11.5745605,4.91117893 10.8339464,4.88159526 L10.7807983,4.88053553 L6.3989544,4.88053887 C6.74008934,4.34908286 7.3156025,4 7.9680948,4 L11.1039198,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>画板备份 8</title>
<g id="画板备份-8" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组">
<circle id="椭圆形" fill="#0A59F7" cx="9" cy="9" r="9"></circle>
<path d="M10.2360985,5.76107106 C10.8402386,5.76107106 11.3299909,6.27979367 11.3299909,6.91967044 L11.3299909,12.8414006 C11.3299909,13.4812774 10.8402386,14 10.2360985,14 L6.09389243,14 C5.48975233,14 5,13.4812774 5,12.8414006 L5,6.91967044 C5,6.27979367 5.48975233,5.76107106 6.09389243,5.76107106 L10.2360985,5.76107106 Z M8.831,7.806 L7.919,7.806 L6.407,10.716 L6.407,11.31 L8.291,11.31 L8.291,12.204 L9.143,12.204 L9.143,11.31 L9.737,11.31 L9.737,10.566 L9.143,10.566 L9.143,9.54 L8.291,9.54 L8.291,10.566 L7.385,10.566 L8.831,7.806 Z M11.1039198,4 C12.151096,4 13,4.89911919 13,6.00823893 L13,10.4881565 C13,11.1802455 12.6694588,11.7905657 12.1664598,12.1516828 L12.1663954,6.34809475 C12.1663954,5.55643325 11.5745605,4.91117893 10.8339464,4.88159526 L10.7807983,4.88053553 L6.3989544,4.88053887 C6.74008934,4.34908286 7.3156025,4 7.9680948,4 L11.1039198,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>画板备份 9</title>
<g id="画板备份-9" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="编组">
<circle id="椭圆形" fill="#0A59F7" cx="9" cy="9" r="9"></circle>
<path d="M10.2360985,5.76107106 C10.8402386,5.76107106 11.3299909,6.27979367 11.3299909,6.91967044 L11.3299909,12.8414006 C11.3299909,13.4812774 10.8402386,14 10.2360985,14 L6.09389243,14 C5.48975233,14 5,13.4812774 5,12.8414006 L5,6.91967044 C5,6.27979367 5.48975233,5.76107106 6.09389243,5.76107106 L10.2360985,5.76107106 Z M9.281,7.806 L6.977,7.806 L6.677,10.194 L7.301,10.5 C7.457,10.24 7.667,10.11 7.931,10.11 C8.135,10.11 8.292,10.177 8.402,10.311 C8.512,10.445 8.567,10.612 8.567,10.812 C8.567,11.012 8.514,11.177 8.408,11.307 C8.302,11.437 8.151,11.502 7.955,11.502 C7.799,11.502 7.663,11.456 7.547,11.364 C7.431,11.272 7.347,11.136 7.295,10.956 L6.593,11.358 C6.693,11.666 6.864,11.896 7.106,12.048 C7.348,12.2 7.635,12.276 7.967,12.276 C8.247,12.276 8.503,12.217 8.735,12.099 C8.967,11.981 9.15,11.809 9.284,11.583 C9.418,11.357 9.485,11.09 9.485,10.782 C9.485,10.498 9.425,10.247 9.305,10.029 C9.185,9.811 9.021,9.643 8.813,9.525 C8.605,9.407 8.375,9.348 8.123,9.348 C7.939,9.348 7.761,9.384 7.589,9.456 L7.709,8.55 L9.281,8.55 L9.281,7.806 Z M11.1039198,4 C12.151096,4 13,4.89911919 13,6.00823893 L13,10.4881565 C13,11.1802455 12.6694588,11.7905657 12.1664598,12.1516828 L12.1663954,6.34809475 C12.1663954,5.55643325 11.5745605,4.91117893 10.8339464,4.88159526 L10.7807983,4.88053553 L6.3989544,4.88053887 C6.74008934,4.34908286 7.3156025,4 7.9680948,4 L11.1039198,4 Z" id="形状结合" fill="#FFFFFF"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB