diff --git a/frameworks/ets/ani/ui_ability/include/ets_ability_context.h b/frameworks/ets/ani/ui_ability/include/ets_ability_context.h index 0b437026eb683fa9ceb0437b24c4b8c6b50b88f1..cc19412ac4faeed60612ddad4d61b5b6900fbc8c 100644 --- a/frameworks/ets/ani/ui_ability/include/ets_ability_context.h +++ b/frameworks/ets/ani/ui_ability/include/ets_ability_context.h @@ -120,6 +120,10 @@ public: static void NativeOnSetRestoreEnabled(ani_env *env, ani_object aniObj, ani_boolean aniEnabled); static void NativeChangeAbilityVisibility(ani_env *env, ani_object aniObj, ani_boolean isShow, ani_object callbackObj); + static void StartAbilityAsCaller(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj); + static void StartRecentAbility(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj); #ifdef SUPPORT_GRAPHICS public: @@ -133,7 +137,8 @@ private: #endif private: void InheritWindowMode(ani_env *env, ani_object aniObj, AAFwk::Want &want); - void OnStartAbility(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object opt, ani_object call); + void OnStartAbility(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object opt, ani_object call, + bool isStartRecent = false); void OnStartAbilityForResult( ani_env *env, ani_object aniObj, ani_object wantObj, ani_object startOptionsObj, ani_object callback); void OnTerminateSelf(ani_env *env, ani_object aniObj, ani_object callback); @@ -182,7 +187,8 @@ private: int32_t GenerateRequestCode(); void OpenAtomicServiceInner(ani_env *env, ani_object aniObj, AAFwk::Want &want, AAFwk::StartOptions &options, std::string appId, ani_object callbackObj); - + void OnStartAbilityAsCaller(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object startOptionsObj, + ani_object callbackObj); std::weak_ptr context_; static std::mutex requestCodeMutex_; sptr freeInstallObserver_ = nullptr; diff --git a/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp b/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp index b2f5b9e467489d68a9501ea816b2c5f0656ca559..1d80cf239e9537ade9f5e94e4c760c304c67289c 100644 --- a/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp +++ b/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp @@ -36,6 +36,7 @@ #include "hilog_tag_wrapper.h" #include "hitrace_meter.h" #include "ipc_skeleton.h" +#include "json_utils.h" #include "tokenid_kit.h" #include "want.h" #ifdef SUPPORT_GRAPHICS @@ -58,6 +59,7 @@ static std::map, EtsKeyCompare> g_c constexpr const char* UI_ABILITY_CONTEXT_CLASS_NAME = "Lapplication/UIAbilityContext/UIAbilityContext;"; constexpr const char* CLEANER_CLASS = "Lapplication/UIAbilityContext/Cleaner;"; const std::string APP_LINKING_ONLY = "appLinkingOnly"; +const std::string JSON_KEY_ERR_MSG = "errMsg"; constexpr const char* SIGNATURE_OPEN_LINK = "Lstd/core/String;Lutils/AbilityUtils/AsyncCallbackWrapper;" "L@ohos/app/ability/OpenLinkOptions/OpenLinkOptions;Lutils/AbilityUtils/AsyncCallbackWrapper;:V"; constexpr const char *SIGNATURE_CONNECT_SERVICE_EXTENSION = @@ -69,6 +71,10 @@ const std::string ATOMIC_SERVICE_PREFIX = "com.atomicservice."; constexpr const char *SIGNATURE_START_ABILITY_BY_TYPE = "Lstd/core/String;Lescompat/Record;Lapplication/AbilityStartCallback/AbilityStartCallback;:L@ohos/base/" "BusinessError;"; +constexpr const char *SIGNATURE_START_ABILITY_AS_CALLER = "L@ohos/app/ability/Want/Want;" + "Lutils/AbilityUtils/AsyncCallbackWrapper;L@ohos/app/ability/StartOptions/StartOptions;:V"; +constexpr const char *SIGNATURE_START_RECENT_ABILITY = "L@ohos/app/ability/Want/Want;" + "Lutils/AbilityUtils/AsyncCallbackWrapper;L@ohos/app/ability/StartOptions/StartOptions;:V"; constexpr int32_t ARGC_ONE = 1; constexpr int32_t ARGC_TWO = 2; @@ -587,6 +593,39 @@ void EtsAbilityContext::SetMissionIcon(ani_env *env, ani_object aniObj, ani_obje } #endif +void EtsAbilityContext::StartAbilityAsCaller(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj) +{ + TAG_LOGD(AAFwkTag::CONTEXT, "StartAbilityAsCaller called"); + auto etsContext = GetEtsAbilityContext(env, aniObj); + if (etsContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null etsContext"); + return; + } + etsContext->OnStartAbilityAsCaller(env, aniObj, wantObj, callbackObj, startOptionsObj); +} + +void EtsAbilityContext::StartRecentAbility(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj) +{ + TAG_LOGD(AAFwkTag::CONTEXT, "StartRecentAbility called"); + auto etsContext = GetEtsAbilityContext(env, aniObj); + if (etsContext == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null etsContext"); + return; + } + ani_status status = ANI_ERROR; + ani_boolean isOptionsUndefined = ANI_FALSE; + if ((status = env->Reference_IsUndefined(startOptionsObj, &isOptionsUndefined)) != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "status: %{public}d", status); + } + if (isOptionsUndefined) { + startOptionsObj = nullptr; + } + etsContext->OnStartAbility(env, aniObj, wantObj, startOptionsObj, callbackObj); +} + + int32_t EtsAbilityContext::GenerateRequestCode() { static int32_t curRequestCode_ = 0; @@ -616,7 +655,7 @@ void EtsAbilityContext::InheritWindowMode(ani_env *env, ani_object aniObj, AAFwk } void EtsAbilityContext::OnStartAbility( - ani_env *env, ani_object aniObj, ani_object wantObj, ani_object opt, ani_object call) + ani_env *env, ani_object aniObj, ani_object wantObj, ani_object opt, ani_object call, bool isStartRecent) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); AAFwk::Want want; @@ -624,6 +663,10 @@ void EtsAbilityContext::OnStartAbility( EtsErrorUtil::ThrowInvalidParamError(env, "Parse param want failed, must be a Want"); return; } + if (isStartRecent) { + TAG_LOGD(AAFwkTag::CONTEXT, "startRecentAbility"); + want.SetParam(AAFwk::Want::PARAM_RESV_START_RECENT, true); + } InheritWindowMode(env, aniObj, want); auto context = context_.lock(); if (context == nullptr) { @@ -1774,6 +1817,44 @@ void EtsAbilityContext::OnSetMissionIcon(ani_env *env, ani_object aniObj, ani_ob } #endif +void EtsAbilityContext::OnStartAbilityAsCaller(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj) +{ + TAG_LOGD(AAFwkTag::CONTEXT, "StartAbilityAsCaller called"); + AAFwk::Want want; + if (!AppExecFwk::UnwrapWant(env, wantObj, want)) { + EtsErrorUtil::ThrowInvalidParamError(env, "Parse param want failed, must be a Want"); + return; + } + InheritWindowMode(env, aniObj, want); + auto context = context_.lock(); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::CONTEXT, "null context"); + EtsErrorUtil::ThrowInvalidParamError(env, "null context"); + return; + } + ani_status status = ANI_ERROR; + ani_boolean isOptionsUndefined = true; + if ((status = env->Reference_IsUndefined(startOptionsObj, &isOptionsUndefined)) != ANI_OK) { + TAG_LOGE(AAFwkTag::CONTEXT, "status: %{public}d", status); + } + ErrCode innerErrCode = ERR_OK; + AAFwk::StartOptions startOptions; + if (!isOptionsUndefined) { + if (!AppExecFwk::UnwrapStartOptionsWithProcessOption(env, startOptionsObj, startOptions)) { + EtsErrorUtil::ThrowInvalidParamError(env, + "Parse param startOptions failed, startOptions must be StartOptions."); + TAG_LOGE(AAFwkTag::CONTEXT, "invalid options"); + return; + } + innerErrCode = context->StartAbilityAsCaller(want, startOptions, -1); + } else { + innerErrCode = context->StartAbilityAsCaller(want, -1); + } + ani_object aniObject = EtsErrorUtil::CreateErrorByNativeErr(env, innerErrCode); + AppExecFwk::AsyncCallback(env, callbackObj, aniObject, nullptr); +} + void EtsAbilityContext::RevokeDelegator(ani_env *env, ani_object aniObj, ani_object callback) { TAG_LOGD(AAFwkTag::CONTEXT, "RevokeDelegator called"); @@ -1931,6 +2012,10 @@ bool BindNativeMethods(ani_env *env, ani_class &cls) "L@ohos/app/ability/Want/Want;IL@ohos/app/ability/StartOptions/StartOptions;" "Lutils/AbilityUtils/AsyncCallbackWrapper;:V", reinterpret_cast(EtsAbilityContext::StartAbilityForResultWithAccountResult) }, + ani_native_function { "nativeStartAbilityAsCaller", SIGNATURE_START_ABILITY_AS_CALLER, + reinterpret_cast(EtsAbilityContext::StartAbilityAsCaller) }, + ani_native_function { "nativeStartRecentAbility", SIGNATURE_START_RECENT_ABILITY, + reinterpret_cast(EtsAbilityContext::StartRecentAbility) }, }; if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) { TAG_LOGE(AAFwkTag::CONTEXT, "Class_BindNativeMethods failed status: %{public}d", status); diff --git a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h index 0bf386f510d09beb1c0eb700555fa8772163d472..51d4147a0df21c924349191b006ceaf3def34080 100644 --- a/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h +++ b/frameworks/ets/ani/ui_extension_ability/include/ets_ui_extension_content_session.h @@ -88,6 +88,8 @@ public: ani_env *env, ani_object obj, ani_string type, ani_ref wantParam, ani_object startCallback); static void NativeSetWindowPrivacyMode( ani_env *env, ani_object obj, ani_boolean isPrivacyMode, ani_object callbackObj); + static void NativeStartAbilityAsCaller(ani_env *env, ani_object aniObj, + ani_object wantObj, ani_object callbackObj, ani_object startOptionsObj); void SendData(ani_env *env, ani_object object, ani_object data); void LoadContent(ani_env *env, ani_object object, ani_string path, ani_object storage); @@ -101,6 +103,8 @@ public: ani_env *env, ani_object obj, ani_boolean isPrivacyMode, ani_object callbackObj); static void CallReceiveDataCallbackForResult( ani_vm *vm, ani_ref callbackRef, const AAFwk::WantParams &wantParams, AAFwk::WantParams &retWantParams); + void OnStartAbilityAsCaller(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj); std::shared_ptr GetContext(); sptr GetUIWindow(); static bool BindNativePtrCleaner(ani_env *env); diff --git a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp index 197078cfbd39c9ef5be60049d4f197b5c26787ca..8d6065fa62da61e89fb227313ae2199c3c2a496c 100644 --- a/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp +++ b/frameworks/ets/ani/ui_extension_ability/src/ets_ui_extension_content_session.cpp @@ -18,6 +18,7 @@ #include "ability_manager_client.h" #include "accesstoken_kit.h" +#include "ani_common_start_options.h" #include "ani_common_util.h" #include "ani_common_want.h" #include "ani_extension_window.h" @@ -55,6 +56,8 @@ constexpr const char *SIGNATURE_GET_UI_EXTENSION_WINDOW_PROXY = ":L@ohos/arkui/uiExtension/uiExtension/WindowProxy;"; constexpr const char *SIGNATURE_SET_WINDOW_PRIVACY_MODE = "ZLutils/AbilityUtils/AsyncCallbackWrapper;:V"; constexpr const char* PERMISSION_PRIVACY_WINDOW = "ohos.permission.PRIVACY_WINDOW"; +constexpr const char *SIGNATURE_START_ABILITY_AS_CALLER = "L@ohos/app/ability/Want/Want;" + "Lutils/AbilityUtils/AsyncCallbackWrapper;L@ohos/app/ability/StartOptions/StartOptions;:V"; } // namespace EtsUIExtensionContentSession* EtsUIExtensionContentSession::GetEtsContentSession(ani_env *env, ani_object obj) @@ -215,6 +218,15 @@ void EtsUIExtensionContentSession::NativeSetWindowPrivacyMode( } } +void EtsUIExtensionContentSession::NativeStartAbilityAsCaller(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj) +{ + auto etsContentSession = EtsUIExtensionContentSession::GetEtsContentSession(env, aniObj); + if (etsContentSession != nullptr) { + etsContentSession->OnStartAbilityAsCaller(env, aniObj, wantObj, callbackObj, startOptionsObj); + } +} + EtsUIExtensionContentSession::EtsUIExtensionContentSession( sptr sessionInfo, sptr uiWindow, std::weak_ptr &context, @@ -293,7 +305,9 @@ ani_status EtsUIExtensionContentSession::BindNativeMethod(ani_env *env, ani_clas ani_native_function {"nativeStartAbilityByTypeSync", SIGNATURE_START_ABILITY_BY_TYPE, reinterpret_cast(EtsUIExtensionContentSession::NativeStartAbilityByTypeSync)}, ani_native_function {"nativeSetWindowPrivacyMode", SIGNATURE_SET_WINDOW_PRIVACY_MODE, - reinterpret_cast(EtsUIExtensionContentSession::NativeSetWindowPrivacyMode)} + reinterpret_cast(EtsUIExtensionContentSession::NativeSetWindowPrivacyMode)}, + ani_native_function {"nativeStartAbilityAsCaller", SIGNATURE_START_ABILITY_AS_CALLER, + reinterpret_cast(EtsUIExtensionContentSession::NativeStartAbilityAsCaller)} }; ani_status status = ANI_ERROR; if ((status = env->Class_BindNativeMethods(cls, methods.data(), methods.size())) != ANI_OK) { @@ -771,6 +785,56 @@ void EtsUIExtensionContentSession::SetWindowPrivacyModeInner(ani_env *env, ani_b } } +void EtsUIExtensionContentSession::OnStartAbilityAsCaller(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object callbackObj, ani_object startOptionsObj) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "StartAbilityAsCaller called"); + AAFwk::Want want; + if (!AppExecFwk::UnwrapWant(env, wantObj, want)) { + EtsErrorUtil::ThrowInvalidParamError(env, "Parse param want failed, must be a Want"); + return; + } + auto etsContentSession = EtsUIExtensionContentSession::GetEtsContentSession(env, aniObj); + if (etsContentSession == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null etsContentSession"); + EtsErrorUtil::ThrowInvalidParamError(env, "null etsContentSession"); + return; + } + auto context = etsContentSession->GetContext(); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null context"); + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + return; + } + if (etsContentSession->sessionInfo_ == nullptr) { + EtsErrorUtil::ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + return; + } + ani_status status = ANI_ERROR; + ani_boolean isOptionsUndefined = true; + if ((status = env->Reference_IsUndefined(startOptionsObj, &isOptionsUndefined)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status); + } + ErrCode innerErrCode = ERR_OK; + AAFwk::StartOptions startOptions; + if (!isOptionsUndefined) { + if (!AppExecFwk::UnwrapStartOptionsWithProcessOption(env, startOptionsObj, startOptions)) { + EtsErrorUtil::ThrowInvalidParamError(env, + "Parse param startOptions failed, startOptions must be StartOptions."); + TAG_LOGE(AAFwkTag::UI_EXT, "invalid options"); + return; + } + innerErrCode = AAFwk::AbilityManagerClient::GetInstance()-> + StartAbilityAsCaller(want, context->GetToken(), etsContentSession->sessionInfo_->callerToken); + } else { + innerErrCode = AAFwk::AbilityManagerClient::GetInstance()-> + StartAbilityAsCaller(want, startOptions, context->GetToken(), etsContentSession->sessionInfo_->callerToken); + } + ani_object aniObject = EtsErrorUtil::CreateErrorByNativeErr(env, innerErrCode); + AppExecFwk::AsyncCallback(env, callbackObj, aniObject, nullptr); +} + + bool EtsUIExtensionContentSession::CheckStartAbilityByTypeParam( ani_env *env, ani_string aniType, ani_ref aniWantParam, std::string &type, AAFwk::WantParams &wantParam) { diff --git a/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets b/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets index b610a808baa1c9b4c69884be638da89ba0dfcbff..ac42425ee3d06729b4891627d17e2690f5ee290e 100644 --- a/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets +++ b/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets @@ -20,7 +20,9 @@ import uiExtensionHost from '@ohos.uiExtensionHost'; import { LocalStorage } from '@ohos.arkui.stateManagement'; import AsyncCallbackWrapper from './utils/AbilityUtils'; import AbilityStartCallback from 'application.AbilityStartCallback'; +import StartOptions from '@ohos.app.ability.StartOptions'; import uiExtension from '@ohos.arkui.uiExtension'; +import Want from '@ohos.app.ability.Want'; class Cleaner { static callback(cleaner: Cleaner): void { @@ -62,6 +64,7 @@ export default class UIExtensionContentSession { native terminateSelfWithResultSync(parameter: AbilityResult, callback:AsyncCallbackWrapper): void; private native nativeStartAbilityByTypeSync(type: string, wantParam: Record, startCallback: AbilityStartCallback): BusinessError; native nativeSetWindowPrivacyMode(isPrivacyMode: boolean, callback:AsyncCallbackWrapper): void; + native nativeStartAbilityAsCaller(want: Want, callback: AsyncCallbackWrapper, options?: StartOptions): void; sendData(data: Record): void { this.nativeSendData(data); @@ -179,4 +182,39 @@ export default class UIExtensionContentSession { this.nativeSetWindowPrivacyMode(isPrivacyMode, asyncCall); }); } + + startAbilityAsCaller(want: Want, callback: AsyncCallback): void { + let asyncCallback = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartAbilityAsCaller(want, asyncCallback, undefined); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + startAbilityAsCaller(want: Want, options: StartOptions, callback: AsyncCallback): void { + let asyncCallback = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartAbilityAsCaller(want, asyncCallback, options); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + startAbilityAsCaller(want: Want, options?: StartOptions): Promise { + return new Promise((resolve: (data: undefined) => void, reject: (err: BusinessError) => void): void => { + let asyncCallback = new AsyncCallbackWrapper((err: BusinessError | null) => { + if (err == null || err.code == 0) { + resolve(undefined); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeStartAbilityAsCaller(want, asyncCallback, options); + }).catch((err: Error): void => { + reject(err as BusinessError); + }); + }); + } } diff --git a/frameworks/ets/ets/application/UIAbilityContext.ets b/frameworks/ets/ets/application/UIAbilityContext.ets index 6cacb80bdb732625bbad23c8850cbe24305f3627..29f95b9c2690e814958b3e06af313db96517ade9 100644 --- a/frameworks/ets/ets/application/UIAbilityContext.ets +++ b/frameworks/ets/ets/application/UIAbilityContext.ets @@ -173,6 +173,10 @@ export default class UIAbilityContext extends Context { private native nativeStartAbilityForResultWithAccountResult(want: Want, accountId: int, options: StartOptions, callback: AsyncCallbackWrapper): void; + private native nativeStartAbilityAsCaller(want: Want, callback: AsyncCallbackWrapper, options?: StartOptions): void; + + private native nativeStartRecentAbility(want: Want, callback: AsyncCallbackWrapper, options?: StartOptions): void; + startAbility(want: Want, callback: AsyncCallback): void { let myCall = new AsyncCallbackWrapper(callback); taskpool.execute((): void => { @@ -774,4 +778,74 @@ hideAbility(): Promise { }); return p; } + + startAbilityAsCaller(want: Want, callback: AsyncCallback): void { + let asyncCallback = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartAbilityAsCaller(want, asyncCallback, undefined); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + startAbilityAsCaller(want: Want, options: StartOptions, callback: AsyncCallback): void { + let asyncCallback = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartAbilityAsCaller(want, asyncCallback, options); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + startAbilityAsCaller(want: Want, options?: StartOptions): Promise { + return new Promise((resolve: (data: undefined) => void, reject: (err: BusinessError) => void): void => { + let asyncCallback = new AsyncCallbackWrapper((err: BusinessError | null) => { + if (err == null || err.code == 0) { + resolve(undefined); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeStartAbilityAsCaller(want, asyncCallback, options); + }).catch((err: Error): void => { + reject(err as BusinessError); + }); + }); + } + + startRecentAbility(want: Want, callback: AsyncCallback): void { + let asyncCallback = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartRecentAbility(want, asyncCallback, undefined); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + startRecentAbility(want: Want, options: StartOptions, callback: AsyncCallback): void { + let asyncCallback = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartRecentAbility(want, asyncCallback, options); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + startRecentAbility(want: Want, options?: StartOptions): Promise { + return new Promise((resolve: (data: undefined) => void, reject: (err: BusinessError) => void): void => { + let asyncCallback = new AsyncCallbackWrapper((err: BusinessError | null) => { + if (err == null || err.code == 0) { + resolve(undefined); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeStartRecentAbility(want, asyncCallback, options); + }).catch((err: Error): void => { + reject(err as BusinessError); + }); + }); + } }