To be allow embeded startup atomic service

Signed-off-by: yuwenze <yuwenze1@huawei.com>
Change-Id: I5a3ef27945280b29698b4be065b84c920a9f87dd
This commit is contained in:
yuwenze
2024-02-29 22:14:39 +08:00
parent 4ea896bfa3
commit b3bc07f7ec
13 changed files with 252 additions and 1 deletions
@@ -38,8 +38,10 @@ template("abilitymanager") {
deps = [
"${ability_runtime_innerkits_path}/ability_manager:ability_manager",
"${ability_runtime_innerkits_path}/app_manager:app_manager",
"${ability_runtime_innerkits_path}/napi_base_context:napi_base_context",
"${ability_runtime_innerkits_path}/runtime:runtime",
"${ability_runtime_napi_path}/inner/napi_common:napi_common",
"${ability_runtime_native_path}/ability:ability_context_native",
"${ability_runtime_native_path}/ability/native:ability_business_error",
"${ability_runtime_native_path}/ability/native:abilitykit_native",
]
@@ -34,6 +34,7 @@
#include "js_runtime.h"
#include "js_runtime_utils.h"
#include "napi/native_api.h"
#include "napi_base_context.h"
#include "napi_common_configuration.h"
#include "napi_common_util.h"
#include "napi_common_want.h"
@@ -115,6 +116,11 @@ public:
GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnOff);
}
static napi_value IsEmbeddedOpenAllowed(napi_env env, napi_callback_info info)
{
GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnIsEmbeddedOpenAllowed);
}
private:
sptr<OHOS::AbilityRuntime::JSAbilityForegroundStateObserver> observerForeground_ = nullptr;
sptr<OHOS::AppExecFwk::IAppMgr> appManager_ = nullptr;
@@ -481,6 +487,56 @@ private:
CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
return result;
}
napi_value OnIsEmbeddedOpenAllowed(napi_env env, NapiCallbackInfo& info)
{
HILOG_DEBUG("Called.");
if (info.argc < ARGC_TWO) {
HILOG_ERROR("Not enough params");
ThrowTooFewParametersError(env);
return CreateJsUndefined(env);
}
bool stageMode = false;
napi_status status = OHOS::AbilityRuntime::IsStageContext(env, info.argv[0], stageMode);
if (status != napi_ok || !stageMode) {
HILOG_ERROR("it is not a stage mode");
ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
return CreateJsUndefined(env);
}
auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[0]);
if (context == nullptr) {
HILOG_ERROR("get context failed");
ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
return CreateJsUndefined(env);
}
auto uiAbilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
if (uiAbilityContext == nullptr) {
HILOG_ERROR("convert to UIAbility context failed");
ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
return CreateJsUndefined(env);
}
std::string appId;
if (!ConvertFromJsValue(env, info.argv[1], appId)) {
HILOG_ERROR("OnOpenAtomicService, parse appId failed.");
ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
return CreateJsUndefined(env);
}
auto token = uiAbilityContext->GetToken();
NapiAsyncTask::CompleteCallback complete = [token, appId](napi_env env, NapiAsyncTask &task, int32_t status) {
auto isAllowed = AbilityManagerClient::GetInstance()->IsEmbeddedOpenAllowed(token, appId);
task.Resolve(env, CreateJsValue(env, isAllowed));
};
napi_value lastParam = (info.argc > ARGC_TWO) ?info. argv[ARGC_TWO] : nullptr;
napi_value result = nullptr;
NapiAsyncTask::Schedule("JsAbilityManager::OnIsEmbeddedOpenAllowed", env,
CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
return result;
}
};
} // namespace
@@ -506,6 +562,7 @@ napi_value JsAbilityManagerInit(napi_env env, napi_value exportObj)
env, exportObj, "getForegroundUIAbilities", moduleName, JsAbilityManager::GetForegroundUIAbilities);
BindNativeFunction(env, exportObj, "on", moduleName, JsAbilityManager::On);
BindNativeFunction(env, exportObj, "off", moduleName, JsAbilityManager::Off);
BindNativeFunction(env, exportObj, "isEmbeddedOpenAllowed", moduleName, JsAbilityManager::IsEmbeddedOpenAllowed);
HILOG_DEBUG("end");
return CreateJsUndefined(env);
}
@@ -66,6 +66,7 @@ constexpr const char* ERROR_MSG_NO_MISSION_LISTENER = "Input error. The specifie
constexpr const char* ERROR_MSG_START_ABILITY_WAITTING = "The previous ability is starting, wait start later.";
constexpr const char* ERROR_MSG_NOT_SELF_APPLICATION = "The target application is not self application.";
// follow ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST of appexecfwk_errors.h in bundle_framework
constexpr int32_t ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST = 8521220;
static std::unordered_map<AbilityErrorCode, const char*> ERR_CODE_MAP = {
@@ -1376,6 +1376,15 @@ public:
int32_t OpenAtomicService(Want& want, sptr<IRemoteObject> callerToken,
int32_t requestCode = DEFAULT_INVAL_VALUE, int32_t userId = DEFAULT_INVAL_VALUE);
/**
* @brief Querying whether to allow embedded startup of atomic service.
*
* @param token The caller UIAbility token.
* @param appId The ID of the application to which this bundle belongs.
* @return Returns true to allow ability to start, or false to reject.
*/
bool IsEmbeddedOpenAllowed(sptr<IRemoteObject> callerToken, const std::string &appId);
private:
AbilityManagerClient();
DISALLOW_COPY_AND_MOVE(AbilityManagerClient);
@@ -1410,6 +1410,18 @@ public:
{
return 0;
}
/**
* @brief Querying whether to allow embedded startup of atomic service.
*
* @param token The caller UIAbility token.
* @param appId The ID of the application to which this bundle belongs.
* @return Returns true to allow ability to start, or false to reject.
*/
virtual bool IsEmbeddedOpenAllowed(sptr<IRemoteObject> callerToken, const std::string &appId)
{
return true;
}
};
} // namespace AAFwk
} // namespace OHOS
@@ -238,6 +238,9 @@ enum class AbilityManagerInterfaceCode {
// Pop-up launch of full-screen atomic service(77)
OPEN_ATOMIC_SERVICE = 77,
// Querying whether to allow embedded startup of atomic service.
IS_EMBEDDED_OPEN_ALLOWED = 78,
// ipc id 1001-2000 for DMS
// ipc id for starting ability (1001)
START_ABILITY = 1001,
@@ -1135,6 +1135,15 @@ public:
*/
virtual int32_t OpenAtomicService(Want& want, sptr<IRemoteObject> callerToken,
int32_t requestCode = DEFAULT_INVAL_VALUE, int32_t userId = DEFAULT_INVAL_VALUE) override;
/**
* @brief Querying whether to allow embedded startup of atomic service.
*
* @param token The caller UIAbility token.
* @param appId The ID of the application to which this bundle belongs.
* @return Returns true to allow ability to start, or false to reject.
*/
virtual bool IsEmbeddedOpenAllowed(sptr<IRemoteObject> callerToken, const std::string &appId) override;
private:
template <typename T>
int GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos);
@@ -281,6 +281,15 @@ public:
virtual int32_t OpenAtomicService(Want& want, sptr<IRemoteObject> callerToken,
int32_t requestCode = DEFAULT_INVAL_VALUE, int32_t userId = DEFAULT_INVAL_VALUE) override;
/**
* @brief Querying whether to allow embedded startup of atomic service.
*
* @param token The caller UIAbility token.
* @param appId The ID of the application to which this bundle belongs.
* @return Returns true to allow ability to start, or false to reject.
*/
virtual bool IsEmbeddedOpenAllowed(sptr<IRemoteObject> callerToken, const std::string &appId) override;
/**
* Start extension ability with want, send want to ability manager service.
*
@@ -1903,6 +1912,9 @@ private:
int32_t SignRestartAppFlag(int32_t userId, const std::string &bundleName);
int32_t CheckRestartAppWant(const AAFwk::Want &want);
bool IsEmbeddedOpenAllowedInner(sptr<IRemoteObject> callerToken, const std::string &appId,
std::shared_ptr<AbilityRecord> callerAbility);
constexpr static int REPOLL_TIME_MICRO_SECONDS = 1000000;
constexpr static int WAITING_BOOT_ANIMATION_TIMER = 5;
@@ -273,6 +273,7 @@ private:
int32_t GetElementNameByAppIdInner(MessageParcel &data, MessageParcel &reply);
int32_t OpenAtomicServiceInner(MessageParcel &data, MessageParcel &reply);
int32_t IsEmbeddedOpenAllowedInner(MessageParcel &data, MessageParcel &reply);
//insight intent related
int32_t StartAbilityByInsightIntentInner(MessageParcel &data, MessageParcel &reply);
@@ -1716,5 +1716,16 @@ int32_t AbilityManagerClient::OpenAtomicService(Want& want, sptr<IRemoteObject>
CHECK_POINTER_RETURN_INVALID_VALUE(abms);
return abms->OpenAtomicService(want, callerToken, requestCode, userId);
}
bool AbilityManagerClient::IsEmbeddedOpenAllowed(sptr<IRemoteObject> callerToken, const std::string &appId)
{
HILOG_DEBUG("Get ui extension host info.");
auto abms = GetAbilityManager();
if (abms == nullptr) {
HILOG_ERROR("abms is nullptr.");
return false;
}
return abms->IsEmbeddedOpenAllowed(callerToken, appId);
}
} // namespace AAFwk
} // namespace OHOS
@@ -4781,5 +4781,38 @@ int32_t AbilityManagerProxy::OpenAtomicService(Want& want, sptr<IRemoteObject> c
}
return reply.ReadInt32();
}
bool AbilityManagerProxy::IsEmbeddedOpenAllowed(sptr<IRemoteObject> callerToken, const std::string &appId)
{
if (callerToken == nullptr) {
HILOG_ERROR("Input param invalid.");
return false;
}
MessageParcel data;
if (!WriteInterfaceToken (data)) {
HILOG_ERROR("Write remote object failed.");
return false;
}
if (!data.WriteBool(true) || !data.WriteRemoteObject(callerToken)) {
HILOG_ERROR("Write flag and callerToken failed.");
return false;
}
if (!data.WriteString(appId)) {
HILOG_ERROR("Write userId failed.");
return false;
}
MessageParcel reply;
MessageOption option;
auto error = SendRequest(AbilityManagerInterfaceCode::IS_EMBEDDED_OPEN_ALLOWED, data, reply, option);
if (error != NO_ERROR) {
HILOG_ERROR("Send request error: %{public}d", error);
return false;
}
return reply.ReadBool();
}
} // namespace AAFwk
} // namespace OHOS
@@ -5256,7 +5256,8 @@ int AbilityManagerService::GenerateAbilityRequest(
return RESOLVE_APP_ERR;
}
if (request.want.GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::ScreenMode::IDLE_SCREEN_MODE) == 0 &&
request.abilityInfo.applicationInfo.bundleType != AppExecFwk::BundleType::ATOMIC_SERVICE) {
(request.abilityInfo.applicationInfo.bundleType != AppExecFwk::BundleType::ATOMIC_SERVICE ||
request.abilityInfo.launchMode != AppExecFwk::LaunchMode::SINGLETON)) {
HILOG_ERROR("The interface of starting atomicService can start only atomicService.");
return TARGET_ABILITY_NOT_SERVICE;
}
@@ -9609,6 +9610,82 @@ int32_t AbilityManagerService::SignRestartAppFlag(int32_t userId, const std::str
missionListManager->SignRestartAppFlag(bundleName);
return ERR_OK;
}
bool AbilityManagerService::IsEmbeddedOpenAllowed(sptr<IRemoteObject> callerToken, const std::string &appId)
{
auto deviceType = OHOS::system::GetDeviceType();
if (deviceType != "phone") {
HILOG_ERROR("device type is not allowd.");
return false;
}
auto accessTokenId = IPCSkeleton::GetCallingTokenID();
auto type = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(accessTokenId);
if (type != Security::AccessToken::TypeATokenTypeEnum::TOKEN_HAP) {
HILOG_ERROR("The caller is not hap.");
return false;
}
if (uiAbilityLifecycleManager_ == nullptr) {
HILOG_ERROR("The SceneBoard not enabled.");
return false;
}
auto isUIAbility = uiAbilityLifecycleManager_->IsContainsAbility(callerToken);
if (!isUIAbility) {
HILOG_ERROR("The caller is not UIAbility.");
return false;
}
auto callerAbility = Token::GetAbilityRecordByToken(callerToken);
if (callerAbility == nullptr) {
HILOG_ERROR("The caller is invalid.");
return false;
}
if (!callerAbility->IsForeground() && !callerAbility->GetAbilityForegroundingFlag()) {
HILOG_ERROR("The caller not foreground.");
return false;
}
return IsEmbeddedOpenAllowedInner(callerToken, appId, callerAbility);
}
bool AbilityManagerService::IsEmbeddedOpenAllowedInner(sptr<IRemoteObject> callerToken, const std::string &appId,
std::shared_ptr<AbilityRecord> callerAbility)
{
auto bms = GetBundleManager();
if (bms == nullptr) {
HILOG_ERROR("bms is invalid.");
return false;
}
auto bundleName = bms->ParseBundleNameByAppId(appId);
HILOG_INFO("bundleName is %{public}s.", bundleName.c_str());
Want launchWant;
auto queryRet = IN_PROCESS_CALL(bms->GetLaunchWantForBundle(bundleName, launchWant, GetUserId()));
if (queryRet != ERR_OK) {
HILOG_ERROR("The method returns err:%{public}d.", queryRet);
return false;
}
std::string abilityName = launchWant.GetElement().GetAbilityName();
if (bundleName.empty() || abilityName.empty()) {
HILOG_ERROR("bundleName: %{public}s, abilityName: %{public}s", bundleName.c_str(), abilityName.c_str());
return false;
}
AppExecFwk::ApplicationInfo appInfo;
bool ans = IN_PROCESS_CALL(bms->GetApplicationInfo(bundleName, AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT,
GetUserId(), appInfo));
if (!ans) {
HILOG_ERROR("Fail to get application info.");
return false;
}
if (appInfo.bundleType != AppExecFwk::BundleType::ATOMIC_SERVICE) {
HILOG_ERROR("The target is not atomic service.");
return false;
}
launchWant.SetParam(Want::PARAM_RESV_CALLER_BUNDLE_NAME, callerAbility->GetElementName().GetBundleName());
auto erms = std::make_shared<EcologicalRuleInterceptor>();
queryRet = erms->DoProcess(launchWant, 0, GetUserId(), true, callerToken);
if (queryRet == ERR_OK) {
return true;
}
HILOG_ERROR("The erms returns err:%{public}d.", queryRet);
return false;
}
} // namespace AAFwk
} // namespace OHOS
@@ -401,6 +401,8 @@ void AbilityManagerStub::FourthStepInit()
&AbilityManagerStub::GetElementNameByAppIdInner;
requestFuncMap_[static_cast<uint32_t>(AbilityManagerInterfaceCode::OPEN_ATOMIC_SERVICE)] =
&AbilityManagerStub::OpenAtomicServiceInner;
requestFuncMap_[static_cast<uint32_t>(AbilityManagerInterfaceCode::IS_EMBEDDED_OPEN_ALLOWED)] =
&AbilityManagerStub::IsEmbeddedOpenAllowedInner;
}
int AbilityManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
@@ -3086,5 +3088,27 @@ int32_t AbilityManagerStub::OpenAtomicServiceInner(MessageParcel &data, MessageP
}
return ERR_OK;
}
int32_t AbilityManagerStub::IsEmbeddedOpenAllowedInner(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> callerToken = nullptr;
if (data.ReadBool()) {
callerToken = data.ReadRemoteObject();
if (callerToken == nullptr) {
HILOG_ERROR("caller token is nullptr.");
return ERR_INVALID_VALUE;
}
}
std::string appId = data.ReadString();
auto result = IsEmbeddedOpenAllowed(callerToken, appId);
if (!reply.WriteInt32(result)) {
HILOG_ERROR("Write result failed.");
return ERR_INVALID_VALUE;
}
return NO_ERROR;
}
} // namespace AAFwk
} // namespace OHOS