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 b37261f2bb61a0505f283bd8ef35b9ea495f23ef..173eb4454f9f9fcb7949cc960d5772f47774591c 100644 --- a/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp +++ b/frameworks/ets/ani/ui_ability/src/ets_ability_context.cpp @@ -55,6 +55,9 @@ constexpr const char *SIGNATURE_ONDISCONNECT = "LbundleManager/ElementName/Eleme constexpr const char *SIGNATURE_CONNECT_SERVICE_EXTENSION = "L@ohos/app/ability/Want/Want;Lability/connectOptions/ConnectOptions;:D"; constexpr const char *SIGNATURE_DISCONNECT_SERVICE_EXTENSION = "DLutils/AbilityUtils/AsyncCallbackWrapper;:V"; +constexpr const char *SIGNATURE_START_ABILITY_BY_TYPE = + "Lstd/core/String;Lescompat/Record;Lapplication/AbilityStartCallback/AbilityStartCallback;:L@ohos/base/" + "BusinessError;"; int64_t RequestCodeFromStringToInt64(const std::string &requestCode) { @@ -990,10 +993,13 @@ ani_object EtsAbilityContext::OnStartAbilityByType( #ifdef SUPPORT_SCREEN innerErrCode = context->StartAbilityByType(type, wantParam, callback); #endif - if (innerErrCode != ERR_OK) { + if (innerErrCode == ERR_OK) { + return EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_OK); + } else if (innerErrCode == static_cast(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)) { + return EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + } else { return EtsErrorUtil::CreateErrorByNativeErr(env, innerErrCode); } - return aniObject; } void EtsAbilityContext::AddFreeInstallObserver(ani_env *env, const AAFwk::Want &want, ani_object callback, @@ -1173,7 +1179,7 @@ bool BindNativeMethods(ani_env *env, ani_class &cls) ani_native_function {"nativeSetColorMode", "L@ohos/app/ability/ConfigurationConstant/ConfigurationConstant/ColorMode;:V", reinterpret_cast(EtsAbilityContext::SetColorMode)}, - ani_native_function { "nativeStartAbilityByTypeSync", nullptr, + ani_native_function { "nativeStartAbilityByTypeSync", SIGNATURE_START_ABILITY_BY_TYPE, reinterpret_cast(EtsAbilityContext::StartAbilityByType) }, }; if ((status = env->Class_BindNativeMethods(cls, functions.data(), functions.size())) != ANI_OK) { 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 ca31238eb4a7dcee77b523fe5fc93dc3fd15e1fd..3764a0551c2b0358055902a20af8bd4c01085d73 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 @@ -115,6 +115,9 @@ private: bool isSyncRegistered_ = false; std::shared_ptr listener_; bool isFirstTriggerBindModal_ = true; +#ifdef SUPPORT_SCREEN + void InitDisplayId(AAFwk::Want &want); +#endif }; } // namespace AbilityRuntime 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 85647e9297957a71f1c98c1c8e7260dbe4f94dc3..22f62d73ba0118993b5d6a80ec9c2ed4686d7a10 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 @@ -36,12 +36,18 @@ namespace OHOS { namespace AbilityRuntime { - +namespace { constexpr int32_t ERR_FAILURE = -1; const char* UI_EXTENSION_CONTENT_SESSION_CLASS_NAME = "L@ohos/app/ability/UIExtensionContentSession/UIExtensionContentSession;"; const char* UI_EXTENSION_CONTENT_SESSION_CLEANER_CLASS_NAME = "L@ohos/app/ability/UIExtensionContentSession/Cleaner;"; +const std::string UIEXTENSION_TARGET_TYPE_KEY = "ability.want.params.uiExtensionTargetType"; +const std::string FLAG_AUTH_READ_URI_PERMISSION = "ability.want.params.uriPermissionFlag"; +constexpr const char *SIGNATURE_START_ABILITY_BY_TYPE = + "Lstd/core/String;Lescompat/Record;Lapplication/AbilityStartCallback/AbilityStartCallback;:L@ohos/base/" + "BusinessError;"; +} // namespace EtsUIExtensionContentSession* EtsUIExtensionContentSession::GetEtsContentSession(ani_env *env, ani_object obj) { @@ -276,7 +282,9 @@ ani_object EtsUIExtensionContentSession::CreateEtsUIExtensionContentSession(ani_ ani_native_function {"nativeSetReceiveDataCallback", nullptr, reinterpret_cast(EtsUIExtensionContentSession::NativeSetReceiveDataCallback)}, ani_native_function {"nativeSetReceiveDataForResultCallback", nullptr, - reinterpret_cast(EtsUIExtensionContentSession::NativeSetReceiveDataForResultCallback)} + reinterpret_cast(EtsUIExtensionContentSession::NativeSetReceiveDataForResultCallback)}, + ani_native_function {"nativeStartAbilityByTypeSync", SIGNATURE_START_ABILITY_BY_TYPE, + reinterpret_cast(EtsUIExtensionContentSession::NativeStartAbilityByTypeSync)} }; status = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); if (status != ANI_OK) { @@ -605,27 +613,43 @@ ani_object EtsUIExtensionContentSession::StartAbilityByTypeSync( env, "Parameter error: Failed to parse wantParam, must be a Record."); return aniObject; } - + wantParam.SetParam(UIEXTENSION_TARGET_TYPE_KEY, AAFwk::String::Box(type)); + AAFwk::Want want; + want.SetParams(wantParam); + if (wantParam.HasParam(FLAG_AUTH_READ_URI_PERMISSION)) { + want.SetFlags(wantParam.GetIntParam(FLAG_AUTH_READ_URI_PERMISSION, 0)); + wantParam.Remove(FLAG_AUTH_READ_URI_PERMISSION); + } +#ifdef SUPPORT_SCREEN + InitDisplayId(want); +#endif ani_vm *vm = nullptr; if (env->GetVM(&vm) != ANI_OK) { TAG_LOGE(AAFwkTag::UI_EXT, "get vm failed"); EtsErrorUtil::ThrowInvalidParamError(env, "Get vm failed."); return aniObject; } - ErrCode innerErrCode = ERR_OK; - std::shared_ptr callback = std::make_shared(vm); - callback->SetEtsCallbackObject(startCallback); - auto context = AbilityRuntime::Context::ConvertTo(context_.lock()); - if (!context) { - TAG_LOGE(AAFwkTag::UI_EXT, "null context"); - return EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT); + std::shared_ptr uiExtensionCallback = std::make_shared(vm); + uiExtensionCallback->SetEtsCallbackObject(startCallback); + if (uiWindow_ == nullptr || uiWindow_->GetUIContent() == nullptr) { + return aniObject; } #ifdef SUPPORT_SCREEN - innerErrCode = context->StartAbilityByType(type, wantParam, callback); -#endif - if (innerErrCode != ERR_OK) { - return EtsErrorUtil::CreateErrorByNativeErr(env, innerErrCode); + Ace::ModalUIExtensionCallbacks callback; + callback.onError = [uiExtensionCallback](int arg, const std::string &str1, const std::string &str2) { + uiExtensionCallback->OnError(arg); + }; + callback.onRelease = [uiExtensionCallback](const auto &arg) { uiExtensionCallback->OnRelease(arg); }; + Ace::ModalUIExtensionConfig config; + int32_t sessionId = uiWindow_->GetUIContent()->CreateModalUIExtension(want, callback, config); + if (sessionId == 0) { + return aniObject; + } else { + uiExtensionCallback->SetUIContent(uiWindow_->GetUIContent()); + uiExtensionCallback->SetSessionId(sessionId); + return EtsErrorUtil::CreateError(env, AbilityErrorCode::ERROR_OK); } +#endif // SUPPORT_SCREEN return aniObject; } @@ -679,5 +703,24 @@ sptr EtsUIExtensionContentSession::GetUIWindow() { return uiWindow_; } +#ifdef SUPPORT_SCREEN +void EtsUIExtensionContentSession::InitDisplayId(AAFwk::Want &want) +{ + auto context = AbilityRuntime::Context::ConvertTo(context_.lock()); + if (!context) { + TAG_LOGE(AAFwkTag::UI_EXT, "null context"); + return; + } + + auto window = context->GetWindow(); + if (window == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null window"); + return; + } + + TAG_LOGI(AAFwkTag::UI_EXT, "window displayId %{public}" PRIu64, window->GetDisplayId()); + want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast(window->GetDisplayId())); +} +#endif } // namespace AbilityRuntime -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/ets/ani/ui_extension_callback/include/ets_ui_extension_callback.h b/frameworks/ets/ani/ui_extension_callback/include/ets_ui_extension_callback.h index a78332203125eb842f56131aa46bc518d93694ab..8dd295dd828549d1c7a593bc86634afd6ed80bde 100644 --- a/frameworks/ets/ani/ui_extension_callback/include/ets_ui_extension_callback.h +++ b/frameworks/ets/ani/ui_extension_callback/include/ets_ui_extension_callback.h @@ -32,10 +32,11 @@ public: private: ani_env *GetAniEnv(); + void CallObjectMethod(const char *name, const char *signature, ...); ani_vm *vm_ = nullptr; ani_ref callback_ = nullptr; }; } // namespace AbilityRuntime } // namespace OHOS -#endif // OHOS_ABILITY_RUNTIME_ETS_UI_EXTENSION_CALLBACK_H \ No newline at end of file +#endif // OHOS_ABILITY_RUNTIME_ETS_UI_EXTENSION_CALLBACK_H diff --git a/frameworks/ets/ani/ui_extension_callback/src/ets_ui_extension_callback.cpp b/frameworks/ets/ani/ui_extension_callback/src/ets_ui_extension_callback.cpp index 342f332d5bd24285d895728d5c30d9a3b5075a96..e1f165398bdf80a466f5cebb424f299d049a138f 100644 --- a/frameworks/ets/ani/ui_extension_callback/src/ets_ui_extension_callback.cpp +++ b/frameworks/ets/ani/ui_extension_callback/src/ets_ui_extension_callback.cpp @@ -49,22 +49,6 @@ EtsUIExtensionCallback::~EtsUIExtensionCallback() void EtsUIExtensionCallback::OnError(int32_t number) { TAG_LOGD(AAFwkTag::UI_EXT, "call"); - auto env = GetAniEnv(); - if (env == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "null env"); - return; - } - ani_status status = ANI_ERROR; - ani_class clsCall = nullptr; - if ((status = env->FindClass(ABILITY_START_CLASS_NAME, &clsCall)) != ANI_OK || clsCall == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "find AbilityStartCallback class failed, status: %{public}d, or null cls", status); - return; - } - ani_method method = nullptr; - if ((status = env->Class_FindMethod(clsCall, "onError", nullptr, &method)) != ANI_OK || method == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "find onError method failed, status: %{public}d, or null method", status); - return; - } std::string name; std::string message; #ifdef SUPPORT_SCREEN @@ -74,21 +58,23 @@ void EtsUIExtensionCallback::OnError(int32_t number) message = "StartAbilityByType failed."; } #endif // SUPPORT_SCREEN - ani_string aniName; - if ((status = env->String_NewUTF8(name.c_str(), name.length(), &aniName)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UI_EXT, "String_NewUTF8 failed, status: %{public}d", status); + auto env = GetAniEnv(); + if (env == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null env"); return; } - ani_string aniMsg; - if ((status = env->String_NewUTF8(message.c_str(), message.length(), &aniMsg)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UI_EXT, "String_NewUTF8 failed, status: %{public}d", status); + ani_string aniName = nullptr; + ani_status status = env->String_NewUTF8(name.c_str(), name.length(), &aniName); + if (status != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "aniName String_NewUTF8 failed, status: %{public}d", status); return; } - if ((status = env->Object_CallMethod_Void(reinterpret_cast(callback_), - method, (ani_double)number, aniName, aniMsg)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UI_EXT, "call onError method failed, status: %{public}d", status); + ani_string aniMsg = nullptr; + if ((status = env->String_NewUTF8(message.c_str(), message.length(), &aniMsg)) != ANI_OK) { + TAG_LOGE(AAFwkTag::UI_EXT, "aniMsg String_NewUTF8 failed, status: %{public}d", status); return; } + CallObjectMethod("onError", nullptr, (ani_double)number, aniName, aniMsg); CloseModalUIExtension(); } @@ -96,30 +82,47 @@ void EtsUIExtensionCallback::OnResult(int32_t resultCode, const AAFwk::Want &wan { TAG_LOGD(AAFwkTag::UI_EXT, "call"); auto env = GetAniEnv(); - if (env == nullptr || callback_ == nullptr) { + if (env == nullptr) { TAG_LOGE(AAFwkTag::UI_EXT, "null env"); return; } - ani_status status = ANI_ERROR; - ani_object startCallback = reinterpret_cast(callback_); - ani_ref onResultRef {}; - if ((status = env->Object_GetPropertyByName_Ref(startCallback, "onResult", &onResultRef)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UI_EXT, "get onResult failed, status: %{public}d", status); - return; - } - ani_fn_object onResultFn = reinterpret_cast(onResultRef); ani_object abilityResultObj = AppExecFwk::WrapAbilityResult(env, resultCode, want); if (abilityResultObj == nullptr) { TAG_LOGE(AAFwkTag::UI_EXT, "create abilityResultObj failed"); return; } - ani_ref argv[] = { abilityResultObj }; - ani_ref result; - if ((status = env->FunctionalObject_Call(onResultFn, 1, argv, &result)) != ANI_OK) { - TAG_LOGE(AAFwkTag::UI_EXT, "call onResult fn failed, status: %{public}d", status); + CallObjectMethod("onResult", nullptr, abilityResultObj); + CloseModalUIExtension(); +} + +void EtsUIExtensionCallback::CallObjectMethod(const char *name, const char *signature, ...) +{ + TAG_LOGD(AAFwkTag::EXT, "name: %{public}s", name); + auto env = GetAniEnv(); + if (env == nullptr || callback_ == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "null env or callback_"); return; } - CloseModalUIExtension(); + ani_class clsCall = nullptr; + ani_status status = env->FindClass(ABILITY_START_CLASS_NAME, &clsCall); + if (status != ANI_OK || clsCall == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "find AbilityStartCallback class failed, status: %{public}d, or null cls", status); + return; + } + ani_method method = nullptr; + if ((status = env->Class_FindMethod(clsCall, name, signature, &method)) != ANI_OK || method == nullptr) { + TAG_LOGE(AAFwkTag::UI_EXT, "find onError method failed, status: %{public}d, or null method", status); + env->ResetError(); + return; + } + va_list args; + va_start(args, signature); + if ((status = env->Object_CallMethod_Void_V(reinterpret_cast(callback_), method, args)) != ANI_OK) { + TAG_LOGE(AAFwkTag::EXT, "Object_CallMethod name: %{public}s, status: %{public}d", name, status); + return; + } + va_end(args); + TAG_LOGI(AAFwkTag::EXT, "CallObjectMethod end, name: %{public}s", name); } void EtsUIExtensionCallback::SetEtsCallbackObject(ani_object aniObject) @@ -155,4 +158,4 @@ ani_env* EtsUIExtensionCallback::GetAniEnv() return env; } } // namespace AbilityRuntime -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets b/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets index 93d3ddb92c49f8b4e0da105e74dbaf5c8b8f9c3d..266dbed17a1cbe272dda6f47f28733f3be3d2845 100644 --- a/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets +++ b/frameworks/ets/ets/@ohos.app.ability.UIExtensionContentSession.ets @@ -125,7 +125,11 @@ export default class UIExtensionContentSession { }); p1.then((e: NullishType) => { let retError = e as BusinessError; - callback(retError, undefined); + if (retError.code === 0) { + callback(null, undefined); + } else { + callback(retError, undefined); + } }, (err: Error): void => { callback(err as BusinessError, undefined); }); diff --git a/frameworks/ets/ets/application/AbilityStartCallback.ets b/frameworks/ets/ets/application/AbilityStartCallback.ets index a076f91f8948048f62fffd2d504c3c7b5a073a03..403bce00b6ea5a1119dd9505b6a06ec1a1a1bbb2 100644 --- a/frameworks/ets/ets/application/AbilityStartCallback.ets +++ b/frameworks/ets/ets/application/AbilityStartCallback.ets @@ -18,5 +18,5 @@ import { AbilityResult } from 'ability.abilityResult'; export default interface AbilityStartCallback { onError(code: number, name: string, message: string): void; - onResult?: (parameter: AbilityResult) => void; + onResult(parameter: AbilityResult): void; } diff --git a/frameworks/ets/ets/application/UIAbilityContext.ets b/frameworks/ets/ets/application/UIAbilityContext.ets index d10042859a7d18d10585b3abdb2aabd407d64ce6..f37db568aafab4b73b1ecf508386099005ef58c7 100644 --- a/frameworks/ets/ets/application/UIAbilityContext.ets +++ b/frameworks/ets/ets/application/UIAbilityContext.ets @@ -424,7 +424,11 @@ export default class UIAbilityContext extends Context { }); p1.then((e: NullishType) => { let retError = e as BusinessError; - callback(retError, undefined); + if (retError.code === 0) { + callback(null, undefined); + } else { + callback(retError, undefined); + } }, (err: Error): void => { callback(err as BusinessError, undefined); }); diff --git a/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp b/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp index c25cacc3d1e4be3ec15015487f001c288120cff5..56174788d251b42a36aac42e8e492555687ab245 100755 --- a/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp +++ b/frameworks/native/ability/native/ui_extension_base/ui_extension_context.cpp @@ -305,56 +305,6 @@ Ace::UIContent* UIExtensionContext::GetUIContent() } return window_->GetUIContent(); } - -ErrCode UIExtensionContext::StartAbilityByType( - const std::string &type, AAFwk::WantParams &wantParam, std::shared_ptr uiExtensionCallback) -{ - TAG_LOGD(AAFwkTag::UI_EXT, "StartAbilityByType call"); - auto uiContent = GetUIContent(); - if (uiContent == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "null uiContent"); - return static_cast(AbilityErrorCode::ERROR_CODE_INNER); - } - wantParam.SetParam(UIEXTENSION_TARGET_TYPE_KEY, AAFwk::String::Box(type)); - AAFwk::Want want; - want.SetParams(wantParam); - if (wantParam.HasParam(FLAG_AUTH_READ_URI_PERMISSION)) { - want.SetFlags(wantParam.GetIntParam(FLAG_AUTH_READ_URI_PERMISSION, 0)); - wantParam.Remove(FLAG_AUTH_READ_URI_PERMISSION); - } - auto window = GetWindow(); - if (window == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "null window"); - return static_cast(AbilityErrorCode::ERROR_CODE_INNER); - } - TAG_LOGI(AAFwkTag::UI_EXT, "window displayId %{public}" PRIu64, window->GetDisplayId()); - want.SetParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, static_cast(window->GetDisplayId())); - - Ace::ModalUIExtensionCallbacks callback; - if (uiExtensionCallback == nullptr) { - TAG_LOGE(AAFwkTag::UI_EXT, "null uiExtensionCallback"); - return static_cast(AbilityErrorCode::ERROR_CODE_INNER); - } - callback.onError = [uiExtensionCallback](int32_t arg, const std::string &str1, const std::string &str2) { - uiExtensionCallback->OnError(arg); - }; - callback.onRelease = [uiExtensionCallback](int32_t arg) { - uiExtensionCallback->OnRelease(arg); - }; - callback.onResult = [uiExtensionCallback](int32_t arg1, const OHOS::AAFwk::Want arg2) { - uiExtensionCallback->OnResult(arg1, arg2); - }; - - Ace::ModalUIExtensionConfig config; - int32_t sessionId = uiContent->CreateModalUIExtension(want, callback, config); - if (sessionId == 0) { - TAG_LOGE(AAFwkTag::UI_EXT, "createModalUIExtension failed"); - return static_cast(AbilityErrorCode::ERROR_CODE_INNER); - } - uiExtensionCallback->SetUIContent(uiContent); - uiExtensionCallback->SetSessionId(sessionId); - return ERR_OK; -} #endif // SUPPORT_SCREEN ErrCode UIExtensionContext::OpenAtomicService(AAFwk::Want& want, const AAFwk::StartOptions &options, int requestCode, RuntimeTask &&task) diff --git a/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h b/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h index 043983fe4c166a5204d033303640ceecc7f9c042..e1d2c24f7e9db98fdd20cd626983676fdb024ea4 100755 --- a/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h +++ b/interfaces/kits/native/ability/native/ui_extension_base/ui_extension_context.h @@ -22,7 +22,6 @@ #include "extension_context.h" #include "free_install_observer_interface.h" #include "start_options.h" -#include "ui_extension_callback.h" #include "ui_holder_extension_context.h" #include "want.h" #include "js_ui_extension_callback.h" @@ -173,8 +172,6 @@ public: sptr GetWindow(); Ace::UIContent* GetUIContent() override; - ErrCode StartAbilityByType(const std::string &type, AAFwk::WantParams &wantParam, - const std::shared_ptr uiExtensionCallback); #endif // SUPPORT_SCREEN ErrCode OpenLink(const AAFwk::Want& want, int reuqestCode);