add restartApp

Signed-off-by: savior-xzh <xuzheheng2@huawei.com>
Change-Id: I00e5fb273c0d56b4b569e366a94b13fcda536859
This commit is contained in:
savior-xzh
2024-02-28 11:21:51 +00:00
parent 79bc5fdb42
commit 0e8182356e
51 changed files with 611 additions and 8 deletions
@@ -173,6 +173,10 @@ class ApplicationContext {
return this.__context_impl__.clearUpApplicationData(callback);
}
restartApp(want) {
return this.__context_impl__.restartApp(want);
}
set area(mode) {
return this.__context_impl__.switchArea(mode);
}
@@ -57,6 +57,9 @@ constexpr const char* ERROR_MSG_GRANT_URI_PERMISSION = "Sandbox application can
constexpr const char* ERROR_MSG_OPERATION_NOT_SUPPORTED = "Operation not supported.";
constexpr const char* ERROR_MSG_CHILD_PROCESS_NUMBER_EXCEEDS_UPPER_BOUND =
"The number of child process exceeds upper bound.";
constexpr const char* ERROR_MSG_RESTART_APP_INCORRECT_ABILITY =
"The target to restart does not belong to the current app or is not a UIAbility.";
constexpr const char* ERROR_MSG_RESTART_APP_FREQUENT = "Restart too frequently. Try again at least 10s later.";
constexpr const char* ERROR_MSG_INVALID_CALLER = "The caller has been released.";
constexpr const char* ERROR_MSG_NO_MISSION_ID = "The specified mission does not exist.";
constexpr const char* ERROR_MSG_NO_MISSION_LISTENER = "Input error. The specified mission listener does not exist.";
@@ -96,6 +99,8 @@ static std::unordered_map<AbilityErrorCode, const char*> ERR_CODE_MAP = {
{ AbilityErrorCode::ERROR_CODE_OPERATION_NOT_SUPPORTED, ERROR_MSG_OPERATION_NOT_SUPPORTED },
{ AbilityErrorCode::ERROR_CODE_CHILD_PROCESS_NUMBER_EXCEEDS_UPPER_BOUND,
ERROR_MSG_CHILD_PROCESS_NUMBER_EXCEEDS_UPPER_BOUND },
{ AbilityErrorCode::ERROR_CODE_RESTART_APP_INCORRECT_ABILITY, ERROR_MSG_RESTART_APP_INCORRECT_ABILITY },
{ AbilityErrorCode::ERROR_CODE_RESTART_APP_FREQUENT, ERROR_MSG_RESTART_APP_FREQUENT },
{ AbilityErrorCode::ERROR_CODE_INVALID_CALLER, ERROR_MSG_INVALID_CALLER },
{ AbilityErrorCode::ERROR_CODE_NO_MISSION_ID, ERROR_MSG_NO_MISSION_ID },
{ AbilityErrorCode::ERROR_CODE_NO_MISSION_LISTENER, ERROR_MSG_NO_MISSION_LISTENER },
@@ -142,6 +147,8 @@ static std::unordered_map<int32_t, AbilityErrorCode> INNER_TO_JS_ERROR_CODE_MAP
{ERR_APP_CONTROLLED, AbilityErrorCode::ERROR_CODE_CONTROLLED},
{ERR_EDM_APP_CONTROLLED, AbilityErrorCode::ERROR_CODE_EDM_CONTROLLED},
{ERR_INSIGHT_INTENT_START_INVALID_COMPONENT, AbilityErrorCode::ERROR_CODE_OPERATION_NOT_SUPPORTED},
{ERR_RESTART_APP_INCORRECT_ABILITY, AbilityErrorCode::ERROR_CODE_RESTART_APP_INCORRECT_ABILITY},
{ERR_RESTART_APP_FREQUENT, AbilityErrorCode::ERROR_CODE_RESTART_APP_FREQUENT},
};
}
+2
View File
@@ -249,6 +249,7 @@ ohos_shared_library("app_context") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
deps = [
"${ability_runtime_innerkits_path}/ability_manager:ability_manager",
"${ability_runtime_innerkits_path}/app_manager:app_manager",
"${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper",
"${ability_runtime_innerkits_path}/runtime:runtime",
@@ -314,6 +315,7 @@ ohos_shared_library("app_context_utils") {
]
external_deps = [
"ability_base:want",
"access_token:libtokenid_sdk",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
@@ -17,6 +17,7 @@
#include <algorithm>
#include "ability_manager_errors.h"
#include "configuration_convertor.h"
#include "hilog_wrapper.h"
#include "running_process_info.h"
@@ -418,6 +419,18 @@ std::string ApplicationContext::GetGroupDir(std::string groupId)
return (contextImpl_ != nullptr) ? contextImpl_->GetGroupDir(groupId) : "";
}
int32_t ApplicationContext::RestartApp(const AAFwk::Want& want)
{
std::string abilityName = want.GetElement().GetAbilityName();
if (abilityName == "") {
HILOG_ERROR("abilityName is empty.");
return ERR_INVALID_VALUE;
}
std::string bundleName = GetBundleName();
const_cast<AAFwk::Want &>(want).SetBundle(bundleName);
return (contextImpl_ != nullptr) ? contextImpl_->RestartApp(want) : ERR_INVALID_VALUE;
}
std::string ApplicationContext::GetDistributedFilesDir()
{
return (contextImpl_ != nullptr) ? contextImpl_->GetDistributedFilesDir() : "";
@@ -18,6 +18,7 @@
#include <cerrno>
#include <regex>
#include "ability_manager_client.h"
#include "app_mgr_client.h"
#include "application_context.h"
#include "bundle_mgr_helper.h"
@@ -957,6 +958,13 @@ int32_t ContextImpl::GetProcessRunningInformation(AppExecFwk::RunningProcessInfo
return result;
}
int32_t ContextImpl::RestartApp(const AAFwk::Want& want)
{
auto result = OHOS::AAFwk::AbilityManagerClient::GetInstance()->RestartApp(want);
HILOG_DEBUG("result is %{public}d.", result);
return result;
}
std::shared_ptr<AppExecFwk::Configuration> ContextImpl::GetConfiguration() const
{
return config_;
@@ -32,6 +32,7 @@
#include "js_error_utils.h"
#include "js_resource_manager_utils.h"
#include "js_runtime_utils.h"
#include "napi_common_want.h"
#include "tokenid_kit.h"
namespace OHOS {
@@ -450,6 +451,49 @@ napi_value JsApplicationContextUtils::OnGetGroupDir(napi_env env, NapiCallbackIn
return result;
}
napi_value JsApplicationContextUtils::RestartApp(napi_env env, napi_callback_info info)
{
HILOG_DEBUG("called");
GET_NAPI_INFO_WITH_NAME_AND_CALL(env, info, JsApplicationContextUtils, OnRestartApp, APPLICATION_CONTEXT_NAME);
}
napi_value JsApplicationContextUtils::OnRestartApp(napi_env env, NapiCallbackInfo& info)
{
// only support one params
if (info.argc == ARGC_ZERO) {
HILOG_ERROR("Not enough params");
AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
return CreateJsUndefined(env);
}
auto applicationContext = applicationContext_.lock();
if (!applicationContext) {
HILOG_WARN("applicationContext is already released");
return CreateJsUndefined(env);
}
AAFwk::Want want;
if (!AppExecFwk::UnwrapWant(env, info.argv[INDEX_ZERO], want)) {
HILOG_ERROR("Parse want failed");
AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
return CreateJsUndefined(env);
}
auto errCode = applicationContext->RestartApp(want);
if (errCode == ERR_OK) {
return CreateJsUndefined(env);
}
if (errCode == ERR_INVALID_VALUE) {
AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER);
} else if (errCode == AAFwk::ERR_RESTART_APP_INCORRECT_ABILITY) {
AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_RESTART_APP_INCORRECT_ABILITY);
} else if (errCode == AAFwk::ERR_RESTART_APP_FREQUENT) {
AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_RESTART_APP_FREQUENT);
} else {
AbilityRuntimeErrorUtil::Throw(env, ERR_ABILITY_RUNTIME_EXTERNAL_INTERNAL_ERROR);
}
HILOG_ERROR("errCode is %{public}d.", errCode);
return CreateJsUndefined(env);
}
napi_value JsApplicationContextUtils::GetBundleCodeDir(napi_env env, napi_callback_info info)
{
HILOG_DEBUG("called");
@@ -1283,6 +1327,8 @@ void JsApplicationContextUtils::BindNativeApplicationContext(napi_env env, napi_
JsApplicationContextUtils::GetRunningProcessInformation);
BindNativeFunction(env, object, "getGroupDir", MD_NAME,
JsApplicationContextUtils::GetGroupDir);
BindNativeFunction(env, object, "restartApp", MD_NAME,
JsApplicationContextUtils::RestartApp);
}
JsAppProcessState JsApplicationContextUtils::ConvertToJsAppProcessState(
@@ -1350,6 +1350,13 @@ public:
ErrCode GetUIExtensionRootHostInfo(const sptr<IRemoteObject> token, UIExtensionHostInfo &hostInfo,
int32_t userId = DEFAULT_INVAL_VALUE);
/**
* @brief Restart app self.
* @param want The ability type must be UIAbility.
* @return Returns ERR_OK on success, others on failure.
*/
int32_t RestartApp(const AAFwk::Want &want);
private:
AbilityManagerClient();
DISALLOW_COPY_AND_MOVE(AbilityManagerClient);
@@ -377,6 +377,16 @@ enum {
* Result(2097223) for query highest priority ability.
*/
ERR_QUERY_HIGHEST_PRIORITY_ABILITY,
/**
* Result(2097224) for the target to restart does not belong to the current app or is not a UIAbility.
*/
ERR_RESTART_APP_INCORRECT_ABILITY,
/**
* Result(2097225) for restart too frequently. Try again at least 10s later.
*/
ERR_RESTART_APP_FREQUENT,
};
enum {
@@ -1376,6 +1376,16 @@ public:
{
return 0;
}
/**
* @brief Restart app self.
* @param want The ability type must be UIAbility.
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t RestartApp(const AAFwk::Want &want)
{
return 0;
}
};
} // namespace AAFwk
} // namespace OHOS
@@ -480,6 +480,9 @@ enum class AbilityManagerInterfaceCode {
SET_APPLICATION_AUTO_STARTUP_BY_EDM = 6113,
// ipc id for cancel application auto startup by EDM
CANCEL_APPLICATION_AUTO_STARTUP_BY_EDM = 6114,
// ipc id for restart app
RESTART_APP = 6115,
};
} // namespace AAFwk
} // namespace OHOS
@@ -551,6 +551,11 @@ public:
* @return Returns ERR_OK on success, others on failure.
*/
virtual int32_t UpdateRenderState(pid_t renderPid, int32_t state) = 0;
virtual int32_t SignRestartAppFlag(const std::string &bundleName)
{
return 0;
}
};
} // namespace AppExecFwk
} // namespace OHOS
@@ -88,6 +88,7 @@ enum class AppMgrInterfaceCode {
REGISTER_RENDER_STATUS_OBSERVER = 62,
UNREGISTER_RENDER_STATUS_OBSERVER = 63,
UPDATE_RENDER_STATUS = 64,
SIGN_RESTART_APP_FLAG = 65,
};
} // AppExecFwk
} // OHOS
@@ -492,6 +492,7 @@ public:
*/
virtual int32_t UpdateRenderState(pid_t renderPid, int32_t state) override;
int32_t SignRestartAppFlag(const std::string &bundleName) override;
private:
bool SendTransactCmd(AppMgrInterfaceCode code, MessageParcel &data, MessageParcel &reply);
bool WriteInterfaceToken(MessageParcel &data);
@@ -124,6 +124,7 @@ private:
int32_t HandleRegisterRenderStateObserver(MessageParcel &data, MessageParcel &reply);
int32_t HandleUnregisterRenderStateObserver(MessageParcel &data, MessageParcel &reply);
int32_t HandleUpdateRenderState(MessageParcel &data, MessageParcel &reply);
int32_t HandleSignRestartAppFlag(MessageParcel &data, MessageParcel &reply);
using AppMgrFunc = int32_t (AppMgrStub::*)(MessageParcel &data, MessageParcel &reply);
std::map<uint32_t, AppMgrFunc> memberFuncMap_;
@@ -1690,5 +1690,27 @@ int32_t AppMgrProxy::UpdateRenderState(pid_t renderPid, int32_t state)
}
return reply.ReadInt32();
}
int32_t AppMgrProxy::SignRestartAppFlag(const std::string &bundleName)
{
HILOG_DEBUG("Called.");
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("Write interface token failed.");
return IPC_PROXY_ERR;
}
if (!data.WriteString(bundleName)) {
HILOG_ERROR("parcel WriteString failed");
return IPC_PROXY_ERR;
}
auto ret = SendRequest(AppMgrInterfaceCode::SIGN_RESTART_APP_FLAG, data, reply, option);
if (ret != NO_ERROR) {
HILOG_ERROR("Send request is failed, error code: %{public}d", ret);
return ret;
}
return reply.ReadInt32();
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -165,6 +165,8 @@ AppMgrStub::AppMgrStub()
&AppMgrStub::HandleUnregisterRenderStateObserver;
memberFuncMap_[static_cast<uint32_t>(AppMgrInterfaceCode::UPDATE_RENDER_STATUS)] =
&AppMgrStub::HandleUpdateRenderState;
memberFuncMap_[static_cast<uint32_t>(AppMgrInterfaceCode::SIGN_RESTART_APP_FLAG)] =
&AppMgrStub::HandleSignRestartAppFlag;
}
AppMgrStub::~AppMgrStub()
@@ -1076,5 +1078,17 @@ int32_t AppMgrStub::HandleUpdateRenderState(MessageParcel &data, MessageParcel &
}
return NO_ERROR;
}
int32_t AppMgrStub::HandleSignRestartAppFlag(MessageParcel &data, MessageParcel &reply)
{
HILOG_DEBUG("Called.");
std::string bundleName = data.ReadString();
auto ret = SignRestartAppFlag(bundleName);
if (!reply.WriteInt32(ret)) {
HILOG_ERROR("Write ret error.");
return IPC_STUB_ERR;
}
return NO_ERROR;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -51,6 +51,8 @@ enum {
ERR_ABILITY_RUNTIME_EXTERNAL_GRANT_URI_PERMISSION = 16000060,
ERR_ABILITY_RUNTIME_OPERATION_NOT_SUPPORTED = 16000061,
ERR_ABILITY_RUNTIME_CHILD_PROCESS_NUMBER_EXCEEDS_UPPER_BOUND = 16000062,
ERR_ABILITY_RUNTIME_RESTART_APP_INCORRECT_ABILITY = 16000063,
ERR_ABILITY_RUNTIME_RESTART_APP_FREQUENT = 16000064,
ERR_ABILITY_RUNTIME_EXTERNAL_EXECUTE_SHELL_COMMAND_FAILED = 16000101,
ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_WANTAGENT = 16000151,
ERR_ABILITY_RUNTIME_EXTERNAL_WANTAGENT_NOT_FOUND = 16000152,
@@ -138,7 +138,11 @@ const std::map<int32_t, std::string> ERROR_MSG_MAP = {
{ ERR_ABILITY_RUNTIME_OPERATION_NOT_SUPPORTED,
"Operation not supported." },
{ ERR_ABILITY_RUNTIME_CHILD_PROCESS_NUMBER_EXCEEDS_UPPER_BOUND,
"The number of child process exceeds upper bound." }
"The number of child process exceeds upper bound." },
{ ERR_ABILITY_RUNTIME_RESTART_APP_INCORRECT_ABILITY,
"The target to restart does not belong to the current app or is not a UIAbility." },
{ ERR_ABILITY_RUNTIME_RESTART_APP_FREQUENT,
"Restart too frequently. Try again at least 10s later." }
};
}
@@ -117,6 +117,12 @@ enum class AbilityErrorCode {
// The number of child process exceeds upper bound.
ERROR_CODE_CHILD_PROCESS_NUMBER_EXCEEDS_UPPER_BOUND = 16000062,
// The target to restart does not belong to the current app or is not a UIAbility.
ERROR_CODE_RESTART_APP_INCORRECT_ABILITY = 16000063,
// Restart too frequently. Try again at least 10s later.
ERROR_CODE_RESTART_APP_FREQUENT = 16000064,
// invalid caller.
ERROR_CODE_INVALID_CALLER = 16200001,
@@ -25,6 +25,9 @@
#include "context_impl.h"
#include "environment_callback.h"
namespace OHOS {
namespace AAFwk {
class Want;
}
namespace AbilityRuntime {
using AppConfigUpdateCallback = std::function<void(const AppExecFwk::Configuration &config)>;
class ApplicationContext : public Context {
@@ -92,6 +95,7 @@ public:
Global::Resource::DeviceType GetDeviceType() const override;
void KillProcessBySelf();
int32_t GetProcessRunningInformation(AppExecFwk::RunningProcessInfo &info);
int32_t RestartApp(const AAFwk::Want& want);
void AttachContextImpl(const std::shared_ptr<ContextImpl> &contextImpl);
@@ -26,6 +26,9 @@ namespace AppExecFwk {
struct RunningProcessInfo;
class BundleMgrHelper;
}
namespace AAFwk {
class Want;
}
namespace AbilityRuntime {
class ContextImpl : public Context {
public:
@@ -319,6 +322,13 @@ public:
*/
int32_t GetProcessRunningInformation(AppExecFwk::RunningProcessInfo &info);
/**
* @brief Restart app
*
* @return error code
*/
int32_t RestartApp(const AAFwk::Want& want);
/**
* @brief Get the token witch the app launched.
*
@@ -93,6 +93,7 @@ public:
napi_value OnSetColorMode(napi_env env, NapiCallbackInfo& info);
napi_value OnSetLanguage(napi_env env, NapiCallbackInfo& info);
napi_value OnClearUpApplicationData(napi_env env, NapiCallbackInfo& info);
napi_value OnRestartApp(napi_env env, NapiCallbackInfo& info);
static napi_value GetCacheDir(napi_env env, napi_callback_info info);
static napi_value GetTempDir(napi_env env, napi_callback_info info);
@@ -110,6 +111,7 @@ public:
static napi_value ClearUpApplicationData(napi_env env, napi_callback_info info);
static napi_value GetRunningProcessInformation(napi_env env, napi_callback_info info);
static napi_value CreateJsApplicationContext(napi_env env);
static napi_value RestartApp(napi_env env, napi_callback_info info);
protected:
std::weak_ptr<ApplicationContext> applicationContext_;
+1
View File
@@ -55,6 +55,7 @@ abilityms_files = [
"src/pending_want_key.cpp",
"src/pending_want_manager.cpp",
"src/pending_want_common_event.cpp",
"src/restart_app_manager.cpp",
"src/ams_configuration_parameter.cpp",
"src/image_info.cpp",
"src/insight_intent_utils.cpp",
@@ -262,6 +262,8 @@ public:
int32_t GetUIExtensionRootHostInfo(const sptr<IRemoteObject> token, UIExtensionHostInfo &hostInfo);
void SignRestartAppFlag(const std::string &bundleName);
// MSG 0 - 20 represents timeout message
static constexpr uint32_t LOAD_TIMEOUT_MSG = 0;
static constexpr uint32_t CONNECT_TIMEOUT_MSG = 1;
@@ -1111,6 +1111,12 @@ public:
int32_t GetUIExtensionRootHostInfo(const sptr<IRemoteObject> token, UIExtensionHostInfo &hostInfo,
int32_t userId = DEFAULT_INVAL_VALUE) override;
/**
* @brief Restart app self.
* @param want The ability type must be UIAbility.
* @return Returns ERR_OK on success, others on failure.
*/
int32_t RestartApp(const AAFwk::Want &want) override;
private:
template <typename T>
int GetParcelableInfos(MessageParcel &reply, std::vector<T> &parcelableInfos);
@@ -1443,6 +1443,13 @@ public:
int32_t GetUIExtensionRootHostInfo(const sptr<IRemoteObject> token, UIExtensionHostInfo &hostInfo,
int32_t userId = DEFAULT_INVAL_VALUE) override;
/**
* @brief Restart app self.
* @param want The ability type must be UIAbility.
* @return Returns ERR_OK on success, others on failure.
*/
int32_t RestartApp(const AAFwk::Want &want) override;
// MSG 0 - 20 represents timeout message
static constexpr uint32_t LOAD_TIMEOUT_MSG = 0;
static constexpr uint32_t ACTIVE_TIMEOUT_MSG = 1;
@@ -1874,6 +1881,9 @@ private:
void WaitBootAnimationStart();
int32_t SignRestartAppFlag(int32_t userId, const std::string &bundleName);
int32_t CheckRestartAppWant(const AAFwk::Want &want);
constexpr static int REPOLL_TIME_MICRO_SECONDS = 1000000;
constexpr static int WAITING_BOOT_ANIMATION_TIMER = 5;
@@ -277,6 +277,7 @@ private:
int32_t GetForegroundUIAbilitiesInner(MessageParcel &data, MessageParcel &reply);
int32_t GetUIExtensionRootHostInfoInner(MessageParcel &data, MessageParcel &reply);
int32_t RestartAppInner(MessageParcel &data, MessageParcel &reply);
};
} // namespace AAFwk
} // namespace OHOS
@@ -949,6 +949,8 @@ public:
bool IsSceneBoard() const;
void SetRestartAppFlag(bool isRestartApp);
bool GetRestartAppFlag() const;
protected:
void SendEvent(uint32_t msg, uint32_t timeOut, int32_t param = -1);
@@ -1160,6 +1162,8 @@ private:
bool isAppAutoStartup_ = false;
bool isConnected = false;
std::atomic_bool backgroundAbilityWindowDelayed_ = false;
bool isRestartApp_ = false; // Only app calling RestartApp can be set to true
};
} // namespace AAFwk
} // namespace OHOS
@@ -225,6 +225,8 @@ public:
int32_t GetMissionCount() const;
void GetActiveAbilityList(const std::string &bundleName, std::vector<std::string> &abilityList,
int32_t pid = NO_PID);
void SignRestartAppFlag(const std::string &bundleName);
private:
std::string GetTypeName();
@@ -349,6 +349,8 @@ public:
const AAFwk::ContinueState &state);
bool IsAbilityStarted(AbilityRequest &abilityRequest, std::shared_ptr<AbilityRecord> &targetRecord);
void SignRestartAppFlag(const std::string &bundleName);
#ifdef SUPPORT_GRAPHICS
public:
/**
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_ABILITY_RUNTIME_RESTART_APP_MANAGER_H
#define OHOS_ABILITY_RUNTIME_RESTART_APP_MANAGER_H
#include <mutex>
#include <string>
#include <unordered_map>
#include "cpp/mutex.h"
#include "nocopyable.h"
namespace OHOS {
namespace AAFwk {
typedef struct RestartAppKey {
std::string bundleName;
int32_t userId = 100;
RestartAppKey(std::string restartBundleName, int32_t restartUserId)
{
bundleName = restartBundleName;
userId = restartUserId;
}
bool operator ==(const struct RestartAppKey &other) const
{
return bundleName == other.bundleName && userId == other.userId;
}
} RestartAppKeyType;
struct RestartAppKeyHash {
size_t operator()(const RestartAppKeyType &p) const
{
return std::hash<std::string>()(p.bundleName) ^ std::hash<int>()(p.userId);
}
};
/**
* @class RestartAppManager
* RestartAppManager provides a facility for managing restart app history.
*/
class RestartAppManager {
public:
using RestartAppMapType = std::unordered_map<RestartAppKeyType, time_t, RestartAppKeyHash>;
virtual ~RestartAppManager() = default;
static RestartAppManager &GetInstance();
bool IsRestartAppFrequent(const RestartAppKeyType &key, time_t time);
void AddRestartAppHistory(const RestartAppKeyType &key, time_t time);
private:
RestartAppManager() = default;
DISALLOW_COPY_AND_MOVE(RestartAppManager);
ffrt::mutex restartAppMapLock_;
RestartAppMapType restartAppHistory_; // RestartAppKey:time
};
} // namespace AAFwk
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_RESTART_APP_MANAGER_H
@@ -55,6 +55,8 @@ public:
}
};
void SignRestartAppFlag(const std::string &bundleName);
/**
* StartUIAbility with request.
*
@@ -2570,5 +2570,16 @@ int32_t AbilityConnectManager::GetUIExtensionRootHostInfo(const sptr<IRemoteObje
CHECK_POINTER_AND_RETURN(uiExtensionAbilityRecordMgr_, ERR_INVALID_VALUE);
return uiExtensionAbilityRecordMgr_->GetUIExtensionRootHostInfo(token, hostInfo);
}
void AbilityConnectManager::SignRestartAppFlag(const std::string &bundleName)
{
std::lock_guard guard(Lock_);
for (auto &[key, abilityRecord] : serviceMap_) {
if (abilityRecord == nullptr || abilityRecord->GetApplicationInfo().bundleName != bundleName) {
continue;
}
abilityRecord->SetRestartAppFlag(true);
}
}
} // namespace AAFwk
} // namespace OHOS
@@ -1687,5 +1687,14 @@ ErrCode AbilityManagerClient::GetUIExtensionRootHostInfo(const sptr<IRemoteObjec
CHECK_POINTER_RETURN_NOT_CONNECTED(abms);
return abms->GetUIExtensionRootHostInfo(token, hostInfo, userId);
}
int32_t AbilityManagerClient::RestartApp(const AAFwk::Want &want)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
HILOG_DEBUG("Called.");
auto abms = GetAbilityManager();
CHECK_POINTER_RETURN_INVALID_VALUE(abms);
return abms->RestartApp(want);
}
} // namespace AAFwk
} // namespace OHOS
@@ -4692,5 +4692,26 @@ int32_t AbilityManagerProxy::GetUIExtensionRootHostInfo(const sptr<IRemoteObject
hostInfo = *info;
return reply.ReadInt32();
}
int32_t AbilityManagerProxy::RestartApp(const AAFwk::Want &want)
{
MessageParcel data;
MessageParcel reply;
MessageOption option;
if (!WriteInterfaceToken(data)) {
HILOG_ERROR("Write interface token failed.");
return IPC_PROXY_ERR;
}
if (!data.WriteParcelable(&want)) {
HILOG_ERROR("want write failed.");
return IPC_PROXY_ERR;
}
auto ret = SendRequest(AbilityManagerInterfaceCode::RESTART_APP, data, reply, option);
if (ret != NO_ERROR) {
HILOG_ERROR("Send request is failed, error code: %{public}d", ret);
return ret;
}
return reply.ReadInt32();
}
} // namespace AAFwk
} // namespace OHOS
@@ -71,6 +71,7 @@
#include "parameters.h"
#include "permission_constants.h"
#include "recovery_param.h"
#include "restart_app_manager.h"
#include "sa_mgr_client.h"
#include "scene_board_judgement.h"
#include "session_info.h"
@@ -9477,8 +9478,101 @@ int32_t AbilityManagerService::GetUIExtensionRootHostInfo(const sptr<IRemoteObje
HILOG_ERROR("Get host info failed with %{public}d.", ret);
return ret;
}
return ERR_OK;
}
int32_t AbilityManagerService::RestartApp(const AAFwk::Want &want)
{
HILOG_DEBUG("call.");
int result = CheckRestartAppWant(want);
if (result != ERR_OK) {
HILOG_ERROR("CheckRestartAppWant error.");
return result;
}
std::string bundleName = want.GetElement().GetBundleName();
int32_t userId = IPCSkeleton::GetCallingUid() / BASE_USER_RANGE;
int64_t now = time(nullptr);
RestartAppKeyType key(bundleName, userId);
if (RestartAppManager::GetInstance().IsRestartAppFrequent(key, now)) {
return AAFwk::ERR_RESTART_APP_FREQUENT;
}
result = SignRestartAppFlag(userId, bundleName);
if (result != ERR_OK) {
HILOG_ERROR("SignRestartAppFlag error.");
return result;
}
result = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance()->KillApplicationSelf();
if (result != ERR_OK) {
HILOG_ERROR("KillApplicationSelf error.");
return result;
}
HILOG_DEBUG("StartAbility begin.");
result = OHOS::AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
if (result != ERR_OK) {
HILOG_ERROR("StartAbility error.");
return result;
}
RestartAppManager::GetInstance().AddRestartAppHistory(key, now);
return result;
}
int32_t AbilityManagerService::CheckRestartAppWant(const AAFwk::Want &want)
{
std::string bundleName = want.GetElement().GetBundleName();
if (!CheckCallingTokenId(bundleName)) {
HILOG_ERROR("Not itself called, not allowed.");
return AAFwk::ERR_RESTART_APP_INCORRECT_ABILITY;
}
auto bms = GetBundleManager();
CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED);
auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
auto userId = IPCSkeleton::GetCallingUid() / BASE_USER_RANGE;
AppExecFwk::AbilityInfo abilityInfo;
bool queryResult = IN_PROCESS_CALL(bms->QueryAbilityInfo(want, abilityInfoFlag, userId, abilityInfo));
if (!queryResult) {
HILOG_ERROR("Query ability info fail.");
return INNER_ERR;
}
if (abilityInfo.name.empty() || abilityInfo.bundleName.empty() || abilityInfo.type != AbilityType::PAGE) {
HILOG_ERROR("Ability is invalid or not UIAbility.");
return AAFwk::ERR_RESTART_APP_INCORRECT_ABILITY;
}
return ERR_OK;
}
int32_t AbilityManagerService::SignRestartAppFlag(int32_t userId, const std::string &bundleName)
{
auto appMgr = GetAppMgr();
if (appMgr == nullptr) {
HILOG_WARN("GetAppMgr failed");
return ERR_INVALID_VALUE;
}
auto ret = IN_PROCESS_CALL(appMgr->SignRestartAppFlag(bundleName));
if (ret != ERR_OK) {
HILOG_ERROR("AppMgr SignRestartAppFlag error");
return ret;
}
auto connectManager = GetConnectManagerByUserId(userId);
connectManager->SignRestartAppFlag(bundleName);
if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
uiAbilityLifecycleManager_->SignRestartAppFlag(bundleName);
return ERR_OK;
}
auto missionListManager = GetListManagerByUserId(userId);
if (missionListManager == nullptr) {
HILOG_ERROR("missionListManager is nullptr. userId:%{public}d", userId);
return ERR_INVALID_VALUE;
}
missionListManager->SignRestartAppFlag(bundleName);
return ERR_OK;
}
} // namespace AAFwk
} // namespace OHOS
@@ -395,6 +395,8 @@ void AbilityManagerStub::FourthStepInit()
&AbilityManagerStub::CancelApplicationAutoStartupByEDMInner;
requestFuncMap_[static_cast<uint32_t>(AbilityManagerInterfaceCode::GET_FOREGROUND_UI_ABILITIES)] =
&AbilityManagerStub::GetForegroundUIAbilitiesInner;
requestFuncMap_[static_cast<uint32_t>(AbilityManagerInterfaceCode::RESTART_APP)] =
&AbilityManagerStub::RestartAppInner;
}
int AbilityManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
@@ -3028,5 +3030,21 @@ int32_t AbilityManagerStub::GetUIExtensionRootHostInfoInner(MessageParcel &data,
return NO_ERROR;
}
int32_t AbilityManagerStub::RestartAppInner(MessageParcel &data, MessageParcel &reply)
{
HILOG_DEBUG("call.");
std::unique_ptr<AAFwk::Want> want(data.ReadParcelable<AAFwk::Want>());
if (want == nullptr) {
HILOG_ERROR("want is nullptr");
return IPC_STUB_ERR;
}
auto result = RestartApp(*want);
if (!reply.WriteInt32(result)) {
HILOG_ERROR("fail to write result.");
return IPC_STUB_ERR;
}
return ERR_OK;
}
} // namespace AAFwk
} // namespace OHOS
+11 -1
View File
@@ -691,7 +691,7 @@ void AbilityRecord::ProcessForegroundAbility(bool isRecent, const AbilityRequest
GrantUriPermission(want_, applicationInfo_.bundleName, false, 0);
}
if (isReady_) {
if (isReady_ && !GetRestartAppFlag()) {
auto handler = DelayedSingleton<AbilityManagerService>::GetInstance()->GetTaskHandler();
if (!handler) {
HILOG_ERROR("Fail to get AbilityEventHandler.");
@@ -3393,5 +3393,15 @@ bool AbilityRecord::IsSceneBoard() const
return GetAbilityInfo().name == AbilityConfig::SCENEBOARD_ABILITY_NAME &&
GetAbilityInfo().bundleName == AbilityConfig::SCENEBOARD_BUNDLE_NAME;
}
void AbilityRecord::SetRestartAppFlag(bool isRestartApp)
{
isRestartApp_ = isRestartApp;
}
bool AbilityRecord::GetRestartAppFlag() const
{
return isRestartApp_;
}
} // namespace AAFwk
} // namespace OHOS
+17
View File
@@ -486,5 +486,22 @@ void MissionList::GetActiveAbilityList(const std::string &bundleName, std::vecto
}
}
}
void MissionList::SignRestartAppFlag(const std::string &bundleName)
{
for (auto mission : missions_) {
if (!mission) {
continue;
}
auto abilityRecord = mission->GetAbilityRecord();
if (!abilityRecord) {
continue;
}
if (abilityRecord->GetApplicationInfo().bundleName != bundleName) {
continue;
}
abilityRecord->SetRestartAppFlag(true);
}
}
} // namespace AAFwk
} // namespace OHOS
@@ -153,7 +153,7 @@ int MissionListManager::StartAbility(AbilityRequest &abilityRequest)
}
auto currentTopAbility = GetCurrentTopAbilityLocked();
if (currentTopAbility) {
if (currentTopAbility && !currentTopAbility->GetRestartAppFlag()) {
std::string element = currentTopAbility->GetElementName().GetURI();
auto state = currentTopAbility->GetAbilityState();
HILOG_DEBUG("current top: %{public}s, state: %{public}s",
@@ -4046,5 +4046,21 @@ void MissionListManager::ReportAbilitAssociatedStartInfoToRSS(const AppExecFwk::
ResourceSchedule::ResType::RES_TYPE_APP_ASSOCIATED_START, type, eventParams);
#endif
}
void MissionListManager::SignRestartAppFlag(const std::string &bundleName)
{
for (const auto& missionList : currentMissionLists_) {
if (!missionList) {
continue;
}
missionList->SignRestartAppFlag(bundleName);
}
if (defaultStandardList_) {
defaultStandardList_->SignRestartAppFlag(bundleName);
}
if (defaultSingleList_) {
defaultSingleList_->SignRestartAppFlag(bundleName);
}
}
} // namespace AAFwk
} // namespace OHOS
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "restart_app_manager.h"
#include "hilog_wrapper.h"
namespace OHOS {
namespace AAFwk {
RestartAppManager &RestartAppManager::GetInstance()
{
static RestartAppManager instance;
return instance;
}
bool RestartAppManager::IsRestartAppFrequent(const RestartAppKeyType &key, time_t time)
{
std::lock_guard<ffrt::mutex> lock(restartAppMapLock_);
constexpr int64_t MIN_RESTART_TIME = 10;
auto it = restartAppHistory_.find(key);
if ((it != restartAppHistory_.end()) && (it->second + MIN_RESTART_TIME > time)) {
HILOG_ERROR("Restart too frequently. Try again at least 10s later.");
return true;
}
return false;
}
void RestartAppManager::AddRestartAppHistory(const RestartAppKeyType &key, time_t time)
{
std::lock_guard<ffrt::mutex> lock(restartAppMapLock_);
HILOG_DEBUG("Refresh history, bundleName=%{public}s, userId=%{public}d", key.bundleName.c_str(), key.userId);
restartAppHistory_[key] = time;
}
} // namespace AAFwk
} // namespace OHOS
@@ -768,7 +768,7 @@ int UIAbilityLifecycleManager::NotifySCBPendingActivation(sptr<SessionInfo> &ses
const AbilityRequest &abilityRequest) const
{
auto abilityRecord = GetAbilityRecordByToken(abilityRequest.callerToken);
if (abilityRecord != nullptr) {
if (abilityRecord != nullptr && !abilityRecord->GetRestartAppFlag()) {
auto callerSessionInfo = abilityRecord->GetSessionInfo();
CHECK_POINTER_AND_RETURN(callerSessionInfo, ERR_INVALID_VALUE);
CHECK_POINTER_AND_RETURN(callerSessionInfo->sessionToken, ERR_INVALID_VALUE);
@@ -2055,5 +2055,16 @@ void UIAbilityLifecycleManager::UpdateSessionInfoBySCB(const std::vector<Session
}
HILOG_INFO("The end of updating session info.");
}
void UIAbilityLifecycleManager::SignRestartAppFlag(const std::string &bundleName)
{
std::lock_guard<ffrt::mutex> guard(sessionLock_);
for (auto &[sessionId, abilityRecord] : sessionAbilityMap_) {
if (abilityRecord == nullptr || abilityRecord->GetApplicationInfo().bundleName != bundleName) {
continue;
}
abilityRecord->SetRestartAppFlag(true);
}
}
} // namespace AAFwk
} // namespace OHOS
@@ -441,6 +441,8 @@ public:
int32_t UpdateRenderState(pid_t renderPid, int32_t state) override;
int32_t SignRestartAppFlag(const std::string &bundleName) override;
private:
/**
* Init, Initialize application services.
@@ -926,6 +926,8 @@ public:
int32_t UpdateRenderState(pid_t renderPid, int32_t state);
int32_t SignRestartAppFlag(const std::string &bundleName);
private:
std::string FaultTypeToString(FaultDataType type);
@@ -243,7 +243,9 @@ public:
* @return Returns the number of queries.
*/
int32_t GetAllAppRunningRecordCountByBundleName(const std::string &bundleName);
int32_t SignRestartAppFlag(const std::string &bundleName);
private:
std::shared_ptr<AbilityRunningRecord> GetAbilityRunningRecord(const int64_t eventId);
void AssignRunningProcessInfoByAppRecord(
@@ -706,6 +706,9 @@ public:
* @param AssignTokenId, the assign tokenId.
*/
void SetAssignTokenId(int32_t tokenId);
void SetRestartAppFlag(bool isRestartApp);
bool GetRestartAppFlag() const;
private:
/**
* SearchTheModuleInfoNeedToUpdated, Get an uninitialized abilityStage data.
@@ -844,6 +847,8 @@ private:
std::set<uint32_t> windowIds_;
std::map<pid_t, std::shared_ptr<ChildProcessRecord>> childProcessRecordMap_;
ffrt::mutex childProcessRecordMapLock_;
bool isRestartApp_ = false; // Only app calling RestartApp can be set to true
};
} // namespace AppExecFwk
} // namespace OHOS
+16
View File
@@ -53,6 +53,7 @@ const std::string TASK_FINISH_USER_TEST = "FinishUserTest";
const std::string TASK_ATTACH_RENDER_PROCESS = "AttachRenderTask";
const std::string TASK_ATTACH_CHILD_PROCESS = "AttachChildProcessTask";
const std::string TASK_EXIT_CHILD_PROCESS_SAFELY = "ExitChildProcessSafelyTask";
const std::string FOUNDATION_PROCESS = "foundation";
} // namespace
REGISTER_SYSTEM_ABILITY_BY_ID(AppMgrService, APP_MGR_SERVICE_ID, true);
@@ -1055,5 +1056,20 @@ int32_t AppMgrService::UpdateRenderState(pid_t renderPid, int32_t state)
}
return appMgrServiceInner_->UpdateRenderState(renderPid, state);
}
int32_t AppMgrService::SignRestartAppFlag(const std::string &bundleName)
{
if (!IsReady()) {
HILOG_ERROR("Not ready.");
return ERR_INVALID_OPERATION;
}
bool isCallingPermission =
AAFwk::PermissionVerification::GetInstance()->CheckSpecificSystemAbilityAccessPermission(FOUNDATION_PROCESS);
if (!isCallingPermission) {
HILOG_ERROR("VerificationAllToken failed.");
return ERR_PERMISSION_DENIED;
}
return appMgrServiceInner_->SignRestartAppFlag(bundleName);
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -5436,5 +5436,15 @@ int32_t AppMgrServiceInner::UpdateRenderState(pid_t renderPid, int32_t state)
HILOG_ERROR("renderPid:%{pubclic}d not exist.", renderPid);
return ERR_INVALID_VALUE;
}
int32_t AppMgrServiceInner::SignRestartAppFlag(const std::string &bundleName)
{
HILOG_DEBUG("call.");
if (!appRunningManager_) {
HILOG_ERROR("appRunningManager_ is nullptr");
return ERR_NO_INIT;
}
return appRunningManager_->SignRestartAppFlag(bundleName);
}
} // namespace AppExecFwk
} // namespace OHOS
+20 -3
View File
@@ -100,7 +100,7 @@ std::shared_ptr<AppRunningRecord> AppRunningManager::CheckAppRunningRecordIsExis
(pair.second->GetProcessName() == processName) &&
(pair.second->GetJointUserId() == jointUserId) &&
!(pair.second->IsTerminating()) &&
!(pair.second->IsKilling());
!(pair.second->IsKilling()) && !(pair.second->GetRestartAppFlag());
};
// If it is not empty, look for whether it can come in the same process
@@ -114,7 +114,7 @@ std::shared_ptr<AppRunningRecord> AppRunningManager::CheckAppRunningRecordIsExis
if (appRecord && appRecord->GetProcessName() == processName &&
(specifiedProcessFlag.empty() ||
appRecord->GetSpecifiedProcessFlag() == specifiedProcessFlag) &&
!(appRecord->IsTerminating()) && !(appRecord->IsKilling())) {
!(appRecord->IsTerminating()) && !(appRecord->IsKilling()) && !(appRecord->GetRestartAppFlag())) {
auto appInfoList = appRecord->GetAppInfoList();
HILOG_DEBUG("appInfoList: %{public}zu, processName: %{public}s, specifiedProcessFlag: %{public}s",
appInfoList.size(), appRecord->GetProcessName().c_str(), specifiedProcessFlag.c_str());
@@ -139,7 +139,7 @@ bool AppRunningManager::CheckAppRunningRecordIsExistByBundleName(const std::stri
}
for (const auto &item : appRunningRecordMap_) {
const auto &appRecord = item.second;
if (appRecord && appRecord->GetBundleName() == bundleName) {
if (appRecord && appRecord->GetBundleName() == bundleName && !(appRecord->GetRestartAppFlag())) {
return true;
}
}
@@ -1126,5 +1126,22 @@ std::shared_ptr<ChildProcessRecord> AppRunningManager::OnChildProcessRemoteDied(
}
return nullptr;
}
int32_t AppRunningManager::SignRestartAppFlag(const std::string &bundleName)
{
HILOG_DEBUG("Called.");
std::lock_guard<ffrt::mutex> guard(lock_);
for (const auto &item : appRunningRecordMap_) {
const auto &appRecord = item.second;
if (appRecord == nullptr || appRecord->GetBundleName() != bundleName) {
continue;
}
HILOG_DEBUG("sign");
appRecord->SetRestartAppFlag(true);
return ERR_OK;
}
HILOG_ERROR("Not find apprecord.");
return ERR_INVALID_VALUE;
}
} // namespace AppExecFwk
} // namespace OHOS
@@ -1940,5 +1940,15 @@ void AppRunningRecord::SetAssignTokenId(int32_t assignTokenId)
{
assignTokenId_ = assignTokenId;
}
void AppRunningRecord::SetRestartAppFlag(bool isRestartApp)
{
isRestartApp_ = isRestartApp;
}
bool AppRunningRecord::GetRestartAppFlag() const
{
return isRestartApp_;
}
} // namespace AppExecFwk
} // namespace OHOS
+1
View File
@@ -155,6 +155,7 @@ ohos_source_set("abilityms_test_source") {
"${ability_runtime_services_path}/abilitymgr/src/pending_want_manager.cpp",
"${ability_runtime_services_path}/abilitymgr/src/pending_want_record.cpp",
"${ability_runtime_services_path}/abilitymgr/src/resident_process_manager.cpp",
"${ability_runtime_services_path}/abilitymgr/src/restart_app_manager.cpp",
"${ability_runtime_services_path}/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp",
"${ability_runtime_services_path}/abilitymgr/src/sender_info.cpp",
"${ability_runtime_services_path}/abilitymgr/src/start_ability_handler.cpp",