diff --git a/frameworks/js/napi/ability_context/ability_context.js b/frameworks/js/napi/ability_context/ability_context.js index 5520e1c41d..19a07430e4 100644 --- a/frameworks/js/napi/ability_context/ability_context.js +++ b/frameworks/js/napi/ability_context/ability_context.js @@ -182,6 +182,11 @@ class AbilityContext extends Context { reportDrawnCompleted(callback) { return this.__context_impl__.reportDrawnCompleted(callback); } + + startAbilityByType(type, wantParam, abilityStartCallback, callback) { + return this.__context_impl__.startAbilityByType(type, wantParam, abilityStartCallback, callback); + } + } export default AbilityContext; diff --git a/frameworks/native/ability/BUILD.gn b/frameworks/native/ability/BUILD.gn index 975fa04cce..6c2f2139f6 100644 --- a/frameworks/native/ability/BUILD.gn +++ b/frameworks/native/ability/BUILD.gn @@ -52,22 +52,26 @@ ohos_shared_library("ability_context_native") { "ability_runtime/js_extension_context.cpp", "ability_runtime/local_call_container.cpp", "ability_runtime/local_call_record.cpp", + "native/js_ui_extension_callback.cpp", ] deps = [ "${ability_runtime_innerkits_path}/ability_manager:ability_manager", "${ability_runtime_innerkits_path}/deps_wrapper:ability_deps_wrapper", "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_napi_path}/inner/napi_common:napi_common", "${ability_runtime_native_path}/ability/native:dialog_request_callback", "${ability_runtime_native_path}/appkit:app_context", "${ability_runtime_native_path}/appkit:app_context_utils", ] external_deps = [ + "ability_base:base", "ability_base:session_info", "ability_base:want", "access_token:libaccesstoken_sdk", "access_token:libtoken_callback_sdk", + "ace_engine:ace_uicontent", "c_utils:utils", "common_event_service:cesfwk_innerkits", "faultloggerd:libdfx_dumpcatcher", @@ -78,6 +82,7 @@ ohos_shared_library("ability_context_native") { "napi:ace_napi", "window_manager:libwsutils", "window_manager:scene_session", + "window_manager:session_manager", ] innerapi_tags = [ "platformsdk" ] diff --git a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp index be51ae65ce..7d8c4a2f8a 100644 --- a/frameworks/native/ability/ability_runtime/ability_context_impl.cpp +++ b/frameworks/native/ability/ability_runtime/ability_context_impl.cpp @@ -28,12 +28,14 @@ #include "session/host/include/zidl/session_interface.h" #include "session_info.h" #include "string_wrapper.h" +#include "ui_content.h" #include "want_params_wrapper.h" namespace OHOS { namespace AbilityRuntime { const size_t AbilityContext::CONTEXT_TYPE_ID(std::hash {} ("AbilityContext")); const std::string START_ABILITY_TYPE = "ABILITY_INNER_START_WITH_ACCOUNT"; +const std::string UIEXTENSION_TARGET_TYPE_KEY = "ability.want.params.uiExtensionTargetType"; struct RequestResult { int32_t resultCode {0}; @@ -732,6 +734,30 @@ Ace::UIContent* AbilityContextImpl::GetUIContent() return abilityCallback->GetUIContent(); } + +ErrCode AbilityContextImpl::StartAbilityByType(const std::string &type, + AAFwk::WantParams &wantParams, const std::shared_ptr &uiExtensionCallbacks) +{ + HILOG_DEBUG("call"); + auto uiContent = GetUIContent(); + if (uiContent == nullptr) { + HILOG_ERROR("uiContent is nullptr"); + return ERR_INVALID_VALUE; + } + wantParams.SetParam(UIEXTENSION_TARGET_TYPE_KEY, AAFwk::String::Box(type)); + AAFwk::Want want; + want.SetParams(wantParams); + Ace::ModalUIExtensionCallbacks callback; + callback.onError = std::bind(&JsUIExtensionCallback::OnError, uiExtensionCallbacks, std::placeholders::_1); + Ace::ModalUIExtensionConfig config; + config.isProhibitBack = true; + int32_t sessionId = uiContent->CreateModalUIExtension(want, callback, config); + if (sessionId == 0) { + HILOG_ERROR("CreateModalUIExtension is failed"); + return ERR_INVALID_VALUE; + } + return ERR_OK; +} #endif } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/ability/native/BUILD.gn b/frameworks/native/ability/native/BUILD.gn index 7ed619de36..ca1d9bbd6f 100644 --- a/frameworks/native/ability/native/BUILD.gn +++ b/frameworks/native/ability/native/BUILD.gn @@ -805,9 +805,11 @@ ohos_shared_library("ui_extension") { ] external_deps = [ + "ability_base:base", "ability_base:want", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", + "ace_engine:ace_uicontent", "c_utils:utils", "eventhandler:libeventhandler", "hilog:libhilog", 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 cf6d820e3c..62f16eac7a 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ability_context.cpp @@ -45,7 +45,10 @@ namespace OHOS { namespace AbilityRuntime { +constexpr int32_t INDEX_ZERO = 0; +constexpr int32_t INDEX_ONE = 1; constexpr int32_t INDEX_TWO = 2; +constexpr int32_t INDEX_THREE = 3; constexpr size_t ARGC_ZERO = 0; constexpr size_t ARGC_ONE = 1; constexpr size_t ARGC_TWO = 2; @@ -194,6 +197,11 @@ napi_value JsAbilityContext::IsTerminating(napi_env env, napi_callback_info info GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnIsTerminating); } +napi_value JsAbilityContext::StartAbilityByType(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityContext, OnStartAbilityByType); +} + void JsAbilityContext::ClearFailedCallConnection( const std::weak_ptr& abilityContext, const std::shared_ptr &callback) { @@ -1350,6 +1358,8 @@ napi_value CreateJsAbilityContext(napi_env env, std::shared_ptr JsAbilityContext::ReportDrawnCompleted); BindNativeFunction(env, object, "setMissionContinueState", moduleName, JsAbilityContext::SetMissionContinueState); + BindNativeFunction(env, object, "startAbilityByType", moduleName, + JsAbilityContext::StartAbilityByType); #ifdef SUPPORT_GRAPHICS BindNativeFunction(env, object, "setMissionLabel", moduleName, JsAbilityContext::SetMissionLabel); @@ -1714,5 +1724,54 @@ napi_value JsAbilityContext::OnSetMissionIcon(napi_env env, NapiCallbackInfo& in return result; } #endif + +napi_value JsAbilityContext::OnStartAbilityByType(napi_env env, NapiCallbackInfo& info) +{ + HILOG_INFO("call"); + if (info.argc < ARGC_THREE) { + HILOG_ERROR("OnStartAbilityByType, Not enough params"); + ThrowTooFewParametersError(env); + return CreateJsUndefined(env); + } + + std::string type; + if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], type)) { + HILOG_ERROR("OnStartAbilityByType, parse type failed."); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + AAFwk::WantParams wantParam; + if (!AppExecFwk::UnwrapWantParams(env, info.argv[INDEX_ONE], wantParam)) { + HILOG_ERROR("OnStartAbilityByType, parse wantParam failed."); + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + std::shared_ptr callback = std::make_shared(env); + callback->SetJsCallbackObject(info.argv[INDEX_TWO]); + NapiAsyncTask::CompleteCallback complete = + [weak = context_, type, wantParam, callback](napi_env env, NapiAsyncTask& task, int32_t status) mutable { + auto context = weak.lock(); + if (!context) { + HILOG_WARN("OnStartAbilityByType context is released"); + task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT)); + return; + } + + auto errcode = context->StartAbilityByType(type, wantParam, callback); + if (errcode != 0) { + task.Reject(env, CreateJsErrorByNativeErr(env, errcode)); + } else { + task.ResolveWithNoError(env, CreateJsUndefined(env)); + } + }; + + napi_value lastParam = (info.argc > ARGC_THREE) ? info.argv[INDEX_THREE] : nullptr; + napi_value result = nullptr; + NapiAsyncTask::ScheduleHighQos("JsAbilityContext::OnStartAbilityByType", + env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result)); + return result; +} } // namespace AbilityRuntime } // namespace OHOS diff --git a/frameworks/native/ability/native/js_ui_extension_callback.cpp b/frameworks/native/ability/native/js_ui_extension_callback.cpp new file mode 100644 index 0000000000..9dc4871aab --- /dev/null +++ b/frameworks/native/ability/native/js_ui_extension_callback.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023 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 "js_ui_extension_callback.h" +#include "ability_business_error.h" +#include "hilog_wrapper.h" +#include "js_runtime_utils.h" +#include "napi/native_api.h" +#include "napi_common_util.h" +#include "ws_common.h" + +namespace OHOS { +namespace AbilityRuntime { +constexpr const char* ERROR_MSG_INNER = "Inner error."; +JsUIExtensionCallback::~JsUIExtensionCallback() +{ + if (jsCallbackObject_ == nullptr) { + return; + } + + uv_loop_t *loop = nullptr; + napi_get_uv_event_loop(env_, &loop); + if (loop == nullptr) { + return; + } + + uv_work_t *work = new (std::nothrow) uv_work_t; + if (work == nullptr) { + return; + } + work->data = reinterpret_cast(jsCallbackObject_.release()); + int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, + [](uv_work_t *work, int status) { + if (work == nullptr) { + return; + } + if (work->data == nullptr) { + delete work; + work = nullptr; + return; + } + delete reinterpret_cast(work->data); + work->data = nullptr; + delete work; + work = nullptr; + }); + if (ret != 0) { + delete reinterpret_cast(work->data); + work->data = nullptr; + delete work; + work = nullptr; + } +} + +void JsUIExtensionCallback::SetJsCallbackObject(napi_value jsCallbackObject) +{ + napi_ref ref = nullptr; + napi_create_reference(env_, jsCallbackObject, 1, &ref); + jsCallbackObject_ = std::unique_ptr(reinterpret_cast(ref)); + if (jsCallbackObject_ == nullptr) { + HILOG_ERROR("jsCallbackObject_ is nullptr"); + } +} + +void JsUIExtensionCallback::OnError(int32_t number) +{ + HILOG_INFO("call"); + if (env_ == nullptr) { + HILOG_ERROR("env_ null"); + return; + } + // js callback should run in js thread + std::shared_ptr jsUIExtensionCallback = shared_from_this(); + std::unique_ptr complete = std::make_unique + ([jsUIExtensionCallback, number](napi_env env, NapiAsyncTask &task, int32_t status) { + if (jsUIExtensionCallback != nullptr) { + jsUIExtensionCallback->CallJsError(number); + } + }); + napi_ref callback = nullptr; + std::unique_ptr execute = nullptr; + NapiAsyncTask::Schedule("JsUIExtensionCallback::OnError:", + env_, std::make_unique(callback, std::move(execute), std::move(complete))); +} + +void JsUIExtensionCallback::CallJsError(int32_t number) +{ + HILOG_INFO("call"); + if (env_ == nullptr) { + HILOG_ERROR("env_ is null, not call js error."); + return; + } + std::string name; + std::string message; + if (number != static_cast(Rosen::WSError::WS_OK)) { + number = static_cast(AbilityErrorCode::ERROR_CODE_INNER); + name = ERROR_MSG_INNER; + message = "StartAbilityByType failed."; + } + napi_value nativeNumber = CreateJsValue(env_, number); + napi_value nativeName = CreateJsValue(env_, name); + napi_value nativeMessage = CreateJsValue(env_, message); + if (jsCallbackObject_ == nullptr) { + HILOG_ERROR("jsCallbackObject_ is nullptr"); + return; + } + napi_value obj = jsCallbackObject_->GetNapiValue(); + if (obj == nullptr) { + HILOG_ERROR("Failed to get js object"); + return; + } + napi_value method = nullptr; + napi_get_named_property(env_, obj, "onError", &method); + if (method == nullptr || AppExecFwk::IsTypeForNapiValue(env_, method, napi_undefined) + || AppExecFwk::IsTypeForNapiValue(env_, method, napi_null)) { + HILOG_ERROR("Failed to get onError method from object"); + return; + } + + napi_value argv[] = { nativeNumber, nativeName, nativeMessage }; + napi_call_function(env_, obj, method, ArraySize(argv), argv, nullptr); + HILOG_INFO("end"); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_content_session.cpp b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_content_session.cpp index dc46c72263..8b12ddc283 100644 --- a/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_content_session.cpp +++ b/frameworks/native/ability/native/ui_extension_ability/js_ui_extension_content_session.cpp @@ -24,12 +24,14 @@ #include "js_error_utils.h" #include "js_runtime_utils.h" #include "js_ui_extension_context.h" +#include "string_wrapper.h" #include "napi_common_start_options.h" #include "napi_common_util.h" #include "napi_common_want.h" #include "native_engine.h" #include "native_value.h" #include "tokenid_kit.h" +#include "ui_content.h" #include "want.h" #include "window.h" @@ -38,9 +40,13 @@ namespace AbilityRuntime { namespace { constexpr int32_t INDEX_ZERO = 0; constexpr int32_t INDEX_ONE = 1; +constexpr int32_t INDEX_TWO = 2; +constexpr int32_t INDEX_THREE = 3; constexpr size_t ARGC_ZERO = 0; constexpr size_t ARGC_ONE = 1; +constexpr size_t ARGC_THREE = 3; constexpr const char* PERMISSION_PRIVACY_WINDOW = "ohos.permission.PRIVACY_WINDOW"; +const std::string UIEXTENSION_TARGET_TYPE_KEY = "ability.want.params.uiExtensionTargetType"; } // namespace #define CHECK_IS_SYSTEM_APP \ @@ -160,6 +166,11 @@ napi_value JsUIExtensionContentSession::SetWindowPrivacyMode(napi_env env, napi_ GET_NAPI_INFO_AND_CALL(env, info, JsUIExtensionContentSession, OnSetWindowPrivacyMode); } +napi_value JsUIExtensionContentSession::StartAbilityByType(napi_env env, napi_callback_info info) +{ + GET_NAPI_INFO_AND_CALL(env, info, JsUIExtensionContentSession, OnStartAbilityByType); +} + napi_value JsUIExtensionContentSession::OnStartAbility(napi_env env, NapiCallbackInfo& info) { HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); @@ -585,6 +596,61 @@ napi_value JsUIExtensionContentSession::OnSetWindowPrivacyMode(napi_env env, Nap return result; } +napi_value JsUIExtensionContentSession::OnStartAbilityByType(napi_env env, NapiCallbackInfo& info) +{ + HILOG_INFO("called"); + if (info.argc < ARGC_THREE) { + ThrowTooFewParametersError(env); + return CreateJsUndefined(env); + } + + std::string type; + if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], type)) { + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + AAFwk::WantParams wantParam; + if (!AppExecFwk::UnwrapWantParams(env, info.argv[INDEX_ONE], wantParam)) { + ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM); + return CreateJsUndefined(env); + } + + wantParam.SetParam(UIEXTENSION_TARGET_TYPE_KEY, AAFwk::String::Box(type)); + AAFwk::Want want; + want.SetParams(wantParam); + std::shared_ptr uiExtensionCallback = std::make_shared(env); + uiExtensionCallback->SetJsCallbackObject(info.argv[INDEX_TWO]); + NapiAsyncTask::CompleteCallback complete = [uiWindow = uiWindow_, type, want, uiExtensionCallback] + (napi_env env, NapiAsyncTask& task, int32_t status) { + if (uiWindow == nullptr) { + task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + auto uiContent = uiWindow->GetUIContent(); + if (uiContent == nullptr) { + task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INNER)); + return; + } + Ace::ModalUIExtensionCallbacks callback; + callback.onError = std::bind(&JsUIExtensionCallback::OnError, uiExtensionCallback, std::placeholders::_1); + Ace::ModalUIExtensionConfig config; + config.isProhibitBack = true; + int32_t sessionId = uiContent->CreateModalUIExtension(want, callback, config); + if (sessionId == 0) { + task.Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INNER)); + } else { + task.ResolveWithNoError(env, CreateJsUndefined(env)); + } + }; + + napi_value lastParam = (info.argc > ARGC_THREE) ? info.argv[INDEX_THREE] : nullptr; + napi_value result = nullptr; + NapiAsyncTask::ScheduleHighQos("JsUIExtensionContentSession::OnStartAbilityByType", + env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result)); + return result; +} + napi_value JsUIExtensionContentSession::CreateJsUIExtensionContentSession(napi_env env, sptr sessionInfo, sptr uiWindow, std::weak_ptr context, @@ -612,6 +678,7 @@ napi_value JsUIExtensionContentSession::CreateJsUIExtensionContentSession(napi_e BindNativeFunction(env, object, "setWindowPrivacyMode", moduleName, SetWindowPrivacyMode); BindNativeFunction(env, object, "startAbility", moduleName, StartAbility); BindNativeFunction(env, object, "startAbilityForResult", moduleName, StartAbilityForResult); + BindNativeFunction(env, object, "startAbilityByType", moduleName, StartAbilityByType); return object; } @@ -640,6 +707,7 @@ napi_value JsUIExtensionContentSession::CreateJsUIExtensionContentSession(napi_e BindNativeFunction(env, object, "setWindowPrivacyMode", moduleName, SetWindowPrivacyMode); BindNativeFunction(env, object, "startAbility", moduleName, StartAbility); BindNativeFunction(env, object, "startAbilityForResult", moduleName, StartAbilityForResult); + BindNativeFunction(env, object, "startAbilityByType", moduleName, StartAbilityByType); return object; } diff --git a/interfaces/kits/native/ability/ability_runtime/ability_context.h b/interfaces/kits/native/ability/ability_runtime/ability_context.h index d3b7a884a5..ca53829e06 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context.h @@ -23,6 +23,7 @@ #include "caller_callback.h" #include "configuration.h" #include "iability_callback.h" +#include "js_ui_extension_callback.h" #include "mission_info.h" #include "native_engine/native_reference.h" #include "native_engine/native_value.h" @@ -333,6 +334,8 @@ public: * @return UIContent object of ACE. */ virtual Ace::UIContent* GetUIContent() = 0; + virtual ErrCode StartAbilityByType(const std::string &type, AAFwk::WantParams &wantParam, + const std::shared_ptr &uiExtensionCallbacks) = 0; #endif virtual bool IsTerminating() = 0; virtual void SetTerminating(bool state) = 0; 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 679124530a..1352d7e889 100644 --- a/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h +++ b/interfaces/kits/native/ability/ability_runtime/ability_context_impl.h @@ -202,6 +202,9 @@ public: */ ErrCode SetMissionContinueState(const AAFwk::ContinueState &state) override; + ErrCode StartAbilityByType(const std::string &type, + AAFwk::WantParams &wantParam, const std::shared_ptr &uiExtensionCallbacks) override; + #ifdef SUPPORT_GRAPHICS /** * @brief Set mission label of this ability. 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 73c7be08a1..71143a295c 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 @@ -59,6 +59,7 @@ public: static napi_value IsTerminating(napi_env env, napi_callback_info info); static napi_value ReportDrawnCompleted(napi_env env, napi_callback_info info); static napi_value SetMissionContinueState(napi_env env, napi_callback_info info); + static napi_value StartAbilityByType(napi_env env, napi_callback_info info); static void ConfigurationUpdated(napi_env env, std::shared_ptr &jsContext, const std::shared_ptr &config); @@ -102,6 +103,7 @@ private: napi_value OnIsTerminating(napi_env env, NapiCallbackInfo& info); napi_value OnReportDrawnCompleted(napi_env env, NapiCallbackInfo& info); napi_value OnSetMissionContinueState(napi_env env, NapiCallbackInfo& info); + napi_value OnStartAbilityByType(napi_env env, NapiCallbackInfo& info); static bool UnWrapWant(napi_env env, napi_value argv, AAFwk::Want& want); static napi_value WrapWant(napi_env env, const AAFwk::Want& want); diff --git a/interfaces/kits/native/ability/native/js_ui_extension_callback.h b/interfaces/kits/native/ability/native/js_ui_extension_callback.h new file mode 100644 index 0000000000..35c33be1ce --- /dev/null +++ b/interfaces/kits/native/ability/native/js_ui_extension_callback.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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_JS_UI_EXTENSION_CALLBACK_H +#define OHOS_ABILITY_RUNTIME_JS_UI_EXTENSION_CALLBACK_H + +#include +#include "native_engine/native_reference.h" + + +namespace OHOS { +namespace AbilityRuntime { +class JsUIExtensionCallback : public std::enable_shared_from_this { +public: + explicit JsUIExtensionCallback(napi_env env) : env_(env) {} + ~JsUIExtensionCallback(); + void OnError(int32_t number); + void SetJsCallbackObject(napi_value jsCallbackObject); + void CallJsError(int32_t number); +private: + napi_env env_ = nullptr; + std::unique_ptr jsCallbackObject_ = nullptr; +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_JS_UI_EXTENSION_CALLBACK_H \ No newline at end of file diff --git a/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_content_session.h b/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_content_session.h index e0b2089269..4c78168de7 100644 --- a/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_content_session.h +++ b/interfaces/kits/native/ability/native/ui_extension_ability/js_ui_extension_content_session.h @@ -67,6 +67,7 @@ public: static napi_value LoadContent(napi_env env, napi_callback_info info); static napi_value SetWindowBackgroundColor(napi_env env, napi_callback_info info); static napi_value SetWindowPrivacyMode(napi_env env, napi_callback_info info); + static napi_value StartAbilityByType(napi_env env, napi_callback_info info); protected: napi_value OnStartAbility(napi_env env, NapiCallbackInfo& info); @@ -78,6 +79,7 @@ protected: napi_value OnLoadContent(napi_env env, NapiCallbackInfo& info); napi_value OnSetWindowBackgroundColor(napi_env env, NapiCallbackInfo& info); napi_value OnSetWindowPrivacyMode(napi_env env, NapiCallbackInfo& info); + napi_value OnStartAbilityByType(napi_env env, NapiCallbackInfo& info); static void CallReceiveDataCallback(napi_env env, std::weak_ptr weakCallback, const AAFwk::WantParams& wantParams); diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 968a20ed65..a4f05442f3 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -1737,6 +1737,8 @@ private: */ void StopSwitchUserDialogInner(const Want &want, const int32_t stopUserId); + void SetPickerElementName(const sptr &extensionSessionInfo); + constexpr static int REPOLL_TIME_MICRO_SECONDS = 1000000; constexpr static int WAITING_BOOT_ANIMATION_TIMER = 5; diff --git a/services/abilitymgr/include/ams_configuration_parameter.h b/services/abilitymgr/include/ams_configuration_parameter.h index 667dc6eb43..1ae0dbb75d 100644 --- a/services/abilitymgr/include/ams_configuration_parameter.h +++ b/services/abilitymgr/include/ams_configuration_parameter.h @@ -36,6 +36,10 @@ constexpr const char* RESIDENT_RESTART_MAX = "resident_restart_max"; constexpr const char* RESTART_INTERVAL_TIME = "restart_interval_time"; constexpr const char* BOOT_ANIMATION_TIMEOUT_TIME = "boot_animation_timeout_time"; constexpr const char* TIMEOUT_UNIT_TIME = "timeout_unit_time"; +constexpr const char* ABILITY_NAME = "ability_name"; +constexpr const char* BUNDLE_NAME = "bundle_name"; +constexpr const char* PICKER_CONFIGURATION = "picker_configuration"; +constexpr const char* PICKER_TYPE = "picker_type"; } // namespace AmsConfig enum class SatrtUiMode { STATUSBAR = 1, NAVIGATIONBAR = 2, STARTUIBOTH = 3 }; @@ -107,6 +111,16 @@ public: */ int GetAppStartTimeoutTime() const; + /** + * set picker json object. + */ + void SetPickerJsonObject(nlohmann::json jsonObject); + + /** + * get picker json object. + */ + nlohmann::json GetPickerJsonObject() const; + enum { READ_OK = 0, READ_FAIL = 1, READ_JSON_FAIL = 2 }; private: @@ -121,9 +135,11 @@ private: int LoadAppConfigurationForStartUpService(nlohmann::json& Object); int LoadAppConfigurationForMemoryThreshold(nlohmann::json& Object); int LoadSystemConfiguration(nlohmann::json& Object); + void LoadPickerConfiguration(nlohmann::json& Object); bool CheckServiceConfigEnable(nlohmann::json& Object, const std::string &configName, JsonValueType type); void UpdateStartUpServiceConfigInteger(nlohmann::json& Object, const std::string &configName, int32_t &value); void UpdateStartUpServiceConfigString(nlohmann::json& Object, const std::string &configName, std::string &value); + void UpdatePickerConfigurationString(nlohmann::json& Object, const std::string &configName, std::string &value); private: bool nonConfigFile_ {false}; @@ -137,6 +153,10 @@ private: int bootAnimationTime_ {5}; std::string deviceType_ {""}; int timeoutUnitTime_ {1000}; + std::string bundleName_ {""}; + std::string abilityName_ {""}; + std::string pickerType_ {""}; + nlohmann::json pickerJsonObject_ = nlohmann::json::object(); }; } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 01a9e5c9c4..19ab95d9f0 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -67,6 +67,7 @@ #include "start_ability_handler/start_ability_sandbox_savefile.h" #include "start_options.h" #include "string_ex.h" +#include "string_wrapper.h" #include "system_ability_definition.h" #include "system_ability_token_callback.h" #include "ui_extension_utils.h" @@ -124,6 +125,7 @@ const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate" const std::string DLP_BUNDLE_NAME = "com.ohos.dlpmanager"; // UIExtension type const std::string UIEXTENSION_TYPE_KEY = "ability.want.params.uiExtensionType"; +const std::string UIEXTENSION_TARGET_TYPE_KEY = "ability.want.params.uiExtensionTargetType"; // Share picker params constexpr char SHARE_PICKER_DIALOG_BUNDLE_NAME_KEY[] = "const.system.sharePicker.bundleName"; constexpr char SHARE_PICKER_DIALOG_ABILITY_NAME_KEY[] = "const.system.sharePicker.abilityName"; @@ -1973,10 +1975,41 @@ int AbilityManagerService::StartExtensionAbilityInner(const Want &want, const sp return eventInfo.errCode; } +void AbilityManagerService::SetPickerElementName(const sptr &extensionSessionInfo) +{ + std::string targetType = extensionSessionInfo->want.GetStringParam(UIEXTENSION_TARGET_TYPE_KEY); + if (extensionSessionInfo->want.GetElement().GetBundleName().empty() && + extensionSessionInfo->want.GetElement().GetAbilityName().empty() && !targetType.empty()) { + nlohmann::json jsonObject = AmsConfigurationParameter::GetInstance().GetPickerJsonObject(); + std::string abilityName; + std::string bundleName; + std::string pickerType; + if (jsonObject.contains(targetType) && + jsonObject.at(targetType).contains(AmsConfig::ABILITY_NAME) && + jsonObject.at(targetType).at(AmsConfig::ABILITY_NAME).is_string()) { + abilityName = jsonObject.at(targetType).at(AmsConfig::ABILITY_NAME).get(); + } + if (jsonObject.contains(targetType) && + jsonObject.at(targetType).contains(AmsConfig::BUNDLE_NAME) && + jsonObject.at(targetType).at(AmsConfig::BUNDLE_NAME).is_string()) { + bundleName = jsonObject.at(targetType).at(AmsConfig::BUNDLE_NAME).get(); + } + if (jsonObject.contains(targetType) && + jsonObject.at(targetType).contains(AmsConfig::PICKER_TYPE) && + jsonObject.at(targetType).at(AmsConfig::PICKER_TYPE).is_string()) { + pickerType = jsonObject.at(targetType).at(AmsConfig::PICKER_TYPE).get(); + } + extensionSessionInfo->want.SetElementName(bundleName, abilityName); + WantParams ¶meters = const_cast(extensionSessionInfo->want.GetParams()); + parameters.SetParam(UIEXTENSION_TYPE_KEY, AAFwk::String::Box(pickerType)); + extensionSessionInfo->want.SetParams(parameters); + } +} int AbilityManagerService::StartUIExtensionAbility(const sptr &extensionSessionInfo, int32_t userId) { HILOG_DEBUG("Start ui extension ability come"); CHECK_POINTER_AND_RETURN(extensionSessionInfo, ERR_INVALID_VALUE); + SetPickerElementName(extensionSessionInfo); std::string extensionTypeStr = extensionSessionInfo->want.GetStringParam(UIEXTENSION_TYPE_KEY); AppExecFwk::ExtensionAbilityType extensionType = extensionTypeStr.empty() ? AppExecFwk::ExtensionAbilityType::UI : AppExecFwk::ConvertToExtensionAbilityType(extensionTypeStr); diff --git a/services/abilitymgr/src/ams_configuration_parameter.cpp b/services/abilitymgr/src/ams_configuration_parameter.cpp index f5b4c94bd5..2e0900e6d5 100644 --- a/services/abilitymgr/src/ams_configuration_parameter.cpp +++ b/services/abilitymgr/src/ams_configuration_parameter.cpp @@ -87,6 +87,18 @@ int AmsConfigurationParameter::GetAppStartTimeoutTime() const return timeoutUnitTime_; } +void AmsConfigurationParameter::SetPickerJsonObject(nlohmann::json Object) +{ + if (Object.contains(AmsConfig::PICKER_CONFIGURATION)) { + pickerJsonObject_ = Object.at(AmsConfig::PICKER_CONFIGURATION); + } +} + +nlohmann::json AmsConfigurationParameter::GetPickerJsonObject() const +{ + return pickerJsonObject_; +} + int AmsConfigurationParameter::LoadAmsConfiguration(const std::string &filePath) { HILOG_DEBUG("%{public}s", __func__); @@ -119,6 +131,7 @@ int AmsConfigurationParameter::LoadAmsConfiguration(const std::string &filePath) } LoadSystemConfiguration(amsJson); + SetPickerJsonObject(amsJson); amsJson.clear(); inFile.close();