diff --git a/frameworks/ets/ani/ui_extension_ability/include/sts_ui_extension_context.h b/frameworks/ets/ani/ui_extension_ability/include/sts_ui_extension_context.h index 95d68fc2ac7f7c9e7a9de4dbf58641af6f4b906c..72e3db4a9102647f9679d864af7b91d9e615a9c9 100644 --- a/frameworks/ets/ani/ui_extension_ability/include/sts_ui_extension_context.h +++ b/frameworks/ets/ani/ui_extension_ability/include/sts_ui_extension_context.h @@ -49,6 +49,8 @@ public: ani_object callback, UIExtensionContext* context); static void NativeSetColorMode(ani_env *env, ani_object aniCls, ani_enum_item aniColorMode); static void NativeReportDrawnCompleted(ani_env *env, ani_object aniCls, ani_object callback); + void StartAbilityForResultInner(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object startOptinsObj, ani_object callback); private: sptr freeInstallObserver_ = nullptr; }; diff --git a/frameworks/ets/ani/ui_extension_ability/src/sts_ui_extension_context.cpp b/frameworks/ets/ani/ui_extension_ability/src/sts_ui_extension_context.cpp index 0d652b15eaad374b8f206deb58daba9ea6473457..cfdca49d4f47c4a5281353abcf185f54e85ad560 100644 --- a/frameworks/ets/ani/ui_extension_ability/src/sts_ui_extension_context.cpp +++ b/frameworks/ets/ani/ui_extension_ability/src/sts_ui_extension_context.cpp @@ -23,6 +23,7 @@ #include "ani_common_start_options.h" #include "ani_common_util.h" #include "ani_enum_convert.h" +#include "ani_common_ability_result.h" namespace OHOS { namespace AbilityRuntime { @@ -110,6 +111,19 @@ static void StartAbilityWithOption([[maybe_unused]] ani_env *env, [[maybe_unused StsUIExtensionContext::GetInstance().StartAbilityInner(env, aniObj, wantObj, opt, call); } +static void StartAbilityForResult(ani_env *env, ani_object aniObj, ani_object wantObj, ani_object callback) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "called"); + StsUIExtensionContext::GetInstance().StartAbilityForResultInner(env, aniObj, wantObj, nullptr, callback); +} + +static void StartAbilityForResultWithOptions(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object startOptionsObj, ani_object callback) +{ + TAG_LOGD(AAFwkTag::UI_EXT, "called"); + StsUIExtensionContext::GetInstance().StartAbilityForResultInner(env, aniObj, wantObj, startOptionsObj, callback); +} + UIExtensionContext* StsUIExtensionContext::GetAbilityContext(ani_env *env, ani_object obj) { TAG_LOGD(AAFwkTag::UI_EXT, "GetAbilityContext start"); @@ -223,6 +237,59 @@ void StsUIExtensionContext::StartAbilityInner([[maybe_unused]] ani_env *env, [[m } } +void StsUIExtensionContext::StartAbilityForResultInner(ani_env *env, ani_object aniObj, ani_object wantObj, + ani_object startOptionsObj, ani_object callback) +{ + auto context = StsUIExtensionContext::GetAbilityContext(env, aniObj); + if (env == nullptr || context == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "env is nullptr or GetAbilityContext is nullptr"); + ThrowStsErrorByNativeErr(env, static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)); + return; + } + + AAFwk::Want want; + OHOS::AppExecFwk::UnwrapWant(env, wantObj, want); + AAFwk::StartOptions startOptions; + if (startOptionsObj) { + OHOS::AppExecFwk::UnwrapStartOptions(env, startOptionsObj, startOptions); + } + + ani_ref callbackRef = nullptr; + env->GlobalReference_Create(callback, &callbackRef); + ani_vm *etsVm = nullptr; + ani_status status = ANI_ERROR; + if ((status = env->GetVM(&etsVm)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status); + return; + } + RuntimeTask task = [etsVm, callbackRef] + (int resultCode, const AAFwk::Want &want, bool isInner) { + TAG_LOGD(AAFwkTag::UI_EXT, "start async callback"); + ani_status status = ANI_ERROR; + ani_env *env = nullptr; + if ((status = etsVm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status); + return; + } + + ani_object abilityResult = AppExecFwk::WrapAbilityResult(env, resultCode, want); + if (abilityResult == nullptr) { + TAG_LOGW(AAFwkTag::UI_EXT, "null abilityResult"); + isInner = true; + resultCode = ERR_INVALID_VALUE; + } + auto errCode = isInner ? resultCode : 0; + AppExecFwk::AsyncCallback(env, reinterpret_cast(callbackRef), + OHOS::AbilityRuntime::CreateStsErrorByNativeErr(env, errCode), abilityResult); + }; + auto requestCode = context->GenerateCurRequestCode(); + (startOptionsObj == nullptr) ? context->StartAbilityForResult(want, requestCode, std::move(task)) + : context->StartAbilityForResult(want, startOptions, requestCode, std::move(task)); + env->GlobalReference_Delete(callbackRef); + return; +} + + void StsUIExtensionContext::NativeSetColorMode(ani_env *env, ani_object aniContext, ani_enum_item aniColorMode) { TAG_LOGD(AAFwkTag::UI_EXT, "NativeSetColorMode called"); @@ -284,7 +351,14 @@ bool BindNativeMethods(ani_env *env, ani_class &cls) ani_native_function { "setColorMode", nullptr, reinterpret_cast(StsUIExtensionContext::NativeSetColorMode)}, ani_native_function { "nativeReportDrawnCompleted", nullptr, - reinterpret_cast(StsUIExtensionContext::NativeReportDrawnCompleted)} + reinterpret_cast(StsUIExtensionContext::NativeReportDrawnCompleted)}, + ani_native_function { "nativeStartAbilityForResult", + "L@ohos/app/ability/Want/Want;Lutils/AbilityUtils/AsyncCallbackWrapper;:V", + reinterpret_cast(StartAbilityForResult) }, + ani_native_function { "nativeStartAbilityForResult", + "L@ohos/app/ability/Want/Want;L@ohos/app/ability/StartOptions/StartOptions;Lutils/AbilityUtils/" + "AsyncCallbackWrapper;:V", + reinterpret_cast(StartAbilityForResultWithOptions) } }; if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) { TAG_LOGE(AAFwkTag::UI_EXT, "status: %{public}d", status); diff --git a/frameworks/ets/ets/application/UIExtensionContext.ets b/frameworks/ets/ets/application/UIExtensionContext.ets index 565278a9ddb11e9a304a76a3e664b5e85e206e42..c9ea566bcf0cf2d0b88aa459077698bb49eaebac 100644 --- a/frameworks/ets/ets/application/UIExtensionContext.ets +++ b/frameworks/ets/ets/application/UIExtensionContext.ets @@ -27,6 +27,8 @@ export default class UIExtensionContext extends ExtensionContext { native terminateSelfWithResultSync(parameter: AbilityResult, callback: AsyncCallbackWrapper): void; private native nativeStartAbilitySync(want: Want, callback: AsyncCallbackWrapper): void; private native nativeStartAbilitySync(want: Want, options: StartOptions, callback:AsyncCallbackWrapper): void; + private native nativeStartAbilityForResult(want: Want, callback:AsyncCallbackWrapper): void; + private native nativeStartAbilityForResult(want: Want, startOptions: StartOptions, callback:AsyncCallbackWrapper): void; terminateSelf(callback:AsyncCallback): void { let myCall = new AsyncCallbackWrapper(callback); @@ -114,4 +116,50 @@ export default class UIExtensionContext extends ExtensionContext { this.nativeReportDrawnCompleted(myCall); }); } + + startAbilityForResult(want: Want, callback: AsyncCallback): void { + let myCall = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartAbilityForResult(want, myCall); + }); + } + + startAbilityForResult(want: Want, startOptions: StartOptions, callback: AsyncCallback): void { + let myCall = new AsyncCallbackWrapper(callback); + taskpool.execute((): void => { + this.nativeStartAbilityForResult(want, startOptions, myCall); + }); + } + + startAbilityForResult(want: Want): Promise{ + let p = new Promise((resolve: (data: AbilityResult)=>void, reject:(err: BusinessError)=>void):void => { + let myCall = new AsyncCallbackWrapper((err: BusinessError, data: AbilityResult)=>{ + if (err.code == 0) { + resolve(data); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeStartAbilityForResult(want, myCall); + }); + }); + return p; + } + + startAbilityForResult(want: Want, startOptions: StartOptions): Promise { + let p = new Promise((resolve: (data: AbilityResult)=>void, reject:(err: BusinessError)=>void):void => { + let myCall = new AsyncCallbackWrapper((err: BusinessError, data: AbilityResult)=>{ + if (err.code == 0) { + resolve(data); + } else { + reject(err); + } + }); + taskpool.execute((): void => { + this.nativeStartAbilityForResult(want, startOptions, myCall); + }); + }); + return p; + } } \ No newline at end of file