diff --git a/bundle.json b/bundle.json index 1f9d759a7c8469cbeb587bde73405a163df6681e..88d49a502f88fc9204e684fd496059c02ff9d498 100644 --- a/bundle.json +++ b/bundle.json @@ -20,7 +20,8 @@ "SystemCapability.Ability.AbilityRuntime.QuickFix", "SystemCapability.Ability.AbilityTools.AbilityAssistant", "SystemCapability.Ability.AppStartup", - "SystemCapability.Ability.AppExtension.PhotoEditorExtension" + "SystemCapability.Ability.AppExtension.PhotoEditorExtension", + "SystemCapability.Ability.AppExtension.VerticalPanel" ], "features": [ "ability_runtime_auto_fill_ability", diff --git a/frameworks/js/napi/BUILD.gn b/frameworks/js/napi/BUILD.gn index ff8a2ff50318fccf62ee49590e67e509f6dbf307..2331587731dfc411f3935be36d6a605bf3a7fb2c 100644 --- a/frameworks/js/napi/BUILD.gn +++ b/frameworks/js/napi/BUILD.gn @@ -26,6 +26,7 @@ group("napi_packages") { "${ability_runtime_napi_path}/ability_context:abilitycontext_napi", "${ability_runtime_napi_path}/ability_manager:abilitymanager", "${ability_runtime_napi_path}/ability_manager:abilitymanager_napi", + "${ability_runtime_napi_path}/ability_vertical_panel:verticalpanelmanager_napi", "${ability_runtime_napi_path}/action_extension_ability:actionextensionability_napi", "${ability_runtime_napi_path}/app/ability_delegator:abilitydelegatorregistry", "${ability_runtime_napi_path}/app/ability_delegator:abilitydelegatorregistry_napi", diff --git a/frameworks/js/napi/ability_vertical_panel/BUILD.gn b/frameworks/js/napi/ability_vertical_panel/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..2cd949b11eae70650c0275314ffd5f289c8390f8 --- /dev/null +++ b/frameworks/js/napi/ability_vertical_panel/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (c) 2025 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. + +import("//build/ohos.gni") +import("//foundation/ability/ability_runtime/ability_runtime.gni") + +ohos_shared_library("verticalpanelmanager_napi") { + + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + + include_dirs = [ + "include", + "${ability_runtime_path}/interfaces/inner_api/", + "${ability_runtime_path}/interfaces/kits/native/appkit/ability_runtime/", + ] + + sources = [ + "js_ability_vertical_panel.cpp", + "js_panel_start_callback.cpp", + "native_module.cpp", + ] + + configs = [ "${ability_runtime_services_path}/common:common_config" ] + + deps = [ + "${ability_runtime_innerkits_path}/runtime:runtime", + "${ability_runtime_innerkits_path}/napi_base_context:napi_base_context", + "${ability_runtime_napi_path}/inner/napi_common:napi_common", + "${ability_runtime_native_path}/ability/native:abilitykit_native", + "${ability_runtime_native_path}/ability:ability_context_native", + ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "ace_engine:ace_uicontent", + "access_token:libtokenid_sdk", + "ipc:ipc_core", + ] + cflags_cc = [] + if (os_dlp_part_enabled) { + cflags_cc += [ "-DWITH_DLP" ] + } + + relative_install_dir = "module/app/ability" + + subsystem_name = "ability" + part_name = "ability_runtime" +} diff --git a/frameworks/js/napi/ability_vertical_panel/js_ability_vertical_panel.cpp b/frameworks/js/napi/ability_vertical_panel/js_ability_vertical_panel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d0ca7dc04ed48d69cb5505f29fa0395a338d373a --- /dev/null +++ b/frameworks/js/napi/ability_vertical_panel/js_ability_vertical_panel.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (c) 2025 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_ability_vertical_panel.h" + +#include "hilog_tag_wrapper.h" +#include "ipc_skeleton.h" +#include "js_panel_start_callback.h" +#include "js_error_utils.h" +#include "js_runtime_utils.h" +#include "napi_base_context.h" +#include "napi_common_util.h" +#include "napi_common_want.h" +#include "native_engine/native_value.h" +#include "screen_config.h" +#include "start_vertical_panel.h" +#include "tokenid_kit.h" + +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_FOUR = 4; + +static void SetNamedProperty(napi_env env, napi_value dstObj, const char *objName, const char *propName) +{ + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "SetNamedProperty called"); + napi_value prop = nullptr; + napi_create_string_utf8(env, objName, NAPI_AUTO_LENGTH, &prop); + napi_set_named_property(env, dstObj, propName, prop); +} + +class JsAbilityVerticalPanel { +public: + JsAbilityVerticalPanel() = default; + ~JsAbilityVerticalPanel() = default; + + static void Finalizer(napi_env env, void *data, void *hint) + { + TAG_LOGI(AAFwkTag::VERTICAL_PANEL, "finalizer"); + std::unique_ptr(static_cast(data)); + } + + static napi_value StartVerticalPanel(napi_env env, napi_callback_info info) + { + GET_NAPI_INFO_AND_CALL(env, info, JsAbilityVerticalPanel, OnStartVerticalPanel); + } + +private: + static bool GetContext(napi_env env, napi_value value, + std::shared_ptr &abilityContext) + { + bool stageMode = false; + napi_status status = OHOS::AbilityRuntime::IsStageContext(env, value, stageMode); + if (status != napi_ok || !stageMode) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "Get context It is not a stage mode"); + return false; + } + + auto context = AbilityRuntime::GetStageModeContext(env, value); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "Get context GetStageModeContext failed"); + return false; + } + + abilityContext = AbilityRuntime::Context::ConvertTo(context); + if (abilityContext == nullptr || abilityContext->GetApplicationInfo() == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "Get context failed"); + return false; + } + + return true; + } + + static bool UnwrapScreenConfig(napi_env env, napi_value param, AAFwk::ScreenConfig &screenConfig) + { + if (!AppExecFwk::IsTypeForNapiValue(env, param, napi_object)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "UnwrapScreenConfig param IsTypeForNapiValue failed"); + return false; + } + + napi_value type = nullptr; + napi_get_named_property(env, param, "type", &type); + if (type == nullptr || !ConvertFromJsValue(env, type, screenConfig.type)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "parse UnwrapScreenConfig failed: type"); + return false; + } + + napi_value sourceAppInfo = nullptr; + napi_get_named_property(env, param, "sourceAppInfo", &sourceAppInfo); + if (sourceAppInfo == nullptr || !AppExecFwk::IsTypeForNapiValue(env, sourceAppInfo, napi_object)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "parse UnwrapScreenConfig failed: sourceAppInfo"); + return false; + } + + napi_valuetype jsValueType = napi_undefined; + napi_value jsProNameList = nullptr; + uint32_t jsProCount = 0; + + NAPI_CALL_BASE(env, napi_get_property_names(env, sourceAppInfo, &jsProNameList), false); + NAPI_CALL_BASE(env, napi_get_array_length(env, jsProNameList, &jsProCount), false); + + napi_value jsProName = nullptr; + napi_value jsProValue = nullptr; + for (uint32_t index = 0; index < jsProCount; index++) { + NAPI_CALL_BASE(env, napi_get_element(env, jsProNameList, index, &jsProName), false); + + std::string strProName = AppExecFwk::UnwrapStringFromJS(env, jsProName); + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "property name=%{public}s", strProName.c_str()); + NAPI_CALL_BASE(env, napi_get_named_property(env, sourceAppInfo, strProName.c_str(), &jsProValue), false); + NAPI_CALL_BASE(env, napi_typeof(env, jsProValue, &jsValueType), false); + + std::string natValue = AppExecFwk::UnwrapStringFromJS(env, jsProValue); + screenConfig.sourceAppInfo[strProName] = natValue; + } + return true; + } + + napi_value ExecuteStartVerticalPanel(napi_env env, + std::shared_ptr abilityContext, + const AAFwk::WantParams &wantParam, + const AAFwk::ScreenConfig &screenConfig, + std::shared_ptr callback) + { + auto innerErrCode = std::make_shared(ERR_OK); + NapiAsyncTask::ExecuteCallback execute = + [abilityContext, wantParamCopy = wantParam, screenConfig, callback, innerErrCode]() mutable { +#ifdef SUPPORT_SCREEN + *innerErrCode = OHOS::AbilityRuntime::StartVerticalPanel( + abilityContext, wantParamCopy, screenConfig, callback); +#endif + }; + NapiAsyncTask::CompleteCallback complete = + [innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) { + if (*innerErrCode == ERR_OK) { + task.ResolveWithNoError(env, CreateJsUndefined(env)); + } else { + task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode)); + } + }; + napi_value result = nullptr; + NapiAsyncTask::ScheduleHighQos("JsAbilityVerticalPanel::OnStartVerticalPanel", + env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result)); + return result; + } + + napi_value OnStartVerticalPanel(napi_env env, NapiCallbackInfo &info) + { + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel call"); + + auto selfToken = IPCSkeleton::GetSelfTokenID(); + if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "This application is not system-app," + "can not use system-api"); + ThrowNotSystemAppError(env); + return CreateJsUndefined(env); + } + + if (info.argc < ARGC_FOUR) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel invalid params"); + ThrowTooFewParametersError(env); + return CreateJsUndefined(env); + } + + std::shared_ptr abilityContext; + if (!GetContext(env, info.argv[INDEX_ZERO], abilityContext)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel parse context failed"); + ThrowInvalidParamError(env, "Parse param context failed, context must be UIAbilityContext."); + return CreateJsUndefined(env); + } + + AAFwk::WantParams wantParam; + if (!AppExecFwk::UnwrapWantParams(env, info.argv[INDEX_ONE], wantParam)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel parse wantParam failed"); + ThrowInvalidParamError(env, "Parse param want failed, want must be Want."); + return CreateJsUndefined(env); + } + + AAFwk::ScreenConfig screenConfig; + if (!UnwrapScreenConfig(env, info.argv[INDEX_TWO], screenConfig)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel parse screenConfig failed"); + ThrowInvalidParamError(env, "Parse param screenConfig failed, screenConfig must be ScreenConfig."); + return CreateJsUndefined(env); + } + + std::shared_ptr callback = std::make_shared(env); + callback->SetJsCallbackObject(info.argv[INDEX_THREE]); + return ExecuteStartVerticalPanel(env, abilityContext, wantParam, screenConfig, callback); + } +}; + +napi_value JsAbilityVerticalPanelInit(napi_env env, napi_value exportObj) +{ + if (env == nullptr || exportObj == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null env or exportObj"); + return nullptr; + } + + napi_value verticalType = nullptr; + napi_create_object(env, &verticalType); + SetNamedProperty(env, verticalType, "navigation", "NAVIGATION"); + + napi_value bundleName = nullptr; + napi_create_string_utf8(env, "bundleName", NAPI_AUTO_LENGTH, &bundleName); + napi_value moduleNameProp = nullptr; + napi_create_string_utf8(env, "moduleName", NAPI_AUTO_LENGTH, &moduleNameProp); + napi_value abilityName = nullptr; + napi_create_string_utf8(env, "abilityName", NAPI_AUTO_LENGTH, &abilityName); + napi_value windowId = nullptr; + napi_create_string_utf8(env, "windowId", NAPI_AUTO_LENGTH, &windowId); + napi_value screenMode = nullptr; + napi_create_string_utf8(env, "screenMode", NAPI_AUTO_LENGTH, &screenMode); + + napi_property_descriptor exportFuncs[] = { + DECLARE_NAPI_PROPERTY("VerticalType", verticalType), + DECLARE_NAPI_PROPERTY("SOURCE_APP_BUNDLE_NAME", bundleName), + DECLARE_NAPI_PROPERTY("SOURCE_APP_MODULE_NAME", moduleNameProp), + DECLARE_NAPI_PROPERTY("SOURCE_APP_ABILITY_NAME", abilityName), + DECLARE_NAPI_PROPERTY("SOURCE_APP_WINDOW_ID", windowId), + DECLARE_NAPI_PROPERTY("SOURCE_APP_SCREEN_MODE", screenMode), + }; + napi_define_properties(env, exportObj, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs); + + auto jsAbilityVerticalPanel = std::make_unique(); + napi_wrap(env, exportObj, jsAbilityVerticalPanel.release(), + JsAbilityVerticalPanel::Finalizer, nullptr, nullptr); + + const char *moduleName = "JsAbilityVerticalPanel"; + BindNativeFunction(env, exportObj, "startVerticalPanel", moduleName, JsAbilityVerticalPanel::StartVerticalPanel); + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "end"); + return CreateJsUndefined(env); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/ability_vertical_panel/js_ability_vertical_panel.h b/frameworks/js/napi/ability_vertical_panel/js_ability_vertical_panel.h new file mode 100644 index 0000000000000000000000000000000000000000..2dda8b46e09a82a73944139b9423f65ef3d03417 --- /dev/null +++ b/frameworks/js/napi/ability_vertical_panel/js_ability_vertical_panel.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 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_ABILITY_VERTICAL_PANEL_H +#define OHOS_ABILITY_RUNTIME_JS_ABILITY_VERTICAL_PANEL_H + +#include "native_engine/native_engine.h" + +namespace OHOS { +namespace AbilityRuntime { +napi_value JsAbilityVerticalPanelInit(napi_env env, napi_value exportObj); +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_JS_ABILITY_VERTICAL_PANEL_H diff --git a/frameworks/js/napi/ability_vertical_panel/js_panel_start_callback.cpp b/frameworks/js/napi/ability_vertical_panel/js_panel_start_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..be6b1607c8bccc260002b0bd9e27afc3317ed970 --- /dev/null +++ b/frameworks/js/napi/ability_vertical_panel/js_panel_start_callback.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2025 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_panel_start_callback.h" + +#include "ability_business_error.h" +#include "hilog_tag_wrapper.h" +#include "js_runtime_utils.h" +#include "napi/native_api.h" +#include "napi_common_util.h" +#include "napi_common_want.h" +#ifdef SUPPORT_SCREEN +#include "ui_content.h" +#include "ws_common.h" +#endif // SUPPORT_SCREEN + +namespace OHOS { +namespace AbilityRuntime { +#ifdef SUPPORT_SCREEN +constexpr const char* ERROR_MSG_INNER = "Inner error."; +#endif // SUPPORT_SCREEN +JsPanelStartCallback::~JsPanelStartCallback() +{ + 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 JsPanelStartCallback::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) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null jsCallbackObject_"); + } +} + +#ifdef SUPPORT_SCREEN +void JsPanelStartCallback::OnError(int32_t number) +{ + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "OnError call"); + if (env_ == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null env_"); + return; + } + // js callback should run in js thread + std::shared_ptr jsPanelStartCallback = shared_from_this(); + std::unique_ptr complete = std::make_unique + ([jsPanelStartCallback, number](napi_env env, NapiAsyncTask &task, int32_t status) { + if (jsPanelStartCallback != nullptr) { + jsPanelStartCallback->CallJsError(number); + } + }); + napi_ref callback = nullptr; + std::unique_ptr execute = nullptr; + NapiAsyncTask::Schedule("JsPanelStartCallback::OnError:", + env_, std::make_unique(callback, std::move(execute), std::move(complete))); + CloseModalUIExtension(); +} + +void JsPanelStartCallback::OnResult(int32_t resultCode, const AAFwk::Want &want) +{ + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "OnResult call"); + if (env_ == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null env_"); + return; + } + // js callback should run in js thread + std::shared_ptr jsPanelStartCallback = shared_from_this(); + std::unique_ptr complete = std::make_unique + ([jsPanelStartCallback, resultCode, want](napi_env env, NapiAsyncTask &task, int32_t status) { + if (jsPanelStartCallback != nullptr) { + jsPanelStartCallback->CallJsResult(resultCode, want); + } + }); + napi_ref callback = nullptr; + std::unique_ptr execute = nullptr; + NapiAsyncTask::Schedule("JsPanelStartCallback::OnResult:", + env_, std::make_unique(callback, std::move(execute), std::move(complete))); + CloseModalUIExtension(); +} +#endif // SUPPORT_SCREEN + +void JsPanelStartCallback::CallJsResult(int32_t resultCode, const AAFwk::Want &want) +{ + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "CallJsResult call"); + if (env_ == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null env_"); + return; + } + + napi_value abilityResult = OHOS::AppExecFwk::WrapAbilityResult(env_, resultCode, want); + if (abilityResult == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null abilityResult"); + return; + } + + if (jsCallbackObject_ == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null jsCallbackObject_ "); + return; + } + napi_value obj = jsCallbackObject_->GetNapiValue(); + if (obj == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null obj"); + return; + } + napi_value method = nullptr; + napi_get_named_property(env_, obj, "onResult", &method); + if (method == nullptr || AppExecFwk::IsTypeForNapiValue(env_, method, napi_undefined) + || AppExecFwk::IsTypeForNapiValue(env_, method, napi_null)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null method"); + return; + } + + napi_value argv[] = { abilityResult }; + napi_call_function(env_, obj, method, ArraySize(argv), argv, nullptr); + TAG_LOGI(AAFwkTag::VERTICAL_PANEL, "end"); +} + +void JsPanelStartCallback::CallJsError(int32_t number) +{ + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "CallJsError call"); + if (env_ == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null env_ "); + return; + } + std::string name; + std::string message; +#ifdef SUPPORT_SCREEN + if (number != static_cast(Rosen::WSError::WS_OK)) { + number = static_cast(AbilityErrorCode::ERROR_CODE_INNER); + name = ERROR_MSG_INNER; + message = "StartVerticalPanel failed."; + } +#endif // SUPPORT_SCREEN + napi_value nativeNumber = CreateJsValue(env_, number); + napi_value nativeName = CreateJsValue(env_, name); + napi_value nativeMessage = CreateJsValue(env_, message); + if (jsCallbackObject_ == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null jsCallbackObject_"); + return; + } + napi_value obj = jsCallbackObject_->GetNapiValue(); + if (obj == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null obj"); + 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)) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null method"); + return; + } + + napi_value argv[] = { nativeNumber, nativeName, nativeMessage }; + napi_call_function(env_, obj, method, ArraySize(argv), argv, nullptr); + TAG_LOGI(AAFwkTag::VERTICAL_PANEL, "end"); +} +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/ability_vertical_panel/js_panel_start_callback.h b/frameworks/js/napi/ability_vertical_panel/js_panel_start_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..0f7f94f7f3ef4089e831d0e11d9da96cd020adb4 --- /dev/null +++ b/frameworks/js/napi/ability_vertical_panel/js_panel_start_callback.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 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_PANEL_START_CALLBACK_H +#define OHOS_ABILITY_RUNTIME_JS_PANEL_START_CALLBACK_H + +#include "native_engine/native_reference.h" +#include "panel_start_callback.h" + +namespace OHOS { +namespace AbilityRuntime { +class JsPanelStartCallback : public PanelStartCallback, + public std::enable_shared_from_this { +public: + explicit JsPanelStartCallback(napi_env env) : env_(env) {} + ~JsPanelStartCallback() override; +#ifdef SUPPORT_SCREEN + void OnError(int32_t number) override; + void OnResult(int32_t resultCode, const AAFwk::Want &want) override; +#endif // SUPPORT_SCREEN + void CallJsResult(int32_t resultCode, const AAFwk::Want &want); + 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_PANEL_START_CALLBACK_H \ No newline at end of file diff --git a/frameworks/js/napi/ability_vertical_panel/native_module.cpp b/frameworks/js/napi/ability_vertical_panel/native_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79f7df9e8b1d4a665cb6bfc9597c2f1cfd1d004c --- /dev/null +++ b/frameworks/js/napi/ability_vertical_panel/native_module.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 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_ability_vertical_panel.h" +#include "native_engine/native_engine.h" + +/* + * The module definition. + */ +static napi_module _module = { + .nm_version = 0, + .nm_filename = nullptr, + .nm_register_func = OHOS::AbilityRuntime::JsAbilityVerticalPanelInit, + .nm_modname = "app.ability.VerticalPanelManager", +}; + +/* + * The module registration. + */ +extern "C" __attribute__((constructor)) void NAPI_application_Ability_VerticalPanel_AutoRegister(void) +{ + napi_module_register(&_module); +} diff --git a/frameworks/native/ability/BUILD.gn b/frameworks/native/ability/BUILD.gn index 27de58ac8a567e0f0c2288d9fb9b69e0b736892a..4fcc13fd0f72f95e946b80d9f7c0827df5c030fc 100644 --- a/frameworks/native/ability/BUILD.gn +++ b/frameworks/native/ability/BUILD.gn @@ -55,6 +55,7 @@ ohos_shared_library("ability_context_native") { sources = [ "ability_runtime/ability_connection.cpp", "ability_runtime/ability_context_impl.cpp", + "ability_runtime/start_vertical_panel.cpp", "ability_runtime/authorization_result.cpp", "ability_runtime/connection_manager.cpp", "ability_runtime/dialog_request_callback_impl.cpp", @@ -63,6 +64,7 @@ ohos_shared_library("ability_context_native") { "ability_runtime/local_call_container.cpp", "ability_runtime/local_call_record.cpp", "native/js_ui_extension_callback.cpp", + "native/panel_start_callback.cpp", ] deps = [ diff --git a/frameworks/native/ability/ability_runtime/start_vertical_panel.cpp b/frameworks/native/ability/ability_runtime/start_vertical_panel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..872d5cfbe05ac98d52f1ddd5403597a416ec40f2 --- /dev/null +++ b/frameworks/native/ability/ability_runtime/start_vertical_panel.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2025 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 "start_vertical_panel.h" + +#include "ability_manager_errors.h" +#include "hilog_tag_wrapper.h" +#include "string_wrapper.h" +#ifdef SUPPORT_SCREEN +#include "ui_content.h" +#endif // SUPPORT_SCREEN + +namespace OHOS { +namespace AbilityRuntime { +#ifdef SUPPORT_SCREEN +constexpr const char* UIEXTENSION_TARGET_TYPE_KEY = "ability.want.params.uiExtensionTargetType"; +constexpr const char* FLAG_AUTH_READ_URI_PERMISSION = "ability.want.params.uriPermissionFlag"; +constexpr const char* SCREENCONFIG_SCREENMODE = "ohos.verticalpanel.screenconfig.screenmode"; +constexpr const char* SCREENCONFIG_BUNDLENAME = "ohos.verticalpanel.screenconfig.bundlename"; +constexpr const char* SCREENCONFIG_MODULENAME = "ohos.verticalpanel.screenconfig.modulename"; +constexpr const char* SCREENCONFIG_ABILITYNAME = "ohos.verticalpanel.screenconfig.abilityname"; +constexpr const char* SCREENCONFIG_WINDOWID = "ohos.verticalpanel.screenconfig.windowid"; +constexpr const char* SCREENMODE = "screenMode"; +constexpr const char* BUNDLENAME = "bundleName"; +constexpr const char* MODULENAME = "moduleName"; +constexpr const char* ABILITYNAME = "abilityName"; +constexpr const char* WINDOWID = "windowId"; + +bool SetParamsForWantParams(AAFwk::WantParams &wantParams, const AAFwk::ScreenConfig &screenConfig) +{ + auto iter = screenConfig.sourceAppInfo.find(SCREENMODE); + if (iter == screenConfig.sourceAppInfo.end()) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "ohos.verticalpanel.screenconfig.screenmode is not exist"); + return false; + } + wantParams.SetParam(SCREENCONFIG_SCREENMODE, AAFwk::String::Box(iter->second)); + + iter = screenConfig.sourceAppInfo.find(BUNDLENAME); + if (iter == screenConfig.sourceAppInfo.end()) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "ohos.verticalpanel.screenconfig.bundlename is not exist"); + return false; + } + wantParams.SetParam(SCREENCONFIG_BUNDLENAME, AAFwk::String::Box(iter->second)); + + iter = screenConfig.sourceAppInfo.find(MODULENAME); + if (iter == screenConfig.sourceAppInfo.end()) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "ohos.verticalpanel.screenconfig.modulename is not exist"); + return false; + } + wantParams.SetParam(SCREENCONFIG_MODULENAME, AAFwk::String::Box(iter->second)); + + iter = screenConfig.sourceAppInfo.find(ABILITYNAME); + if (iter == screenConfig.sourceAppInfo.end()) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "ohos.verticalpanel.screenconfig.abilityname is not exist"); + return false; + } + wantParams.SetParam(SCREENCONFIG_ABILITYNAME, AAFwk::String::Box(iter->second)); + + iter = screenConfig.sourceAppInfo.find(WINDOWID); + if (iter == screenConfig.sourceAppInfo.end()) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "ohos.verticalpanel.screenconfig.windowId is not exist"); + return false; + } + wantParams.SetParam(SCREENCONFIG_WINDOWID, AAFwk::String::Box(iter->second)); + return true; +} + +ErrCode StartVerticalPanel(std::shared_ptr context, + AAFwk::WantParams &wantParams, + const AAFwk::ScreenConfig &screenConfig, + std::shared_ptr panelStartCallback) +{ + TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "StartVerticalPanel call"); + if (context == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "StartVerticalPanel null content"); + return ERR_INVALID_VALUE; + } + auto uiContent = context->GetUIContent(); + if (uiContent == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "StartVerticalPanel null uiContent"); + return AAFwk::ERR_MAIN_WINDOW_NOT_EXIST; + } + wantParams.SetParam(UIEXTENSION_TARGET_TYPE_KEY, AAFwk::String::Box(screenConfig.type)); + if (!SetParamsForWantParams(wantParams, screenConfig)) { + return ERR_INVALID_VALUE; + } + AAFwk::Want want; + want.SetParams(wantParams); + if (wantParams.HasParam(FLAG_AUTH_READ_URI_PERMISSION)) { + int32_t flag = wantParams.GetIntParam(FLAG_AUTH_READ_URI_PERMISSION, 0); + want.SetFlags(flag); + wantParams.Remove(FLAG_AUTH_READ_URI_PERMISSION); + } + if (panelStartCallback == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "StartVerticalPanel null panelStartCallback"); + return ERR_INVALID_VALUE; + } + Ace::ModalUIExtensionCallbacks callback; + callback.onError = [panelStartCallback](int32_t arg, const std::string &str1, const std::string &str2) { + panelStartCallback->OnError(arg); + }; + callback.onRelease = [panelStartCallback](int32_t arg) { + panelStartCallback->OnRelease(arg); + }; + callback.onResult = [panelStartCallback](int32_t arg1, const OHOS::AAFwk::Want arg2) { + panelStartCallback->OnResult(arg1, arg2); + }; + Ace::ModalUIExtensionConfig config; + int32_t sessionId = uiContent->CreateModalUIExtension(want, callback, config); + if (sessionId == 0) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "StartVerticalPanel createModalUIExtension failed"); + return ERR_INVALID_VALUE; + } + panelStartCallback->SetUIContent(uiContent); + panelStartCallback->SetSessionId(sessionId); + return ERR_OK; +} +#endif // SUPPORT_SCREEN +} // namespace AbilityRuntime +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp b/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp index f6db665400be587340e09cc2a791973e94793cea..ff3c963bfef5d74db43ffa7fb4cb64f33cb7415b 100644 --- a/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp +++ b/frameworks/native/ability/native/ability_business_error/ability_business_error.cpp @@ -145,6 +145,8 @@ constexpr const char* ERROR_MSG_NOT_SUPPORT_START_PLUGIN_UI_ABILITY = "Starting a plugin UIAbility is not supported."; constexpr const char* ERROR_MSG_NOT_SUPPORT_START_DLP_FILES = "Starting DLP files is not supported."; +constexpr const char* ERROR_MSG_MAIN_WINDOW_NOT_EXIST = + "The main window of this ability does not exist."; // follow ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST of appexecfwk_errors.h in bundle_framework constexpr int32_t ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST = 8521220; @@ -246,6 +248,7 @@ static std::unordered_map ERR_CODE_MAP = { { AbilityErrorCode::ERROR_CODE_NOT_SUPPORT_START_REMOTE_UI_ABILITY, ERROR_MSG_NOT_SUPPORT_START_REMOTE_UI_ABILITY }, { AbilityErrorCode::ERROR_CODE_NOT_SUPPORT_START_PLUGIN_UI_ABILITY, ERROR_MSG_NOT_SUPPORT_START_PLUGIN_UI_ABILITY }, { AbilityErrorCode::ERROR_CODE_NOT_SUPPORT_START_DLP_FILES, ERROR_MSG_NOT_SUPPORT_START_DLP_FILES }, + { AbilityErrorCode::ERROR_CODE_MAIN_WINDOW_NOT_EXIST, ERROR_MSG_MAIN_WINDOW_NOT_EXIST }, }; static std::unordered_map INNER_TO_JS_ERROR_CODE_MAP { @@ -352,6 +355,7 @@ static std::unordered_map INNER_TO_JS_ERROR_CODE_MAP {START_UI_ABILITIES_NOT_SUPPORT_OPERATE_REMOTE, AbilityErrorCode::ERROR_CODE_NOT_SUPPORT_START_REMOTE_UI_ABILITY }, {START_UI_ABILITIES_NOT_SUPPORT_START_PLUGIN, AbilityErrorCode::ERROR_CODE_NOT_SUPPORT_START_PLUGIN_UI_ABILITY }, {START_UI_ABILITIES_NOT_SUPPORT_DLP, AbilityErrorCode::ERROR_CODE_NOT_SUPPORT_START_DLP_FILES }, + {ERR_MAIN_WINDOW_NOT_EXIST, AbilityErrorCode::ERROR_CODE_MAIN_WINDOW_NOT_EXIST }, }; } diff --git a/frameworks/native/ability/native/panel_start_callback.cpp b/frameworks/native/ability/native/panel_start_callback.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7d707fff11ad98e78ae29d1de02c3a8e23c4d48d --- /dev/null +++ b/frameworks/native/ability/native/panel_start_callback.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 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 "panel_start_callback.h" + +#include "hilog_tag_wrapper.h" +#ifdef SUPPORT_SCREEN +#include "ui_content.h" +#include "ws_common.h" +#endif // SUPPORT_SCREEN + +namespace OHOS { +namespace AbilityRuntime { +void PanelStartCallback::SetSessionId(int32_t sessionId) +{ + sessionId_ = sessionId; +} +#ifdef SUPPORT_SCREEN +void PanelStartCallback::SetUIContent(Ace::UIContent* uiContent) +{ + uiContent_ = uiContent; +} + +void PanelStartCallback::OnRelease(int32_t code) +{ + TAG_LOGI(AAFwkTag::VERTICAL_PANEL, "call, code:%{public}d", code); + CloseModalUIExtension(); +} + +void PanelStartCallback::CloseModalUIExtension() +{ + if (uiContent_ == nullptr) { + TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null uiContent_"); + return; + } + uiContent_->CloseModalUIExtension(sessionId_); +} +#endif // SUPPORT_SCREEN +} // namespace AbilityRuntime +} // namespace OHOS diff --git a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h index 9c0a801305949f4c5940d13fbb292c003ace465b..b96dfa27987b6d5e132a9758e2b591a85b51213f 100644 --- a/interfaces/inner_api/ability_manager/include/ability_manager_errors.h +++ b/interfaces/inner_api/ability_manager/include/ability_manager_errors.h @@ -1060,6 +1060,11 @@ enum { ERR_REFINEMENT_INVALID_CALLER_END = 2099199, + /** + * Result (2099200) for main window of this ability does not exist. + */ + ERR_MAIN_WINDOW_NOT_EXIST = 2099200, + /** * Native error(3000000) for target bundle not exist. */ diff --git a/interfaces/inner_api/ability_manager/include/screen_config.h b/interfaces/inner_api/ability_manager/include/screen_config.h new file mode 100644 index 0000000000000000000000000000000000000000..7a827772dcd78ceb8a54e673e57998bd7b09f1c2 --- /dev/null +++ b/interfaces/inner_api/ability_manager/include/screen_config.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 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_SCREEN_CONFIG_H +#define OHOS_ABILITY_RUNTIME_SCREEN_CONFIG_H + +#include +#include + +namespace OHOS { +namespace AAFwk { +struct ScreenConfig { + std::string type; + std::map sourceAppInfo; +}; +} // namespace AAFwk +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_SCREEN_CONFIG_H \ No newline at end of file diff --git a/interfaces/kits/native/ability/ability_runtime/start_vertical_panel.h b/interfaces/kits/native/ability/ability_runtime/start_vertical_panel.h new file mode 100644 index 0000000000000000000000000000000000000000..8482b6c1df08ec653ccfcb14cd1ab7860ea04cf7 --- /dev/null +++ b/interfaces/kits/native/ability/ability_runtime/start_vertical_panel.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 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_START_VERTICAL_PANEL_H +#define OHOS_ABILITY_RUNTIME_START_VERTICAL_PANEL_H + +#include "ability_context.h" +#include "panel_start_callback.h" +#include "screen_config.h" +#include "want_params.h" + +namespace OHOS { +namespace AbilityRuntime { +#ifdef SUPPORT_SCREEN + ErrCode StartVerticalPanel(std::shared_ptr context, + AAFwk::WantParams &wantParams, + const AAFwk::ScreenConfig &screenConfig, + std::shared_ptr panelStartCallback); +#endif +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_START_VERTICAL_PANEL_H \ No newline at end of file diff --git a/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h b/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h index 075f1e7263bedca32abd0861d77bfcb470c2ae6d..e2f30da75dded49882fd53375a6421e14ce17427 100644 --- a/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h +++ b/interfaces/kits/native/ability/native/ability_business_error/ability_business_error.h @@ -282,6 +282,8 @@ enum class AbilityErrorCode { ERROR_CODE_NOT_SUPPORT_START_DLP_FILES = 16000126, + ERROR_CODE_MAIN_WINDOW_NOT_EXIST = 16000135, + // target bundle is not in u1 ERROR_CODE_NO_U1 = 16000204, diff --git a/interfaces/kits/native/ability/native/panel_start_callback.h b/interfaces/kits/native/ability/native/panel_start_callback.h new file mode 100644 index 0000000000000000000000000000000000000000..e1244bcfdca3375c9f7b6a6244096eaf332504ae --- /dev/null +++ b/interfaces/kits/native/ability/native/panel_start_callback.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 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_PANEL_START_CALLBACK_H +#define OHOS_ABILITY_RUNTIME_PANEL_START_CALLBACK_H + +#include + +#include "want.h" + +namespace OHOS { +namespace Ace { +class UIContent; +} +namespace AbilityRuntime { +class PanelStartCallback { +public: + PanelStartCallback() = default; + virtual ~PanelStartCallback() = default; + void SetSessionId(int32_t sessionId); +#ifdef SUPPORT_SCREEN + virtual void OnError(int32_t number) = 0; + virtual void OnResult(int32_t resultCode, const AAFwk::Want &want) = 0; + void OnRelease(int32_t code); + void SetUIContent(Ace::UIContent *uiContent); + void CloseModalUIExtension(); +#endif // SUPPORT_SCREEN +private: + int32_t sessionId_ = 0; +#ifdef SUPPORT_SCREEN + Ace::UIContent *uiContent_ = nullptr; +#endif // SUPPORT_SCREEN +}; +} // namespace AbilityRuntime +} // namespace OHOS +#endif // OHOS_ABILITY_RUNTIME_PANEL_START_CALLBACK_H diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 2a291424e2d6d2fb30893c35ae3f6aa9b1e0bae9..7f5466a64095fd7f3196df2efba09cf9bc949a99 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -2591,7 +2591,13 @@ private: */ void StopSwitchUserDialogInner(const Want &want, const int32_t stopUserId); - void SetPickerElementName(const sptr &extensionSessionInfo, int32_t userId); + /** + * judge system params for picker + * @param WantParams, The wantparams of the want. + */ + bool JudgeSystemParamsForPicker(const WantParams ¶meters); + + void SetPickerElementNameAndParams(const sptr &extensionSessionInfo, int32_t userId); void SetAutoFillElementName(const sptr &extensionSessionInfo); diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index da29f8b836b117a1a7d275125e438efa832b421e..fdbc77ca40006375536dca2b198ed094f88310a7 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -243,12 +243,13 @@ constexpr const char* LIFE_CYCLE_STATE_FOREGROUND_DONE = "foreground done"; constexpr const char* LIFE_CYCLE_STATE_BACKGROUND_DONE = "background done"; const std::unordered_set COMMON_PICKER_TYPE = { - "share", "action" + "share", "action", "navigation", "mail", "finance", "flight", "express", "photoEditor" }; std::atomic g_isDmsAlive = false; constexpr int32_t PIPE_MSG_READ_BUFFER = 1024; constexpr const char* APPSPAWN_STARTED = "startup.service.ctl.appspawn.pid"; constexpr const char* APP_LINKING_ONLY = "appLinkingOnly"; +constexpr const char* SCREENCONFIG_SCREENMODE = "ohos.verticalpanel.screenconfig.screenmode"; void SendAbilityEvent(const EventName &eventName, HiSysEventType type, const EventInfo &eventInfo) { @@ -3756,7 +3757,21 @@ int32_t AbilityManagerService::StartExtensionAbilityInner(const Want &want, cons return eventInfo.errCode; } -void AbilityManagerService::SetPickerElementName(const sptr &extensionSessionInfo, int32_t userId) +bool AbilityManagerService::JudgeSystemParamsForPicker(const WantParams ¶meters) +{ + auto systemParamsForPickerMap = parameters.GetParams(); + if (systemParamsForPickerMap.find(SCREENCONFIG_SCREENMODE) == systemParamsForPickerMap.end()) { + return true; + } + + if (AAFwk::PermissionVerification::GetInstance()->JudgeCallerIsAllowedToUseSystemAPI()) { + return true; + } + TAG_LOGE(AAFwkTag::ABILITYMGR, "caller no system-app, can not use system-api"); + return false; +} + +void AbilityManagerService::SetPickerElementNameAndParams(const sptr &extensionSessionInfo, int32_t userId) { CHECK_POINTER_IS_NULLPTR(extensionSessionInfo); std::string targetType = extensionSessionInfo->want.GetStringParam(UIEXTENSION_TARGET_TYPE_KEY); @@ -3769,6 +3784,10 @@ void AbilityManagerService::SetPickerElementName(const sptr &extens extensionSessionInfo->want.SetElementName(bundleName, abilityName); WantParams ¶meters = const_cast(extensionSessionInfo->want.GetParams()); parameters.SetParam(UIEXTENSION_TYPE_KEY, AAFwk::String::Box("sys/commonUI")); + if (!JudgeSystemParamsForPicker(parameters)) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "parames include systemApi but not a systemAPP"); + extensionSessionInfo->want.RemoveParam(SCREENCONFIG_SCREENMODE); + } extensionSessionInfo->want.SetParams(parameters); return; } @@ -3807,6 +3826,11 @@ void AbilityManagerService::SetPickerElementName(const sptr &extens extensionSessionInfo->want.SetElementName(bundleName, abilityName); WantParams ¶meters = const_cast(extensionSessionInfo->want.GetParams()); parameters.SetParam(UIEXTENSION_TYPE_KEY, AAFwk::String::Box(pickerType)); + + if (!JudgeSystemParamsForPicker(parameters)) { + TAG_LOGI(AAFwkTag::ABILITYMGR, "parames include systemApi but not a systemAPP"); + extensionSessionInfo->want.RemoveParam(SCREENCONFIG_SCREENMODE); + } extensionSessionInfo->want.SetParams(parameters); } } @@ -3875,7 +3899,7 @@ int AbilityManagerService::StartUIExtensionAbility(const sptr &exte TAG_LOGD(AAFwkTag::UI_EXT, "StartUIExtensionAbility begin"); CheckExtensionRateLimit(); CHECK_POINTER_AND_RETURN(extensionSessionInfo, ERR_INVALID_VALUE); - SetPickerElementName(extensionSessionInfo, userId); + SetPickerElementNameAndParams(extensionSessionInfo, userId); SetAutoFillElementName(extensionSessionInfo); EventInfo eventInfo = BuildEventInfo(extensionSessionInfo->want, userId); eventInfo.persistentId = extensionSessionInfo->persistentId; diff --git a/services/common/include/hilog_tag_wrapper.h b/services/common/include/hilog_tag_wrapper.h index 5aaa6001aa88f0a99a8976ec25e42c5ec37a186a..ed76e625613feca3e2298f493030876d007eba99 100644 --- a/services/common/include/hilog_tag_wrapper.h +++ b/services/common/include/hilog_tag_wrapper.h @@ -98,8 +98,8 @@ enum class AAFwkLogTag : uint32_t { LOCAL_CALL = DEFAULT + 0x60, // 0xD001360 SA_INTERCEPTOR, - - APP_SERVICE_EXT = DEFAULT + 0x70, // 0xD001370 + APP_SERVICE_EXT, + VERTICAL_PANEL, END = 256, // N.B. never use it }; @@ -177,7 +177,7 @@ inline const char* GetDomainName5(AAFwkLogTag tag) inline const char* GetDomainName6(AAFwkLogTag tag) { - const char* tagNames[] = { "LocalCall" }; + const char* tagNames[] = { "LocalCall", "SaInterceptor", "AppServiceExt", "VerticalPanel" }; uint32_t offset = GetOffset(tag, AAFwkLogTag::LOCAL_CALL); if (offset >= sizeof(tagNames) / sizeof(const char*)) { return "UN"; diff --git a/test/unittest/ability_manager_service_third_test/ability_manager_service_third_test.cpp b/test/unittest/ability_manager_service_third_test/ability_manager_service_third_test.cpp index 5ef97093c07127ee2bf56af65459d16485e9916b..3efb95faabb3496108fbefe3528440ca9ebebb78 100644 --- a/test/unittest/ability_manager_service_third_test/ability_manager_service_third_test.cpp +++ b/test/unittest/ability_manager_service_third_test/ability_manager_service_third_test.cpp @@ -998,39 +998,39 @@ HWTEST_F(AbilityManagerServiceThirdTest, RegisterSessionHandler_002, TestSize.Le /* * Feature: AbilityManagerService - * Function: SetPickerElementName + * Function: SetPickerElementNameAndParams * SubFunction: NA - * FunctionPoints: AbilityManagerService SetPickerElementName + * FunctionPoints: AbilityManagerService SetPickerElementNameAndParams */ -HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementName_001, TestSize.Level1) +HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementNameAndParams_001, TestSize.Level1) { auto abilityMs_ = std::make_shared(); EXPECT_NE(abilityMs_, nullptr); - abilityMs_->SetPickerElementName(nullptr, USER_ID_U100); + abilityMs_->SetPickerElementNameAndParams(nullptr, USER_ID_U100); } /* * Feature: AbilityManagerService - * Function: SetPickerElementName + * Function: SetPickerElementNameAndParams * SubFunction: NA - * FunctionPoints: AbilityManagerService SetPickerElementName + * FunctionPoints: AbilityManagerService SetPickerElementNameAndParams */ -HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementName_002, TestSize.Level1) +HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementNameAndParams_002, TestSize.Level1) { auto abilityMs_ = std::make_shared(); EXPECT_NE(abilityMs_, nullptr); sptr sessionInfo = new SessionInfo(); const sptr extensionSessionInfo = sessionInfo; - abilityMs_->SetPickerElementName(extensionSessionInfo, USER_ID_U100); + abilityMs_->SetPickerElementNameAndParams(extensionSessionInfo, USER_ID_U100); } /* * Feature: AbilityManagerService - * Function: SetPickerElementName + * Function: SetPickerElementNameAndParams * SubFunction: NA - * FunctionPoints: AbilityManagerService SetPickerElementName + * FunctionPoints: AbilityManagerService SetPickerElementNameAndParams */ -HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementName_003, TestSize.Level1) +HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementNameAndParams_003, TestSize.Level1) { auto abilityMs_ = std::make_shared(); EXPECT_NE(abilityMs_, nullptr); @@ -1040,16 +1040,16 @@ HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementName_003, TestSize.Leve want.SetParam("ability.want.params.uiExtensionTargetType", type); sessionInfo->want = want; const sptr extensionSessionInfo = sessionInfo; - abilityMs_->SetPickerElementName(extensionSessionInfo, USER_ID_U100); + abilityMs_->SetPickerElementNameAndParams(extensionSessionInfo, USER_ID_U100); } /* * Feature: AbilityManagerService - * Function: SetPickerElementName + * Function: SetPickerElementNameAndParams * SubFunction: NA - * FunctionPoints: AbilityManagerService SetPickerElementName + * FunctionPoints: AbilityManagerService SetPickerElementNameAndParams */ -HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementName_004, TestSize.Level1) +HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementNameAndParams_004, TestSize.Level1) { auto abilityMs_ = std::make_shared(); EXPECT_NE(abilityMs_, nullptr); @@ -1058,7 +1058,7 @@ HWTEST_F(AbilityManagerServiceThirdTest, SetPickerElementName_004, TestSize.Leve want.SetElementName("com.example.share", "ShareUIExtensionAbility"); sessionInfo->want = want; const sptr extensionSessionInfo = sessionInfo; - abilityMs_->SetPickerElementName(extensionSessionInfo, USER_ID_U100); + abilityMs_->SetPickerElementNameAndParams(extensionSessionInfo, USER_ID_U100); } /*