diff --git a/frameworks/js/napi/ability_context/ability_context.js b/frameworks/js/napi/ability_context/ability_context.js index 17c442c76827901099d7353ef91dd8bb9e3f8cab..a2767f53a5ce7fde678e8d0125f121d28b70bd44 100644 --- a/frameworks/js/napi/ability_context/ability_context.js +++ b/frameworks/js/napi/ability_context/ability_context.js @@ -264,6 +264,10 @@ class AbilityContext extends Context { setOnNewWantSkipScenarios(scenarios) { return this.__context_impl__.setOnNewWantSkipScenarios(scenarios); } + + restartApp(want) { + return this.__context_impl__.restartApp(want); + } } export default AbilityContext; diff --git a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp index 39bc51ebfd04fe1ab7b7447aa72318507812a64b..30658bc440090b2731d6b5acbe7ad087b9b1fd8e 100644 --- a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp +++ b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp @@ -1450,6 +1450,12 @@ ErrCode AbilityContextImpl::SetOnNewWantSkipScenarios(int32_t scenarios) return AAFwk::AbilityManagerClient::GetInstance()->SetOnNewWantSkipScenarios(token_, scenarios); } +ErrCode AbilityContextImpl::RestartAppWithWindow(const Want &want) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + return AAFwk::AbilityManagerClient::GetInstance()->RestartAppWithWindow(want, token_); +} + ErrCode AbilityContextImpl::AddCompletionHandlerForAtomicService(const std::string &requestId, OnAtomicRequestSuccess onRequestSucc, OnAtomicRequestFailure onRequestFail, const std::string &appId) { diff --git a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp index f273f8edd43439279851c2edb8e7bf912f220204..4d4333e1dbf62f8c51a07758047482889aeed605 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp @@ -462,6 +462,11 @@ napi_value JsAbilityContext::SetOnNewWantSkipScenarios(napi_env env, napi_callba GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnSetOnNewWantSkipScenarios); } +napi_value JsAbilityContext::RestartAppWithWindow(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnRestartAppWithWindow); +} + void JsAbilityContext::ClearFailedCallConnection( const std::weak_ptr& abilityContext, const std::shared_ptr &callback) { @@ -2281,6 +2286,8 @@ napi_value CreateJsAbilityContext(napi_env env, std::shared_ptr JsAbilityContext::DisconnectAppServiceExtensionAbility); BindNativeFunction(env, object, "setOnNewWantSkipScenarios", moduleName, JsAbilityContext::SetOnNewWantSkipScenarios); + BindNativeFunction(env, object, "restartApp", moduleName, + JsAbilityContext::RestartAppWithWindow); return object; } @@ -3191,6 +3198,46 @@ napi_value JsAbilityContext::OnConnectAppServiceExtensionAbility(napi_env env, N return ConnectExtensionAbilityCommon(env, info, AppExecFwk::ExtensionAbilityType::APP_SERVICE); } +napi_value JsAbilityContext::OnRestartAppWithWindow(napi_env env, NapiCallbackInfo& info) +{ + TAG_LOGD(AAFwkTag::APPKIT, "OnRestartAppWithWindow called"); + if (info.argc < ARGC_ONE) { + ThrowTooFewParametersError(env); + return CreateJsUndefined(env); + } + AAFwk::Want want; + if (!AppExecFwk::UnwrapWant(env, info.argv[INDEX_ZERO], want)) { + TAG_LOGE(AAFwkTag::APPKIT, "Parse want failed"); + ThrowInvalidParamError(env, "Parse param want failed, want must be Want."); + return CreateJsUndefined(env); + } + + auto innerErrCode = std::make_shared(ERR_OK); + NapiAsyncTask::ExecuteCallback execute = + [weak = context_, innerErrCode, want] { + auto context = weak.lock(); + if (!context) { + TAG_LOGW(AAFwkTag::CONTEXT, "released context"); + *innerErrCode = static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + return; + } + *innerErrCode = context->RestartAppWithWindow(want); + }; + NapiAsyncTask::CompleteCallback complete = + [innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) { + if (*innerErrCode == ERR_OK) { + task.Resolve(env, CreateJsUndefined(env)); + } else { + task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode)); + } + }; + + napi_value result = nullptr; + NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnSetOnNewWantSkipScenarios", + env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result)); + return result; +} + int32_t JsAbilityContext::GenerateRequestCode() { std::lock_guard lock(requestCodeMutex_); diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_client.h b/interfaces/inner_api/ability_manager/include/ability_manager_client.h index 60e6e80a8145c07cdc6d07e8519968e74412c9ca..d08445842efe3b94174d9c1617428ea461e38042 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_client.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_client.h @@ -1541,6 +1541,14 @@ public: */ int32_t RestartApp(const AAFwk::Want &want); + /** + * @brief Restart app with window. + * @param want The want of the ability to start in new process. + * @param callerToken The caller ability token. + * @return Returns ERR_OK on success, others on failure. + */ + int32_t RestartAppWithWindow(const AAFwk::Want &want, sptr callerToken); + /** * @brief Get host info of root caller. * diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h index c04c88ea43ab51e130c205d27b365d65a3ec4de9..d8cec7220318f39381e81a8aacf31583d67f227e 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_interface.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_interface.h @@ -2327,6 +2327,17 @@ public: { return 0; } + + /** + * Restart app with window. + * @param want The want of the ability to start in new process. + * @param callerToken The caller ability token. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t RestartAppWithWindow(const AAFwk::Want &want, sptr callerToken) + { + return 0; + } }; } // namespace AAFwk } // namespace OHOS diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h index 38921bbefa86f6498becfbbe6c854196e2cc31cb..305fa51d4a923f4b0a89a6d17eb1b7b854ddaa97 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_ipc_interface_code.h @@ -670,6 +670,9 @@ enum class AbilityManagerInterfaceCode { // preload application PRELOAD_APPLICATION = 6151, + + // restart app with window + RESTART_APP_WITH_WINDOW = 6152, }; } // namespace AAFwk } // namespace OHOS diff --git a/interfaces/inner_api/ability_manager/include/ability_state.h b/interfaces/inner_api/ability_manager/include/ability_state.h index e1dc60c851caec9a2cc250ee72ff6e073c547b65..12cae4d6f37ea6501b804d19a94b41d05d3bcfa2 100644 --- a/interfaces/inner_api/ability_manager/include/ability_state.h +++ b/interfaces/inner_api/ability_manager/include/ability_state.h @@ -16,9 +16,7 @@ #ifndef OHOS_ABILITY_RUNTIME_ABILITY_STATE_H #define OHOS_ABILITY_RUNTIME_ABILITY_STATE_H -#include - -#include "parcel.h" +#include namespace OHOS { namespace AAFwk { @@ -69,6 +67,13 @@ enum UserStatus { ASSERT_CONTINUE, ASSERT_RETRY, }; + +enum class RestartMode: uint8_t { + RESTART_NONE, + RESTART_APP, + RESTART_OTHER_ABILITY, + RESTART_SAME_ABILITY, +}; } // namespace AAFwk } // namespace OHOS #endif // OHOS_ABILITY_RUNTIME_ABILITY_STATE_H diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context.h b/interfaces/kits/native/ability/ability_runtime/ability_context.h index 1bc0b053dec44c07ec9e944136ed29da03c93cda..65c568beff8c4bc7dd3aebb99dcac7ef660f4320 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context.h @@ -396,6 +396,7 @@ public: virtual void SetHookOff(bool hookOff) = 0; virtual ErrCode RevokeDelegator() = 0; virtual ErrCode SetOnNewWantSkipScenarios(int32_t scenarios) = 0; + virtual ErrCode RestartAppWithWindow(const AAFwk::Want &want) = 0; void SetScreenMode(int32_t screenMode) { screenMode_ = screenMode; diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h b/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h index 35bdfd8339a9d81ee005826b29feec727ed2e6e7..0c095dc65677ac3cace73ef784be4b28562ca41d 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h @@ -371,6 +371,7 @@ public: ErrCode ConnectExtensionAbilityWithExtensionType(const AAFwk::Want& want, const sptr& connectCallback, AppExecFwk::ExtensionAbilityType extensionType) override; ErrCode SetOnNewWantSkipScenarios(int32_t scenarios) override; + ErrCode RestartAppWithWindow(const Want &want) override; ErrCode AddCompletionHandlerForAtomicService(const std::string &requestId, OnAtomicRequestSuccess onRequestSucc, OnAtomicRequestFailure onRequestFail, const std::string &appId) override; diff --git a/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h b/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h index b1e8c0b70fcdbe862641925c40ca96ac43aeadef..afc03be607208893ea31e85acbcdb10f2dc65881 100644 --- a/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h +++ b/interfaces/kits/native/ability/native/ability_runtime/js_ability_context.h @@ -80,6 +80,7 @@ public: static napi_value StopAppServiceExtensionAbility(napi_env env, napi_callback_info info); static napi_value ConnectAppServiceExtensionAbility(napi_env env, napi_callback_info info); static napi_value DisconnectAppServiceExtensionAbility(napi_env env, napi_callback_info info); + static napi_value RestartAppWithWindow(napi_env env, napi_callback_info info); static void ConfigurationUpdated(napi_env env, std::shared_ptr &jsContext, const std::shared_ptr &config); @@ -157,6 +158,7 @@ private: napi_value OnStartAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info); napi_value OnStopAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info); napi_value OnConnectAppServiceExtensionAbility(napi_env env, NapiCallbackInfo& info); + napi_value OnRestartAppWithWindow(napi_env env, NapiCallbackInfo& info); napi_value StartExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, AppExecFwk::ExtensionAbilityType extensionType); napi_value StopExtensionAbilityCommon(napi_env env, NapiCallbackInfo& info, diff --git a/services/abilitymgr/include/ability_manager_proxy.h b/services/abilitymgr/include/ability_manager_proxy.h index 90aa5002ea4b2fc397d3db6430d780e1c1cdde08..028f159b5e4fc626e042d2105a66d2912adb483a 100644 --- a/services/abilitymgr/include/ability_manager_proxy.h +++ b/services/abilitymgr/include/ability_manager_proxy.h @@ -1805,6 +1805,13 @@ public: */ virtual int32_t PreloadApplication(const std::string &bundleName, int32_t userId, int32_t appIndex) override; + /** + * Restart app with window. + * @param want The want of the ability to start in new process. + * @param callerToken The caller ability token. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t RestartAppWithWindow(const AAFwk::Want &want, sptr callerToken) override; private: template int GetParcelableInfos(MessageParcel &reply, std::vector &parcelableInfos); diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 01a1152b878bc8b22ee26bcd026ad37ddb947a5f..d9f66b6d3d258c69e97eb190544cb9a248c60c32 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -2128,6 +2128,14 @@ public: */ virtual int32_t PreloadApplication(const std::string &bundleName, int32_t userId, int32_t appIndex) override; + /** + * Restart app with window. + * @param want The want of the ability to start in new process. + * @param callerToken The caller ability token. + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t RestartAppWithWindow(const AAFwk::Want &want, sptr callerToken) override; + // MSG 0 - 20 represents timeout message static constexpr uint32_t LOAD_TIMEOUT_MSG = 0; static constexpr uint32_t ACTIVE_TIMEOUT_MSG = 1; @@ -2808,6 +2816,7 @@ private: int32_t OpenLinkInner(const Want &want, sptr callerToken, int32_t userId, int requestCode, bool removeInsightIntentFlag); int32_t KillProcessWithReasonInner(int32_t pid, const ExitReason &reason, bool isKillPrecedeStart); + int32_t RestartAppInner(const AAFwk::Want &want, bool isAppRecovery, sptr callerToken); #ifdef BGTASKMGR_CONTINUOUS_TASK_ENABLE std::shared_ptr bgtaskObserver_; #endif diff --git a/services/abilitymgr/include/ability_manager_stub.h b/services/abilitymgr/include/ability_manager_stub.h index d98997a80753b95c2bce08bb0361cd2dad7cc6e9..c425251641c39ba702d8d2f2dc83bc6ea289c25d 100644 --- a/services/abilitymgr/include/ability_manager_stub.h +++ b/services/abilitymgr/include/ability_manager_stub.h @@ -342,6 +342,7 @@ private: int32_t SetOnNewWantSkipScenariosInner(MessageParcel &data, MessageParcel &reply); int32_t NotifyStartupExceptionBySCBInner(MessageParcel &data, MessageParcel &reply); int32_t PreloadApplicationInner(MessageParcel &data, MessageParcel &reply); + int32_t RestartAppWithWindowInner(MessageParcel &data, MessageParcel &reply); int OnRemoteRequestInnerFirst(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/services/abilitymgr/include/ability_record.h b/services/abilitymgr/include/ability_record.h index 79b765ebba50246adbebed8b66a80c3bad361b11..b8a6947ac4e08acb58b700100f44916a13ee5cee 100644 --- a/services/abilitymgr/include/ability_record.h +++ b/services/abilitymgr/include/ability_record.h @@ -1139,6 +1139,14 @@ public: void SetRestartAppFlag(bool isRestartApp); bool GetRestartAppFlag() const; + void SetRestartMode(RestartMode restartMode) + { + restartMode_ = restartMode; + } + RestartMode GetRestartMode() const + { + return restartMode_; + } void SetKillForPermissionUpdateFlag(bool isKillForPermissionUpdate); bool GetKillForPermissionUpdateFlag() const; @@ -1423,12 +1431,12 @@ private: bool isAssertDebug_ = false; bool isAppAutoStartup_ = false; bool isConnected = false; - bool isRestartApp_ = false; // Only app calling RestartApp can be set to true bool isLaunching_ = true; bool securityFlag_ = false; bool isHook_ = false; bool hookOff_ = false; bool isPluginAbility_ = false; + RestartMode restartMode_ = RestartMode::RESTART_NONE; std::atomic_bool isCallerSetProcess_ = false; // new version std::atomic_bool backgroundAbilityWindowDelayed_ = false; diff --git a/services/abilitymgr/src/ability_manager_client.cpp b/services/abilitymgr/src/ability_manager_client.cpp index e4149b294d189bc161089b437af22d1e793e1e44..781e22f81657fe16528e7ec42f25d42816a50cd6 100644 --- a/services/abilitymgr/src/ability_manager_client.cpp +++ b/services/abilitymgr/src/ability_manager_client.cpp @@ -2017,6 +2017,15 @@ int32_t AbilityManagerClient::RestartApp(const AAFwk::Want &want) return abms->RestartApp(want); } +int32_t AbilityManagerClient::RestartAppWithWindow(const AAFwk::Want &want, sptr callerToken) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + TAG_LOGI(AAFwkTag::ABILITYMGR, "RestartAppWithWindow"); + auto abms = GetAbilityManager(); + CHECK_POINTER_RETURN_INVALID_VALUE(abms); + return abms->RestartAppWithWindow(want, callerToken); +} + int32_t AbilityManagerClient::OpenAtomicService(Want& want, const StartOptions &options, sptr callerToken, int32_t requestCode, int32_t userId) { diff --git a/services/abilitymgr/src/ability_manager_proxy.cpp b/services/abilitymgr/src/ability_manager_proxy.cpp index 8ab7a0ec36fb0271e9bc7d2162079b9b9957befd..50d47b2fb8c805d3375a7a867d75ba465e34e7a7 100644 --- a/services/abilitymgr/src/ability_manager_proxy.cpp +++ b/services/abilitymgr/src/ability_manager_proxy.cpp @@ -7179,5 +7179,31 @@ int32_t AbilityManagerProxy::PreloadApplication(const std::string &bundleName, i return reply.ReadInt32(); } + +int32_t AbilityManagerProxy::RestartAppWithWindow(const AAFwk::Want &want, sptr callerToken) +{ + MessageParcel data; + if (!WriteInterfaceToken(data)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "writeInterfaceToken fail"); + return ERR_WRITE_INTERFACE_TOKEN_FAILED; + } + + MessageParcel reply; + MessageOption option; + if (!data.WriteParcelable(&want)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "want write fail"); + return IPC_PROXY_ERR; + } + if (callerToken == nullptr || !data.WriteRemoteObject(callerToken)) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "callerToken error"); + return IPC_PROXY_ERR; + } + auto ret = SendRequest(AbilityManagerInterfaceCode::RESTART_APP_WITH_WINDOW, data, reply, option); + if (ret != NO_ERROR) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "request error:%{public}d", ret); + return ret; + } + return reply.ReadInt32(); +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index b69764e9456788210ecf46cc19b29d7992275f0f..e4421f89dea3d8ca6f90a9a92c024b76e2bc3a4d 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -13098,6 +13098,12 @@ int32_t AbilityManagerService::GetUIExtensionSessionInfo(const sptr callerToken) { XCOLLIE_TIMER_LESS(__PRETTY_FUNCTION__); TAG_LOGI(AAFwkTag::ABILITYMGR, "RestartApp, isAppRecovery: %{public}d", isAppRecovery); @@ -13133,7 +13139,7 @@ int32_t AbilityManagerService::RestartApp(const AAFwk::Want &want, bool isAppRec (const_cast(want)).SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, processInfo.appCloneIndex); (const_cast(want)).SetParam(AAFwk::Want::APP_INSTANCE_KEY, processInfo.instanceKey); (const_cast(want)).RemoveParam(Want::CREATE_APP_INSTANCE_KEY); - result = StartAbilityWrap(want, nullptr, DEFAULT_INVAL_VALUE, false, DEFAULT_INVAL_VALUE, false, 0, true); + result = StartAbilityWrap(want, callerToken, DEFAULT_INVAL_VALUE, false, DEFAULT_INVAL_VALUE, false, 0, true); if (result != ERR_OK) { TAG_LOGE(AAFwkTag::ABILITYMGR, "startAbility error"); return result; @@ -13156,7 +13162,7 @@ int32_t AbilityManagerService::CheckRestartAppWant(const AAFwk::Want &want, int3 CHECK_POINTER_AND_RETURN(bms, GET_ABILITY_SERVICE_FAILED); auto abilityInfoFlag = AbilityRuntime::StartupUtil::BuildAbilityInfoFlag(); - TAG_LOGD(AAFwkTag::ABILITYMGR, + TAG_LOGI(AAFwkTag::ABILITYMGR, "bundleName: %{public}s, abilityName: %{public}s, appIndex: %{public}d, userId: %{public}d", want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str(), appIndex, userId); AppExecFwk::AbilityInfo abilityInfo; @@ -15159,5 +15165,41 @@ int32_t AbilityManagerService::PreloadApplication(const std::string &bundleName, { return PreloadManagerService::GetInstance().PreloadApplication(bundleName, userId, appIndex); } + +int32_t AbilityManagerService::RestartAppWithWindow(const AAFwk::Want &want, sptr callerToken) +{ + TAG_LOGI(AAFwkTag::ABILITYMGR, "RestartAppWithWindow"); + if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled() || + !AppUtils::GetInstance().IsSupportRestartAppWithWindow()) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "not supported"); + return ERR_CAPABILITY_NOT_SUPPORT; // for js 801 + } + + auto callerRecord = Token::GetAbilityRecordByToken(callerToken); + CHECK_POINTER_AND_RETURN_LOG(callerRecord, ERR_NULL_OBJECT, "callerRecord null"); + if (!IsAppSelfCalled(callerRecord)) { + return ERR_INVALID_CALLER; + } + + if (callerRecord->GetAbilityInfo().type != AbilityType::PAGE) { + return ERR_INVALID_CALLER; + } + + if (!callerRecord->IsForeground()) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "ability not foregorund state"); + return ERR_ABILITY_NOT_FOREGROUND; + } + + // to be simple, want has abilityName, and moduleName ignored + // no implicit supported + auto element = want.GetElement(); + if (element.GetAbilityName() == callerRecord->GetAbilityInfo().name) { + callerRecord->SetRestartMode(RestartMode::RESTART_SAME_ABILITY); + } else { + callerRecord->SetRestartMode(RestartMode::RESTART_OTHER_ABILITY); + } + + return RestartAppInner(want, false, callerToken); +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_stub.cpp b/services/abilitymgr/src/ability_manager_stub.cpp index e5d8a75a12ed859921d589b4c6a60b40b98aafc7..ffcb55f8d0b81feb0cc32b9293004ef6e510af4f 100644 --- a/services/abilitymgr/src/ability_manager_stub.cpp +++ b/services/abilitymgr/src/ability_manager_stub.cpp @@ -903,6 +903,9 @@ int AbilityManagerStub::OnRemoteRequestInnerTwentyFirst(uint32_t code, MessagePa if (interfaceCode == AbilityManagerInterfaceCode::PRELOAD_APPLICATION) { return PreloadApplicationInner(data, reply); } + if (interfaceCode == AbilityManagerInterfaceCode::RESTART_APP_WITH_WINDOW) { + return RestartAppWithWindowInner(data, reply); + } return ERR_CODE_NOT_EXIST; } @@ -4942,5 +4945,25 @@ int AbilityManagerStub::PreloadApplicationInner(MessageParcel &data, MessageParc } return result; } + +int AbilityManagerStub::RestartAppWithWindowInner(MessageParcel &data, MessageParcel &reply) +{ + HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); + std::unique_ptr want(data.ReadParcelable()); + if (want == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "null want"); + return ERR_NULL_OBJECT; + } + sptr token = data.ReadRemoteObject(); + if (token == nullptr) { + TAG_LOGE(AAFwkTag::ABILITYMGR, "read ability token fail"); + return ERR_NULL_OBJECT; + } + int32_t result = RestartAppWithWindow(*want, token); + if (!reply.WriteInt32(result)) { + return ERR_WRITE_RESULT_CODE_FAILED; + } + return result; +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_record.cpp b/services/abilitymgr/src/ability_record.cpp index 590bb0a7f2375d975a2b890747b9972b50eb53e4..462a793e217981e9a94282123aa0022732863340 100644 --- a/services/abilitymgr/src/ability_record.cpp +++ b/services/abilitymgr/src/ability_record.cpp @@ -3763,12 +3763,16 @@ bool AbilityRecord::IsSceneBoard() const void AbilityRecord::SetRestartAppFlag(bool isRestartApp) { - isRestartApp_ = isRestartApp; + if (isRestartApp) { + restartMode_ = RestartMode::RESTART_APP; + } else { + restartMode_ = RestartMode::RESTART_NONE; + } } bool AbilityRecord::GetRestartAppFlag() const { - return isRestartApp_; + return restartMode_ != RestartMode::RESTART_NONE; } void AbilityRecord::SetKillForPermissionUpdateFlag(bool isKillForPermissionUpdate) diff --git a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp index bc8182027013fdab24a885a4168b0a52a78d6d0d..36697ef379e98cce957da65c3cc0d835f1fbf8a3 100644 --- a/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp +++ b/services/abilitymgr/src/scene_board/ui_ability_lifecycle_manager.cpp @@ -1558,10 +1558,17 @@ int UIAbilityLifecycleManager::NotifySCBPendingActivation(sptr &ses (sessionInfo->want).GetIntParam(Want::PARAM_APP_CLONE_INDEX_KEY, 0), sessionInfo->instanceKey.c_str(), hasStartWindow, backgroundColor.c_str(), sessionInfo->hideStartWindow); auto abilityRecord = GetAbilityRecordByToken(abilityRequest.callerToken); - if (abilityRecord != nullptr && !abilityRecord->GetRestartAppFlag()) { + if (abilityRecord != nullptr && abilityRecord->GetRestartMode() != RestartMode::RESTART_APP) { auto callerSessionInfo = abilityRecord->GetSessionInfo(); CHECK_POINTER_AND_RETURN(callerSessionInfo, ERR_INVALID_VALUE); CHECK_POINTER_AND_RETURN(callerSessionInfo->sessionToken, ERR_INVALID_VALUE); + if (abilityRecord->GetRestartMode() == RestartMode::RESTART_SAME_ABILITY) { + sessionInfo->sessionToken = callerSessionInfo->sessionToken; + sessionInfo->persistentId = callerSessionInfo->persistentId; + } + if (abilityRecord->GetRestartMode() != RestartMode::RESTART_NONE) { + sessionInfo->callerToken = nullptr; // in case verify caller token fail + } auto callerSession = iface_cast(callerSessionInfo->sessionToken); CHECK_POINTER_AND_RETURN(callerSession, ERR_INVALID_VALUE); CheckCallerFromBackground(abilityRecord, sessionInfo); @@ -2264,7 +2271,8 @@ void UIAbilityLifecycleManager::OnAbilityDied(std::shared_ptr abi static_cast(ErrorLifecycleState::ABILITY_STATE_LOW_MEMORY_KILL) : static_cast(ErrorLifecycleState::ABILITY_STATE_SKIP_KILL_IN_STARTUP); NotifySCBToHandleException(abilityRecord, errCode, abilityRecord->GetKillReason()); - } else if (!abilityRecord->GetRestartAppFlag()) { + } else if (abilityRecord->GetRestartMode() != RestartMode::RESTART_APP && + abilityRecord->GetRestartMode() != RestartMode::RESTART_SAME_ABILITY) { // window no destroy NotifySCBToHandleException(abilityRecord, static_cast(ErrorLifecycleState::ABILITY_STATE_DIED), "onAbilityDied"); } @@ -3595,6 +3603,9 @@ void UIAbilityLifecycleManager::SignRestartAppFlag(int32_t uid, const std::strin abilityRecord->GetInstanceKey() != instanceKey) { continue; } + if (abilityRecord->GetRestartAppFlag()) { + return; + } abilityRecord->SetRestartAppFlag(true); std::string reason = "onAbilityDied"; if (isAppRecovery) {