From e1f415d7c667d2d073177b4ff5ea4d4c914a7cb3 Mon Sep 17 00:00:00 2001 From: xying6 Date: Tue, 29 Apr 2025 16:55:35 +0800 Subject: [PATCH 01/93] =?UTF-8?q?=E5=88=92=E8=AF=8DSA-=E6=8C=89=E9=9C=80?= =?UTF-8?q?=E5=90=AF=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- README.md | 58 ++++----- bundle.json | 40 +++++++ etc/init/BUILD.gn | 21 ++++ etc/init/word_selection.cfg | 16 +++ sa_profile/8567.json | 44 +++++++ sa_profile/BUILD.gn | 21 ++++ service/BUILD.gn | 48 ++++++++ service/include/word_selection_interface.h | 36 ++++++ service/include/word_selection_proxy.h | 39 +++++++ service/include/word_selection_service.h | 56 +++++++++ service/include/word_selection_stub.h | 30 +++++ service/src/word_selection_proxy.cpp | 42 +++++++ service/src/word_selection_service.cpp | 129 +++++++++++++++++++++ service/src/word_selection_stub.cpp | 37 ++++++ utils/include/word_selection_log.h | 50 ++++++++ word_selection.gni | 41 +++++++ 16 files changed, 680 insertions(+), 28 deletions(-) create mode 100644 bundle.json create mode 100644 etc/init/BUILD.gn create mode 100644 etc/init/word_selection.cfg create mode 100644 sa_profile/8567.json create mode 100644 sa_profile/BUILD.gn create mode 100644 service/BUILD.gn create mode 100644 service/include/word_selection_interface.h create mode 100644 service/include/word_selection_proxy.h create mode 100644 service/include/word_selection_service.h create mode 100644 service/include/word_selection_stub.h create mode 100644 service/src/word_selection_proxy.cpp create mode 100644 service/src/word_selection_service.cpp create mode 100644 service/src/word_selection_stub.cpp create mode 100644 utils/include/word_selection_log.h create mode 100644 word_selection.gni diff --git a/README.md b/README.md index 2246be8..e55ea80 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,41 @@ -# systemabilitymgr_selectionfwk +# Word Selection -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} -#### 软件架构 -软件架构说明 +## Introduction +The Word Selection module provides the following functions: -#### 安装教程 +1. A +2. B +3. C -1. xxxx -2. xxxx -3. xxxx +## Directory Structure -#### 使用说明 +Copied from powermgr: -1. xxxx -2. xxxx -3. xxxx +``` +/base/word_selection +├── figures # Architecture +├── frameworks # Framework layer +│ ├── napi # NAPI layer +│ └── native # Native layer +├── interfaces # API layer +│ └── inner_api # Internal APIs +├── power_dialog # Power dialog +├── sa_profile # SA profile +└── services # Service layer +│ ├── native # Native layer +│ └── zidl # Zidl API layer +├── test # Test cases +│ ├── fuzztest # Fuzz test +│ ├── unittest # Unit test +│ ├── systemtest # System test +│ └── utils # Test tools +└── utils # Utilities +``` -#### 参与贡献 -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +## Repositories Involved -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +Repositories Involved diff --git a/bundle.json b/bundle.json new file mode 100644 index 0000000..e87e955 --- /dev/null +++ b/bundle.json @@ -0,0 +1,40 @@ +{ + "name": "@ohos/word_selection", + "description": "Provide word selection capabilities", + "version": "1.0", + "license": "Apache License 2.0", + "segment": { + "destPath": "base/word_selection" + }, + "component": { + "name": "word_selection", + "subsystem": "word_selection_system", + "syscap": [], + "features": [], + "adapted_system_type": [ + "standard" + ], + "rom": "5120KB", + "ram": "5120KB", + "deps": { + "components": [ + "c_utils", + "ipc", + "safwk", + "hilog", + "samgr", + "input" + ], + "third_party": [ + ] + }, + "build": { + "sub_component": [ + "//base/word_selection/etc/init:word_selection_cfg", + "//base/word_selection/service:word_selection_base", + "//base/word_selection/sa_profile:word_selection_sa_profile" + ], + "inner_kits": [] + } + } + } \ No newline at end of file diff --git a/etc/init/BUILD.gn b/etc/init/BUILD.gn new file mode 100644 index 0000000..f0d59eb --- /dev/null +++ b/etc/init/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (C) 2024 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") + +## Install word_selection.cfg to /system/etc/init/word_selection.cfg +ohos_prebuilt_etc("word_selection_cfg") { + source = "word_selection.cfg" + relative_install_dir = "init" + part_name = "word_selection" + subsystem_name = "word_selection_system" +} \ No newline at end of file diff --git a/etc/init/word_selection.cfg b/etc/init/word_selection.cfg new file mode 100644 index 0000000..b824b0d --- /dev/null +++ b/etc/init/word_selection.cfg @@ -0,0 +1,16 @@ +{ + "services" : [{ + "name" : "word_selection", + "path" : ["/system/bin/sa_main", "/system/profile/word_selection.json"], + "ondemand": true, + "importance" : -20, + "once" : 0, + "uid" : "system", + "gid" : ["system", "shell"], + "permission" : [ + "ohos.permission.INPUT_MONITORING" + ], + "secon" : "u:r:powermgr:s0" + } + ] +} diff --git a/sa_profile/8567.json b/sa_profile/8567.json new file mode 100644 index 0000000..4833784 --- /dev/null +++ b/sa_profile/8567.json @@ -0,0 +1,44 @@ +{ + "process": "word_selection", + "systemability": [ + { + "name": 8567, + "libpath": "libword_selection_base.z.so", + "run-on-create": false, + "distributed": false, + "bootphase": "BootStartPhase", + "dump_level": 1, + "auto-restart" : true, + "start-on-demand": { + "allow-update": true, + "commonevent": [ + { + "name": "usual.event.SCREEN_ON", + "conditions": [ + { + "eventId": "param", + "name": "persist.sys.sa.word_selection.enable", + "value": "1" + } + ] + } + ] + }, + "stop-on-demand": { + "allow-update": true, + "commonevent": [ + { + "name": "usual.event.SCREEN_ON", + "conditions": [ + { + "eventId": "param", + "name": "persist.sys.sa.word_selection.enable", + "value": "0" + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn new file mode 100644 index 0000000..89e7aa5 --- /dev/null +++ b/sa_profile/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2021-2022 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/sa_profile/sa_profile.gni") +import("../word_selection.gni") + +ohos_sa_profile("word_selection_sa_profile") { + sources = [ "8567.json" ] + + part_name = "word_selection" +} \ No newline at end of file diff --git a/service/BUILD.gn b/service/BUILD.gn new file mode 100644 index 0000000..e7c602e --- /dev/null +++ b/service/BUILD.gn @@ -0,0 +1,48 @@ +# Copyright (c) 2022 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/test.gni") +import("//build/config/components/idl_tool/idl.gni") + +config("word_selection_sa_config") { + visibility = [ ":*" ] + include_dirs = [ + "include", + "../utils/include", + ] +} + +ohos_shared_library("word_selection_base") { + sources = [ + "src/word_selection_proxy.cpp", + "src/word_selection_service.cpp", + "src/word_selection_stub.cpp", + ] + configs = [ + ":word_selection_sa_config", + ] + + deps = [ ] + + external_deps = [ + "c_utils:utils", + "ipc:ipc_single", + "hilog:libhilog", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + "input:libmmi-client", + ] + + part_name = "word_selection" + subsystem_name = "word_selection_system" +} \ No newline at end of file diff --git a/service/include/word_selection_interface.h b/service/include/word_selection_interface.h new file mode 100644 index 0000000..1efba6a --- /dev/null +++ b/service/include/word_selection_interface.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 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 BASE_WORD_SELECTION_INTERFACE_H +#define BASE_WORD_SELECTION_INTERFACE_H + +#include + +#include "iremote_broker.h" +#include "iremote_object.h" +#include "iremote_stub.h" +#include "iremote_proxy.h" + +namespace OHOS { +class WordSelectionInterface : public IRemoteBroker { +public: + virtual int32_t AddVolume(int volume) = 0; + enum { + ADD_VOLUME = 1, + }; + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.test.WordSelectionSAInterface"); +}; +} +#endif // BASE_WORD_SELECTION_INTERFACE_H \ No newline at end of file diff --git a/service/include/word_selection_proxy.h b/service/include/word_selection_proxy.h new file mode 100644 index 0000000..f0d7531 --- /dev/null +++ b/service/include/word_selection_proxy.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 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 BASE_WORD_SELECTION_PROXY_H +#define BASE_WORD_SELECTION_PROXY_H + +#include + +#include "word_selection_interface.h" +#include "iremote_broker.h" +#include "iremote_proxy.h" +#include "refbase.h" + +namespace OHOS { +class WordSelectionProxy : public IRemoteProxy { +public: + explicit WordSelectionProxy(const sptr& impl) + : IRemoteProxy(impl) {} + ~WordSelectionProxy() = default; + + int AddVolume(int volume) override; +private: + static inline BrokerDelegator delegator_; +}; +} + +#endif // BASE_WORD_SELECTION_PROXY_H \ No newline at end of file diff --git a/service/include/word_selection_service.h b/service/include/word_selection_service.h new file mode 100644 index 0000000..56f81ca --- /dev/null +++ b/service/include/word_selection_service.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 BASE_WORD_SELECTION_SERVICE_H +#define BASE_WORD_SELECTION_SERVICE_H + +#include + +#include "word_selection_stub.h" +#include "refbase.h" +#include "system_ability.h" +#include + +namespace OHOS { +using namespace MMI; +class WordSelectionService : public SystemAbility, public WordSelectionStub { + DECLARE_SYSTEM_ABILITY(WordSelectionService); + +public: + WordSelectionService(int32_t saId, bool runOnCreate); + ~WordSelectionService(); + + int AddVolume(int volume) override; +protected: + void OnStart() override; + void OnStop() override; + void HandleKeyEvent(int32_t keyCode); + void HandlePointEvent(int32_t type); +private: + int32_t inputMonitorId_ {-1}; + void InputMonitorInit(); + void InputMonitorCancel(); +}; + +class WordSelectionInputMonitor : public IInputEventConsumer { +public: + virtual void OnInputEvent(std::shared_ptr keyEvent) const; + virtual void OnInputEvent(std::shared_ptr pointerEvent) const; + virtual void OnInputEvent(std::shared_ptr axisEvent) const; +}; + +} + +#endif // BASE_WORD_SELECTION_SERVICE_H \ No newline at end of file diff --git a/service/include/word_selection_stub.h b/service/include/word_selection_stub.h new file mode 100644 index 0000000..ee4bf44 --- /dev/null +++ b/service/include/word_selection_stub.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 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 BASE_WORD_SELECTION_STUB_H +#define BASE_WORD_SELECTION_STUB_H + +#include "word_selection_interface.h" +#include "iremote_stub.h" +#include "refbase.h" + +namespace OHOS { +class WordSelectionStub : public IRemoteStub { +public: + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; +}; +} + +#endif // BASE_WORD_SELECTION_STUB_H \ No newline at end of file diff --git a/service/src/word_selection_proxy.cpp b/service/src/word_selection_proxy.cpp new file mode 100644 index 0000000..22de9eb --- /dev/null +++ b/service/src/word_selection_proxy.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 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 "word_selection_proxy.h" + +#include "iremote_object.h" +#include "message_option.h" +#include "message_parcel.h" + +namespace OHOS { +namespace { + const int DEFAULT_INT_RET = -1; +} + +int WordSelectionProxy::AddVolume(int volume) +{ + auto remote = Remote(); + if (remote == nullptr) { + return DEFAULT_INT_RET; + } + MessageParcel data; + data.WriteInt32(volume); + MessageParcel reply; + MessageOption option; + remote->SendRequest(ADD_VOLUME, data, reply, option); + + int32_t result = reply.ReadInt32(); + return result; +} +} \ No newline at end of file diff --git a/service/src/word_selection_service.cpp b/service/src/word_selection_service.cpp new file mode 100644 index 0000000..0367a97 --- /dev/null +++ b/service/src/word_selection_service.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2021 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 "word_selection_service.h" + +#include "iremote_object.h" +#include "system_ability_definition.h" +#include "word_selection_log.h" +#include + +using namespace OHOS; +REGISTER_SYSTEM_ABILITY_BY_ID(WordSelectionService, WORD_SELECTION_SA_ID, true); + +WordSelectionService::WordSelectionService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) +{ + LOG_INFO("[YMZ][WordSelectionService] saID=%{public}d runOnCreate=%{public}d", saId, runOnCreate); +} + +WordSelectionService::~WordSelectionService() +{ + LOG_INFO("[YMZ][~WordSelectionService]"); +} + +int WordSelectionService::AddVolume(int volume) +{ + LOG_INFO("[YMZ][WordSelectionService][AddVolume]begin"); + return (volume + 1); +} + +void WordSelectionService::OnStart() +{ + LOG_INFO("[YMZ][WordSelectionService][OnStart]begin"); + Publish(this); + InputMonitorInit(); + LOG_INFO("[YMZ][WordSelectionService][OnStart]end"); +} + +void WordSelectionService::OnStop() +{ + LOG_INFO("[YMZ][WordSelectionService][OnStop]begin"); + InputMonitorCancel(); + LOG_INFO("[YMZ][WordSelectionService][OnStop]end"); +} + + +void WordSelectionService::InputMonitorInit() +{ + LOG_INFO("[YMZ]WordSelection service input monitor init"); + std::shared_ptr inputMonitor = std::make_shared(); + if (inputMonitorId_ < 0) { + inputMonitorId_ = + InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); + } +} + +void WordSelectionService::InputMonitorCancel() +{ + LOG_INFO("[YMZ]WordSelection service input monitor cancel"); + InputManager* inputManager = InputManager::GetInstance(); + if (inputMonitorId_ >= 0) { + inputManager->RemoveMonitor(inputMonitorId_); + inputMonitorId_ = -1; + } +} + +void WordSelectionService::HandleKeyEvent(int32_t keyCode) +{ +#ifdef HAS_MULTIMODALINPUT_INPUT_PART + LOG_INFO("[YMZ] keyCode: %{public}d", keyCode); + int64_t now = static_cast(time(nullptr)); + if (IsScreenOn()) { + this->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false); + } else { + if (keyCode == KeyEvent::KEYCODE_F1) { + POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Wakeup by double click"); + std::string reason = "double click"; + reason.append(std::to_string(keyCode)); + this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK, reason); + } else if (keyCode >= KeyEvent::KEYCODE_0 && keyCode <= KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN) { + POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Wakeup by keyboard"); + std::string reason = "keyboard:"; + reason.append(std::to_string(keyCode)); + this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD, reason); + } + } +#endif +} + +void WordSelectionService::HandlePointEvent(int32_t type) +{ +#ifdef HAS_MULTIMODALINPUT_INPUT_PART + LOG_INFO("type: %{public}d", type); + int64_t now = static_cast(time(nullptr)); + if (this->IsScreenOn()) { + this->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_ATTENTION, false); + } else { + if (type == PointerEvent::SOURCE_TYPE_MOUSE) { + std::string reason = "mouse click"; + POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Wakeup by mouse"); + this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_MOUSE, reason); + } + } +#endif +} + +// foundation/multimodalinput/input/interfaces/native/innerkits/event/include/key_event.h +void WordSelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const +{ + LOG_INFO("[YMZ]keyId: %{public}d", keyEvent->GetKeyCode()); +} + +void WordSelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const +{ + LOG_INFO("[YMZ]pointerEvent: %{public}d", (int32_t)pointerEvent->GetPointerAction()); +} + +void WordSelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const {}; \ No newline at end of file diff --git a/service/src/word_selection_stub.cpp b/service/src/word_selection_stub.cpp new file mode 100644 index 0000000..53601a3 --- /dev/null +++ b/service/src/word_selection_stub.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 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 "word_selection_stub.h" + +#include "errors.h" +#include "ipc_object_stub.h" +#include "ipc_types.h" +#include "message_option.h" +#include "message_parcel.h" + +namespace OHOS { +int32_t WordSelectionStub::OnRemoteRequest(uint32_t code, + MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + switch (code) { + case ADD_VOLUME: { + bool ret = reply.WriteInt32(AddVolume(data.ReadInt32())); + return (ret ? ERR_OK : ERR_FLATTEN_OBJECT); + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } +} +} \ No newline at end of file diff --git a/utils/include/word_selection_log.h b/utils/include/word_selection_log.h new file mode 100644 index 0000000..5252402 --- /dev/null +++ b/utils/include/word_selection_log.h @@ -0,0 +1,50 @@ +/* + * 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 WORD_SELECTION_LOG_H +#define WORD_SELECTION_LOG_H +#include "hilog/log.h" +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#undef LOG_TAG +#define LOG_TAG "WORD_SELETION" +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD002901 + +#ifndef WORD_SELETION_DEBUG_ENABLE +#define WORD_SELETION_DEBUG_ENABLE 0 +#endif + +#define FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) +#define DEMO_LOG(func, fmt, args...) \ + do { \ + func(LOG_CORE, "{%{public}s:%{public}d %{public}s()} " fmt, FILENAME, __LINE__, __FUNCTION__, ##args); \ + } while (false) + +#define LOG_DEBUG(fmt, ...) DEMO_LOG(HILOG_DEBUG, fmt, ##__VA_ARGS__) +#define LOG_INFO(fmt, ...) DEMO_LOG(HILOG_INFO, fmt, ##__VA_ARGS__) +#define LOG_WARN(fmt, ...) DEMO_LOG(HILOG_WARN, fmt, ##__VA_ARGS__) +#define LOG_ERROR(fmt, ...) DEMO_LOG(HILOG_ERROR, fmt, ##__VA_ARGS__) +#define LOG_FATAL(fmt, ...) DEMO_LOG(HILOG_FATAL, fmt, ##__VA_ARGS__) + +#ifdef __cplusplus +} +#endif + +#endif // WORD_SELECTION_LOG_H \ No newline at end of file diff --git a/word_selection.gni b/word_selection.gni new file mode 100644 index 0000000..fbed2c8 --- /dev/null +++ b/word_selection.gni @@ -0,0 +1,41 @@ +# Copyright (c) 2021 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") + +declare_args() { + word_selection_feature_test_one = true +} + + +ability_runtime_path = "//foundation/ability/ability_runtime" + +ability_runtime_inner_api_path = "${ability_runtime_path}/interfaces/inner_api" + +ability_runtime_services_path = "${ability_runtime_path}/services" +word_selection_part_name = "word_selection" + +word_selection_root_path = "//base/word_selection" + +word_selection_service_path = "${word_selection_root_path}/services" + +word_selection_service_zidl = "${word_selection_service_path}/zidl" + +word_selection_framework = "${word_selection_root_path}/frameworks" +word_selection_framework_native = "${word_selection_framework}/native" + +word_selection_inner_api = "${word_selection_root_path}/interfaces/inner_api" + +word_selection_utils_path = "${word_selection_root_path}/utils" + +system_type = "default" \ No newline at end of file -- Gitee From a785f88c0df7c8c0a8dfdff0ce0905900d1fce42 Mon Sep 17 00:00:00 2001 From: xying6 Date: Wed, 30 Apr 2025 08:40:19 +0800 Subject: [PATCH 02/93] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=88=92=E8=AF=8DSA?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BB=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 12 ++++++------ etc/init/BUILD.gn | 6 +++--- sa_profile/BUILD.gn | 2 +- service/BUILD.gn | 6 +++--- service/include/word_selection_service.h | 1 + service/src/word_selection_service.cpp | 6 ++++++ utils/include/word_selection_log.h | 2 +- 7 files changed, 21 insertions(+), 14 deletions(-) diff --git a/bundle.json b/bundle.json index e87e955..d1185d6 100644 --- a/bundle.json +++ b/bundle.json @@ -4,11 +4,11 @@ "version": "1.0", "license": "Apache License 2.0", "segment": { - "destPath": "base/word_selection" + "destPath": "foundation/systemabilitymgr/word_selection" }, "component": { - "name": "word_selection", - "subsystem": "word_selection_system", + "name": "selectionfwk", + "subsystem": "systemabilitymgr", "syscap": [], "features": [], "adapted_system_type": [ @@ -30,9 +30,9 @@ }, "build": { "sub_component": [ - "//base/word_selection/etc/init:word_selection_cfg", - "//base/word_selection/service:word_selection_base", - "//base/word_selection/sa_profile:word_selection_sa_profile" + "//foundation/systemabilitymgr/selection_fwk/etc/init:word_selection_cfg", + "//foundation/systemabilitymgr/selection_fwk/service:word_selection_base", + "//foundation/systemabilitymgr/selection_fwk/sa_profile:word_selection_sa_profile" ], "inner_kits": [] } diff --git a/etc/init/BUILD.gn b/etc/init/BUILD.gn index f0d59eb..cd0775b 100644 --- a/etc/init/BUILD.gn +++ b/etc/init/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (C) 2024 Huawei Device Co., Ltd. +# 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 @@ -16,6 +16,6 @@ import("//build/ohos.gni") ohos_prebuilt_etc("word_selection_cfg") { source = "word_selection.cfg" relative_install_dir = "init" - part_name = "word_selection" - subsystem_name = "word_selection_system" + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" } \ No newline at end of file diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn index 89e7aa5..66325b2 100644 --- a/sa_profile/BUILD.gn +++ b/sa_profile/BUILD.gn @@ -17,5 +17,5 @@ import("../word_selection.gni") ohos_sa_profile("word_selection_sa_profile") { sources = [ "8567.json" ] - part_name = "word_selection" + part_name = "selectionfwk" } \ No newline at end of file diff --git a/service/BUILD.gn b/service/BUILD.gn index e7c602e..0a7eea8 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Huawei Device Co., Ltd. +# 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 @@ -43,6 +43,6 @@ ohos_shared_library("word_selection_base") { "input:libmmi-client", ] - part_name = "word_selection" - subsystem_name = "word_selection_system" + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" } \ No newline at end of file diff --git a/service/include/word_selection_service.h b/service/include/word_selection_service.h index 56f81ca..6aba968 100644 --- a/service/include/word_selection_service.h +++ b/service/include/word_selection_service.h @@ -33,6 +33,7 @@ public: ~WordSelectionService(); int AddVolume(int volume) override; + int32_t Dump(int32_t fd, const std::vector &args) override; protected: void OnStart() override; void OnStop() override; diff --git a/service/src/word_selection_service.cpp b/service/src/word_selection_service.cpp index 0367a97..0660258 100644 --- a/service/src/word_selection_service.cpp +++ b/service/src/word_selection_service.cpp @@ -39,6 +39,12 @@ int WordSelectionService::AddVolume(int volume) return (volume + 1); } +int32_t WordSelectionService::Dump(int32_t fd, const std::vector &args) +{ + dprintf(fd, "---------------------WordSelectionService::Dump--------------------\n"); + return OHOS::NO_ERROR; +} + void WordSelectionService::OnStart() { LOG_INFO("[YMZ][WordSelectionService][OnStart]begin"); diff --git a/utils/include/word_selection_log.h b/utils/include/word_selection_log.h index 5252402..fa3b22f 100644 --- a/utils/include/word_selection_log.h +++ b/utils/include/word_selection_log.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 -- Gitee From 5acd87dcd7a2990c9978eff813c4ad555da21e93 Mon Sep 17 00:00:00 2001 From: xying6 Date: Wed, 30 Apr 2025 17:55:13 +0800 Subject: [PATCH 03/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=8E=A5=E5=8F=A3idl?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- service/BUILD.gn | 27 ++++++++---- ...ction_stub.h => IWordSelectionService.idl} | 21 ++-------- service/include/word_selection_interface.h | 36 ---------------- service/include/word_selection_proxy.h | 39 ----------------- service/include/word_selection_service.h | 8 ++-- service/libword_selection_service.map | 8 ++++ service/src/word_selection_proxy.cpp | 42 ------------------- service/src/word_selection_service.cpp | 4 +- service/src/word_selection_stub.cpp | 37 ---------------- 9 files changed, 37 insertions(+), 185 deletions(-) rename service/{include/word_selection_stub.h => IWordSelectionService.idl} (54%) delete mode 100644 service/include/word_selection_interface.h delete mode 100644 service/include/word_selection_proxy.h create mode 100644 service/libword_selection_service.map delete mode 100644 service/src/word_selection_proxy.cpp delete mode 100644 service/src/word_selection_stub.cpp diff --git a/service/BUILD.gn b/service/BUILD.gn index 0a7eea8..2a1dc7b 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/test.gni") +import("//build/ohos.gni") import("//build/config/components/idl_tool/idl.gni") config("word_selection_sa_config") { @@ -19,20 +19,31 @@ config("word_selection_sa_config") { include_dirs = [ "include", "../utils/include", + "${target_gen_dir}", ] } +idl_interface_sources = [ + "${target_gen_dir}/word_selection_service_proxy.cpp", + "${target_gen_dir}/word_selection_service_stub.cpp", +] + +idl_gen_interface("word_selection_service_interface") { + src_idl = rebase_path("IWordSelectionService.idl") + dst_file = string_join(",", idl_interface_sources) +} + ohos_shared_library("word_selection_base") { + configs = [ ":word_selection_sa_config", ] + shlib_type = "sa" + version_script = "libword_selection_service.map" + output_values = get_target_outputs(":word_selection_service_interface") + sources = [ - "src/word_selection_proxy.cpp", "src/word_selection_service.cpp", - "src/word_selection_stub.cpp", - ] - configs = [ - ":word_selection_sa_config", ] - - deps = [ ] + sources += filter_include(output_values, [ "*.cpp" ]) + deps = [ ":word_selection_service_interface" ] external_deps = [ "c_utils:utils", diff --git a/service/include/word_selection_stub.h b/service/IWordSelectionService.idl similarity index 54% rename from service/include/word_selection_stub.h rename to service/IWordSelectionService.idl index ee4bf44..f2ba9d1 100644 --- a/service/include/word_selection_stub.h +++ b/service/IWordSelectionService.idl @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 @@ -12,19 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#ifndef BASE_WORD_SELECTION_STUB_H -#define BASE_WORD_SELECTION_STUB_H - -#include "word_selection_interface.h" -#include "iremote_stub.h" -#include "refbase.h" - -namespace OHOS { -class WordSelectionStub : public IRemoteStub { -public: - int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; -}; -} - -#endif // BASE_WORD_SELECTION_STUB_H \ No newline at end of file +interface OHOS.SelectionFwk.IWordSelectionService { + int AddVolume([in] int volume); +} \ No newline at end of file diff --git a/service/include/word_selection_interface.h b/service/include/word_selection_interface.h deleted file mode 100644 index 1efba6a..0000000 --- a/service/include/word_selection_interface.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2022 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 BASE_WORD_SELECTION_INTERFACE_H -#define BASE_WORD_SELECTION_INTERFACE_H - -#include - -#include "iremote_broker.h" -#include "iremote_object.h" -#include "iremote_stub.h" -#include "iremote_proxy.h" - -namespace OHOS { -class WordSelectionInterface : public IRemoteBroker { -public: - virtual int32_t AddVolume(int volume) = 0; - enum { - ADD_VOLUME = 1, - }; - DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.test.WordSelectionSAInterface"); -}; -} -#endif // BASE_WORD_SELECTION_INTERFACE_H \ No newline at end of file diff --git a/service/include/word_selection_proxy.h b/service/include/word_selection_proxy.h deleted file mode 100644 index f0d7531..0000000 --- a/service/include/word_selection_proxy.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2022 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 BASE_WORD_SELECTION_PROXY_H -#define BASE_WORD_SELECTION_PROXY_H - -#include - -#include "word_selection_interface.h" -#include "iremote_broker.h" -#include "iremote_proxy.h" -#include "refbase.h" - -namespace OHOS { -class WordSelectionProxy : public IRemoteProxy { -public: - explicit WordSelectionProxy(const sptr& impl) - : IRemoteProxy(impl) {} - ~WordSelectionProxy() = default; - - int AddVolume(int volume) override; -private: - static inline BrokerDelegator delegator_; -}; -} - -#endif // BASE_WORD_SELECTION_PROXY_H \ No newline at end of file diff --git a/service/include/word_selection_service.h b/service/include/word_selection_service.h index 6aba968..cd95912 100644 --- a/service/include/word_selection_service.h +++ b/service/include/word_selection_service.h @@ -18,21 +18,21 @@ #include -#include "word_selection_stub.h" +#include "word_selection_service_stub.h" #include "refbase.h" #include "system_ability.h" #include -namespace OHOS { +namespace OHOS::SelectionFwk { using namespace MMI; -class WordSelectionService : public SystemAbility, public WordSelectionStub { +class WordSelectionService : public SystemAbility, public WordSelectionServiceStub { DECLARE_SYSTEM_ABILITY(WordSelectionService); public: WordSelectionService(int32_t saId, bool runOnCreate); ~WordSelectionService(); - int AddVolume(int volume) override; + ErrCode AddVolume(int32_t volume, int32_t& funcResult) override; int32_t Dump(int32_t fd, const std::vector &args) override; protected: void OnStart() override; diff --git a/service/libword_selection_service.map b/service/libword_selection_service.map new file mode 100644 index 0000000..547ed48 --- /dev/null +++ b/service/libword_selection_service.map @@ -0,0 +1,8 @@ +{ + global: + extern "C++" { + OHOS::SelectionFwk::WordSelectionService::AddVolume*; + }; + local: + *; +}; \ No newline at end of file diff --git a/service/src/word_selection_proxy.cpp b/service/src/word_selection_proxy.cpp deleted file mode 100644 index 22de9eb..0000000 --- a/service/src/word_selection_proxy.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2022 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 "word_selection_proxy.h" - -#include "iremote_object.h" -#include "message_option.h" -#include "message_parcel.h" - -namespace OHOS { -namespace { - const int DEFAULT_INT_RET = -1; -} - -int WordSelectionProxy::AddVolume(int volume) -{ - auto remote = Remote(); - if (remote == nullptr) { - return DEFAULT_INT_RET; - } - MessageParcel data; - data.WriteInt32(volume); - MessageParcel reply; - MessageOption option; - remote->SendRequest(ADD_VOLUME, data, reply, option); - - int32_t result = reply.ReadInt32(); - return result; -} -} \ No newline at end of file diff --git a/service/src/word_selection_service.cpp b/service/src/word_selection_service.cpp index 0660258..ee6e3aa 100644 --- a/service/src/word_selection_service.cpp +++ b/service/src/word_selection_service.cpp @@ -21,6 +21,7 @@ #include using namespace OHOS; +using namespace OHOS::SelectionFwk; REGISTER_SYSTEM_ABILITY_BY_ID(WordSelectionService, WORD_SELECTION_SA_ID, true); WordSelectionService::WordSelectionService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) @@ -33,7 +34,7 @@ WordSelectionService::~WordSelectionService() LOG_INFO("[YMZ][~WordSelectionService]"); } -int WordSelectionService::AddVolume(int volume) +ErrCode WordSelectionService::AddVolume(int32_t volume, int32_t& funcResult) { LOG_INFO("[YMZ][WordSelectionService][AddVolume]begin"); return (volume + 1); @@ -60,7 +61,6 @@ void WordSelectionService::OnStop() LOG_INFO("[YMZ][WordSelectionService][OnStop]end"); } - void WordSelectionService::InputMonitorInit() { LOG_INFO("[YMZ]WordSelection service input monitor init"); diff --git a/service/src/word_selection_stub.cpp b/service/src/word_selection_stub.cpp deleted file mode 100644 index 53601a3..0000000 --- a/service/src/word_selection_stub.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2022 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 "word_selection_stub.h" - -#include "errors.h" -#include "ipc_object_stub.h" -#include "ipc_types.h" -#include "message_option.h" -#include "message_parcel.h" - -namespace OHOS { -int32_t WordSelectionStub::OnRemoteRequest(uint32_t code, - MessageParcel& data, MessageParcel& reply, MessageOption& option) -{ - switch (code) { - case ADD_VOLUME: { - bool ret = reply.WriteInt32(AddVolume(data.ReadInt32())); - return (ret ? ERR_OK : ERR_FLATTEN_OBJECT); - } - default: - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); - } -} -} \ No newline at end of file -- Gitee From 3ec3d8604d02d9871953a4efb776e05d8ce0ad80 Mon Sep 17 00:00:00 2001 From: xying6 Date: Wed, 7 May 2025 17:31:39 +0800 Subject: [PATCH 04/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9SA=E4=B8=BAselection=5F?= =?UTF-8?q?service=20=E5=8F=8A=20SA=E6=8C=89=E7=B3=BB=E7=BB=9F=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=90=AF=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 74 ++++++++-------- etc/init/BUILD.gn | 5 +- ...rd_selection.cfg => selection_service.cfg} | 7 +- etc/para/BUILD.gn | 28 +++++++ etc/para/selection.para | 16 ++++ etc/para/selection.para.dac | 14 ++++ sa_profile/{8567.json => 8500.json} | 34 +++----- sa_profile/BUILD.gn | 6 +- word_selection.gni => selection_service.gni | 0 service/BUILD.gn | 22 ++--- ...ctionService.idl => ISelectionService.idl} | 2 +- ...election_service.h => selection_service.h} | 26 +++--- ...n_service.map => libselection_service.map} | 2 +- ...tion_service.cpp => selection_service.cpp} | 84 ++++++++++++------- .../{word_selection_log.h => selection_log.h} | 24 +++--- 15 files changed, 210 insertions(+), 134 deletions(-) rename etc/init/{word_selection.cfg => selection_service.cfg} (56%) create mode 100644 etc/para/BUILD.gn create mode 100644 etc/para/selection.para create mode 100644 etc/para/selection.para.dac rename sa_profile/{8567.json => 8500.json} (34%) rename word_selection.gni => selection_service.gni (100%) rename service/{IWordSelectionService.idl => ISelectionService.idl} (92%) rename service/include/{word_selection_service.h => selection_service.h} (69%) rename service/{libword_selection_service.map => libselection_service.map} (48%) rename service/src/{word_selection_service.cpp => selection_service.cpp} (50%) rename utils/include/{word_selection_log.h => selection_log.h} (62%) diff --git a/bundle.json b/bundle.json index d1185d6..3643016 100644 --- a/bundle.json +++ b/bundle.json @@ -1,40 +1,42 @@ { - "name": "@ohos/word_selection", - "description": "Provide word selection capabilities", - "version": "1.0", - "license": "Apache License 2.0", - "segment": { - "destPath": "foundation/systemabilitymgr/word_selection" + "name": "@ohos/selection_service", + "description": "Provide word selection capabilities", + "version": "1.0", + "license": "Apache License 2.0", + "segment": { + "destPath": "foundation/systemabilitymgr/selection_service" + }, + "component": { + "name": "selectionfwk", + "subsystem": "systemabilitymgr", + "syscap": [], + "features": [], + "adapted_system_type": [ + "standard" + ], + "rom": "5831KB", + "ram": "5831KB", + "deps": { + "components": [ + "c_utils", + "ipc", + "safwk", + "hilog", + "samgr", + "input" + ], + "third_party": [ + ] }, - "component": { - "name": "selectionfwk", - "subsystem": "systemabilitymgr", - "syscap": [], - "features": [], - "adapted_system_type": [ - "standard" + "build": { + "sub_component": [ + "//foundation/systemabilitymgr/selection_fwk/etc/init:selection_service_cfg", + "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para", + "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para_dac", + "//foundation/systemabilitymgr/selection_fwk/service:selection_service", + "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile" ], - "rom": "5120KB", - "ram": "5120KB", - "deps": { - "components": [ - "c_utils", - "ipc", - "safwk", - "hilog", - "samgr", - "input" - ], - "third_party": [ - ] - }, - "build": { - "sub_component": [ - "//foundation/systemabilitymgr/selection_fwk/etc/init:word_selection_cfg", - "//foundation/systemabilitymgr/selection_fwk/service:word_selection_base", - "//foundation/systemabilitymgr/selection_fwk/sa_profile:word_selection_sa_profile" - ], - "inner_kits": [] - } + "inner_kits": [] } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/etc/init/BUILD.gn b/etc/init/BUILD.gn index cd0775b..6da8595 100644 --- a/etc/init/BUILD.gn +++ b/etc/init/BUILD.gn @@ -12,9 +12,8 @@ # limitations under the License. import("//build/ohos.gni") -## Install word_selection.cfg to /system/etc/init/word_selection.cfg -ohos_prebuilt_etc("word_selection_cfg") { - source = "word_selection.cfg" +ohos_prebuilt_etc("selection_service_cfg") { + source = "selection_service.cfg" relative_install_dir = "init" part_name = "selectionfwk" subsystem_name = "systemabilitymgr" diff --git a/etc/init/word_selection.cfg b/etc/init/selection_service.cfg similarity index 56% rename from etc/init/word_selection.cfg rename to etc/init/selection_service.cfg index b824b0d..06570f2 100644 --- a/etc/init/word_selection.cfg +++ b/etc/init/selection_service.cfg @@ -1,15 +1,18 @@ { "services" : [{ - "name" : "word_selection", - "path" : ["/system/bin/sa_main", "/system/profile/word_selection.json"], + "name" : "selection_service", + "path" : ["/system/bin/sa_main", "/system/profile/selection_service.json"], "ondemand": true, "importance" : -20, "once" : 0, "uid" : "system", "gid" : ["system", "shell"], + "apl": "system_basic", "permission" : [ "ohos.permission.INPUT_MONITORING" ], + "permission_acls" : ["ohos.permission.INPUT_MONITORING"], + "caps" : [], "secon" : "u:r:powermgr:s0" } ] diff --git a/etc/para/BUILD.gn b/etc/para/BUILD.gn new file mode 100644 index 0000000..2fb6af2 --- /dev/null +++ b/etc/para/BUILD.gn @@ -0,0 +1,28 @@ +# 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") + +ohos_prebuilt_etc("selection_para") { + source = "./selection.para" + module_install_dir = "etc/param" + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} + +ohos_prebuilt_etc("selection_para_dac") { + source = "./selection.para.dac" + module_install_dir = "etc/param" + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} diff --git a/etc/para/selection.para b/etc/para/selection.para new file mode 100644 index 0000000..073203e --- /dev/null +++ b/etc/para/selection.para @@ -0,0 +1,16 @@ +# 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. + +sys.selection.switch.username = off +sys.selection.trigger.username = ctrl +sys.selection.app.username = com.hm.youdao diff --git a/etc/para/selection.para.dac b/etc/para/selection.para.dac new file mode 100644 index 0000000..91f5f12 --- /dev/null +++ b/etc/para/selection.para.dac @@ -0,0 +1,14 @@ +# 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. + +sys.selection. = sysselection:sysselection:0775 \ No newline at end of file diff --git a/sa_profile/8567.json b/sa_profile/8500.json similarity index 34% rename from sa_profile/8567.json rename to sa_profile/8500.json index 4833784..bc133d2 100644 --- a/sa_profile/8567.json +++ b/sa_profile/8500.json @@ -1,9 +1,9 @@ { - "process": "word_selection", + "process": "selection_service", "systemability": [ { - "name": 8567, - "libpath": "libword_selection_base.z.so", + "name": 8500, + "libpath": "libselection_service.z.so", "run-on-create": false, "distributed": false, "bootphase": "BootStartPhase", @@ -11,32 +11,20 @@ "auto-restart" : true, "start-on-demand": { "allow-update": true, - "commonevent": [ + "param": [ { - "name": "usual.event.SCREEN_ON", - "conditions": [ - { - "eventId": "param", - "name": "persist.sys.sa.word_selection.enable", - "value": "1" - } - ] + "name":"sys.selection.switch.username", + "value":"on" } ] }, "stop-on-demand": { "allow-update": true, - "commonevent": [ - { - "name": "usual.event.SCREEN_ON", - "conditions": [ - { - "eventId": "param", - "name": "persist.sys.sa.word_selection.enable", - "value": "0" - } - ] - } + "param": [ + { + "name":"sys.selection.switch.username", + "value":"off" + } ] } } diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn index 66325b2..87a3f4e 100644 --- a/sa_profile/BUILD.gn +++ b/sa_profile/BUILD.gn @@ -12,10 +12,10 @@ # limitations under the License. import("//build/ohos/sa_profile/sa_profile.gni") -import("../word_selection.gni") +import("../selection_service.gni") -ohos_sa_profile("word_selection_sa_profile") { - sources = [ "8567.json" ] +ohos_sa_profile("selection_service_sa_profile") { + sources = [ "8500.json" ] part_name = "selectionfwk" } \ No newline at end of file diff --git a/word_selection.gni b/selection_service.gni similarity index 100% rename from word_selection.gni rename to selection_service.gni diff --git a/service/BUILD.gn b/service/BUILD.gn index 2a1dc7b..0a6f0c6 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -14,7 +14,7 @@ import("//build/ohos.gni") import("//build/config/components/idl_tool/idl.gni") -config("word_selection_sa_config") { +config("selection_sa_config") { visibility = [ ":*" ] include_dirs = [ "include", @@ -24,26 +24,26 @@ config("word_selection_sa_config") { } idl_interface_sources = [ - "${target_gen_dir}/word_selection_service_proxy.cpp", - "${target_gen_dir}/word_selection_service_stub.cpp", + "${target_gen_dir}/selection_service_proxy.cpp", + "${target_gen_dir}/selection_service_stub.cpp", ] -idl_gen_interface("word_selection_service_interface") { - src_idl = rebase_path("IWordSelectionService.idl") +idl_gen_interface("selection_service_interface") { + src_idl = rebase_path("ISelectionService.idl") dst_file = string_join(",", idl_interface_sources) } -ohos_shared_library("word_selection_base") { - configs = [ ":word_selection_sa_config", ] +ohos_shared_library("selection_service") { + configs = [ ":selection_sa_config", ] shlib_type = "sa" - version_script = "libword_selection_service.map" - output_values = get_target_outputs(":word_selection_service_interface") + version_script = "libselection_service.map" + output_values = get_target_outputs(":selection_service_interface") sources = [ - "src/word_selection_service.cpp", + "src/selection_service.cpp", ] sources += filter_include(output_values, [ "*.cpp" ]) - deps = [ ":word_selection_service_interface" ] + deps = [ ":selection_service_interface" ] external_deps = [ "c_utils:utils", diff --git a/service/IWordSelectionService.idl b/service/ISelectionService.idl similarity index 92% rename from service/IWordSelectionService.idl rename to service/ISelectionService.idl index f2ba9d1..5897a3d 100644 --- a/service/IWordSelectionService.idl +++ b/service/ISelectionService.idl @@ -12,6 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -interface OHOS.SelectionFwk.IWordSelectionService { +interface OHOS.SelectionFwk.ISelectionService { int AddVolume([in] int volume); } \ No newline at end of file diff --git a/service/include/word_selection_service.h b/service/include/selection_service.h similarity index 69% rename from service/include/word_selection_service.h rename to service/include/selection_service.h index cd95912..d34af8e 100644 --- a/service/include/word_selection_service.h +++ b/service/include/selection_service.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,24 +13,27 @@ * limitations under the License. */ -#ifndef BASE_WORD_SELECTION_SERVICE_H -#define BASE_WORD_SELECTION_SERVICE_H +#ifndef SELECTION_SERVICE_H +#define SELECTION_SERVICE_H +#include #include -#include "word_selection_service_stub.h" +#include "selection_service_stub.h" #include "refbase.h" #include "system_ability.h" #include namespace OHOS::SelectionFwk { using namespace MMI; -class WordSelectionService : public SystemAbility, public WordSelectionServiceStub { - DECLARE_SYSTEM_ABILITY(WordSelectionService); +class SelectionService : public SystemAbility, public SelectionServiceStub { + DECLARE_SYSTEM_ABILITY(SelectionService); public: - WordSelectionService(int32_t saId, bool runOnCreate); - ~WordSelectionService(); + static sptr GetInstance(); + SelectionService(); + SelectionService(int32_t saId, bool runOnCreate); + ~SelectionService(); ErrCode AddVolume(int32_t volume, int32_t& funcResult) override; int32_t Dump(int32_t fd, const std::vector &args) override; @@ -43,9 +46,12 @@ private: int32_t inputMonitorId_ {-1}; void InputMonitorInit(); void InputMonitorCancel(); + + static sptr instance_; + static std::shared_mutex adminLock_; }; -class WordSelectionInputMonitor : public IInputEventConsumer { +class SelectionInputMonitor : public IInputEventConsumer { public: virtual void OnInputEvent(std::shared_ptr keyEvent) const; virtual void OnInputEvent(std::shared_ptr pointerEvent) const; @@ -54,4 +60,4 @@ public: } -#endif // BASE_WORD_SELECTION_SERVICE_H \ No newline at end of file +#endif // SELECTION_SERVICE_H \ No newline at end of file diff --git a/service/libword_selection_service.map b/service/libselection_service.map similarity index 48% rename from service/libword_selection_service.map rename to service/libselection_service.map index 547ed48..4f4d1a2 100644 --- a/service/libword_selection_service.map +++ b/service/libselection_service.map @@ -1,7 +1,7 @@ { global: extern "C++" { - OHOS::SelectionFwk::WordSelectionService::AddVolume*; + OHOS::SelectionFwk::SelectionService::AddVolume*; }; local: *; diff --git a/service/src/word_selection_service.cpp b/service/src/selection_service.cpp similarity index 50% rename from service/src/word_selection_service.cpp rename to service/src/selection_service.cpp index ee6e3aa..82be63c 100644 --- a/service/src/word_selection_service.cpp +++ b/service/src/selection_service.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,67 +13,87 @@ * limitations under the License. */ -#include "word_selection_service.h" +#include "selection_service.h" #include "iremote_object.h" #include "system_ability_definition.h" -#include "word_selection_log.h" +#include "selection_log.h" #include using namespace OHOS; using namespace OHOS::SelectionFwk; -REGISTER_SYSTEM_ABILITY_BY_ID(WordSelectionService, WORD_SELECTION_SA_ID, true); -WordSelectionService::WordSelectionService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) +const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(SelectionService::GetInstance().GetRefPtr()); +std::shared_mutex SelectionService::adminLock_; +sptr SelectionService::instance_; + +sptr SelectionService::GetInstance() +{ + if (instance_ == nullptr) { + std::unique_lock autoLock(adminLock_); + if (instance_ == nullptr) { + SELECTION_HILOGI("SelectionService:GetInstance instance = new SelectionService()"); + instance_ = new (std::nothrow) SelectionService(); + } + } + return instance_; +} + +SelectionService::SelectionService() : SystemAbility(SELECTION_SA_ID, true) +{ + SELECTION_HILOGI("[SelectionService] SelectionService()"); +} + +SelectionService::SelectionService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) { - LOG_INFO("[YMZ][WordSelectionService] saID=%{public}d runOnCreate=%{public}d", saId, runOnCreate); + SELECTION_HILOGI("[SelectionService] saID=%{public}d runOnCreate=%{public}d", saId, runOnCreate); } -WordSelectionService::~WordSelectionService() +SelectionService::~SelectionService() { - LOG_INFO("[YMZ][~WordSelectionService]"); + SELECTION_HILOGI("[~SelectionService]"); } -ErrCode WordSelectionService::AddVolume(int32_t volume, int32_t& funcResult) +ErrCode SelectionService::AddVolume(int32_t volume, int32_t& funcResult) { - LOG_INFO("[YMZ][WordSelectionService][AddVolume]begin"); + SELECTION_HILOGI("[SelectionService][AddVolume]begin"); return (volume + 1); } -int32_t WordSelectionService::Dump(int32_t fd, const std::vector &args) +int32_t SelectionService::Dump(int32_t fd, const std::vector &args) { - dprintf(fd, "---------------------WordSelectionService::Dump--------------------\n"); + dprintf(fd, "---------------------SelectionService::Dump--------------------\n"); return OHOS::NO_ERROR; } -void WordSelectionService::OnStart() +void SelectionService::OnStart() { - LOG_INFO("[YMZ][WordSelectionService][OnStart]begin"); + SELECTION_HILOGI("[SelectionService][OnStart]begin"); Publish(this); InputMonitorInit(); - LOG_INFO("[YMZ][WordSelectionService][OnStart]end"); + SELECTION_HILOGI("[SelectionService][OnStart]end"); } -void WordSelectionService::OnStop() +void SelectionService::OnStop() { - LOG_INFO("[YMZ][WordSelectionService][OnStop]begin"); + SELECTION_HILOGI("[SelectionService][OnStop]begin"); InputMonitorCancel(); - LOG_INFO("[YMZ][WordSelectionService][OnStop]end"); + SELECTION_HILOGI("[SelectionService][OnStop]end"); } -void WordSelectionService::InputMonitorInit() +void SelectionService::InputMonitorInit() { - LOG_INFO("[YMZ]WordSelection service input monitor init"); - std::shared_ptr inputMonitor = std::make_shared(); + SELECTION_HILOGI("[SelectionService] input monitor init"); + std::shared_ptr inputMonitor = std::make_shared(); if (inputMonitorId_ < 0) { inputMonitorId_ = InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); } } -void WordSelectionService::InputMonitorCancel() +void SelectionService::InputMonitorCancel() { - LOG_INFO("[YMZ]WordSelection service input monitor cancel"); + SELECTION_HILOGI("[SelectionService] input monitor cancel"); InputManager* inputManager = InputManager::GetInstance(); if (inputMonitorId_ >= 0) { inputManager->RemoveMonitor(inputMonitorId_); @@ -81,10 +101,10 @@ void WordSelectionService::InputMonitorCancel() } } -void WordSelectionService::HandleKeyEvent(int32_t keyCode) +void SelectionService::HandleKeyEvent(int32_t keyCode) { #ifdef HAS_MULTIMODALINPUT_INPUT_PART - LOG_INFO("[YMZ] keyCode: %{public}d", keyCode); + SELECTION_HILOGI("[YMZ] keyCode: %{public}d", keyCode); int64_t now = static_cast(time(nullptr)); if (IsScreenOn()) { this->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false); @@ -104,10 +124,10 @@ void WordSelectionService::HandleKeyEvent(int32_t keyCode) #endif } -void WordSelectionService::HandlePointEvent(int32_t type) +void SelectionService::HandlePointEvent(int32_t type) { #ifdef HAS_MULTIMODALINPUT_INPUT_PART - LOG_INFO("type: %{public}d", type); + SELECTION_HILOGI("type: %{public}d", type); int64_t now = static_cast(time(nullptr)); if (this->IsScreenOn()) { this->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_ATTENTION, false); @@ -122,14 +142,14 @@ void WordSelectionService::HandlePointEvent(int32_t type) } // foundation/multimodalinput/input/interfaces/native/innerkits/event/include/key_event.h -void WordSelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const +void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { - LOG_INFO("[YMZ]keyId: %{public}d", keyEvent->GetKeyCode()); + SELECTION_HILOGI("[SelectionService] keyId: %{public}d", keyEvent->GetKeyCode()); } -void WordSelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const +void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { - LOG_INFO("[YMZ]pointerEvent: %{public}d", (int32_t)pointerEvent->GetPointerAction()); + SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", (int32_t)pointerEvent->GetPointerAction()); } -void WordSelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const {}; \ No newline at end of file +void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const {}; \ No newline at end of file diff --git a/utils/include/word_selection_log.h b/utils/include/selection_log.h similarity index 62% rename from utils/include/word_selection_log.h rename to utils/include/selection_log.h index fa3b22f..0cad06c 100644 --- a/utils/include/word_selection_log.h +++ b/utils/include/selection_log.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef WORD_SELECTION_LOG_H -#define WORD_SELECTION_LOG_H +#ifndef SELECTION_LOG_H +#define SELECTION_LOG_H #include "hilog/log.h" #include @@ -23,28 +23,28 @@ extern "C" { #endif #undef LOG_TAG -#define LOG_TAG "WORD_SELETION" +#define LOG_TAG "SELETION_SERVICE" #undef LOG_DOMAIN #define LOG_DOMAIN 0xD002901 -#ifndef WORD_SELETION_DEBUG_ENABLE -#define WORD_SELETION_DEBUG_ENABLE 0 +#ifndef SELETION_DEBUG_ENABLE +#define SELETION_DEBUG_ENABLE 0 #endif #define FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) -#define DEMO_LOG(func, fmt, args...) \ +#define HILOG_PRINT(func, fmt, args...) \ do { \ func(LOG_CORE, "{%{public}s:%{public}d %{public}s()} " fmt, FILENAME, __LINE__, __FUNCTION__, ##args); \ } while (false) -#define LOG_DEBUG(fmt, ...) DEMO_LOG(HILOG_DEBUG, fmt, ##__VA_ARGS__) -#define LOG_INFO(fmt, ...) DEMO_LOG(HILOG_INFO, fmt, ##__VA_ARGS__) -#define LOG_WARN(fmt, ...) DEMO_LOG(HILOG_WARN, fmt, ##__VA_ARGS__) -#define LOG_ERROR(fmt, ...) DEMO_LOG(HILOG_ERROR, fmt, ##__VA_ARGS__) -#define LOG_FATAL(fmt, ...) DEMO_LOG(HILOG_FATAL, fmt, ##__VA_ARGS__) +#define SELECTION_HILOGD(fmt, ...) HILOG_PRINT(HILOG_DEBUG, fmt, ##__VA_ARGS__) +#define SELECTION_HILOGI(fmt, ...) HILOG_PRINT(HILOG_INFO, fmt, ##__VA_ARGS__) +#define SELECTION_HILOGW(fmt, ...) HILOG_PRINT(HILOG_WARN, fmt, ##__VA_ARGS__) +#define SELECTION_HILOGE(fmt, ...) HILOG_PRINT(HILOG_ERROR, fmt, ##__VA_ARGS__) +#define SELECTION_HILOGF(fmt, ...) HILOG_PRINT(HILOG_FATAL, fmt, ##__VA_ARGS__) #ifdef __cplusplus } #endif -#endif // WORD_SELECTION_LOG_H \ No newline at end of file +#endif // SELECTION_LOG_H \ No newline at end of file -- Gitee From 8aa5ed879f801e1a725f5db630510b2f055bb42a Mon Sep 17 00:00:00 2001 From: fanzhe Date: Fri, 9 May 2025 16:47:10 +0800 Subject: [PATCH 05/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9uid,gid=E4=B8=BAsyssele?= =?UTF-8?q?ction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- etc/init/selection_service.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/init/selection_service.cfg b/etc/init/selection_service.cfg index 06570f2..43bb341 100644 --- a/etc/init/selection_service.cfg +++ b/etc/init/selection_service.cfg @@ -5,15 +5,15 @@ "ondemand": true, "importance" : -20, "once" : 0, - "uid" : "system", - "gid" : ["system", "shell"], + "uid" : "sysselection", + "gid" : ["sysselection", "shell"], "apl": "system_basic", "permission" : [ "ohos.permission.INPUT_MONITORING" ], "permission_acls" : ["ohos.permission.INPUT_MONITORING"], "caps" : [], - "secon" : "u:r:powermgr:s0" + "secon" : "u:r:selection_service:s0" } ] } -- Gitee From d178451029f95e2e7183fefea32e4571dd2d8a07 Mon Sep 17 00:00:00 2001 From: "yangmaoquan@chinasoftinc.com" Date: Fri, 9 May 2025 17:21:40 +0800 Subject: [PATCH 06/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0watchparameter=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan@chinasoftinc.com Signed-off-by: Sunjiamei --- bundle.json | 1 + service/BUILD.gn | 1 + service/src/selection_service.cpp | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/bundle.json b/bundle.json index 3643016..e15879d 100644 --- a/bundle.json +++ b/bundle.json @@ -23,6 +23,7 @@ "safwk", "hilog", "samgr", + "init", "input" ], "third_party": [ diff --git a/service/BUILD.gn b/service/BUILD.gn index 0a6f0c6..3498e25 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -48,6 +48,7 @@ ohos_shared_library("selection_service") { external_deps = [ "c_utils:utils", "ipc:ipc_single", + "init:libbeget_proxy", "hilog:libhilog", "safwk:system_ability_fwk", "samgr:samgr_proxy", diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 82be63c..f5eea94 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -19,6 +19,7 @@ #include "system_ability_definition.h" #include "selection_log.h" #include +#include "parameter.h" using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -66,11 +67,23 @@ int32_t SelectionService::Dump(int32_t fd, const std::vector &ar return OHOS::NO_ERROR; } +static void WatchParameterFunc(const char *key, const char *value, void *context) +{ + (void)context; + SELECTION_HILOGI("sys.selection.switch.username, value=%{public}s", value); +} + +void WatchParams() +{ + WatchParameter("sys.selection.switch.username", WatchParameterFunc, nullptr); +} + void SelectionService::OnStart() { SELECTION_HILOGI("[SelectionService][OnStart]begin"); Publish(this); InputMonitorInit(); + WatchParams(); SELECTION_HILOGI("[SelectionService][OnStart]end"); } -- Gitee From d0dab393c155f485f810964f97e95bd3e930fb36 Mon Sep 17 00:00:00 2001 From: xying6 Date: Mon, 12 May 2025 10:07:46 +0800 Subject: [PATCH 07/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- README.md | 59 ++++++++++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index e55ea80..e318d69 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,30 @@ -# Word Selection +## 划词服务代码环境搭建 - -## Introduction - -The Word Selection module provides the following functions: - -1. A -2. B -3. C - -## Directory Structure - -Copied from powermgr: +### 代码结构 ``` -/base/word_selection -├── figures # Architecture -├── frameworks # Framework layer -│ ├── napi # NAPI layer -│ └── native # Native layer -├── interfaces # API layer -│ └── inner_api # Internal APIs -├── power_dialog # Power dialog -├── sa_profile # SA profile -└── services # Service layer -│ ├── native # Native layer -│ └── zidl # Zidl API layer -├── test # Test cases -│ ├── fuzztest # Fuzz test -│ ├── unittest # Unit test -│ ├── systemtest # System test -│ └── utils # Test tools -└── utils # Utilities +│ ├── base +│ │ ├── startup +│ │ │ └── init => 代码提交仓: https://gitee.com/sinall/startup_init.git, selection_fwk分支 +│ │ └── security +│ │ └── selinux_adapter => 代码提交仓: https://gitee.com/sinall/security_selinux_adapter.git, selection_fwk分支 +│ ├── foundation +│ │ └── systemabilitymgr +│ │ ├── samgr => 代码提交仓: https://gitee.com/sinall/systemabilitymgr_samgr.git, selection_fwk分支 +│ │ └── selection_fwk => 代码提交仓: https://gitee.com/sinall/selection_fwk.git, master分支 +│ ├── productdefine +│ │ └── common => 代码提交仓: https://gitee.com/sinall/productdefine_common.git, selection_fwk分支 ``` +更新命令: - -## Repositories Involved - -Repositories Involved +``` +在代码仓库对应目录下执行以下命令 +1. selection_fwk仓库: +git clone https://gitee.com/sinall/selection_fwk.git +2. 其余仓库 +$ cd foundation/systemabilitymgr/samgr(修改为对应仓库路径) +$ git remote add sinall https://gitee.com/sinall/systemabilitymgr_samgr.git(修改为对应仓库的网址) +$ git fetch sinall selection_fwk +$ git checkout -b selection_fwk sinall/selection_fwk +``` -- Gitee From 9b961f3685180fa0406b9ef67b612a9a8efbc987 Mon Sep 17 00:00:00 2001 From: xying6 Date: Mon, 12 May 2025 14:47:06 +0800 Subject: [PATCH 08/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=A3=80=E8=A7=86?= =?UTF-8?q?=E6=84=8F=E8=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- README.md | 60 +++++++++++++++++++++++++++++-- etc/para/selection.para | 6 ++-- etc/para/selection.para.dac | 2 +- sa_profile/8500.json | 4 +-- service/src/selection_service.cpp | 2 +- 5 files changed, 65 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e318d69..fee8861 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,13 @@ │ │ └── common => 代码提交仓: https://gitee.com/sinall/productdefine_common.git, selection_fwk分支 ``` -更新命令: +### 更新代码命令 + +- 初次环境搭建,在代码仓库对应目录下执行以下命令 ``` -在代码仓库对应目录下执行以下命令 1. selection_fwk仓库: +cd foundation/systemabilitymgr git clone https://gitee.com/sinall/selection_fwk.git 2. 其余仓库 $ cd foundation/systemabilitymgr/samgr(修改为对应仓库路径) @@ -28,3 +30,57 @@ $ git remote add sinall https://gitee.com/sinall/systemabilitymgr_samgr.git( $ git fetch sinall selection_fwk $ git checkout -b selection_fwk sinall/selection_fwk ``` + +- 后续更新代码 + +``` +cd foundation/systemabilitymgr(修改为对应的仓库路径) +git pull --reb sinall master(修改为对应的分支名) +``` + +### 编译命令 + +- 全量编译 + +``` +修改build.gn文件后编译命令 +$ ./build.sh --product-name rk3568 --ccache +未修改build.gn文件编译命令 +$ ./build.sh --product-name rk3568 --ccache --fast-rebuild +``` + +- 单独编译 + +``` +$ ./build.sh --product-name rk3568 --ccache --build-target selectionfwk +``` + +### 测试命令 + +1. 测试启动服务 + +``` +# ps -ef | grep selection_service +未启动服务 +# param set sys.selection.switch.username on +# ps -e未启动服务f | grep selection_service +服务已启动 +``` + +2. 测试关闭服务 (系统参数关闭会延时,等待约20-30s) + +``` +# ps -ef | grep selection_service +服务已启动 +# param set sys.selection.switch.username off +# ps -ef | grep selection_service +服务已退出 +``` + +3. 获取日志命令 + +``` +# dmesg | grep selection_service +# hilog -b D +# hilog | grep 8500 +``` diff --git a/etc/para/selection.para b/etc/para/selection.para index 073203e..7eb6fb9 100644 --- a/etc/para/selection.para +++ b/etc/para/selection.para @@ -11,6 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -sys.selection.switch.username = off -sys.selection.trigger.username = ctrl -sys.selection.app.username = com.hm.youdao +persist.sys.selection.switch.username = off +persist.sys.selection.trigger.username = ctrl +persist.sys.selection.app.username = com.hm.youdao diff --git a/etc/para/selection.para.dac b/etc/para/selection.para.dac index 91f5f12..5e0c38f 100644 --- a/etc/para/selection.para.dac +++ b/etc/para/selection.para.dac @@ -11,4 +11,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -sys.selection. = sysselection:sysselection:0775 \ No newline at end of file +persist.sys.selection. = sysselection:sysselection:0775 \ No newline at end of file diff --git a/sa_profile/8500.json b/sa_profile/8500.json index bc133d2..e4cca62 100644 --- a/sa_profile/8500.json +++ b/sa_profile/8500.json @@ -13,7 +13,7 @@ "allow-update": true, "param": [ { - "name":"sys.selection.switch.username", + "name":"persist.sys.selection.switch.username", "value":"on" } ] @@ -22,7 +22,7 @@ "allow-update": true, "param": [ { - "name":"sys.selection.switch.username", + "name":"persist.sys.selection.switch.username", "value":"off" } ] diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index f5eea94..54d0e00 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -40,7 +40,7 @@ sptr SelectionService::GetInstance() return instance_; } -SelectionService::SelectionService() : SystemAbility(SELECTION_SA_ID, true) +SelectionService::SelectionService() : SystemAbility(SELECTION_FWK_SA_ID, true) { SELECTION_HILOGI("[SelectionService] SelectionService()"); } -- Gitee From 2416ceb02aa754a23e318b3c52bee6b4e561d8c1 Mon Sep 17 00:00:00 2001 From: xying6 Date: Tue, 13 May 2025 14:10:28 +0800 Subject: [PATCH 09/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9watchParam?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- service/src/selection_service.cpp | 9 +++++++-- utils/include/selection_log.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 54d0e00..3b36a7b 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -70,12 +70,17 @@ int32_t SelectionService::Dump(int32_t fd, const std::vector &ar static void WatchParameterFunc(const char *key, const char *value, void *context) { (void)context; - SELECTION_HILOGI("sys.selection.switch.username, value=%{public}s", value); + SELECTION_HILOGI("WatchParameterFunc begin"); + SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); } void WatchParams() { - WatchParameter("sys.selection.switch.username", WatchParameterFunc, nullptr); + SELECTION_HILOGI("WatchParams begin"); + WatchParameter("persist.sys.selection.switch.username", WatchParameterFunc, nullptr); + WatchParameter("persist.sys.selection.trigger.username", WatchParameterFunc, nullptr); + WatchParameter("persist.sys.selection.app.username", WatchParameterFunc, nullptr); + SELECTION_HILOGI("WatchParams end"); } void SelectionService::OnStart() diff --git a/utils/include/selection_log.h b/utils/include/selection_log.h index 0cad06c..11d585f 100644 --- a/utils/include/selection_log.h +++ b/utils/include/selection_log.h @@ -23,7 +23,7 @@ extern "C" { #endif #undef LOG_TAG -#define LOG_TAG "SELETION_SERVICE" +#define LOG_TAG "SELECTION_SERVICE" #undef LOG_DOMAIN #define LOG_DOMAIN 0xD002901 -- Gitee From d869cf8cf2b952f328c3291164db69767ac69ca5 Mon Sep 17 00:00:00 2001 From: "yangmaoquan@chinasoftinc.com" Date: Tue, 13 May 2025 10:35:18 +0800 Subject: [PATCH 10/93] =?UTF-8?q?=E6=BB=91=E5=8A=A8=E9=80=89=E8=AF=8D?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- service/include/selection_service.h | 24 ++++++++ service/src/selection_service.cpp | 88 ++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index d34af8e..0460ea4 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -26,6 +26,23 @@ namespace OHOS::SelectionFwk { using namespace MMI; + +constexpr const char *SYS_SELECTION_SWITCH_USERNAM = "sys.selection.switch.username"; +constexpr const char *SYS_SELECTION_TRIGGER_USERNAM = "sys.selection.trigger.username"; +constexpr const char *SYS_SELECTION_APP_USERNAM = "sys.selection.app.username"; + +typedef enum SelectInputState { + SELECT_INPUT_INITIAL = 0, + SELECT_INPUT_WORD_BEGIN = 1, + SELECT_INPUT_WAIT_LEFT_MOVE = 2, + SELECT_INPUT_LEFT_MOVE = 3, + SELECT_INPUT_WAIT_DOUBLE_CLICK = 4, + SELECT_INPUT_WAIT_TRIBLE_CLICK = 5, + SELECT_INPUT_DOUBLE_CLICKED = 6, + + SELECT_INPUT_WAIT_CTRL + +} SelectInputState; class SelectionService : public SystemAbility, public SelectionServiceStub { DECLARE_SYSTEM_ABILITY(SelectionService); @@ -56,6 +73,13 @@ public: virtual void OnInputEvent(std::shared_ptr keyEvent) const; virtual void OnInputEvent(std::shared_ptr pointerEvent) const; virtual void OnInputEvent(std::shared_ptr axisEvent) const; + +private: + void InputInitialProcess(std::shared_ptr pointerEvent) const; + void InputWordBeginProcess(std::shared_ptr pointerEvent) const; + void InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const; + void InjectCtrlC() const; + static uint32_t curSelectState; }; } diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 3b36a7b..ffe8e93 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -23,11 +23,14 @@ using namespace OHOS; using namespace OHOS::SelectionFwk; +using namespace OHOS::MMI; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(SelectionService::GetInstance().GetRefPtr()); std::shared_mutex SelectionService::adminLock_; sptr SelectionService::instance_; +uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; + sptr SelectionService::GetInstance() { if (instance_ == nullptr) { @@ -165,9 +168,92 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con SELECTION_HILOGI("[SelectionService] keyId: %{public}d", keyEvent->GetKeyCode()); } +void SelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + int32_t buttonId = pointerEvent->GetButtonId(); + if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && buttonId == PointerEvent::MOUSE_BUTTON_LEFT) { + curSelectState = SELECT_INPUT_WORD_BEGIN; + } + return; +} + +void SelectionInputMonitor::InputWordBeginProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (action == PointerEvent::POINTER_ACTION_MOVE) { + curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + } else if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + curSelectState = SELECT_INPUT_WAIT_DOUBLE_CLICK; + } + return; +} + +void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + curSelectState = SELECT_INPUT_LEFT_MOVE; + } + return; +} + +void SelectionInputMonitor::InjectCtrlC() const +{ + auto keyDownEvent = KeyEvent::Create(); + keyDownEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + std::vector downKey; + downKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); + downKey.push_back(KeyEvent::KEYCODE_C); + keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + + KeyEvent::KeyItem downItem[downKey.size()]; + for (size_t i = 0; i < downKey.size(); i++) { + downItem[i].SetKeyCode(downKey[i]); + downItem[i].SetPressed(true); + downItem[i].SetDownTime(500); + keyDownEvent->AddPressedKeyItems(downItem[i]); + } + InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); +} + void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { - SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", (int32_t)pointerEvent->GetPointerAction()); + int32_t action = pointerEvent->GetPointerAction(); + int32_t buttonId = pointerEvent->GetButtonId(); + SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", action); + SELECTION_HILOGI("[SelectionService] buttonId: %{public}d", buttonId); + if (curSelectState == SELECT_INPUT_INITIAL && buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { + return; + } + + switch (curSelectState) + { + case SELECT_INPUT_INITIAL: + InputInitialProcess(pointerEvent); + break; + + case SELECT_INPUT_WORD_BEGIN: + InputWordBeginProcess(pointerEvent); + break; + + case SELECT_INPUT_WAIT_LEFT_MOVE: + InputWordWaitLeftMoveProcess(pointerEvent); + break; + + default: + break; + } + + if (curSelectState == SELECT_INPUT_LEFT_MOVE) { + // world selection action + SELECTION_HILOGI("[SelectionService] first, end word selection action."); + InjectCtrlC(); + SELECTION_HILOGI("[SelectionService] first, end inject ctrl + c."); + curSelectState = SELECT_INPUT_INITIAL; + } + return; } void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const {}; \ No newline at end of file -- Gitee From e74c9e3b9b576dfbf75c9ed9996b8cba88c55c50 Mon Sep 17 00:00:00 2001 From: xying6 Date: Wed, 14 May 2025 10:34:55 +0800 Subject: [PATCH 11/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9WatchParams=E5=9B=9E?= =?UTF-8?q?=E8=B0=83=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- service/include/selection_service.h | 5 +++-- service/src/selection_service.cpp | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 0460ea4..9eb367a 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -43,6 +43,7 @@ typedef enum SelectInputState { SELECT_INPUT_WAIT_CTRL } SelectInputState; + class SelectionService : public SystemAbility, public SelectionServiceStub { DECLARE_SYSTEM_ABILITY(SelectionService); @@ -60,10 +61,11 @@ protected: void HandleKeyEvent(int32_t keyCode); void HandlePointEvent(int32_t type); private: - int32_t inputMonitorId_ {-1}; void InputMonitorInit(); void InputMonitorCancel(); + void WatchParams(); + int32_t inputMonitorId_ {-1}; static sptr instance_; static std::shared_mutex adminLock_; }; @@ -81,7 +83,6 @@ private: void InjectCtrlC() const; static uint32_t curSelectState; }; - } #endif // SELECTION_SERVICE_H \ No newline at end of file diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index ffe8e93..8aecd7d 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -77,12 +77,26 @@ static void WatchParameterFunc(const char *key, const char *value, void *context SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); } -void WatchParams() +static void WatchTriggerMode(const char *key, const char *value, void *context) +{ + (void)context; + SELECTION_HILOGI("WatchParameterFunc begin"); + SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); +} + +static void WatchAppSwitch(const char *key, const char *value, void *context) +{ + (void)context; + SELECTION_HILOGI("WatchParameterFunc begin"); + SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); +} + +void SelectionService::WatchParams() { SELECTION_HILOGI("WatchParams begin"); WatchParameter("persist.sys.selection.switch.username", WatchParameterFunc, nullptr); - WatchParameter("persist.sys.selection.trigger.username", WatchParameterFunc, nullptr); - WatchParameter("persist.sys.selection.app.username", WatchParameterFunc, nullptr); + WatchParameter("persist.sys.selection.trigger.username", WatchTriggerMode, nullptr); + WatchParameter("persist.sys.selection.app.username", WatchAppSwitch, nullptr); SELECTION_HILOGI("WatchParams end"); } -- Gitee From 8ec2f0cb3b389bb580c09453c067e5cc4ec9f2d2 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Wed, 14 May 2025 14:15:27 +0800 Subject: [PATCH 12/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0selection=20extensionAb?= =?UTF-8?q?ility=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 9 ++- .../napi/selection_extension_ability/BUILD.gn | 50 ++++++++++++++ .../selection_extension_ability.js | 36 ++++++++++ .../selection_extension_ability_module.cpp | 54 +++++++++++++++ .../native/selection_extension/BUILD.gn | 68 +++++++++++++++++++ .../include/selection_extension.h | 51 ++++++++++++++ .../include/selection_extension_context.h | 29 ++++++++ .../selection_extension_module_loader.h | 43 ++++++++++++ .../src/selection_extension.cpp | 43 ++++++++++++ .../src/selection_extension_context.cpp | 20 ++++++ .../src/selection_extension_module_loader.cpp | 43 ++++++++++++ 11 files changed, 444 insertions(+), 2 deletions(-) create mode 100644 frameworks/js/napi/selection_extension_ability/BUILD.gn create mode 100644 frameworks/js/napi/selection_extension_ability/selection_extension_ability.js create mode 100644 frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp create mode 100644 frameworks/native/selection_extension/BUILD.gn create mode 100644 frameworks/native/selection_extension/include/selection_extension.h create mode 100644 frameworks/native/selection_extension/include/selection_extension_context.h create mode 100644 frameworks/native/selection_extension/include/selection_extension_module_loader.h create mode 100644 frameworks/native/selection_extension/src/selection_extension.cpp create mode 100644 frameworks/native/selection_extension/src/selection_extension_context.cpp create mode 100644 frameworks/native/selection_extension/src/selection_extension_module_loader.cpp diff --git a/bundle.json b/bundle.json index e15879d..14daad0 100644 --- a/bundle.json +++ b/bundle.json @@ -24,7 +24,10 @@ "hilog", "samgr", "init", - "input" + "input", + "napi", + "ability_base", + "ability_runtime" ], "third_party": [ ] @@ -35,7 +38,9 @@ "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para", "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para_dac", "//foundation/systemabilitymgr/selection_fwk/service:selection_service", - "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile" + "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile", + "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", + "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native" ], "inner_kits": [] } diff --git a/frameworks/js/napi/selection_extension_ability/BUILD.gn b/frameworks/js/napi/selection_extension_ability/BUILD.gn new file mode 100644 index 0000000..4669200 --- /dev/null +++ b/frameworks/js/napi/selection_extension_ability/BUILD.gn @@ -0,0 +1,50 @@ +# 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("//build/templates/abc/ohos_abc.gni") + +es2abc_gen_abc("gen_selection_extension_ability_abc") { + src_js = rebase_path("selection_extension_ability.js") + dst_file = rebase_path(target_out_dir + "/selection_extension_ability.abc") + in_puts = [ "selection_extension_ability.js" ] + out_puts = [ target_out_dir + "/selection_extension_ability.abc" ] + extra_args = [ "--module" ] +} + +gen_js_obj("selection_extension_ability_js") { + input = "selection_extension_ability.js" + output = target_out_dir + "/selection_extension_ability.o" +} + +gen_js_obj("selection_extension_ability_abc") { + input = get_label_info(":gen_selection_extension_ability_abc", + "target_out_dir") + "/selection_extension_ability.abc" + output = target_out_dir + "/selection_extension_ability_abc.o" + dep = ":gen_selection_extension_ability_abc" +} + +ohos_shared_library("selectionextensionability_napi") { + sources = [ "selection_extension_ability_module.cpp" ] + + deps = [ + ":selection_extension_ability_abc", + ":selection_extension_ability_js", + ] + + external_deps = [ "napi:ace_napi" ] + + relative_install_dir = "module/app/ability" + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/frameworks/js/napi/selection_extension_ability/selection_extension_ability.js b/frameworks/js/napi/selection_extension_ability/selection_extension_ability.js new file mode 100644 index 0000000..30c73ff --- /dev/null +++ b/frameworks/js/napi/selection_extension_ability/selection_extension_ability.js @@ -0,0 +1,36 @@ +/* + * 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. + */ + +let ExtensionAbility = requireNapi('app.ability.ExtensionAbility'); + +class SelectionExtensionAbility extends ExtensionAbility { + onCreate(want) { + console.log('onCreate, want:' + want.abilityName); + } + + onConnect(want) { + console.log('onConnect, want:' + want.abilityName); + } + + onDisconnect(want) { + console.log('onDisconnect'); + } + + onDestroy() { + console.log('onDestroy'); + } +} + +export default SelectionExtensionAbility; diff --git a/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp new file mode 100644 index 0000000..59a78e9 --- /dev/null +++ b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp @@ -0,0 +1,54 @@ +/* + * 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 "native_engine/native_engine.h" + +extern const char _binary_selection_extension_ability_js_start[]; +extern const char _binary_selection_extension_ability_js_end[]; +extern const char _binary_selection_extension_ability_abc_start[]; +extern const char _binary_selection_extension_ability_abc_end[]; + +static napi_module _module = { + .nm_filename = "app/ability/libselectionextensionability_napi.so/selection_extension_ability.js", + .nm_modname = "app.ability.SelectionExtensionAbility", +}; + +extern "C" __attribute__((constructor)) void NAPI_app_ability_SelectionExtensionAbility_AutoRegister() +{ + napi_module_register(&_module); +} + +extern "C" __attribute__((visibility("default"))) void + NAPI_app_ability_SelectionExtensionAbility_GetJSCode(const char** buf, int* bufLen) +{ + if (buf != nullptr) { + *buf = _binary_selection_extension_ability_js_start; + } + + if (bufLen != nullptr) { + *bufLen = _binary_selection_extension_ability_js_end - _binary_selection_extension_ability_js_start; + } +} + +extern "C" __attribute__((visibility("default"))) void + NAPI_app_ability_SelectionExtensionAbility_GetABCCode(const char** buf, int* buflen) +{ + if (buf != nullptr) { + *buf = _binary_selection_extension_ability_abc_start; + } + if (buflen != nullptr) { + *buflen = _binary_selection_extension_ability_abc_end - _binary_selection_extension_ability_abc_start; + } +} diff --git a/frameworks/native/selection_extension/BUILD.gn b/frameworks/native/selection_extension/BUILD.gn new file mode 100644 index 0000000..2a3f2de --- /dev/null +++ b/frameworks/native/selection_extension/BUILD.gn @@ -0,0 +1,68 @@ +# 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("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") + + +ohos_shared_library("selection_extension_ability_native") { + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + + cflags_cc = [ + "-fdata-sections", + "-ffunction-sections", + "-Os", + ] + + include_dirs = [ + "include" + ] + + sources = [ + "src/selection_extension.cpp", + "src/selection_extension_context.cpp", + "src/selection_extension_module_loader.cpp" + ] + + + deps = [ + + ] + + external_deps = [ + "ability_base:want", + "ability_runtime:ability_connect_callback_stub", + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:app_context", + "ability_runtime:extensionkit_native", + "ability_runtime:napi_common", + "ability_runtime:runtime", + "c_utils:utils", + "ipc:ipc_napi", + "napi:ace_napi", + "hilog:libhilog", + ] + + relative_install_dir = "extensionability/" + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/frameworks/native/selection_extension/include/selection_extension.h b/frameworks/native/selection_extension/include/selection_extension.h new file mode 100644 index 0000000..3ac7909 --- /dev/null +++ b/frameworks/native/selection_extension/include/selection_extension.h @@ -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. + */ + +#ifndef SELECTION_EXTENSION_H +#define SELECTION_EXTENSION_H + +#include "extension_base.h" +#include "selection_extension_context.h" + +namespace OHOS::AbilityRuntime { +class SelectionExtension : public ExtensionBase { +public: + SelectionExtension() = default; + virtual ~SelectionExtension() = default; + + /** + * @brief Init the extension. + * + * @param record the extension record. + * @param application the application info. + * @param handler the extension handler. + * @param token the remote token. + */ + virtual void Init(const std::shared_ptr& record, + const std::shared_ptr& application, + std::shared_ptr& handler, + const sptr& token) override; + + /** + * @brief Create Extension. + * + * @param runtime The runtime. + * @return The InputMethodExtension instance. + */ + static SelectionExtension* Create(const std::unique_ptr& runtime); +}; +} // namespace OHOS::AbilityRuntime + +#endif \ No newline at end of file diff --git a/frameworks/native/selection_extension/include/selection_extension_context.h b/frameworks/native/selection_extension/include/selection_extension_context.h new file mode 100644 index 0000000..7dbd620 --- /dev/null +++ b/frameworks/native/selection_extension/include/selection_extension_context.h @@ -0,0 +1,29 @@ +/* + * 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 SELECTION_EXTENSION_CONTEXT_H +#define SELECTION_EXTENSION_CONTEXT_H + +#include "extension_context.h" +#include "want.h" + +namespace OHOS::AbilityRuntime { +class SelectionExtensionContext : public ExtensionContext { +public: + SelectionExtensionContext() = default; + virtual ~SelectionExtensionContext() = default; +}; +} // namespace OHOS::AbilityRuntime +#endif diff --git a/frameworks/native/selection_extension/include/selection_extension_module_loader.h b/frameworks/native/selection_extension/include/selection_extension_module_loader.h new file mode 100644 index 0000000..65cb68c --- /dev/null +++ b/frameworks/native/selection_extension/include/selection_extension_module_loader.h @@ -0,0 +1,43 @@ +/* + * 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 SELECTION_EXTENSION_MODULE_LOADER_H +#define SELECTION_EXTENSION_MODULE_LOADER_H + +#include "extension_module_loader.h" + +namespace OHOS::AbilityRuntime { +class SelectionExtensionModuleLoader : public ExtensionModuleLoader, public Singleton { + DECLARE_SINGLETON(SelectionExtensionModuleLoader); + +public: + /** + * @brief Create Extension. + * + * @param runtime The runtime. + * @return The Extension instance. + */ + virtual Extension* Create(const std::unique_ptr& runtime) const override; + + /** + * @brief Get Extension config params. + * + * @return The Extension config params. + */ + virtual std::map GetParams() override; +}; +} // namespace OHOS::AbilityRuntime + +#endif \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/selection_extension.cpp b/frameworks/native/selection_extension/src/selection_extension.cpp new file mode 100644 index 0000000..50ead80 --- /dev/null +++ b/frameworks/native/selection_extension/src/selection_extension.cpp @@ -0,0 +1,43 @@ +/* + * 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 "selection_extension.h" +#include "runtime.h" + +namespace OHOS::AbilityRuntime { +using namespace OHOS::AppExecFwk; + +SelectionExtension* SelectionExtension::Create(const std::unique_ptr& runtime) +{ + if (runtime == nullptr) { + return new SelectionExtension(); + } + switch (runtime->GetLanguage()) { + case Runtime::Language::JS: + return SelectionExtension::Create(runtime); + default: + return new SelectionExtension(); + } +} + +void SelectionExtension::Init(const std::shared_ptr& record, + const std::shared_ptr& application, + std::shared_ptr& handler, + const sptr& token) +{ + ExtensionBase::Init(record, application, handler, token); +} + +} // namespace OHOS::AbilityRuntime \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/selection_extension_context.cpp b/frameworks/native/selection_extension/src/selection_extension_context.cpp new file mode 100644 index 0000000..c584c14 --- /dev/null +++ b/frameworks/native/selection_extension/src/selection_extension_context.cpp @@ -0,0 +1,20 @@ +/* + * 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 "selection_extension_context.h" + +namespace OHOS::AbilityRuntime { + +} \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp new file mode 100644 index 0000000..1b398e9 --- /dev/null +++ b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp @@ -0,0 +1,43 @@ +/* + * 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 "selection_extension_module_loader.h" +#include "selection_extension.h" + +namespace OHOS::AbilityRuntime { + +SelectionExtensionModuleLoader::SelectionExtensionModuleLoader() = default; +SelectionExtensionModuleLoader::~SelectionExtensionModuleLoader() = default; +Extension* SelectionExtensionModuleLoader::Create(const std::unique_ptr& runtime) const +{ + return SelectionExtension::Create(runtime); +} + +std::map SelectionExtensionModuleLoader::GetParams() +{ + // TODO:确定type和name + std::map params; + // type means extension type in ExtensionAbilityType of extension_ability_info.h + // params.insert(std::pair("type", "2")); + // extension name + // params.insert(std::pair("name", "SelectionExtensionAbility")); + return params; +} + +extern "C" __attribute__((visibility("default"))) void* OHOS_EXTENSION_GetExtensionModule() +{ + return &SelectionExtensionModuleLoader::GetInstance(); +} +} // namespace OHOS::AbilityRuntime \ No newline at end of file -- Gitee From 73e8d6385938c7a02331c7517358b52d9e517092 Mon Sep 17 00:00:00 2001 From: xying6 Date: Wed, 14 May 2025 17:38:30 +0800 Subject: [PATCH 13/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E7=94=9F=E5=91=BD?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E7=AE=A1=E7=90=86=E5=88=87=E6=8D=A2Extension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- etc/init/selection_service.cfg | 5 +- .../selection_extension_ability_module.cpp | 4 +- .../native/selection_extension/BUILD.gn | 3 +- .../include/js_selection_extension.h | 94 ++++++++++ .../include/selection_extension.h | 16 +- .../include/selection_extension_context.h | 2 +- .../src/js_selection_extension.cpp | 162 ++++++++++++++++++ .../src/selection_extension.cpp | 4 +- .../src/selection_extension_module_loader.cpp | 8 +- service/BUILD.gn | 2 + service/include/selection_service.h | 5 + service/src/selection_service.cpp | 67 +++++++- 12 files changed, 348 insertions(+), 24 deletions(-) create mode 100644 frameworks/native/selection_extension/include/js_selection_extension.h create mode 100644 frameworks/native/selection_extension/src/js_selection_extension.cpp diff --git a/etc/init/selection_service.cfg b/etc/init/selection_service.cfg index 43bb341..0f753fb 100644 --- a/etc/init/selection_service.cfg +++ b/etc/init/selection_service.cfg @@ -9,7 +9,10 @@ "gid" : ["sysselection", "shell"], "apl": "system_basic", "permission" : [ - "ohos.permission.INPUT_MONITORING" + "ohos.permission.INPUT_MONITORING", + "ohos.permission.GET_RUNNING_INFO", + "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", + "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT" ], "permission_acls" : ["ohos.permission.INPUT_MONITORING"], "caps" : [], diff --git a/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp index 59a78e9..7ec965f 100644 --- a/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp +++ b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp @@ -21,8 +21,8 @@ extern const char _binary_selection_extension_ability_abc_start[]; extern const char _binary_selection_extension_ability_abc_end[]; static napi_module _module = { - .nm_filename = "app/ability/libselectionextensionability_napi.so/selection_extension_ability.js", - .nm_modname = "app.ability.SelectionExtensionAbility", + .nm_filename = "libselectionextensionability_napi.so/selection_extension_ability.js", + .nm_modname = "SelectionExtensionAbility", }; extern "C" __attribute__((constructor)) void NAPI_app_ability_SelectionExtensionAbility_AutoRegister() diff --git a/frameworks/native/selection_extension/BUILD.gn b/frameworks/native/selection_extension/BUILD.gn index 2a3f2de..140c15e 100644 --- a/frameworks/native/selection_extension/BUILD.gn +++ b/frameworks/native/selection_extension/BUILD.gn @@ -38,7 +38,8 @@ ohos_shared_library("selection_extension_ability_native") { sources = [ "src/selection_extension.cpp", "src/selection_extension_context.cpp", - "src/selection_extension_module_loader.cpp" + "src/selection_extension_module_loader.cpp", + "src/js_selection_extension.cpp", ] diff --git a/frameworks/native/selection_extension/include/js_selection_extension.h b/frameworks/native/selection_extension/include/js_selection_extension.h new file mode 100644 index 0000000..cba8c63 --- /dev/null +++ b/frameworks/native/selection_extension/include/js_selection_extension.h @@ -0,0 +1,94 @@ +/* + * 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 JS_SELECTION_EXTENSION_H +#define JS_SELECTION_EXTENSION_H +#include "selection_extension.h" + +namespace OHOS::AbilityRuntime { +class JsRuntime; + +class JsSelectionExtension : public SelectionExtension { +public: + explicit JsSelectionExtension(JsRuntime& jsRuntime); + virtual ~JsSelectionExtension() override; + /** + * @brief Create JsSelectionExtension. + * + * @param runtime The runtime. + * @return The JsSelectionExtension instance. + */ + static JsSelectionExtension* Create(const std::unique_ptr& runtime); + /** + * @brief Init the extension. + * + * @param record the extension record. + * @param application the application info. + * @param handler the extension handler. + * @param token the remote token. + */ + virtual void Init(const std::shared_ptr& record, + const std::shared_ptr& application, + std::shared_ptr& handler, + const sptr& token) override; + + /** + * @brief Called when this extension is started. You must override this function if you want to perform some + * initialization operations during extension startup. + * + * This function can be called only once in the entire lifecycle of an extension. + * @param Want Indicates the {@link Want} structure containing startup information about the extension. + */ + virtual void OnStart(const AAFwk::Want& want) override; + + /** + * @brief Called when this Service extension is connected for the first time. + * + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing connection information about the Service extension. + * @return Returns a pointer to the sid of the connected Service extension. + */ + virtual sptr OnConnect(const AAFwk::Want& want) override; + + /** + * @brief Called when all abilities connected to this Service extension are disconnected. + * + * You can override this function to implement your own processing logic. + * + */ + virtual void OnDisconnect(const AAFwk::Want& want) override; + + /** + * @brief Called when this extension enters the STATE_STOP state. + * + * The extension in the STATE_STOP is being destroyed. + * You can override this function to implement your own processing logic. + */ + virtual void OnStop() override; + +private: + napi_value CallObjectMethod(const char* methodName, const napi_value* argv = nullptr, size_t argc = 0); + void GetSrcPath(std::string& srcPath); + void BindContext(); + +private: + JsRuntime& jsRuntime_; + std::unique_ptr jsObj_; + std::shared_ptr shellContextRef_ = nullptr; +}; +} // namespace OHOS::AbilityRuntime + +#endif // JS_SELECTION_EXTENSION_H \ No newline at end of file diff --git a/frameworks/native/selection_extension/include/selection_extension.h b/frameworks/native/selection_extension/include/selection_extension.h index 3ac7909..d983eda 100644 --- a/frameworks/native/selection_extension/include/selection_extension.h +++ b/frameworks/native/selection_extension/include/selection_extension.h @@ -25,6 +25,14 @@ public: SelectionExtension() = default; virtual ~SelectionExtension() = default; + /** + * @brief Create Extension. + * + * @param runtime The runtime. + * @return The InputMethodExtension instance. + */ + static SelectionExtension* Create(const std::unique_ptr& runtime); + /** * @brief Init the extension. * @@ -37,14 +45,6 @@ public: const std::shared_ptr& application, std::shared_ptr& handler, const sptr& token) override; - - /** - * @brief Create Extension. - * - * @param runtime The runtime. - * @return The InputMethodExtension instance. - */ - static SelectionExtension* Create(const std::unique_ptr& runtime); }; } // namespace OHOS::AbilityRuntime diff --git a/frameworks/native/selection_extension/include/selection_extension_context.h b/frameworks/native/selection_extension/include/selection_extension_context.h index 7dbd620..3299c1a 100644 --- a/frameworks/native/selection_extension/include/selection_extension_context.h +++ b/frameworks/native/selection_extension/include/selection_extension_context.h @@ -26,4 +26,4 @@ public: virtual ~SelectionExtensionContext() = default; }; } // namespace OHOS::AbilityRuntime -#endif +#endif // SELECTION_EXTENSION_CONTEXT_H diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp new file mode 100644 index 0000000..d705bc8 --- /dev/null +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -0,0 +1,162 @@ +/* + * 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_selection_extension.h" +#include "hilog_wrapper.h" +#include "js_runtime.h" +#include "js_runtime_utils.h" +#include "napi/native_api.h" +#include "napi_common_want.h" + +namespace OHOS::AbilityRuntime { +namespace { +constexpr size_t ARGC_ONE = 1; +} + +JsSelectionExtension::JsSelectionExtension(JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {} +JsSelectionExtension::~JsSelectionExtension() +{ + jsRuntime_.FreeNativeReference(std::move(jsObj_)); +} + +JsSelectionExtension* JsSelectionExtension::Create(const std::unique_ptr& runtime) +{ + return new (std::nothrow) JsSelectionExtension(static_cast(*runtime)); +} + +void JsSelectionExtension::Init(const std::shared_ptr& record, + const std::shared_ptr& application, + std::shared_ptr& handler, + const sptr& token) +{ + SelectionExtension::Init(record, application, handler, token); + std::string srcPath; + GetSrcPath(srcPath); + if (srcPath.empty()) { + HILOG_ERROR("failed to get srcPath!"); + return; + } + + std::string moduleName(Extension::abilityInfo_->moduleName); + moduleName.append("::").append(abilityInfo_->name); + HILOG_INFO("JsSelectionExtension, module: %{public}s, srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str()); + HandleScope handleScope(jsRuntime_); + jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, + abilityInfo_->compileMode == CompileMode::ES_MODULE); + if (jsObj_ == nullptr) { + HILOG_ERROR("failed to init jsObj_!"); + return; + } + BindContext(); +} + +void JsSelectionExtension::OnStart(const AAFwk::Want& want) +{ + Extension::OnStart(want); + HILOG_INFO("JsSelectionExtension OnStart begin."); + napi_env env = jsRuntime_.GetNapiEnv(); + napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); + napi_value argv[] = {napiWant}; + CallObjectMethod("onCreate", argv, ARGC_ONE); + HILOG_INFO("%{public}s end.", __func__); +} + +sptr JsSelectionExtension::OnConnect(const AAFwk::Want& want) +{ + return nullptr; +} + +void JsSelectionExtension::OnDisconnect(const AAFwk::Want& want) {} + +void JsSelectionExtension::OnStop() {} + +napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const napi_value* argv, size_t argc) +{ + HILOG_INFO("JsSelectionExtension::CallObjectMethod(%{public}s), start.", methodName); + + if (jsObj_ == nullptr) { + HILOG_ERROR("not found JsSelectionExtension.js."); + return nullptr; + } + + HandleScope handleScope(jsRuntime_); + napi_env env = jsRuntime_.GetNapiEnv(); + napi_value obj = jsObj_->GetNapiValue(); + if (obj == nullptr) { + HILOG_ERROR("failed to get JsSelectionExtension object!"); + return nullptr; + } + + napi_value method = nullptr; + napi_get_named_property(env, obj, methodName, &method); + if (method == nullptr) { + HILOG_ERROR("failed to get '%{public}s' from JsSelectionExtension object!", methodName); + return nullptr; + } + HILOG_INFO("JsSelectionExtension::CallFunction(%{public}s), success.", methodName); + napi_value result = nullptr; + if (napi_call_function(env, obj, method, argc, argv, &result) != napi_ok) { + return nullptr; + } + return result; +} + +void JsSelectionExtension::GetSrcPath(std::string& srcPath) +{ + if (!Extension::abilityInfo_->isModuleJson) { + /* temporary compatibility api8 + config.json */ + srcPath.append(Extension::abilityInfo_->package); + srcPath.append("/assets/js/"); + if (!Extension::abilityInfo_->srcPath.empty()) { + srcPath.append(Extension::abilityInfo_->srcPath); + } + srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc"); + return; + } + + if (!Extension::abilityInfo_->srcEntrance.empty()) { + srcPath.append(Extension::abilityInfo_->moduleName + "/"); + srcPath.append(Extension::abilityInfo_->srcEntrance); + srcPath.erase(srcPath.rfind('.')); + srcPath.append(".abc"); + } +} + +void JsSelectionExtension::BindContext() +{ + // TODO: + + // auto env = jsRuntime_.GetNapiEnv(); + // napi_value obj = jsObj_->GetNapiValue(); + // if (!CheckTypeForNapiValue(env, obj, napi_object)) { + // HILOG_ERROR("check type failed"); + // return; + // } + + // auto context = GetContext(); + // if (context == nullptr) { + // HILOG_ERROR("failed to get context!"); + // return; + // } + + // napi_value contextObj = CreateJsSelectionExtensionContext(env, context); + // auto contextRef = jsRuntime_.LoadSystemModule("SelectionExtensionContext", &contextObj, ARGC_ONE); + // if (!contextRef) { + // HILOG_ERROR("context is nullptr"); + // return; + // } +} + +} // namespace OHOS::AbilityRuntime \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/selection_extension.cpp b/frameworks/native/selection_extension/src/selection_extension.cpp index 50ead80..09ff3e0 100644 --- a/frameworks/native/selection_extension/src/selection_extension.cpp +++ b/frameworks/native/selection_extension/src/selection_extension.cpp @@ -14,6 +14,7 @@ */ #include "selection_extension.h" +#include "js_selection_extension.h" #include "runtime.h" namespace OHOS::AbilityRuntime { @@ -26,7 +27,7 @@ SelectionExtension* SelectionExtension::Create(const std::unique_ptr& r } switch (runtime->GetLanguage()) { case Runtime::Language::JS: - return SelectionExtension::Create(runtime); + return JsSelectionExtension::Create(runtime); default: return new SelectionExtension(); } @@ -37,6 +38,7 @@ void SelectionExtension::Init(const std::shared_ptr& record, std::shared_ptr& handler, const sptr& token) { + HILOG_INFO("call SelectionExtension::Init"); ExtensionBase::Init(record, application, handler, token); } diff --git a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp index 1b398e9..4d7e0a9 100644 --- a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp @@ -20,6 +20,7 @@ namespace OHOS::AbilityRuntime { SelectionExtensionModuleLoader::SelectionExtensionModuleLoader() = default; SelectionExtensionModuleLoader::~SelectionExtensionModuleLoader() = default; + Extension* SelectionExtensionModuleLoader::Create(const std::unique_ptr& runtime) const { return SelectionExtension::Create(runtime); @@ -27,13 +28,8 @@ Extension* SelectionExtensionModuleLoader::Create(const std::unique_ptr std::map SelectionExtensionModuleLoader::GetParams() { - // TODO:确定type和name - std::map params; // type means extension type in ExtensionAbilityType of extension_ability_info.h - // params.insert(std::pair("type", "2")); - // extension name - // params.insert(std::pair("name", "SelectionExtensionAbility")); - return params; + return {{"type", "509"}, {"name", "SelectionExtensionAbility"}}; } extern "C" __attribute__((visibility("default"))) void* OHOS_EXTENSION_GetExtensionModule() diff --git a/service/BUILD.gn b/service/BUILD.gn index 3498e25..13c2c7a 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -46,6 +46,8 @@ ohos_shared_library("selection_service") { deps = [ ":selection_service_interface" ] external_deps = [ + "ability_base:want", + "ability_runtime:ability_manager", "c_utils:utils", "ipc:ipc_single", "init:libbeget_proxy", diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 9eb367a..511d6c0 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -55,6 +55,8 @@ public: ErrCode AddVolume(int32_t volume, int32_t& funcResult) override; int32_t Dump(int32_t fd, const std::vector &args) override; + int32_t StartNewAbility(const std::string& bundleName, const std::string& abilityName); + void StopCurrentAbility(); protected: void OnStart() override; void OnStop() override; @@ -66,6 +68,9 @@ private: void WatchParams(); int32_t inputMonitorId_ {-1}; + std::mutex abilityMutex_; + std::string currentBundleName_ = ""; + std::string currentAbilityName_ = ""; static sptr instance_; static std::shared_mutex adminLock_; }; diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 8aecd7d..ac476e8 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -15,6 +15,7 @@ #include "selection_service.h" +#include "ability_manager_client.h" #include "iremote_object.h" #include "system_ability_definition.h" #include "selection_log.h" @@ -84,11 +85,69 @@ static void WatchTriggerMode(const char *key, const char *value, void *context) SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); } +void SelectionService::StopCurrentAbility() +{ + std::lock_guard lock(abilityMutex_); + if (currentBundleName_.empty() || currentAbilityName_.empty()) { + SELECTION_HILOGD("No ability running"); + return; + } + SELECTION_HILOGD("Stop current ability: %{public}s/%{public}s", currentBundleName_.c_str(), + currentAbilityName_.c_str()); + + AAFwk::Want want; + want.SetElementName(currentBundleName_, currentAbilityName_); + int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility(want, nullptr); + if (ret != ERR_OK) { + SELECTION_HILOGE("StopServiceAbility failed, ret: %{public}d", ret); + return; + } + + currentBundleName_.clear(); + currentAbilityName_.clear(); +} + +int32_t SelectionService::StartNewAbility( const std::string& bundleName, const std::string& abilityName) +{ + SELECTION_HILOGD("Start new SelectionExtension, bundleName:%{public}s, abilityName:%{public}s", bundleName.c_str(), + abilityName.c_str()); + AAFwk::Want want; + want.SetElementName(bundleName, abilityName); + + auto ret = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(want, nullptr); + if (ret != 0) { + SELECTION_HILOGE("StartExtensionAbility failed %{public}d", ret); + return ret; + } + + currentBundleName_ = bundleName; + currentAbilityName_ = abilityName; + SELECTION_HILOGD("StartExtensionAbility success"); + return 0; +} + static void WatchAppSwitch(const char *key, const char *value, void *context) { - (void)context; - SELECTION_HILOGI("WatchParameterFunc begin"); - SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); + SELECTION_HILOGD("WatchAppSwitch begin"); + SELECTION_HILOGD("%{public}s: value=%{public}s", key, value); + SelectionService *selectionService = static_cast(context); + if (selectionService == nullptr) { + SELECTION_HILOGE("selectionService is nullptr"); + return; + } + + const std::string appInfo = value; + auto pos = appInfo.find('/'); + if (pos == std::string::npos || pos + 1 >= appInfo.size()) { + SELECTION_HILOGE("app info: %{public}s is abnormal!", appInfo.c_str()); + return; + } + const std::string bundleName = appInfo.substr(0, pos); + const std::string extName = appInfo.substr(pos + 1); + SELECTION_HILOGD("bundleName: %{public}s, extName: %{public}s", bundleName.c_str(), extName.c_str()); + selectionService->StopCurrentAbility(); + auto ret = selectionService->StartNewAbility(bundleName, extName); + SELECTION_HILOGD("StartExtensionAbility ret = %{public}d", ret); } void SelectionService::WatchParams() @@ -96,7 +155,7 @@ void SelectionService::WatchParams() SELECTION_HILOGI("WatchParams begin"); WatchParameter("persist.sys.selection.switch.username", WatchParameterFunc, nullptr); WatchParameter("persist.sys.selection.trigger.username", WatchTriggerMode, nullptr); - WatchParameter("persist.sys.selection.app.username", WatchAppSwitch, nullptr); + WatchParameter("persist.sys.selection.app.username", WatchAppSwitch, this); SELECTION_HILOGI("WatchParams end"); } -- Gitee From fcb06e25567d0b9f3afa56675cd52ab768058f1c Mon Sep 17 00:00:00 2001 From: "yangmaoquan@chinasoftinc.com" Date: Thu, 15 May 2025 15:52:18 +0800 Subject: [PATCH 14/93] =?UTF-8?q?=E6=BB=91=E5=8A=A8=E9=80=89=E8=AF=8D?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan@chinasoftinc.com Signed-off-by: Sunjiamei --- service/include/selection_service.h | 9 ++- service/src/selection_service.cpp | 119 ++++++++++++++++++---------- 2 files changed, 81 insertions(+), 47 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 511d6c0..f42083d 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -27,9 +27,10 @@ namespace OHOS::SelectionFwk { using namespace MMI; -constexpr const char *SYS_SELECTION_SWITCH_USERNAM = "sys.selection.switch.username"; -constexpr const char *SYS_SELECTION_TRIGGER_USERNAM = "sys.selection.trigger.username"; -constexpr const char *SYS_SELECTION_APP_USERNAM = "sys.selection.app.username"; +constexpr const char *SYS_SELECTION_SWITCH_USERNAM = "persist.sys.selection.switch.username"; +constexpr const char *SYS_SELECTION_TRIGGER_USERNAM = "persist.sys.selection.trigger.username"; +constexpr const char *SYS_SELECTION_APP_USERNAM = "persist.sys.selection.app.username"; +constexpr const char *SYS_SELECTION_TRIGGER_VAL = "ctrl"; typedef enum SelectInputState { SELECT_INPUT_INITIAL = 0, @@ -81,6 +82,8 @@ public: virtual void OnInputEvent(std::shared_ptr pointerEvent) const; virtual void OnInputEvent(std::shared_ptr axisEvent) const; +public: + static bool ctrlSelectFlag; private: void InputInitialProcess(std::shared_ptr pointerEvent) const; void InputWordBeginProcess(std::shared_ptr pointerEvent) const; diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index ac476e8..db8d1c8 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -31,6 +31,7 @@ std::shared_mutex SelectionService::adminLock_; sptr SelectionService::instance_; uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; +bool SelectionInputMonitor::ctrlSelectFlag = false; sptr SelectionService::GetInstance() { @@ -83,6 +84,14 @@ static void WatchTriggerMode(const char *key, const char *value, void *context) (void)context; SELECTION_HILOGI("WatchParameterFunc begin"); SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); + if (strcmp(key, SYS_SELECTION_TRIGGER_USERNAM) == 0) { + if (strcmp(value, SYS_SELECTION_TRIGGER_VAL) == 0) { + SelectionInputMonitor::ctrlSelectFlag = true; + } else { + SelectionInputMonitor::ctrlSelectFlag = false; + } + SELECTION_HILOGI("ctrlSelectFlag is %{public}d", SelectionInputMonitor::ctrlSelectFlag); + } } void SelectionService::StopCurrentAbility() @@ -153,9 +162,9 @@ static void WatchAppSwitch(const char *key, const char *value, void *context) void SelectionService::WatchParams() { SELECTION_HILOGI("WatchParams begin"); - WatchParameter("persist.sys.selection.switch.username", WatchParameterFunc, nullptr); - WatchParameter("persist.sys.selection.trigger.username", WatchTriggerMode, nullptr); - WatchParameter("persist.sys.selection.app.username", WatchAppSwitch, this); + WatchParameter(SYS_SELECTION_SWITCH_USERNAM, WatchParameterFunc, nullptr); + WatchParameter(SYS_SELECTION_TRIGGER_USERNAM, WatchTriggerMode, nullptr); + WatchParameter(SYS_SELECTION_APP_USERNAM, WatchAppSwitch, this); SELECTION_HILOGI("WatchParams end"); } @@ -238,9 +247,67 @@ void SelectionService::HandlePointEvent(int32_t type) // foundation/multimodalinput/input/interfaces/native/innerkits/event/include/key_event.h void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { + SELECTION_HILOGI("[SelectionService] into keyEvent"); + int32_t keyCode = keyEvent->GetKeyCode(); SELECTION_HILOGI("[SelectionService] keyId: %{public}d", keyEvent->GetKeyCode()); + if (keyCode == KeyEvent::KEYCODE_CTRL_LEFT || keyCode == KeyEvent::KEYCODE_CTRL_RIGHT) { + SELECTION_HILOGI("[SelectionService] Processed ctrl key."); + if (ctrlSelectFlag && curSelectState == SELECT_INPUT_WAIT_CTRL) { + curSelectState = SELECT_INPUT_LEFT_MOVE; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); + } + } + +} + +void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const +{ + SELECTION_HILOGI("[SelectionService] into PointerEvent"); + int32_t action = pointerEvent->GetPointerAction(); + int32_t buttonId = pointerEvent->GetButtonId(); + SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", action); + SELECTION_HILOGI("[SelectionService] buttonId: %{public}d", buttonId); + if (curSelectState == SELECT_INPUT_INITIAL && buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { + return; + } + if (curSelectState == SELECT_INPUT_WAIT_CTRL) { + curSelectState = SELECT_INPUT_INITIAL; + } + + switch (curSelectState) + { + case SELECT_INPUT_INITIAL: + InputInitialProcess(pointerEvent); + break; + + case SELECT_INPUT_WORD_BEGIN: + InputWordBeginProcess(pointerEvent); + break; + + case SELECT_INPUT_WAIT_LEFT_MOVE: + InputWordWaitLeftMoveProcess(pointerEvent); + break; + + default: + break; + } + + if (curSelectState == SELECT_INPUT_LEFT_MOVE) { + // world selection action + SELECTION_HILOGI("[SelectionService] first, end word selection action."); + InjectCtrlC(); + SELECTION_HILOGI("[SelectionService] first, end inject ctrl + c."); + curSelectState = SELECT_INPUT_INITIAL; + } + return; } +void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const +{ + SELECTION_HILOGI("[SelectionService] into axisEvent"); +}; + + void SelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); @@ -266,7 +333,11 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptrGetPointerAction(); if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { - curSelectState = SELECT_INPUT_LEFT_MOVE; + if (ctrlSelectFlag) { + curSelectState = SELECT_INPUT_WAIT_CTRL; + } else { + curSelectState = SELECT_INPUT_LEFT_MOVE; + } } return; } @@ -290,43 +361,3 @@ void SelectionInputMonitor::InjectCtrlC() const } InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); } - -void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const -{ - int32_t action = pointerEvent->GetPointerAction(); - int32_t buttonId = pointerEvent->GetButtonId(); - SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", action); - SELECTION_HILOGI("[SelectionService] buttonId: %{public}d", buttonId); - if (curSelectState == SELECT_INPUT_INITIAL && buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { - return; - } - - switch (curSelectState) - { - case SELECT_INPUT_INITIAL: - InputInitialProcess(pointerEvent); - break; - - case SELECT_INPUT_WORD_BEGIN: - InputWordBeginProcess(pointerEvent); - break; - - case SELECT_INPUT_WAIT_LEFT_MOVE: - InputWordWaitLeftMoveProcess(pointerEvent); - break; - - default: - break; - } - - if (curSelectState == SELECT_INPUT_LEFT_MOVE) { - // world selection action - SELECTION_HILOGI("[SelectionService] first, end word selection action."); - InjectCtrlC(); - SELECTION_HILOGI("[SelectionService] first, end inject ctrl + c."); - curSelectState = SELECT_INPUT_INITIAL; - } - return; -} - -void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const {}; \ No newline at end of file -- Gitee From 672ddcfbb4d64dc53f47bc33625518df3e254c28 Mon Sep 17 00:00:00 2001 From: fbb Date: Thu, 15 May 2025 18:34:05 +0800 Subject: [PATCH 15/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0selectionability?= =?UTF-8?q?=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 4 +- frameworks/js/napi/selection_ability/BUILD.gn | 45 +++++++++++++++++ .../js/napi/selection_ability/js_panel.cpp | 0 .../js/napi/selection_ability/js_panel.h | 0 .../js_selection_ability.cpp | 22 +++++++++ .../selection_ability/js_selection_ability.h | 32 +++++++++++++ .../selection_ability_module.cpp | 48 +++++++++++++++++++ frameworks/native/selection_ability/BUILD.gn | 44 +++++++++++++++++ .../include/selection_ability.h | 0 .../include/selection_panel.h | 0 .../src/selection_ability.cpp | 0 .../selection_ability/src/selection_panel.cpp | 0 12 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 frameworks/js/napi/selection_ability/BUILD.gn create mode 100644 frameworks/js/napi/selection_ability/js_panel.cpp create mode 100644 frameworks/js/napi/selection_ability/js_panel.h create mode 100644 frameworks/js/napi/selection_ability/js_selection_ability.cpp create mode 100644 frameworks/js/napi/selection_ability/js_selection_ability.h create mode 100644 frameworks/js/napi/selection_ability/selection_ability_module.cpp create mode 100644 frameworks/native/selection_ability/BUILD.gn create mode 100644 frameworks/native/selection_ability/include/selection_ability.h create mode 100644 frameworks/native/selection_ability/include/selection_panel.h create mode 100644 frameworks/native/selection_ability/src/selection_ability.cpp create mode 100644 frameworks/native/selection_ability/src/selection_panel.cpp diff --git a/bundle.json b/bundle.json index 14daad0..b7e1f99 100644 --- a/bundle.json +++ b/bundle.json @@ -40,7 +40,9 @@ "//foundation/systemabilitymgr/selection_fwk/service:selection_service", "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile", "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", - "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native" + "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native", + "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionability_napi", + "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_ability:selectionability" ], "inner_kits": [] } diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn new file mode 100644 index 0000000..9236e17 --- /dev/null +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -0,0 +1,45 @@ +# 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") + +ohos_shared_library("selectionability_napi") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + sources = [ + "js_selection_ability.cpp", + "selection_ability_module.cpp", + ] + + include_dirs = [ + ".", + "../../../../utils/include", + "${target_gen_dir}", + ] + + external_deps = [ + "hilog:libhilog", + "napi:ace_napi", + ] + + relative_install_dir = "module" + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/js/napi/selection_ability/js_selection_ability.cpp b/frameworks/js/napi/selection_ability/js_selection_ability.cpp new file mode 100644 index 0000000..6008642 --- /dev/null +++ b/frameworks/js/napi/selection_ability/js_selection_ability.cpp @@ -0,0 +1,22 @@ +#include "js_selection_ability.h" + +#include "napi/native_node_api.h" +#include "selection_log.h" + +using namespace OHOS::SelectionFwk; + +napi_value JsSelectionAbility::GetSelectionAbility(napi_env env, napi_callback_info info) +{ + SELECTION_HILOGI("GetSelectionAbility"); + return nullptr; +} + +napi_value JsSelectionAbility::Init(napi_env env, napi_value exports) +{ + SELECTION_HILOGI("napi init"); + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("getSelectionAbility", GetSelectionAbility), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties)); + return exports; +} \ No newline at end of file diff --git a/frameworks/js/napi/selection_ability/js_selection_ability.h b/frameworks/js/napi/selection_ability/js_selection_ability.h new file mode 100644 index 0000000..3c7c4a3 --- /dev/null +++ b/frameworks/js/napi/selection_ability/js_selection_ability.h @@ -0,0 +1,32 @@ +/* + * 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 JS_SELECTION_ABILITY_H +#define JS_SELECTION_ABILITY_H + +#include "napi/native_api.h" + +namespace OHOS { +namespace SelectionFwk { +class JsSelectionAbility { +public: + JsSelectionAbility() = default; + ~JsSelectionAbility() = default; + static napi_value Init(napi_env env, napi_value exports); + static napi_value GetSelectionAbility(napi_env env, napi_callback_info info); +}; +} //SelectionFwk +} //OHOS +#endif //JS_SELECTION_ABILITY_H \ No newline at end of file diff --git a/frameworks/js/napi/selection_ability/selection_ability_module.cpp b/frameworks/js/napi/selection_ability/selection_ability_module.cpp new file mode 100644 index 0000000..e15bbdc --- /dev/null +++ b/frameworks/js/napi/selection_ability/selection_ability_module.cpp @@ -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. + */ + +#include "js_selection_ability.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +EXTERN_C_START +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports) +{ + OHOS::SelectionFwk::JsSelectionAbility::Init(env, exports); + return exports; +} +EXTERN_C_END + +/* + * module define + */ +static napi_module _module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "selectionAbility", + .nm_priv = ((void *)0), + .reserved = { 0 } }; +/* + * module register + */ +extern "C" __attribute__((constructor)) void Register() +{ + napi_module_register(&_module); +} \ No newline at end of file diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn new file mode 100644 index 0000000..00b6458 --- /dev/null +++ b/frameworks/native/selection_ability/BUILD.gn @@ -0,0 +1,44 @@ +# 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") + +ohos_shared_library("selectionability") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + sources = [ + "src/selection_ability.cpp", + ] + + include_dirs = [ + ".", + "../../../utils/include", + "${target_gen_dir}", + ] + + external_deps = [ + "hilog:libhilog", + "napi:ace_napi", + ] + + relative_install_dir = "module" + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/frameworks/native/selection_ability/include/selection_ability.h b/frameworks/native/selection_ability/include/selection_ability.h new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp new file mode 100644 index 0000000..e69de29 -- Gitee From aa502afbfad484ceed6049308908eb9a31203198 Mon Sep 17 00:00:00 2001 From: "yangmaoquan@chinasoftinc.com" Date: Fri, 16 May 2025 09:30:44 +0800 Subject: [PATCH 16/93] =?UTF-8?q?=E6=BB=91=E5=8A=A8=E9=80=89=E8=AF=8D?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan@chinasoftinc.com Signed-off-by: Sunjiamei --- service/include/selection_service.h | 13 ++++- service/src/selection_service.cpp | 74 ++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index f42083d..3eaae61 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -31,8 +31,9 @@ constexpr const char *SYS_SELECTION_SWITCH_USERNAM = "persist.sys.selection.swit constexpr const char *SYS_SELECTION_TRIGGER_USERNAM = "persist.sys.selection.trigger.username"; constexpr const char *SYS_SELECTION_APP_USERNAM = "persist.sys.selection.app.username"; constexpr const char *SYS_SELECTION_TRIGGER_VAL = "ctrl"; +constexpr const uint32_t DOUBLE_CLICK_TIME = 400; -typedef enum SelectInputState { +typedef enum { SELECT_INPUT_INITIAL = 0, SELECT_INPUT_WORD_BEGIN = 1, SELECT_INPUT_WAIT_LEFT_MOVE = 2, @@ -45,6 +46,13 @@ typedef enum SelectInputState { } SelectInputState; +typedef enum { + SUB_INITIAL = 0, + SUB_WAIT_PRESS_DOWN = 1, + SUB_WAIT_PRESS_MOVE = 2, + SUB_WAIT_PRESS_UP = 3, +} SelectInputSubState; + class SelectionService : public SystemAbility, public SelectionServiceStub { DECLARE_SYSTEM_ABILITY(SelectionService); @@ -88,8 +96,11 @@ private: void InputInitialProcess(std::shared_ptr pointerEvent) const; void InputWordBeginProcess(std::shared_ptr pointerEvent) const; void InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const; + void InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const; void InjectCtrlC() const; static uint32_t curSelectState; + static uint32_t subSelectState; + static int64_t lastClickTime; }; } diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index db8d1c8..a4254e1 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -21,6 +21,7 @@ #include "selection_log.h" #include #include "parameter.h" +#include using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -31,6 +32,8 @@ std::shared_mutex SelectionService::adminLock_; sptr SelectionService::instance_; uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; +uint32_t SelectionInputMonitor::subSelectState = SUB_INITIAL; +int64_t SelectionInputMonitor::lastClickTime = 0; bool SelectionInputMonitor::ctrlSelectFlag = false; sptr SelectionService::GetInstance() @@ -72,6 +75,12 @@ int32_t SelectionService::Dump(int32_t fd, const std::vector &ar return OHOS::NO_ERROR; } +static int64_t GetCurrentTimeMillis() { + auto now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + return std::chrono::duration_cast(duration).count(); +} + static void WatchParameterFunc(const char *key, const char *value, void *context) { (void)context; @@ -191,6 +200,7 @@ void SelectionService::InputMonitorInit() if (inputMonitorId_ < 0) { inputMonitorId_ = InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); + SELECTION_HILOGI("[SelectionService] input monitor init end"); } } @@ -247,9 +257,9 @@ void SelectionService::HandlePointEvent(int32_t type) // foundation/multimodalinput/input/interfaces/native/innerkits/event/include/key_event.h void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { - SELECTION_HILOGI("[SelectionService] into keyEvent"); + SELECTION_HILOGD("[SelectionService] into keyEvent"); int32_t keyCode = keyEvent->GetKeyCode(); - SELECTION_HILOGI("[SelectionService] keyId: %{public}d", keyEvent->GetKeyCode()); + SELECTION_HILOGD("[SelectionService] keyId: %{public}d", keyCode); if (keyCode == KeyEvent::KEYCODE_CTRL_LEFT || keyCode == KeyEvent::KEYCODE_CTRL_RIGHT) { SELECTION_HILOGI("[SelectionService] Processed ctrl key."); if (ctrlSelectFlag && curSelectState == SELECT_INPUT_WAIT_CTRL) { @@ -262,17 +272,19 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { - SELECTION_HILOGI("[SelectionService] into PointerEvent"); + SELECTION_HILOGD("[SelectionService] into PointerEvent"); int32_t action = pointerEvent->GetPointerAction(); int32_t buttonId = pointerEvent->GetButtonId(); - SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", action); - SELECTION_HILOGI("[SelectionService] buttonId: %{public}d", buttonId); + SELECTION_HILOGD("[SelectionService] pointerEvent: %{public}d", action); + SELECTION_HILOGD("[SelectionService] buttonId: %{public}d", buttonId); if (curSelectState == SELECT_INPUT_INITIAL && buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { return; } if (curSelectState == SELECT_INPUT_WAIT_CTRL) { + SELECTION_HILOGI("[SelectionService] pointerEvent: curSelectState == SELECT_INPUT_WAIT_CTRL. return."); curSelectState = SELECT_INPUT_INITIAL; } + SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); switch (curSelectState) { @@ -287,18 +299,21 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv case SELECT_INPUT_WAIT_LEFT_MOVE: InputWordWaitLeftMoveProcess(pointerEvent); break; + case SELECT_INPUT_WAIT_DOUBLE_CLICK: + InputWordWaitDoubleClickProcess(pointerEvent); + break; default: break; } - - if (curSelectState == SELECT_INPUT_LEFT_MOVE) { + if (curSelectState == SELECT_INPUT_LEFT_MOVE || curSelectState == SELECT_INPUT_DOUBLE_CLICKED) { // world selection action SELECTION_HILOGI("[SelectionService] first, end word selection action."); InjectCtrlC(); SELECTION_HILOGI("[SelectionService] first, end inject ctrl + c."); curSelectState = SELECT_INPUT_INITIAL; } + return; } @@ -314,6 +329,9 @@ void SelectionInputMonitor::InputInitialProcess(std::shared_ptr po int32_t buttonId = pointerEvent->GetButtonId(); if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && buttonId == PointerEvent::MOUSE_BUTTON_LEFT) { curSelectState = SELECT_INPUT_WORD_BEGIN; + subSelectState = SUB_INITIAL; + lastClickTime = GetCurrentTimeMillis(); + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); } return; } @@ -323,8 +341,12 @@ void SelectionInputMonitor::InputWordBeginProcess(std::shared_ptr int32_t action = pointerEvent->GetPointerAction(); if (action == PointerEvent::POINTER_ACTION_MOVE) { curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + subSelectState = SUB_WAIT_PRESS_UP; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); } else if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { curSelectState = SELECT_INPUT_WAIT_DOUBLE_CLICK; + subSelectState = SUB_WAIT_PRESS_DOWN; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_DOUBLE_CLICK."); } return; } @@ -335,13 +357,51 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + int32_t buttonId = pointerEvent->GetButtonId(); + if (buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL."); + return; + } + if (subSelectState == SUB_WAIT_PRESS_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + subSelectState = SUB_WAIT_PRESS_UP; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_PRESS_UP."); + return; + } + if (subSelectState == SUB_WAIT_PRESS_UP && action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + auto curTime = GetCurrentTimeMillis(); + if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { + curSelectState = SELECT_INPUT_DOUBLE_CLICKED; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_DOUBLE_CLICKED."); + return; + } + curSelectState = SELECT_INPUT_WAIT_DOUBLE_CLICK; + subSelectState = SUB_WAIT_PRESS_DOWN; + lastClickTime = curTime; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_DOUBLE_CLICK."); + return; + } + + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL."); + return; +} + void SelectionInputMonitor::InjectCtrlC() const { auto keyDownEvent = KeyEvent::Create(); -- Gitee From 0667289d7b33f3e73a58c2d2a20e0102ceb62c44 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Wed, 14 May 2025 19:09:44 +0800 Subject: [PATCH 17/93] selectionEvent Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- bundle.json | 11 +- common/BUILD.gn | 65 ++++ common/block_data.h | 75 ++++ common/callback_handler.cpp | 49 +++ common/callback_handler.h | 69 ++++ common/callback_object.cpp | 87 +++++ common/callback_object.h | 57 +++ common/event_checker.cpp | 33 ++ common/event_checker.h | 33 ++ common/js_utils.cpp | 349 ++++++++++++++++++ common/js_utils.h | 187 ++++++++++ common/selectionmethod_trace.cpp | 59 +++ common/selectionmethod_trace.h | 47 +++ common/util.cpp | 119 ++++++ common/util.h | 131 +++++++ frameworks/js/napi/selection_ability/BUILD.gn | 17 + .../js_selection_ability.cpp | 175 ++++++++- .../selection_ability/js_selection_ability.h | 25 +- frameworks/js/napi/selectionability/BUILD.gn | 69 ++++ .../js_selection_ability_engine.cpp | 200 ++++++++++ .../js_selection_ability_engine.h | 53 +++ .../selection_engine_module.cpp | 47 +++ selection_service.gni | 13 +- service/BUILD.gn | 7 +- service/include/selection_service.h | 19 + service/src/selection_service.cpp | 58 +++ utils/include/selection_log.h | 103 ++++++ 27 files changed, 2137 insertions(+), 20 deletions(-) create mode 100644 common/BUILD.gn create mode 100644 common/block_data.h create mode 100644 common/callback_handler.cpp create mode 100644 common/callback_handler.h create mode 100644 common/callback_object.cpp create mode 100644 common/callback_object.h create mode 100644 common/event_checker.cpp create mode 100644 common/event_checker.h create mode 100644 common/js_utils.cpp create mode 100644 common/js_utils.h create mode 100644 common/selectionmethod_trace.cpp create mode 100644 common/selectionmethod_trace.h create mode 100644 common/util.cpp create mode 100644 common/util.h create mode 100644 frameworks/js/napi/selectionability/BUILD.gn create mode 100644 frameworks/js/napi/selectionability/js_selection_ability_engine.cpp create mode 100644 frameworks/js/napi/selectionability/js_selection_ability_engine.h create mode 100644 frameworks/js/napi/selectionability/selection_engine_module.cpp diff --git a/bundle.json b/bundle.json index b7e1f99..827ff75 100644 --- a/bundle.json +++ b/bundle.json @@ -19,21 +19,27 @@ "deps": { "components": [ "c_utils", + "eventhandler", "ipc", + "napi", "safwk", "hilog", + "hitrace", "samgr", "init", "input", "napi", "ability_base", - "ability_runtime" + "ability_runtime", + "window_manager", + "resource_management" ], "third_party": [ ] }, "build": { "sub_component": [ + "//foundation/systemabilitymgr/selection_fwk/common:selection_common", "//foundation/systemabilitymgr/selection_fwk/etc/init:selection_service_cfg", "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para", "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para_dac", @@ -41,8 +47,7 @@ "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile", "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native", - "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionability_napi", - "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_ability:selectionability" + "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionability_napi" ], "inner_kits": [] } diff --git a/common/BUILD.gn b/common/BUILD.gn new file mode 100644 index 0000000..cb77afd --- /dev/null +++ b/common/BUILD.gn @@ -0,0 +1,65 @@ +# 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. + +import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//build/ohos.gni") + +config("selection_js_common_public_config") { + visibility = [ "./*" ] + include_dirs = [ + "./", + ] +} + +ohos_static_library("selection_common") { + branch_protector_ret = "pac_ret" + + include_dirs = [ + "./", + "../utils/include", + ] + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + sources = [ + "event_checker.cpp", + "callback_handler.cpp", + "callback_object.cpp", + "util.cpp", + "selectionmethod_trace.cpp", + "js_utils.cpp" + ] + + ldflags = [ "-Wl,--exclude-libs=ALL" ] + cflags = [ + "-fdata-sections", + "-ffunction-sections", + "-fvisibility=hidden", + "-Wno-c99-designator", + ] + public_configs = [ ":selection_js_common_public_config" ] + deps = [] + external_deps = [ + "eventhandler:libeventhandler", + "napi:ace_napi", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", + "ability_base:want", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} diff --git a/common/block_data.h b/common/block_data.h new file mode 100644 index 0000000..78db7d5 --- /dev/null +++ b/common/block_data.h @@ -0,0 +1,75 @@ +/* + * 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_BLOCK_DATA_H +#define OHOS_BLOCK_DATA_H +#include +#include + +namespace OHOS { +namespace SelectionFwk { +template +class BlockData { +public: + explicit BlockData(uint32_t interval, const T &invalid = T()) : INTERVAL(interval), data_(invalid) + { + } + + ~BlockData() + { + } + +public: + void SetValue(const T &data) + { + std::lock_guard lock(mutex_); + data_ = data; + isSet_ = true; + cv_.notify_one(); + } + + T GetValue() + { + std::unique_lock lock(mutex_); + cv_.wait_for(lock, std::chrono::milliseconds(INTERVAL), [this]() { return isSet_; }); + T data = data_; + return data; + } + + bool GetValue(T &data) + { + std::unique_lock lock(mutex_); + cv_.wait_for(lock, std::chrono::milliseconds(INTERVAL), [this]() { return isSet_; }); + data = data_; + return isSet_; + } + + void Clear(const T &invalid = T()) + { + std::lock_guard lock(mutex_); + isSet_ = false; + data_ = invalid; + } + +private: + bool isSet_ = false; + const uint32_t INTERVAL; + T data_; + std::mutex mutex_; + std::condition_variable cv_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // OHOS_BLOCK_DATA_H diff --git a/common/callback_handler.cpp b/common/callback_handler.cpp new file mode 100644 index 0000000..4196a5c --- /dev/null +++ b/common/callback_handler.cpp @@ -0,0 +1,49 @@ +/* + * 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 "callback_handler.h" + +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { +constexpr size_t MAX_ARGV_COUNT = 10; +void JsCallbackHandler::Execute(const std::shared_ptr &object, const ArgContainer &argContainer, + napi_value &output) +{ + if (object->threadId_ != std::this_thread::get_id()) { + SELECTION_HILOGW("threadId not same!"); + return; + } + napi_value argv[MAX_ARGV_COUNT] = { nullptr }; + if (argContainer.argvProvider != nullptr && !argContainer.argvProvider(object->env_, argv, MAX_ARGV_COUNT)) { + return; + } + napi_value callback = nullptr; + napi_value global = nullptr; + napi_get_reference_value(object->env_, object->callback_, &callback); + if (callback == nullptr) { + SELECTION_HILOGE("callback is nullptr!"); + return; + } + napi_get_global(object->env_, &global); + SelectionMethodSyncTrace tracer("Execute napi_call_function"); + auto status = napi_call_function(object->env_, global, callback, argContainer.argc, argv, &output); + if (status != napi_ok) { + output = nullptr; + } +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/common/callback_handler.h b/common/callback_handler.h new file mode 100644 index 0000000..3655ecb --- /dev/null +++ b/common/callback_handler.h @@ -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. + */ +#ifndef OHOS_SELECTION_CALLBACK_HANDLER_H +#define OHOS_SELECTION_CALLBACK_HANDLER_H + +#include +#include "selectionmethod_trace.h" +#include "callback_object.h" +#include "util.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace SelectionFwk { +class JsCallbackHandler { +public: + using ArgvProvider = std::function; + struct ArgContainer { + size_t argc{ 0 }; + ArgvProvider argvProvider{ nullptr }; + }; + // 0 means the callback has no param. + static void Traverse(const std::vector> &objects, + const ArgContainer &argContainer = { 0, nullptr }) + { + SelectionMethodSyncTrace tracer("Traverse callback"); + for (const auto &object : objects) { + if (object == nullptr) { + continue; + } + JsUtil::ScopeGuard scopeGuard(object->env_); + napi_value jsOutput = nullptr; + Execute(object, argContainer, jsOutput); + } + } + template + static void Traverse(const std::vector> &objects, + const ArgContainer &argContainer, T &output) + { + SelectionMethodSyncTrace tracer("Traverse callback with output"); + for (const auto &object : objects) { + JsUtil::ScopeGuard scopeGuard(object->env_); + napi_value jsOutput = nullptr; + Execute(object, argContainer, jsOutput); + if (jsOutput != nullptr && JsUtil::GetValue(object->env_, jsOutput, output)) { + break; + } + } + } + +private: + static void Execute(const std::shared_ptr &object, const ArgContainer &argContainer, + napi_value &output); +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // OHOS_SELECTION_CALLBACK_HANDLER_H diff --git a/common/callback_object.cpp b/common/callback_object.cpp new file mode 100644 index 0000000..d661443 --- /dev/null +++ b/common/callback_object.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022 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 "callback_object.h" +#include "selection_log.h" + +#include + +namespace OHOS { +namespace SelectionFwk { +constexpr int32_t MAX_TIMEOUT = 2000; +JSCallbackObject::JSCallbackObject(napi_env env, napi_value callback, std::thread::id threadId, + std::shared_ptr jsHandler) + : env_(env), threadId_(threadId), jsHandler_(jsHandler) +{ + napi_create_reference(env, callback, 1, &callback_); +} + +JSCallbackObject::~JSCallbackObject() +{ + if (callback_ != nullptr) { + if (threadId_ == std::this_thread::get_id()) { + napi_delete_reference(env_, callback_); + env_ = nullptr; + return; + } + isDone_ = std::make_shared>(MAX_TIMEOUT, false); + std::string type = "~JSCallbackObject"; + auto eventHandler = jsHandler_; + if (eventHandler == nullptr) { + SELECTION_HILOGE("eventHandler is nullptr!"); + return; + } + auto task = [env = env_, callback = callback_, isDone = isDone_]() { + napi_delete_reference(env, callback); + bool isFinish = true; + isDone->SetValue(isFinish); + }; + eventHandler->PostTask(task, type); + isDone_->GetValue(); + } + env_ = nullptr; +} + + +JSMsgHandlerCallbackObject::JSMsgHandlerCallbackObject(napi_env env, napi_value onTerminated, napi_value onMessage) + : env_(env), handler_(AppExecFwk::EventHandler::Current()), threadId_(std::this_thread::get_id()) +{ + napi_create_reference(env, onTerminated, 1, &onTerminatedCallback_); + napi_create_reference(env, onMessage, 1, &onMessageCallback_); +} + +JSMsgHandlerCallbackObject::~JSMsgHandlerCallbackObject() +{ + if (threadId_ == std::this_thread::get_id()) { + if (onTerminatedCallback_ != nullptr) { + napi_delete_reference(env_, onTerminatedCallback_); + } + if (onMessageCallback_ != nullptr) { + napi_delete_reference(env_, onMessageCallback_); + } + env_ = nullptr; + return; + } + SELECTION_HILOGW("Thread id is not same, abstract destructor is run in muti-thread!"); + env_ = nullptr; +} + +std::shared_ptr JSMsgHandlerCallbackObject::GetEventHandler() +{ + std::lock_guard lock(eventHandlerMutex_); + return handler_; +} +} // namespace SelectionFwk +} // namespace OHOS diff --git a/common/callback_object.h b/common/callback_object.h new file mode 100644 index 0000000..cf18785 --- /dev/null +++ b/common/callback_object.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 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_CALLBACK_OBJECT_H +#define OHOS_CALLBACK_OBJECT_H + +#include +#include + +#include "block_data.h" +#include "event_handler.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace SelectionFwk { +class JSCallbackObject { +public: + JSCallbackObject(napi_env env, napi_value callback, std::thread::id threadId, + std::shared_ptr jsHandler); + ~JSCallbackObject(); + napi_ref callback_ = nullptr; + napi_env env_{}; + std::thread::id threadId_; + std::shared_ptr> isDone_; + std::shared_ptr jsHandler_; +}; + +// Ensure this object abstract in constract thread. +class JSMsgHandlerCallbackObject { +public: + JSMsgHandlerCallbackObject(napi_env env, napi_value onTerminated, napi_value onMessage); + ~JSMsgHandlerCallbackObject(); + napi_env env_{}; + napi_ref onTerminatedCallback_ = nullptr; + napi_ref onMessageCallback_ = nullptr; + std::shared_ptr GetEventHandler(); + +private: + std::mutex eventHandlerMutex_; + std::shared_ptr handler_ = nullptr; + std::thread::id threadId_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // OHOS_CALLBACK_OBJECT_H diff --git a/common/event_checker.cpp b/common/event_checker.cpp new file mode 100644 index 0000000..bdbc5e4 --- /dev/null +++ b/common/event_checker.cpp @@ -0,0 +1,33 @@ +/* + * 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 "event_checker.h" +#include + +namespace OHOS { +namespace SelectionFwk { +const std::unordered_set EVENT_TYPES[static_cast(EventSubscribeModule::MODULE_END)] = { + [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionEvent", "selectionPanelEvent" } +}; + +bool EventChecker::IsValidEventType(EventSubscribeModule module, const std::string &type) +{ + if (module < EventSubscribeModule::MODULE_BEGIN || module >= EventSubscribeModule::MODULE_END) { + return false; + } + return EVENT_TYPES[static_cast(module)].find(type) != EVENT_TYPES[static_cast(module)].end(); +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/common/event_checker.h b/common/event_checker.h new file mode 100644 index 0000000..85a335e --- /dev/null +++ b/common/event_checker.h @@ -0,0 +1,33 @@ +/* + * 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_EVENT_CHECK_H +#define OHOS_EVENT_CHECK_H +#include + +namespace OHOS { +namespace SelectionFwk { +enum class EventSubscribeModule : uint32_t { + MODULE_BEGIN = 0, + SELECTION_METHOD_ABILITY, + MODULE_END, +}; +class EventChecker { +public: + static bool IsValidEventType(EventSubscribeModule module, const std::string &type); +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // OHOS_EVENT_CHECK_H diff --git a/common/js_utils.cpp b/common/js_utils.cpp new file mode 100644 index 0000000..a4d691e --- /dev/null +++ b/common/js_utils.cpp @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2022-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_utils.h" + +namespace OHOS { +namespace SelectionFwk { +constexpr int32_t STR_MAX_LENGTH = 4096; +constexpr size_t STR_TAIL_LENGTH = 1; +constexpr size_t ARGC_MAX = 6; + +const std::map JsUtils::ERROR_CODE_MAP = { + { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER }, + { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION }, + { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION }, + { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_EDITABLE }, + { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED }, + { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS }, + { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS }, + { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS }, + { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST }, + { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER }, + { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IME_START_INPUT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME }, + { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE }, + { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME }, + { ErrorCode::ERROR_ENABLE_IME, EXCEPTION_IMMS }, + { ErrorCode::ERROR_NOT_CURRENT_IME, EXCEPTION_IMMS }, + { ErrorCode::ERROR_PANEL_NOT_FOUND, EXCEPTION_PANEL_NOT_FOUND }, + { ErrorCode::ERROR_WINDOW_MANAGER, EXCEPTION_WINDOW_MANAGER }, + { ErrorCode::ERROR_GET_TEXT_CONFIG, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_TEXT_LISTENER_ERROR, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED, EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED }, + { ErrorCode::ERROR_INVALID_RANGE, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_SECURITY_MODE_OFF, EXCEPTION_BASIC_MODE }, + { ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST, EXCEPTION_REQUEST_NOT_ACCEPT }, + { ErrorCode::ERROR_MESSAGE_HANDLER, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_INVALID_PANEL_TYPE, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, + { ErrorCode::ERROR_INVALID_PANEL_FLAG, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, + { ErrorCode::ERROR_IMA_CHANNEL_NULLPTR, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_IPC_REMOTE_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMA_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_INPUT_TYPE_NOT_FOUND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_MALLOC_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_START_TIMEOUT, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED }, +}; + +const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { + { EXCEPTION_PERMISSION, "the permissions check fails." }, + { EXCEPTION_SYSTEM_PERMISSION, "not system application." }, + { EXCEPTION_PARAMCHECK, "the parameters check fails." }, + { EXCEPTION_UNSUPPORTED, "capability not supported." }, + { EXCEPTION_PACKAGEMANAGER, "bundle manager error." }, + { EXCEPTION_IMENGINE, "input method engine error. Possible causes: 1.input method panel not created.\ + 2.the input method application does not subscribe to related events." }, + { EXCEPTION_IMCLIENT, "input method client error. Possible causes: 1.the edit box is not focused.\ + 2.no edit box is bound to current input method application." }, + { EXCEPTION_IME, "not an input method application." }, + { EXCEPTION_CONFPERSIST, "configuration persistence error." }, + { EXCEPTION_CONTROLLER, "input method controller error.\ + Possible cause: create InputmethodController object failed." }, + { EXCEPTION_SETTINGS, "input method setter error. Possible cause: create InputmethodSetting object failed." }, + { EXCEPTION_IMMS, "input method manager service error. Possible cause: a system error, such as null pointer,\ + IPC exception." }, + { EXCEPTION_DETACHED, "input method client detached." }, + { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." }, + { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." }, + { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." }, + { EXCEPTION_WINDOW_MANAGER, "window manager service error." }, + { EXCEPTION_BASIC_MODE, "the input method is basic mode." }, + { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." }, + { EXCEPTION_EDITABLE, "the edit mode need enable." }, + { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." }, +}; + +const std::map JsUtils::PARAMETER_TYPE = { + { TYPE_UNDEFINED, "napi_undefine." }, + { TYPE_NULL, "napi_null." }, + { TYPE_BOOLEAN, "napi_boolean." }, + { TYPE_NUMBER, "napi_number." }, + { TYPE_STRING, "napi_string." }, + { TYPE_SYMBOL, "napi_symbol." }, + { TYPE_OBJECT, "napi_object." }, + { TYPE_FUNCTION, "napi_function." }, + { TYPE_EXTERNAL, "napi_external." }, + { TYPE_BIGINT, "napi_bigint." }, + { TYPE_ARRAY_BUFFER, "ArrayBuffer." }, + { TYPE_ARRAY, "napi_array." }, +}; + +void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type) +{ + std::string errMsg = ToMessage(err); + napi_value error; + napi_value code; + napi_value message; + if (type == TypeCode::TYPE_NONE) { + errMsg = errMsg + " " + msg; + SELECTION_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); + } else { + auto iter = PARAMETER_TYPE.find(type); + if (iter != PARAMETER_TYPE.end()) { + errMsg = errMsg + "The type of " + msg + " must be " + iter->second; + SELECTION_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); + } + } + NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message)); + NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error)); + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code)); + NAPI_CALL_RETURN_VOID(env, napi_throw(env, error)); +} + +napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg) +{ + SELECTION_HILOGD("ToError start"); + napi_value errorObj; + NAPI_CALL(env, napi_create_object(env, &errorObj)); + napi_value errorCode = nullptr; + NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode)); + napi_value errorMessage = nullptr; + std::string errMsg = ToMessage(Convert(code)) + " " + msg; + NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errorMessage)); + NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode)); + NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage)); + SELECTION_HILOGD("ToError end"); + return errorObj; +} + +int32_t JsUtils::Convert(int32_t code) +{ + SELECTION_HILOGD("Convert start."); + auto iter = ERROR_CODE_MAP.find(code); + if (iter != ERROR_CODE_MAP.end()) { + SELECTION_HILOGD("ErrorCode: %{public}d", iter->second); + return iter->second; + } + SELECTION_HILOGD("Convert end."); + return ERROR_CODE_QUERY_FAILED; +} + +const std::string JsUtils::ToMessage(int32_t code) +{ + SELECTION_HILOGD("ToMessage start"); + auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code); + if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) { + SELECTION_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str()); + return iter->second; + } + return "error is out of definition."; +} + +bool JsUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId) +{ + if (copy == nullptr) { + return value == nullptr; + } + + if (threadId != std::this_thread::get_id()) { + SELECTION_HILOGD("napi_value can not be compared"); + return false; + } + + napi_value copyValue = nullptr; + napi_get_reference_value(env, copy, ©Value); + + bool isEquals = false; + napi_strict_equals(env, value, copyValue, &isEquals); + SELECTION_HILOGD("value compare result: %{public}d", isEquals); + return isEquals; +} + +void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_MAX; + void *native = nullptr; + napi_value self = nullptr; + napi_value argv[ARGC_MAX] = { nullptr }; + napi_status status = napi_invalid_arg; + napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr); + + status = napi_unwrap(env, self, &native); + CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr); + return native; +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); + return napi_get_value_int32(env, in, &out); +} + +/* napi_value <-> uint32_t */ +napi_status JsUtils::GetValue(napi_env env, napi_value in, uint32_t &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); + return napi_get_value_uint32(env, in, &out); +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure); + return napi_get_value_bool(env, in, &out); +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure); + return napi_get_value_double(env, in, &out); +} + +/* napi_value <-> std::string */ +napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out) +{ + SELECTION_HILOGD("JsUtils get string value in."); + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure); + + size_t maxLen = STR_MAX_LENGTH; + status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen); + if (maxLen <= 0) { + return status; + } + SELECTION_HILOGD("napi_value -> std::string get length %{public}zu", maxLen); + char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH]; + if (buf != nullptr) { + size_t len = 0; + status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len); + if (status == napi_ok) { + buf[len] = 0; + out = std::string(buf); + } + delete[] buf; + } else { + status = napi_generic_failure; + } + return status; +} + +/* napi_value <-> std::unordered_map */ + +napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out) +{ + napi_valuetype valueType = napi_undefined; + napi_status status = napi_typeof(env, in, &valueType); + if ((status == napi_ok) && (valueType == napi_object)) { + status = napi_get_named_property(env, in, type.c_str(), &out); + return status; + } + return napi_generic_failure; +} + +napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out) +{ + return napi_create_string_utf8(env, in.c_str(), in.size(), &out); +} + +napi_value JsUtils::GetValue(napi_env env, const std::vector &in) +{ + void *data = nullptr; + napi_value arrayBuffer = nullptr; + size_t length = in.size(); + NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer)); + // 0 means the size of data. + CHECK_RETURN(length != 0, "Data size is 0.", arrayBuffer); + if (memcpy_s(data, length, reinterpret_cast(in.data()), length) != 0) { + return nullptr; + } + return arrayBuffer; +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, std::vector &out) +{ + size_t length = 0; + void *data = nullptr; + auto status = napi_get_arraybuffer_info(env, in, &data, &length); + if (status != napi_ok) { + SELECTION_HILOGE("Get ArrayBuffer info failed!"); + return status; + } + if (data == nullptr && length == 0) { + SELECTION_HILOGE("Empty ArrayBuffer."); + out.clear(); + return napi_ok; + } + if (data == nullptr) { + SELECTION_HILOGE("ArrayBuffer data is nullptr!"); + return napi_generic_failure; + } + SELECTION_HILOGD("ArrayBuffer data size: %{public}zu.", length); + out.assign(reinterpret_cast(data), reinterpret_cast(data) + length); + return napi_ok; +} + +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/common/js_utils.h b/common/js_utils.h new file mode 100644 index 0000000..e98d419 --- /dev/null +++ b/common/js_utils.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2022-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 INTERFACE_KITS_JS_UTILS_H +#define INTERFACE_KITS_JS_UTILS_H + +#include + +#include "ability.h" +#include "selection_log.h" +#include "callback_object.h" +#include "util.h" +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "string_ex.h" + +using Ability = OHOS::AppExecFwk::Ability; +namespace OHOS { +namespace SelectionFwk { +enum IMFErrorCode : int32_t { + EXCEPTION_PERMISSION = 201, + EXCEPTION_SYSTEM_PERMISSION = 202, + EXCEPTION_PARAMCHECK = 401, + EXCEPTION_UNSUPPORTED = 801, + EXCEPTION_PACKAGEMANAGER = 12800001, + EXCEPTION_IMENGINE = 12800002, + EXCEPTION_IMCLIENT = 12800003, + EXCEPTION_IME = 12800004, + EXCEPTION_CONFPERSIST = 12800005, + EXCEPTION_CONTROLLER = 12800006, + EXCEPTION_SETTINGS = 12800007, + EXCEPTION_IMMS = 12800008, + EXCEPTION_DETACHED = 12800009, + EXCEPTION_DEFAULTIME = 12800010, + EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED = 12800011, + EXCEPTION_PANEL_NOT_FOUND = 12800012, + EXCEPTION_WINDOW_MANAGER = 12800013, + EXCEPTION_BASIC_MODE = 12800014, + EXCEPTION_REQUEST_NOT_ACCEPT = 12800015, + EXCEPTION_EDITABLE = 12800016, + EXCEPTION_INVALID_PANEL_TYPE_FLAG = 12800017, +}; + +enum TypeCode : int32_t { + TYPE_NONE = 0, + TYPE_UNDEFINED, + TYPE_NULL, + TYPE_BOOLEAN, + TYPE_NUMBER, + TYPE_STRING, + TYPE_SYMBOL, + TYPE_OBJECT, + TYPE_FUNCTION, + TYPE_EXTERNAL, + TYPE_BIGINT, + TYPE_ARRAY_BUFFER, + TYPE_ARRAY, +}; + +/* check condition, return and logging if condition not true. */ +#define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + return retVal; \ + } \ + } while (0) + +#define PARAM_CHECK_RETURN_VOID(env, condition, message, typeCode) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + return; \ + } \ + } while (0) + +#define RESULT_CHECK_RETURN(env, condition, errCode, message, typeCode, retVal) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, errCode, message, typeCode); \ + return retVal; \ + } \ + } while (0) + +#define RESULT_CHECK_RETURN_VOID(env, condition, errCode, message, typeCode) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, errCode, message, typeCode); \ + return; \ + } \ + } while (0) + +/* check condition, return and logging. */ +#define CHECK_RETURN_VOID(condition, message) \ + do { \ + if (!(condition)) { \ + SELECTION_HILOGE("test (" #condition ") failed: " message); \ + return; \ + } \ + } while (0) + +/* check condition, return and logging. */ +#define CHECK_RETURN(condition, message, retVal) \ + do { \ + if (!(condition)) { \ + SELECTION_HILOGE("test (" #condition ") failed: " message); \ + return retVal; \ + } \ + } while (0) + +struct JsPropertyInfo { + napi_valuetype type; + TypeCode typeCode; + std::string propertyName; +}; + +class JsUtils { +public: + static void ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type); + + static napi_value ToError(napi_env env, int32_t code, const std::string &msg); + + static int32_t Convert(int32_t code); + + static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId); + + static void *GetNativeSelf(napi_env env, napi_callback_info info); + + static const std::string ToMessage(int32_t code); + + template + static bool ReadOptionalProperty(napi_env env, napi_value object, const JsPropertyInfo &jsPropInfo, T &value) + { + if (!JsUtil::HasProperty(env, object, jsPropInfo.propertyName.c_str())) { + return false; + } + napi_value jsObject = nullptr; + napi_get_named_property(env, object, jsPropInfo.propertyName.c_str(), &jsObject); + PARAM_CHECK_RETURN(env, JsUtil::GetType(env, jsObject) == jsPropInfo.type, jsPropInfo.propertyName, + jsPropInfo.typeCode, false); + PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, jsObject, value) == napi_ok, + "failed to convert " + jsPropInfo.propertyName, TYPE_NONE, false); + return true; + } + + static napi_status GetValue(napi_env env, napi_value in, int32_t &out); + static napi_status GetValue(napi_env env, napi_value in, uint32_t &out); + static napi_status GetValue(napi_env env, napi_value in, bool &out); + static napi_status GetValue(napi_env env, napi_value in, double &out); + static napi_status GetValue(napi_env env, napi_value in, std::string &out); + + + static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); + + static napi_status GetValue(napi_env env, napi_value in, std::vector &out); + + + static napi_value GetValue(napi_env env, const std::vector &in); + static napi_status GetValue(napi_env env, const std::string &in, napi_value &out); + +private: + static const std::map ERROR_CODE_MAP; + + static const std::map ERROR_CODE_CONVERT_MESSAGE_MAP; + + static const std::map PARAMETER_TYPE; + + static constexpr int32_t ERROR_CODE_QUERY_FAILED = 1; + + static constexpr uint8_t MAX_ARGMENT_COUNT = 10; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // INTERFACE_KITS_JS_UTILS_H \ No newline at end of file diff --git a/common/selectionmethod_trace.cpp b/common/selectionmethod_trace.cpp new file mode 100644 index 0000000..8de772a --- /dev/null +++ b/common/selectionmethod_trace.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022-2022 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 "selectionmethod_trace.h" + +#include "hitrace_meter.h" + +namespace OHOS { +namespace SelectionFwk { +constexpr uint64_t HITRACE_TAG_MISC = (1ULL << 41); // Notification module tag. +void InitHiTrace() +{ + UpdateTraceLabel(); +} + +void ValueTrace(const std::string &name, int64_t count) +{ + CountTrace(HITRACE_TAG_MISC, name, count); +} + +void StartAsync(const std::string &value, int32_t taskId) +{ + StartAsyncTrace(HITRACE_TAG_MISC, value, taskId); +} + +void FinishAsync(const std::string &value, int32_t taskId) +{ + FinishAsyncTrace(HITRACE_TAG_MISC, value, taskId); +} + +SelectionMethodSyncTrace::SelectionMethodSyncTrace(const std::string &value) +{ + StartTrace(HITRACE_TAG_MISC, value); +} + +SelectionMethodSyncTrace::SelectionMethodSyncTrace(const std::string &value, const std::string &id) +{ + auto info = value + "_" + id; + StartTrace(HITRACE_TAG_MISC, info); +} + +SelectionMethodSyncTrace::~SelectionMethodSyncTrace() +{ + FinishTrace(HITRACE_TAG_MISC); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/common/selectionmethod_trace.h b/common/selectionmethod_trace.h new file mode 100644 index 0000000..11738f3 --- /dev/null +++ b/common/selectionmethod_trace.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022-2022 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 SELECTIONMETHOD_TRACE_H +#define SELECTIONMETHOD_TRACE_H + +#include + +namespace OHOS { +namespace SelectionFwk { +void InitHiTrace(); +void ValueTrace(const std::string &name, int64_t count); + +void StartAsync(const std::string &value, int32_t taskId); +void FinishAsync(const std::string &value, int32_t taskId); + +class SelectionMethodSyncTrace { +public: + explicit SelectionMethodSyncTrace(const std::string &value); + SelectionMethodSyncTrace(const std::string &value, const std::string &id); + virtual ~SelectionMethodSyncTrace(); +}; + +enum class TraceTaskId : int32_t { + ONSTART_EXTENSION, + ONSTART_MIDDLE_EXTENSION, + ONCREATE_EXTENSION, + ONCONNECT_EXTENSION, + ONCONNECT_MIDDLE_EXTENSION, + ON_KEY_EVENT, + ON_FULL_KEY_EVENT, +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // SELECTIONMETHOD_TRACE_H \ No newline at end of file diff --git a/common/util.cpp b/common/util.cpp new file mode 100644 index 0000000..26438fe --- /dev/null +++ b/common/util.cpp @@ -0,0 +1,119 @@ +/* + * 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 "util.h" + +#include "string_ex.h" + +namespace OHOS { +namespace SelectionFwk { +constexpr int64_t JS_NUMBER_MAX_VALUE = (1LL << 53) - 1; +napi_valuetype JsUtil::GetType(napi_env env, napi_value in) +{ + napi_valuetype valueType = napi_undefined; + napi_typeof(env, in, &valueType); + return valueType; +} +bool JsUtil::HasProperty(napi_env env, napi_value object, const std::string &property) +{ + bool hasProperty = false; + napi_status status = napi_has_named_property(env, object, property.c_str(), &hasProperty); + if (status == napi_ok && hasProperty) { + return true; + } + return false; +} +bool JsUtil::GetValue(napi_env env, napi_value in, std::string &out) +{ + size_t size = 0; + auto status = napi_get_value_string_utf8(env, in, nullptr, 0, &size); + if (status != napi_ok) { + return false; + } + out.resize(size + 1, 0); + status = napi_get_value_string_utf8(env, in, const_cast(out.data()), size + 1, &size); + out.resize(size); + return status == napi_ok; +} + +bool JsUtil::GetValue(napi_env env, napi_value in, std::u16string &out) +{ + std::string tempOut; + bool ret = GetValue(env, in, tempOut); + if (ret) { + out = Str8ToStr16(tempOut); + } + return ret; +} +bool JsUtil::GetValue(napi_env env, napi_value in, int32_t &out) +{ + return napi_get_value_int32(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, uint32_t &out) +{ + return napi_get_value_uint32(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, int64_t &out) +{ + return napi_get_value_int64(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, bool &out) +{ + return napi_get_value_bool(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, double &out) +{ + return napi_get_value_double(env, in, &out) == napi_ok; +} +napi_value JsUtil::GetValue(napi_env env, napi_value in) +{ + return in; +} +napi_value JsUtil::GetValue(napi_env env, const std::string &in) +{ + napi_value out = nullptr; + napi_create_string_utf8(env, in.c_str(), in.length(), &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, int32_t in) +{ + napi_value out = nullptr; + napi_create_int32(env, in, &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, uint32_t in) +{ + napi_value out = nullptr; + napi_create_uint32(env, in, &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, int64_t in) +{ + if (in > JS_NUMBER_MAX_VALUE) { + // cannot exceed the range of js + return nullptr; + } + napi_value out = nullptr; + napi_create_int64(env, in, &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, bool in) +{ + napi_value out = nullptr; + napi_get_boolean(env, in, &out); + return out; +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/common/util.h b/common/util.h new file mode 100644 index 0000000..8e6efaf --- /dev/null +++ b/common/util.h @@ -0,0 +1,131 @@ +/* + * 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_UTIL_H +#define OHOS_UTIL_H +#include +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +namespace OHOS { +namespace SelectionFwk { +class JsUtil { +public: + static napi_valuetype GetType(napi_env env, napi_value in); + static bool HasProperty(napi_env env, napi_value object, const std::string &property); + // js to native + static bool GetValue(napi_env env, napi_value in, std::string &out); + static bool GetValue(napi_env env, napi_value in, std::u16string &out); + static bool GetValue(napi_env env, napi_value in, int32_t &out); + static bool GetValue(napi_env env, napi_value in, uint32_t &out); + static bool GetValue(napi_env env, napi_value in, int64_t &out); + static bool GetValue(napi_env env, napi_value in, bool &out); + static bool GetValue(napi_env env, napi_value in, double &out); + template + static bool GetValue(napi_env env, napi_value in, std::vector &items) + { + uint32_t len = 0; + napi_get_array_length(env, in, &len); + items.resize(len); + for (uint32_t i = 0; i < len; i++) { + napi_value item = nullptr; + auto status = napi_get_element(env, in, i, &item); + T buff{}; + if (status != napi_ok || !GetValue(env, item, buff)) { + return false; + } + items[i] = std::move(buff); + } + return true; + } + + // native to js + static napi_value GetValue(napi_env env, napi_value in); + static napi_value GetValue(napi_env env, const std::string &in); + static napi_value GetValue(napi_env env, int32_t in); + static napi_value GetValue(napi_env env, uint32_t in); + static napi_value GetValue(napi_env env, int64_t in); + static napi_value GetValue(napi_env env, bool in); + template + static napi_value GetValue(napi_env env, const std::vector &items) + { + napi_value array = nullptr; + auto status = napi_create_array(env, &array); + if (status != napi_ok) { + return nullptr; + } + uint32_t index = 0; + for (const T &item : items) { + auto itemValue = GetValue(env, item); + if (itemValue == nullptr) { + return nullptr; + } + status = napi_set_element(env, array, index++, itemValue); + if (status != napi_ok) { + return nullptr; + } + } + return array; + } + class Object { + public: + template + static bool WriteProperty(napi_env env, napi_value object, const std::string &property, const T &value) + { + return napi_set_named_property(env, object, property.c_str(), GetValue(env, value)) == napi_ok; + } + template + static bool ReadProperty(napi_env env, napi_value object, const std::string &property, T &value) + { + napi_value propValue = nullptr; + napi_get_named_property(env, object, property.c_str(), &propValue); + return GetValue(env, propValue, value); + } + }; + class Const { + public: + static napi_value Null(napi_env env) + { + napi_value value = nullptr; + napi_get_null(env, &value); + return value; + } + static napi_value Undefined(napi_env env) + { + napi_value value = nullptr; + napi_get_undefined(env, &value); + return value; + } + }; + class ScopeGuard { + public: + explicit ScopeGuard(napi_env env) : env_(env), scope_(nullptr) + { + napi_open_handle_scope(env_, &scope_); + } + ~ScopeGuard() + { + napi_close_handle_scope(env_, scope_); + } + + private: + napi_env env_; + napi_handle_scope scope_; + }; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // OHOS_UTIL_H diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 9236e17..3bdf428 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") +import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") ohos_shared_library("selectionability_napi") { branch_protector_ret = "pac_ret" @@ -34,9 +35,25 @@ ohos_shared_library("selectionability_napi") { "${target_gen_dir}", ] + deps = [ + "${selection_fwk_root_path}/common:selection_common", + ] + external_deps = [ + "ability_base:configuration", + "ability_runtime:ability_context_native", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "ability_runtime:napi_base_context", + "c_utils:utils", + "eventhandler:libeventhandler", "hilog:libhilog", + "ipc:ipc_core", + "ipc:ipc_single", "napi:ace_napi", + "window_manager:libwm_lite", + "resource_management:global_resmgr", + "ability_runtime:app_context", ] relative_install_dir = "module" diff --git a/frameworks/js/napi/selection_ability/js_selection_ability.cpp b/frameworks/js/napi/selection_ability/js_selection_ability.cpp index 6008642..1ea4a5d 100644 --- a/frameworks/js/napi/selection_ability/js_selection_ability.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_ability.cpp @@ -1,9 +1,20 @@ #include "js_selection_ability.h" +#include "event_checker.h" +#include "js_utils.h" #include "napi/native_node_api.h" #include "selection_log.h" +#include "util.h" -using namespace OHOS::SelectionFwk; +namespace OHOS { +namespace SelectionFwk { +constexpr size_t ARGC_ONE = 1; +constexpr size_t ARGC_TWO = 2; + +const std::string JsSelectionAbility::KDS_CLASS_NAME = "SelectionAbility"; +thread_local napi_ref JsSelectionAbility::KDSRef_ = nullptr; +std::mutex JsSelectionAbility::selectionMutex_; +std::shared_ptr JsSelectionAbility::selectionDelegate_{ nullptr }; napi_value JsSelectionAbility::GetSelectionAbility(napi_env env, napi_callback_info info) { @@ -11,12 +22,170 @@ napi_value JsSelectionAbility::GetSelectionAbility(napi_env env, napi_callback_i return nullptr; } +std::shared_ptr JsSelectionAbility::GetJsSelectionAbility() +{ + if (selectionDelegate_ == nullptr) { + std::lock_guard lock(selectionMutex_); + if (selectionDelegate_ == nullptr) { + auto delegate = std::make_shared(); + if (delegate == nullptr) { + SELECTION_HILOGE("keyboard delegate is nullptr!"); + return nullptr; + } + selectionDelegate_ = delegate; + } + } + return selectionDelegate_; +} + +napi_value JsSelectionAbility::JsConstructor(napi_env env, napi_callback_info cbinfo) +{ + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr)); + auto delegate = GetJsSelectionAbility(); + if (delegate == nullptr) { + SELECTION_HILOGE("failed to get delegate!"); + napi_value result = nullptr; + napi_get_null(env, &result); + return result; + } + napi_status status = napi_wrap( + env, thisVar, delegate.get(), [](napi_env env, void *nativeObject, void *hint) {}, nullptr, nullptr); + if (status != napi_ok) { + SELECTION_HILOGE("failed to wrap: %{public}d!", status); + return nullptr; + } + return thisVar; +}; + +napi_value JsSelectionAbility::Subscribe(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_TWO; + napi_value argv[ARGC_TWO] = { nullptr }; + napi_value thisVar = nullptr; + void *data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); + std::string type; + // 2 means least param num. + if (argc < 2 || !JsUtil::GetValue(env, argv[0], type) || + !EventChecker::IsValidEventType(EventSubscribeModule::SELECTION_METHOD_ABILITY, type) || + JsUtil::GetType(env, argv[1]) != napi_function) { + SELECTION_HILOGE("subscribe failed, type: %{public}s!", type.c_str()); + return nullptr; + } + SELECTION_HILOGE("subscribe type: %{public}s.", type.c_str()); + auto selectionAbility = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); + if (selectionAbility == nullptr) { + return nullptr; + } + std::shared_ptr callback = + std::make_shared(env, argv[1], std::this_thread::get_id(), + AppExecFwk::EventHandler::Current()); + selectionAbility->RegisterListener(argv[ARGC_ONE], type, callback); + + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + + +napi_value JsSelectionAbility::UnSubscribe(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_TWO; + napi_value argv[ARGC_TWO] = { nullptr }; + napi_value thisVar = nullptr; + void *data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); + std::string type; + // 1 means least param num. + if (argc < 1 || !JsUtil::GetValue(env, argv[0], type) || + !EventChecker::IsValidEventType(EventSubscribeModule::SELECTION_METHOD_ABILITY, type)) { + SELECTION_HILOGE("unsubscribe failed, type: %{public}s!", type.c_str()); + return nullptr; + } + + // if the second param is not napi_function/napi_null/napi_undefined, return + auto paramType = JsUtil::GetType(env, argv[1]); + if (paramType != napi_function && paramType != napi_null && paramType != napi_undefined) { + return nullptr; + } + // if the second param is napi_function, delete it, else delete all + argv[1] = paramType == napi_function ? argv[1] : nullptr; + + SELECTION_HILOGD("unsubscribe type: %{public}s.", type.c_str()); + auto delegate = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); + if (delegate == nullptr) { + return nullptr; + } + delegate->UnRegisterListener(argv[ARGC_ONE], type); + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + +void JsSelectionAbility::RegisterListener(napi_value callback, std::string type, + std::shared_ptr callbackObj) +{ + SELECTION_HILOGD("RegisterListener %{public}s", type.c_str()); + std::lock_guard lock(mutex_); + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + SELECTION_HILOGD("methodName %{public}s is not registered!", type.c_str()); + } + auto callbacks = jsCbMap_[type]; + bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr cb) { + return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_); + }); + if (ret) { + SELECTION_HILOGD("JsSelectionAbility callback already registered!"); + return; + } + + SELECTION_HILOGI("add %{public}s callbackObj into jsCbMap_.", type.c_str()); + jsCbMap_[type].push_back(std::move(callbackObj)); +} + +void JsSelectionAbility::UnRegisterListener(napi_value callback, std::string type) +{ + SELECTION_HILOGI("unregister listener: %{public}s.", type.c_str()); + std::lock_guard lock(mutex_); + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + SELECTION_HILOGE("methodName %{public}s is not unregistered!", type.c_str()); + return; + } + + if (callback == nullptr) { + jsCbMap_.erase(type); + SELECTION_HILOGE("callback is nullptr!"); + return; + } + + for (auto item = jsCbMap_[type].begin(); item != jsCbMap_[type].end(); item++) { + if ((callback != nullptr) && + (JsUtils::Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_))) { + jsCbMap_[type].erase(item); + break; + } + } + if (jsCbMap_[type].empty()) { + jsCbMap_.erase(type); + } +} + napi_value JsSelectionAbility::Init(napi_env env, napi_value exports) { SELECTION_HILOGI("napi init"); napi_property_descriptor properties[] = { DECLARE_NAPI_FUNCTION("getSelectionAbility", GetSelectionAbility), + DECLARE_NAPI_FUNCTION("on", Subscribe), + DECLARE_NAPI_FUNCTION("off", UnSubscribe), }; - NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties)); + + napi_value cons = nullptr; + NAPI_CALL(env, napi_define_class(env, KDS_CLASS_NAME.c_str(), KDS_CLASS_NAME.size(), JsConstructor, nullptr, + sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons)); + NAPI_CALL(env, napi_create_reference(env, cons, 1, &KDSRef_)); + NAPI_CALL(env, napi_set_named_property(env, exports, KDS_CLASS_NAME.c_str(), cons)); return exports; -} \ No newline at end of file +} +} // namespace OHOS::SelectionFwk +} // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/js_selection_ability.h b/frameworks/js/napi/selection_ability/js_selection_ability.h index 3c7c4a3..ab22754 100644 --- a/frameworks/js/napi/selection_ability/js_selection_ability.h +++ b/frameworks/js/napi/selection_ability/js_selection_ability.h @@ -16,7 +16,13 @@ #ifndef JS_SELECTION_ABILITY_H #define JS_SELECTION_ABILITY_H +#include +#include +#include + #include "napi/native_api.h" +#include "util.h" +#include "callback_object.h" namespace OHOS { namespace SelectionFwk { @@ -26,7 +32,24 @@ public: ~JsSelectionAbility() = default; static napi_value Init(napi_env env, napi_value exports); static napi_value GetSelectionAbility(napi_env env, napi_callback_info info); + static napi_value Subscribe(napi_env env, napi_callback_info info); + static napi_value UnSubscribe(napi_env env, napi_callback_info info); + +private: + static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); + static std::shared_ptr GetJsSelectionAbility(); + void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); + void UnRegisterListener(napi_value callback, std::string type); + +private: + static const std::string KDS_CLASS_NAME; + static thread_local napi_ref KDSRef_; + std::map>> jsCbMap_; + static std::mutex selectionMutex_; + static std::shared_ptr selectionDelegate_; + std::recursive_mutex mutex_; + }; } //SelectionFwk } //OHOS -#endif //JS_SELECTION_ABILITY_H \ No newline at end of file +#endif //JS_SELECTION_ABILITY_H diff --git a/frameworks/js/napi/selectionability/BUILD.gn b/frameworks/js/napi/selectionability/BUILD.gn new file mode 100644 index 0000000..481eba1 --- /dev/null +++ b/frameworks/js/napi/selectionability/BUILD.gn @@ -0,0 +1,69 @@ +# Copyright (C) 2022 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("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//build/ohos.gni") + +ohos_shared_library("selectionabilityengine") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + + include_dirs = [ + "${selection_fwk_root_path}/utils/include", + ] + ldflags = [ "-Wl,--exclude-libs=ALL" ] + cflags_cc = [ + "-fvisibility=hidden", + "-fvisibility-inlines-hidden", + "-fdata-sections", + "-ffunction-sections", + "-Os", + ] + sources = [ + "js_selection_ability_engine.cpp", + "selection_engine_module.cpp", + ] + + deps = [ + "${selection_fwk_root_path}/common:selection_common", + ] + + external_deps = [ + "ability_base:configuration", + "ability_runtime:ability_context_native", + "ability_runtime:abilitykit_native", + "ability_runtime:extensionkit_native", + "ability_runtime:napi_base_context", + "c_utils:utils", + "eventhandler:libeventhandler", + "hilog:libhilog", + "ipc:ipc_core", + "ipc:ipc_single", + "napi:ace_napi", + "window_manager:libwm_lite", + "resource_management:global_resmgr", + "ability_runtime:app_context", + ] + + + relative_install_dir = "module" + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} diff --git a/frameworks/js/napi/selectionability/js_selection_ability_engine.cpp b/frameworks/js/napi/selectionability/js_selection_ability_engine.cpp new file mode 100644 index 0000000..d8f4be7 --- /dev/null +++ b/frameworks/js/napi/selectionability/js_selection_ability_engine.cpp @@ -0,0 +1,200 @@ +/* + * 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. + */ + +#undef LOG_TAG +#define LOG_TAG "SELECTION_ABILITY" + +#include "js_selection_ability_engine.h" +#include "selection_log.h" +#include "util.h" +#include "event_checker.h" +#include "js_utils.h" + + + +namespace OHOS { +namespace SelectionFwk { +constexpr size_t ARGC_ONE = 1; +constexpr size_t ARGC_TWO = 2; + +const std::string JsSelectionAbilityEngine::KDS_CLASS_NAME = "SelectionAbility"; +thread_local napi_ref JsSelectionAbilityEngine::KDSRef_ = nullptr; +std::mutex JsSelectionAbilityEngine::selectionMutex_; +std::shared_ptr JsSelectionAbilityEngine::selectionDelegate_{ nullptr }; + +napi_value JsSelectionAbilityEngine::Init(napi_env env, napi_value exports) +{ + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("on", Subscribe), + DECLARE_NAPI_FUNCTION("off", UnSubscribe), + }; + napi_value cons = nullptr; + NAPI_CALL(env, napi_define_class(env, KDS_CLASS_NAME.c_str(), KDS_CLASS_NAME.size(), JsConstructor, nullptr, + sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons)); + NAPI_CALL(env, napi_create_reference(env, cons, 1, &KDSRef_)); + NAPI_CALL(env, napi_set_named_property(env, exports, KDS_CLASS_NAME.c_str(), cons)); + return exports; +} + +std::shared_ptr JsSelectionAbilityEngine::GetSelectionAbilityEngine() +{ + if (selectionDelegate_ == nullptr) { + std::lock_guard lock(selectionMutex_); + if (selectionDelegate_ == nullptr) { + auto delegate = std::make_shared(); + if (delegate == nullptr) { + SELECTION_HILOGE("keyboard delegate is nullptr!"); + return nullptr; + } + selectionDelegate_ = delegate; + } + } + return selectionDelegate_; +} + +napi_value JsSelectionAbilityEngine::JsConstructor(napi_env env, napi_callback_info cbinfo) +{ + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr)); + auto delegate = GetSelectionAbilityEngine(); + if (delegate == nullptr) { + SELECTION_HILOGE("failed to get delegate!"); + napi_value result = nullptr; + napi_get_null(env, &result); + return result; + } + napi_status status = napi_wrap( + env, thisVar, delegate.get(), [](napi_env env, void *nativeObject, void *hint) {}, nullptr, nullptr); + if (status != napi_ok) { + SELECTION_HILOGE("failed to wrap: %{public}d!", status); + return nullptr; + } + return thisVar; +}; + +napi_value JsSelectionAbilityEngine::Subscribe(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_TWO; + napi_value argv[ARGC_TWO] = { nullptr }; + napi_value thisVar = nullptr; + void *data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); + std::string type; + // 2 means least param num. + if (argc < 2 || !JsUtil::GetValue(env, argv[0], type) || + !EventChecker::IsValidEventType(EventSubscribeModule::SELECTION_METHOD_ABILITY, type) || + JsUtil::GetType(env, argv[1]) != napi_function) { + SELECTION_HILOGE("subscribe failed, type: %{public}s!", type.c_str()); + return nullptr; + } + SELECTION_HILOGE("subscribe type: %{public}s.", type.c_str()); + auto engine = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); + if (engine == nullptr) { + return nullptr; + } + std::shared_ptr callback = + std::make_shared(env, argv[1], std::this_thread::get_id(), + AppExecFwk::EventHandler::Current()); + engine->RegisterListener(argv[ARGC_ONE], type, callback); + + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + + +napi_value JsSelectionAbilityEngine::UnSubscribe(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_TWO; + napi_value argv[ARGC_TWO] = { nullptr }; + napi_value thisVar = nullptr; + void *data = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); + std::string type; + // 1 means least param num. + if (argc < 1 || !JsUtil::GetValue(env, argv[0], type) || + !EventChecker::IsValidEventType(EventSubscribeModule::SELECTION_METHOD_ABILITY, type)) { + SELECTION_HILOGE("unsubscribe failed, type: %{public}s!", type.c_str()); + return nullptr; + } + + // if the second param is not napi_function/napi_null/napi_undefined, return + auto paramType = JsUtil::GetType(env, argv[1]); + if (paramType != napi_function && paramType != napi_null && paramType != napi_undefined) { + return nullptr; + } + // if the second param is napi_function, delete it, else delete all + argv[1] = paramType == napi_function ? argv[1] : nullptr; + + SELECTION_HILOGD("unsubscribe type: %{public}s.", type.c_str()); + auto delegate = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); + if (delegate == nullptr) { + return nullptr; + } + delegate->UnRegisterListener(argv[ARGC_ONE], type); + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + +void JsSelectionAbilityEngine::RegisterListener(napi_value callback, std::string type, + std::shared_ptr callbackObj) +{ + SELECTION_HILOGD("RegisterListener %{public}s", type.c_str()); + std::lock_guard lock(mutex_); + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + SELECTION_HILOGD("methodName %{public}s is not registered!", type.c_str()); + } + auto callbacks = jsCbMap_[type]; + bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr cb) { + return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_); + }); + if (ret) { + SELECTION_HILOGD("JsSelectionAbilityEngine callback already registered!"); + return; + } + + SELECTION_HILOGI("add %{public}s callbackObj into jsCbMap_.", type.c_str()); + jsCbMap_[type].push_back(std::move(callbackObj)); +} + +void JsSelectionAbilityEngine::UnRegisterListener(napi_value callback, std::string type) +{ + SELECTION_HILOGI("unregister listener: %{public}s.", type.c_str()); + std::lock_guard lock(mutex_); + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + SELECTION_HILOGE("methodName %{public}s is not unregistered!", type.c_str()); + return; + } + + if (callback == nullptr) { + jsCbMap_.erase(type); + SELECTION_HILOGE("callback is nullptr!"); + return; + } + + for (auto item = jsCbMap_[type].begin(); item != jsCbMap_[type].end(); item++) { + if ((callback != nullptr) && + (JsUtils::Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_))) { + jsCbMap_[type].erase(item); + break; + } + } + if (jsCbMap_[type].empty()) { + jsCbMap_.erase(type); + } +} +} // namespace OHOS::SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/selectionability/js_selection_ability_engine.h b/frameworks/js/napi/selectionability/js_selection_ability_engine.h new file mode 100644 index 0000000..f83ea89 --- /dev/null +++ b/frameworks/js/napi/selectionability/js_selection_ability_engine.h @@ -0,0 +1,53 @@ +/* + * 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 INTERFACE_KITS_JS_SELECTION_ABILITY_ENGINE_H +#define INTERFACE_KITS_JS_SELECTION_ABILITY_ENGINE_H +#include +#include +#include + +#include "napi/native_api.h" +#include "util.h" +#include "callback_object.h" + + +namespace OHOS { +namespace SelectionFwk { +class JsSelectionAbilityEngine { +public: + JsSelectionAbilityEngine() = default; + ~JsSelectionAbilityEngine() = default; + static napi_value Init(napi_env env, napi_value exports); + static napi_value Subscribe(napi_env env, napi_callback_info info); + static napi_value UnSubscribe(napi_env env, napi_callback_info info); + +private: + static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); + static std::shared_ptr GetSelectionAbilityEngine(); + void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); + void UnRegisterListener(napi_value callback, std::string type); + +private: + static const std::string KDS_CLASS_NAME; + static thread_local napi_ref KDSRef_; + std::map>> jsCbMap_; + static std::mutex selectionMutex_; + static std::shared_ptr selectionDelegate_; + std::recursive_mutex mutex_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // INTERFACE_KITS_JS_SELECTION_ABILITY_ENGINE_H \ No newline at end of file diff --git a/frameworks/js/napi/selectionability/selection_engine_module.cpp b/frameworks/js/napi/selectionability/selection_engine_module.cpp new file mode 100644 index 0000000..eaf28b0 --- /dev/null +++ b/frameworks/js/napi/selectionability/selection_engine_module.cpp @@ -0,0 +1,47 @@ +/* + * 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_selection_ability_engine.h" +#include "selection_log.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +EXTERN_C_START +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports) +{ + OHOS::SelectionFwk::JsSelectionAbilityEngine::Init(env, exports); + return exports; +} +EXTERN_C_END +/* + * module define + */ +static napi_module _module = { .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "selectionAbilityEngine", + .nm_priv = ((void *)0), + .reserved = { 0 } }; +/* + * module register + */ +extern "C" __attribute__((constructor)) void Register() +{ + napi_module_register(&_module); +} \ No newline at end of file diff --git a/selection_service.gni b/selection_service.gni index fbed2c8..8cdad4c 100644 --- a/selection_service.gni +++ b/selection_service.gni @@ -25,17 +25,6 @@ ability_runtime_inner_api_path = "${ability_runtime_path}/interfaces/inner_api" ability_runtime_services_path = "${ability_runtime_path}/services" word_selection_part_name = "word_selection" -word_selection_root_path = "//base/word_selection" - -word_selection_service_path = "${word_selection_root_path}/services" - -word_selection_service_zidl = "${word_selection_service_path}/zidl" - -word_selection_framework = "${word_selection_root_path}/frameworks" -word_selection_framework_native = "${word_selection_framework}/native" - -word_selection_inner_api = "${word_selection_root_path}/interfaces/inner_api" - -word_selection_utils_path = "${word_selection_root_path}/utils" +selection_fwk_root_path = "//foundation/systemabilitymgr/selection_fwk" system_type = "default" \ No newline at end of file diff --git a/service/BUILD.gn b/service/BUILD.gn index 13c2c7a..190e0f2 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -13,6 +13,7 @@ import("//build/ohos.gni") import("//build/config/components/idl_tool/idl.gni") +import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") config("selection_sa_config") { visibility = [ ":*" ] @@ -43,12 +44,16 @@ ohos_shared_library("selection_service") { "src/selection_service.cpp", ] sources += filter_include(output_values, [ "*.cpp" ]) - deps = [ ":selection_service_interface" ] + deps = [ + ":selection_service_interface", + "${selection_fwk_root_path}/common:selection_common" + ] external_deps = [ "ability_base:want", "ability_runtime:ability_manager", "c_utils:utils", + "napi:ace_napi", "ipc:ipc_single", "init:libbeget_proxy", "hilog:libhilog", diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 3eaae61..a7664fe 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -19,6 +19,7 @@ #include #include +#include "callback_object.h" #include "selection_service_stub.h" #include "refbase.h" #include "system_ability.h" @@ -72,6 +73,22 @@ protected: void HandleKeyEvent(int32_t keyCode); void HandlePointEvent(int32_t type); private: + + struct SelectionEntry { + std::vector> vecCopy; + std::string type; + std::string text; + SelectionEntry(const std::vector> &cbVec, const std::string &type) + : vecCopy(cbVec), type(type) + { + } + }; + + using EntrySetter = std::function; + int32_t OnSelectionEvent(std::string &selectionData); + std::shared_ptr GetEntry(const std::string &type, EntrySetter entrySetter = nullptr); + static std::shared_ptr GetEventHandler(); + void InputMonitorInit(); void InputMonitorCancel(); void WatchParams(); @@ -82,6 +99,8 @@ private: std::string currentAbilityName_ = ""; static sptr instance_; static std::shared_mutex adminLock_; + static std::mutex eventHandlerMutex_; + static std::shared_ptr handler_; }; class SelectionInputMonitor : public IInputEventConsumer { diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index a4254e1..a227586 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -17,6 +17,7 @@ #include "ability_manager_client.h" #include "iremote_object.h" +#include "callback_handler.h" #include "system_ability_definition.h" #include "selection_log.h" #include @@ -30,6 +31,8 @@ using namespace OHOS::MMI; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(SelectionService::GetInstance().GetRefPtr()); std::shared_mutex SelectionService::adminLock_; sptr SelectionService::instance_; +std::mutex SelectionService::eventHandlerMutex_; +std::shared_ptr SelectionService::handler_{ nullptr }; uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; uint32_t SelectionInputMonitor::subSelectState = SUB_INITIAL; @@ -202,6 +205,11 @@ void SelectionService::InputMonitorInit() InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); SELECTION_HILOGI("[SelectionService] input monitor init end"); } + + { + std::lock_guard lock(eventHandlerMutex_); + handler_ = AppExecFwk::EventHandler::Current(); + } } void SelectionService::InputMonitorCancel() @@ -421,3 +429,53 @@ void SelectionInputMonitor::InjectCtrlC() const } InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); } + +std::shared_ptr SelectionService::GetEventHandler() +{ + std::lock_guard lock(eventHandlerMutex_); + return handler_; +} + + +int32_t SelectionService::OnSelectionEvent(std::string &selectionData) +{ + SELECTION_HILOGI("OnSelectionEvent begin"); + std::string type = "selectionEvent"; + + if (selectionData.empty()) { + SELECTION_HILOGE("selectionData is empty"); + return 1; + } + + auto entry = GetEntry(type, [&selectionData](SelectionEntry &entry) { entry.text = selectionData; }); + if (entry == nullptr) { + SELECTION_HILOGE("failed to get uv entry!"); + return 1; + } + + auto eventHandler = GetEventHandler(); + if (eventHandler == nullptr) { + SELECTION_HILOGE("eventHandler is nullptr!"); + return 1; + } + + SELECTION_HILOGI("selectionData is [%{public}s]", selectionData.c_str()); + + + auto task = [entry]() { + auto getTextChangeProperty = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { + if (argc == 0) { + return false; + } + // 0 means the first param of callback. + napi_create_string_utf8(env, entry->text.c_str(), NAPI_AUTO_LENGTH, &args[0]); + return true; + }; + // 1 means callback has one param. + JsCallbackHandler::Traverse(entry->vecCopy, { 1, getTextChangeProperty }); + }; + eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); + + SELECTION_HILOGI("OnSelectionEvent end"); + return 0; +} diff --git a/utils/include/selection_log.h b/utils/include/selection_log.h index 11d585f..82fdd8f 100644 --- a/utils/include/selection_log.h +++ b/utils/include/selection_log.h @@ -43,6 +43,109 @@ extern "C" { #define SELECTION_HILOGE(fmt, ...) HILOG_PRINT(HILOG_ERROR, fmt, ##__VA_ARGS__) #define SELECTION_HILOGF(fmt, ...) HILOG_PRINT(HILOG_FATAL, fmt, ##__VA_ARGS__) +namespace ErrorCode { +// Error Code definition in the input method management system +enum { + ERROR_STATUS_UNKNOWN_TRANSACTION = -EBADMSG, // unknown transaction + + // binder exception error code from Status.h + ERROR_EX_ILLEGAL_ARGUMENT = -3, // illegal argument exception + ERROR_EX_NULL_POINTER = -4, // null pointer exception + ERROR_EX_ILLEGAL_STATE = -5, // illegal state exception + ERROR_EX_PARCELABLE = -6, // parcelable exception + ERROR_EX_UNSUPPORTED_OPERATION = -7, // unsupported operation exception + ERROR_EX_SERVICE_SPECIFIC = -8, // service specific exception + // no error + NO_ERROR = 0, // no error + + ERROR_NULL_POINTER, // null pointer + ERROR_BAD_PARAMETERS, // bad parameters + ERROR_SUBSCRIBE_KEYBOARD_EVENT, + + ERROR_CONTROLLER_INVOKING_FAILED, + ERROR_PERSIST_CONFIG, + ERROR_KBD_HIDE_FAILED, + ERROR_PACKAGE_MANAGER, + ERROR_REMOTE_CLIENT_DIED, + + ERROR_NOT_CURRENT_IME, + ERROR_NOT_IME, + ERROR_NOT_AI_APP_IME, + ERROR_ADD_DEATH_RECIPIENT_FAILED, + ERROR_STATUS_SYSTEM_PERMISSION, // not system application + ERROR_PARAMETER_CHECK_FAILED, + ERROR_KEYWORD_NOT_FOUND, + ERROR_ENABLE_IME, + ERROR_NOT_DEFAULT_IME, + ERROR_ENABLE_SECURITY_MODE, + ERROR_DISPATCH_KEY_EVENT, + ERROR_INVALID_PRIVATE_COMMAND_SIZE, + ERROR_PANEL_NOT_FOUND, + ERROR_WINDOW_MANAGER, + ERROR_GET_TEXT_CONFIG, + ERROR_SYSTEM_CMD_CHANNEL_ERROR, + ERROR_INVALID_PRIVATE_COMMAND, + ERROR_OS_ACCOUNT, + ERROR_TASK_MANAGER_PEND_FAILED, + ERROR_INVALID_PANEL_TYPE, + ERROR_INVALID_PANEL_FLAG, + ERROR_MSG_HANDLER_NOT_REGIST, + ERROR_SECURITY_MODE_OFF, + ERROR_MESSAGE_HANDLER, + ERROR_INVALID_ARRAY_BUFFER_SIZE, + ERROR_SERVICE_START_FAILED, + ERROR_JS_CB_NOT_REGISTER, // only for hiSysEvent + ERROR_DEAL_TIMEOUT, // only for hiSysEvent + ERROR_IPC_REMOTE_NULLPTR, + + ERROR_IMA_BEGIN, + ERROR_IME, + ERROR_OPERATE_PANEL, + ERROR_IMA_CHANNEL_NULLPTR, + ERROR_IMA_NULLPTR, + ERROR_IMA_END, + + ERROR_IMC_BEGIN, + ERROR_CLIENT_NOT_EDITABLE, + ERROR_TEXT_PREVIEW_NOT_SUPPORTED, + ERROR_TEXT_LISTENER_ERROR, + ERROR_INVALID_RANGE, + ERROR_CLIENT_NOT_BOUND, + ERROR_IMC_NULLPTR, + ERROR_IMC_END, + + ERROR_IMSA_BEGIN, + ERROR_PARSE_CONFIG_FILE, + ERROR_IME_START_INPUT_FAILED, + ERROR_STATUS_PERMISSION_DENIED, + ERROR_CLIENT_NOT_FOCUSED, + ERROR_CLIENT_NULL_POINTER, + ERROR_CLIENT_ADD_FAILED, + ERROR_CLIENT_NOT_FOUND, + ERROR_IME_NOT_STARTED, + ERROR_KBD_SHOW_FAILED, // failed to show keyboard + ERROR_IMSA_INPUT_TYPE_NOT_FOUND, + ERROR_IMSA_DEFAULT_IME_NOT_FOUND, + ERROR_IMSA_CLIENT_INPUT_READY_FAILED, + ERROR_IMSA_MALLOC_FAILED, + ERROR_IMSA_NULLPTR, + ERROR_IMSA_USER_SESSION_NOT_FOUND, + ERROR_IMSA_GET_IME_INFO_FAILED, + ERROR_IMSA_IME_TO_START_NULLPTR, + ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, + ERROR_IMSA_IME_EVENT_CONVERT_FAILED, + ERROR_IMSA_IME_CONNECT_FAILED, + ERROR_IMSA_IME_DISCONNECT_FAILED, + ERROR_IMSA_IME_START_TIMEOUT, + ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, + ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, + ERROR_DEVICE_UNSUPPORTED, + ERROR_SCENE_UNSUPPORTED, + ERROR_PRIVATE_COMMAND_IS_EMPTY, + ERROR_IMSA_END, +}; +}; // namespace ErrorCode + #ifdef __cplusplus } #endif -- Gitee From d2721cc1f54e20737824b327e1246e6c6e8bb6e7 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Fri, 16 May 2025 17:39:42 +0800 Subject: [PATCH 18/93] =?UTF-8?q?=E6=BB=91=E5=8A=A8=E9=80=89=E8=AF=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- service/include/selection_service.h | 3 +-- service/src/selection_service.cpp | 29 ++++++++++++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index a7664fe..e42ff9e 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -43,8 +43,6 @@ typedef enum { SELECT_INPUT_WAIT_TRIBLE_CLICK = 5, SELECT_INPUT_DOUBLE_CLICKED = 6, - SELECT_INPUT_WAIT_CTRL - } SelectInputState; typedef enum { @@ -52,6 +50,7 @@ typedef enum { SUB_WAIT_PRESS_DOWN = 1, SUB_WAIT_PRESS_MOVE = 2, SUB_WAIT_PRESS_UP = 3, + SUB_WAIT_CTRL = 4, } SelectInputSubState; class SelectionService : public SystemAbility, public SelectionServiceStub { diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index a227586..ba9a5b5 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -270,9 +270,17 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con SELECTION_HILOGD("[SelectionService] keyId: %{public}d", keyCode); if (keyCode == KeyEvent::KEYCODE_CTRL_LEFT || keyCode == KeyEvent::KEYCODE_CTRL_RIGHT) { SELECTION_HILOGI("[SelectionService] Processed ctrl key."); - if (ctrlSelectFlag && curSelectState == SELECT_INPUT_WAIT_CTRL) { + if (ctrlSelectFlag && curSelectState == SELECT_INPUT_WAIT_LEFT_MOVE && subSelectState == SUB_WAIT_CTRL) { curSelectState = SELECT_INPUT_LEFT_MOVE; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); + return; + } + if (ctrlSelectFlag && curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK && subSelectState == SUB_WAIT_CTRL) { + curSelectState = SELECT_INPUT_DOUBLE_CLICKED; + subSelectState = SUB_INITIAL; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); + return; } } @@ -288,9 +296,11 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv if (curSelectState == SELECT_INPUT_INITIAL && buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { return; } - if (curSelectState == SELECT_INPUT_WAIT_CTRL) { + if (subSelectState == SUB_WAIT_CTRL) { SELECTION_HILOGI("[SelectionService] pointerEvent: curSelectState == SELECT_INPUT_WAIT_CTRL. return."); curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + return; } SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); @@ -364,8 +374,8 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptrGetPointerAction(); if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { if (ctrlSelectFlag) { - curSelectState = SELECT_INPUT_WAIT_CTRL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_CTRL."); + subSelectState = SUB_WAIT_CTRL; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_CTRL."); } else { curSelectState = SELECT_INPUT_LEFT_MOVE; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_LEFT_MOVE."); @@ -392,9 +402,14 @@ void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr Date: Fri, 16 May 2025 17:51:23 +0800 Subject: [PATCH 19/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9selection=20ability?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=20&=20=E5=AE=9E=E7=8E=B0GetSelectionAbility?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 2 +- frameworks/js/napi/selection_ability/BUILD.gn | 6 +- .../js_selection_engine_setting.cpp} | 189 ++++++++++-------- ...bility.h => js_selection_engine_setting.h} | 20 +- .../selection_ability_module.cpp | 48 ----- .../selection_engine_module.cpp | 11 +- frameworks/js/napi/selectionability/BUILD.gn | 69 ------- .../js_selection_ability_engine.h | 53 ----- 8 files changed, 128 insertions(+), 270 deletions(-) rename frameworks/js/napi/{selectionability/js_selection_ability_engine.cpp => selection_ability/js_selection_engine_setting.cpp} (69%) rename frameworks/js/napi/selection_ability/{js_selection_ability.h => js_selection_engine_setting.h} (72%) delete mode 100644 frameworks/js/napi/selection_ability/selection_ability_module.cpp rename frameworks/js/napi/{selectionability => selection_ability}/selection_engine_module.cpp (83%) delete mode 100644 frameworks/js/napi/selectionability/BUILD.gn delete mode 100644 frameworks/js/napi/selectionability/js_selection_ability_engine.h diff --git a/bundle.json b/bundle.json index 827ff75..3ca62e5 100644 --- a/bundle.json +++ b/bundle.json @@ -47,7 +47,7 @@ "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile", "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native", - "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionability_napi" + "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionengine_napi" ], "inner_kits": [] } diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 3bdf428..6ec481b 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -14,7 +14,7 @@ import("//build/ohos.gni") import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") -ohos_shared_library("selectionability_napi") { +ohos_shared_library("selectionengine_napi") { branch_protector_ret = "pac_ret" sanitize = { boundary_sanitize = true @@ -25,8 +25,8 @@ ohos_shared_library("selectionability_napi") { ubsan = true } sources = [ - "js_selection_ability.cpp", - "selection_ability_module.cpp", + "js_selection_engine_setting.cpp", + "selection_engine_module.cpp", ] include_dirs = [ diff --git a/frameworks/js/napi/selectionability/js_selection_ability_engine.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp similarity index 69% rename from frameworks/js/napi/selectionability/js_selection_ability_engine.cpp rename to frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index d8f4be7..912979e 100644 --- a/frameworks/js/napi/selectionability/js_selection_ability_engine.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -1,90 +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. - */ - -#undef LOG_TAG -#define LOG_TAG "SELECTION_ABILITY" - -#include "js_selection_ability_engine.h" -#include "selection_log.h" -#include "util.h" +#include "js_selection_engine_setting.h" + #include "event_checker.h" #include "js_utils.h" +#include "napi/native_node_api.h" +#include "selection_log.h" +#include "util.h" +using namespace OHOS::SelectionFwk; - -namespace OHOS { -namespace SelectionFwk { constexpr size_t ARGC_ONE = 1; constexpr size_t ARGC_TWO = 2; -const std::string JsSelectionAbilityEngine::KDS_CLASS_NAME = "SelectionAbility"; -thread_local napi_ref JsSelectionAbilityEngine::KDSRef_ = nullptr; -std::mutex JsSelectionAbilityEngine::selectionMutex_; -std::shared_ptr JsSelectionAbilityEngine::selectionDelegate_{ nullptr }; +const std::string JsSelectionEngineSetting::KDS_CLASS_NAME = "SelectionAbility"; +thread_local napi_ref JsSelectionEngineSetting::KDSRef_ = nullptr; +std::mutex JsSelectionEngineSetting::selectionMutex_; +std::shared_ptr JsSelectionEngineSetting::selectionDelegate_{ nullptr }; -napi_value JsSelectionAbilityEngine::Init(napi_env env, napi_value exports) -{ - napi_property_descriptor properties[] = { - DECLARE_NAPI_FUNCTION("on", Subscribe), - DECLARE_NAPI_FUNCTION("off", UnSubscribe), - }; - napi_value cons = nullptr; - NAPI_CALL(env, napi_define_class(env, KDS_CLASS_NAME.c_str(), KDS_CLASS_NAME.size(), JsConstructor, nullptr, - sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons)); - NAPI_CALL(env, napi_create_reference(env, cons, 1, &KDSRef_)); - NAPI_CALL(env, napi_set_named_property(env, exports, KDS_CLASS_NAME.c_str(), cons)); - return exports; -} -std::shared_ptr JsSelectionAbilityEngine::GetSelectionAbilityEngine() +napi_value JsSelectionEngineSetting::GetSelectionAbility(napi_env env, napi_callback_info info) { - if (selectionDelegate_ == nullptr) { - std::lock_guard lock(selectionMutex_); - if (selectionDelegate_ == nullptr) { - auto delegate = std::make_shared(); - if (delegate == nullptr) { - SELECTION_HILOGE("keyboard delegate is nullptr!"); - return nullptr; - } - selectionDelegate_ = delegate; - } - } - return selectionDelegate_; -} + SELECTION_HILOGI("SelectionEngineSetting---GetSelectionAbility"); -napi_value JsSelectionAbilityEngine::JsConstructor(napi_env env, napi_callback_info cbinfo) -{ - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr)); - auto delegate = GetSelectionAbilityEngine(); - if (delegate == nullptr) { - SELECTION_HILOGE("failed to get delegate!"); - napi_value result = nullptr; - napi_get_null(env, &result); - return result; - } - napi_status status = napi_wrap( - env, thisVar, delegate.get(), [](napi_env env, void *nativeObject, void *hint) {}, nullptr, nullptr); - if (status != napi_ok) { - SELECTION_HILOGE("failed to wrap: %{public}d!", status); - return nullptr; - } - return thisVar; -}; + return GetSEInstance(env, info); +} -napi_value JsSelectionAbilityEngine::Subscribe(napi_env env, napi_callback_info info) +napi_value JsSelectionEngineSetting::Subscribe(napi_env env, napi_callback_info info) { size_t argc = ARGC_TWO; napi_value argv[ARGC_TWO] = { nullptr }; @@ -100,7 +40,7 @@ napi_value JsSelectionAbilityEngine::Subscribe(napi_env env, napi_callback_info return nullptr; } SELECTION_HILOGE("subscribe type: %{public}s.", type.c_str()); - auto engine = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); + auto engine = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); if (engine == nullptr) { return nullptr; } @@ -115,7 +55,7 @@ napi_value JsSelectionAbilityEngine::Subscribe(napi_env env, napi_callback_info } -napi_value JsSelectionAbilityEngine::UnSubscribe(napi_env env, napi_callback_info info) +napi_value JsSelectionEngineSetting::UnSubscribe(napi_env env, napi_callback_info info) { size_t argc = ARGC_TWO; napi_value argv[ARGC_TWO] = { nullptr }; @@ -139,7 +79,7 @@ napi_value JsSelectionAbilityEngine::UnSubscribe(napi_env env, napi_callback_inf argv[1] = paramType == napi_function ? argv[1] : nullptr; SELECTION_HILOGD("unsubscribe type: %{public}s.", type.c_str()); - auto delegate = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); + auto delegate = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); if (delegate == nullptr) { return nullptr; } @@ -149,7 +89,14 @@ napi_value JsSelectionAbilityEngine::UnSubscribe(napi_env env, napi_callback_inf return result; } -void JsSelectionAbilityEngine::RegisterListener(napi_value callback, std::string type, +napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_info info) +{ + SELECTION_HILOGI("SelectionEngineSetting---CreatePanel"); + + return nullptr; +} + +void JsSelectionEngineSetting::RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj) { SELECTION_HILOGD("RegisterListener %{public}s", type.c_str()); @@ -162,7 +109,7 @@ void JsSelectionAbilityEngine::RegisterListener(napi_value callback, std::string return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_); }); if (ret) { - SELECTION_HILOGD("JsSelectionAbilityEngine callback already registered!"); + SELECTION_HILOGD("JsSelectionEngineSetting callback already registered!"); return; } @@ -170,7 +117,7 @@ void JsSelectionAbilityEngine::RegisterListener(napi_value callback, std::string jsCbMap_[type].push_back(std::move(callbackObj)); } -void JsSelectionAbilityEngine::UnRegisterListener(napi_value callback, std::string type) +void JsSelectionEngineSetting::UnRegisterListener(napi_value callback, std::string type) { SELECTION_HILOGI("unregister listener: %{public}s.", type.c_str()); std::lock_guard lock(mutex_); @@ -196,5 +143,81 @@ void JsSelectionAbilityEngine::UnRegisterListener(napi_value callback, std::stri jsCbMap_.erase(type); } } -} // namespace OHOS::SelectionFwk -} // namespace OHOS \ No newline at end of file + +napi_value JsSelectionEngineSetting::GetSEInstance(napi_env env, napi_callback_info info) +{ + napi_value instance = nullptr; + napi_value cons = nullptr; + if (napi_get_reference_value(env, KDSRef_, &cons) != napi_ok) { + SELECTION_HILOGI("failed to get reference value."); + return nullptr; + } + if (napi_new_instance(env, cons, 0, nullptr, &instance) != napi_ok) { + SELECTION_HILOGI("failed to new instance."); + return nullptr; + } + return instance; +} + +std::shared_ptr JsSelectionEngineSetting::GetJsSelectionEngineSetting() +{ + if (selectionDelegate_ == nullptr) { + std::lock_guard lock(selectionMutex_); + if (selectionDelegate_ == nullptr) { + auto delegate = std::make_shared(); + if (delegate == nullptr) { + SELECTION_HILOGE("keyboard delegate is nullptr!"); + return nullptr; + } + selectionDelegate_ = delegate; + } + } + return selectionDelegate_; +} + +napi_value JsSelectionEngineSetting::JsConstructor(napi_env env, napi_callback_info cbinfo) +{ + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr)); + auto delegate = GetJsSelectionEngineSetting(); + if (delegate == nullptr) { + SELECTION_HILOGE("failed to get delegate!"); + napi_value result = nullptr; + napi_get_null(env, &result); + return result; + } + napi_status status = napi_wrap( + env, thisVar, delegate.get(), [](napi_env env, void *nativeObject, void *hint) {}, nullptr, nullptr); + if (status != napi_ok) { + SELECTION_HILOGE("failed to wrap: %{public}d!", status); + return nullptr; + } + return thisVar; +}; + +napi_value JsSelectionEngineSetting::Init(napi_env env, napi_value exports) +{ + SELECTION_HILOGI("napi init"); + napi_property_descriptor descriptor[] = { + DECLARE_NAPI_FUNCTION("getSelectionAbility", GetSelectionAbility), + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor)); + return InitProperty(env, exports); +} + +napi_value JsSelectionEngineSetting::InitProperty(napi_env env, napi_value exports) +{ + SELECTION_HILOGI("napi init"); + napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("on", Subscribe), + DECLARE_NAPI_FUNCTION("off", UnSubscribe), + DECLARE_NAPI_FUNCTION("createPanel", CreatePanel), + }; + + napi_value cons = nullptr; + NAPI_CALL(env, napi_define_class(env, KDS_CLASS_NAME.c_str(), KDS_CLASS_NAME.size(), JsConstructor, nullptr, + sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons)); + NAPI_CALL(env, napi_create_reference(env, cons, 1, &KDSRef_)); + NAPI_CALL(env, napi_set_named_property(env, exports, KDS_CLASS_NAME.c_str(), cons)); + return exports; +} diff --git a/frameworks/js/napi/selection_ability/js_selection_ability.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h similarity index 72% rename from frameworks/js/napi/selection_ability/js_selection_ability.h rename to frameworks/js/napi/selection_ability/js_selection_engine_setting.h index ab22754..c8cb30e 100644 --- a/frameworks/js/napi/selection_ability/js_selection_ability.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -13,12 +13,13 @@ * limitations under the License. */ -#ifndef JS_SELECTION_ABILITY_H -#define JS_SELECTION_ABILITY_H +#ifndef JS_SELECTION_ENGINE_SETTING_H +#define JS_SELECTION_ENGINE_SETTING_H #include #include #include +#include #include "napi/native_api.h" #include "util.h" @@ -26,18 +27,21 @@ namespace OHOS { namespace SelectionFwk { -class JsSelectionAbility { +class JsSelectionEngineSetting { public: - JsSelectionAbility() = default; - ~JsSelectionAbility() = default; + JsSelectionEngineSetting() = default; + ~JsSelectionEngineSetting() = default; static napi_value Init(napi_env env, napi_value exports); + static napi_value InitProperty(napi_env env, napi_value exports); static napi_value GetSelectionAbility(napi_env env, napi_callback_info info); static napi_value Subscribe(napi_env env, napi_callback_info info); static napi_value UnSubscribe(napi_env env, napi_callback_info info); + static napi_value CreatePanel(napi_env env, napi_callback_info info); private: + static napi_value GetSEInstance(napi_env env, napi_callback_info info); static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); - static std::shared_ptr GetJsSelectionAbility(); + static std::shared_ptr GetJsSelectionEngineSetting(); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); @@ -46,10 +50,10 @@ private: static thread_local napi_ref KDSRef_; std::map>> jsCbMap_; static std::mutex selectionMutex_; - static std::shared_ptr selectionDelegate_; + static std::shared_ptr selectionDelegate_; std::recursive_mutex mutex_; }; } //SelectionFwk } //OHOS -#endif //JS_SELECTION_ABILITY_H +#endif //JS_SELECTION_ENGINE_SETTING_H diff --git a/frameworks/js/napi/selection_ability/selection_ability_module.cpp b/frameworks/js/napi/selection_ability/selection_ability_module.cpp deleted file mode 100644 index e15bbdc..0000000 --- a/frameworks/js/napi/selection_ability/selection_ability_module.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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_selection_ability.h" -#include "napi/native_api.h" -#include "napi/native_node_api.h" - -EXTERN_C_START -/* - * function for module exports - */ -static napi_value Init(napi_env env, napi_value exports) -{ - OHOS::SelectionFwk::JsSelectionAbility::Init(env, exports); - return exports; -} -EXTERN_C_END - -/* - * module define - */ -static napi_module _module = { - .nm_version = 1, - .nm_flags = 0, - .nm_filename = nullptr, - .nm_register_func = Init, - .nm_modname = "selectionAbility", - .nm_priv = ((void *)0), - .reserved = { 0 } }; -/* - * module register - */ -extern "C" __attribute__((constructor)) void Register() -{ - napi_module_register(&_module); -} \ No newline at end of file diff --git a/frameworks/js/napi/selectionability/selection_engine_module.cpp b/frameworks/js/napi/selection_ability/selection_engine_module.cpp similarity index 83% rename from frameworks/js/napi/selectionability/selection_engine_module.cpp rename to frameworks/js/napi/selection_ability/selection_engine_module.cpp index eaf28b0..2ac7b3e 100644 --- a/frameworks/js/napi/selectionability/selection_engine_module.cpp +++ b/frameworks/js/napi/selection_ability/selection_engine_module.cpp @@ -13,8 +13,7 @@ * limitations under the License. */ -#include "js_selection_ability_engine.h" -#include "selection_log.h" +#include "js_selection_engine_setting.h" #include "napi/native_api.h" #include "napi/native_node_api.h" @@ -24,18 +23,20 @@ EXTERN_C_START */ static napi_value Init(napi_env env, napi_value exports) { - OHOS::SelectionFwk::JsSelectionAbilityEngine::Init(env, exports); + OHOS::SelectionFwk::JsSelectionEngineSetting::Init(env, exports); return exports; } EXTERN_C_END + /* * module define */ -static napi_module _module = { .nm_version = 1, +static napi_module _module = { + .nm_version = 1, .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, - .nm_modname = "selectionAbilityEngine", + .nm_modname = "selectionEngine", .nm_priv = ((void *)0), .reserved = { 0 } }; /* diff --git a/frameworks/js/napi/selectionability/BUILD.gn b/frameworks/js/napi/selectionability/BUILD.gn deleted file mode 100644 index 481eba1..0000000 --- a/frameworks/js/napi/selectionability/BUILD.gn +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright (C) 2022 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("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") -import("//build/ohos.gni") - -ohos_shared_library("selectionabilityengine") { - branch_protector_ret = "pac_ret" - sanitize = { - boundary_sanitize = true - cfi = true - cfi_cross_dso = true - debug = false - integer_overflow = true - ubsan = true - } - - include_dirs = [ - "${selection_fwk_root_path}/utils/include", - ] - ldflags = [ "-Wl,--exclude-libs=ALL" ] - cflags_cc = [ - "-fvisibility=hidden", - "-fvisibility-inlines-hidden", - "-fdata-sections", - "-ffunction-sections", - "-Os", - ] - sources = [ - "js_selection_ability_engine.cpp", - "selection_engine_module.cpp", - ] - - deps = [ - "${selection_fwk_root_path}/common:selection_common", - ] - - external_deps = [ - "ability_base:configuration", - "ability_runtime:ability_context_native", - "ability_runtime:abilitykit_native", - "ability_runtime:extensionkit_native", - "ability_runtime:napi_base_context", - "c_utils:utils", - "eventhandler:libeventhandler", - "hilog:libhilog", - "ipc:ipc_core", - "ipc:ipc_single", - "napi:ace_napi", - "window_manager:libwm_lite", - "resource_management:global_resmgr", - "ability_runtime:app_context", - ] - - - relative_install_dir = "module" - part_name = "selectionfwk" - subsystem_name = "systemabilitymgr" -} diff --git a/frameworks/js/napi/selectionability/js_selection_ability_engine.h b/frameworks/js/napi/selectionability/js_selection_ability_engine.h deleted file mode 100644 index f83ea89..0000000 --- a/frameworks/js/napi/selectionability/js_selection_ability_engine.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 INTERFACE_KITS_JS_SELECTION_ABILITY_ENGINE_H -#define INTERFACE_KITS_JS_SELECTION_ABILITY_ENGINE_H -#include -#include -#include - -#include "napi/native_api.h" -#include "util.h" -#include "callback_object.h" - - -namespace OHOS { -namespace SelectionFwk { -class JsSelectionAbilityEngine { -public: - JsSelectionAbilityEngine() = default; - ~JsSelectionAbilityEngine() = default; - static napi_value Init(napi_env env, napi_value exports); - static napi_value Subscribe(napi_env env, napi_callback_info info); - static napi_value UnSubscribe(napi_env env, napi_callback_info info); - -private: - static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); - static std::shared_ptr GetSelectionAbilityEngine(); - void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); - void UnRegisterListener(napi_value callback, std::string type); - -private: - static const std::string KDS_CLASS_NAME; - static thread_local napi_ref KDSRef_; - std::map>> jsCbMap_; - static std::mutex selectionMutex_; - static std::shared_ptr selectionDelegate_; - std::recursive_mutex mutex_; -}; -} // namespace SelectionFwk -} // namespace OHOS -#endif // INTERFACE_KITS_JS_SELECTION_ABILITY_ENGINE_H \ No newline at end of file -- Gitee From dc367d96b877b6bd1ac06284e91df2ed140561d6 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Mon, 19 May 2025 11:24:24 +0800 Subject: [PATCH 20/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0extension=20ability=20o?= =?UTF-8?q?nCreate=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- frameworks/js/napi/selection_extension_ability/BUILD.gn | 2 +- .../selection_extension_ability_module.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frameworks/js/napi/selection_extension_ability/BUILD.gn b/frameworks/js/napi/selection_extension_ability/BUILD.gn index 4669200..f102505 100644 --- a/frameworks/js/napi/selection_extension_ability/BUILD.gn +++ b/frameworks/js/napi/selection_extension_ability/BUILD.gn @@ -44,7 +44,7 @@ ohos_shared_library("selectionextensionability_napi") { external_deps = [ "napi:ace_napi" ] - relative_install_dir = "module/app/ability" + relative_install_dir = "module" subsystem_name = "systemabilitymgr" part_name = "selectionfwk" } diff --git a/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp index 7ec965f..1c7edbe 100644 --- a/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp +++ b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp @@ -25,13 +25,13 @@ static napi_module _module = { .nm_modname = "SelectionExtensionAbility", }; -extern "C" __attribute__((constructor)) void NAPI_app_ability_SelectionExtensionAbility_AutoRegister() +extern "C" __attribute__((constructor)) void NAPI_SelectionExtensionAbility_AutoRegister() { napi_module_register(&_module); } extern "C" __attribute__((visibility("default"))) void - NAPI_app_ability_SelectionExtensionAbility_GetJSCode(const char** buf, int* bufLen) + NAPI_SelectionExtensionAbility_GetJSCode(const char** buf, int* bufLen) { if (buf != nullptr) { *buf = _binary_selection_extension_ability_js_start; @@ -43,7 +43,7 @@ extern "C" __attribute__((visibility("default"))) void } extern "C" __attribute__((visibility("default"))) void - NAPI_app_ability_SelectionExtensionAbility_GetABCCode(const char** buf, int* buflen) + NAPI_SelectionExtensionAbility_GetABCCode(const char** buf, int* buflen) { if (buf != nullptr) { *buf = _binary_selection_extension_ability_abc_start; -- Gitee From 23988cf26c5548b3871a57480cedd69d2722a43c Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Tue, 20 May 2025 18:43:06 +0800 Subject: [PATCH 21/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9SelectionExtensionAbili?= =?UTF-8?q?ty=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../src/js_selection_extension.cpp | 25 +++---------------- .../src/selection_extension_module_loader.cpp | 2 +- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index d705bc8..1e101b7 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -14,7 +14,6 @@ */ #include "js_selection_extension.h" -#include "hilog_wrapper.h" #include "js_runtime.h" #include "js_runtime_utils.h" #include "napi/native_api.h" @@ -64,8 +63,8 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor void JsSelectionExtension::OnStart(const AAFwk::Want& want) { - Extension::OnStart(want); HILOG_INFO("JsSelectionExtension OnStart begin."); + Extension::OnStart(want); napi_env env = jsRuntime_.GetNapiEnv(); napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); napi_value argv[] = {napiWant}; @@ -75,6 +74,8 @@ void JsSelectionExtension::OnStart(const AAFwk::Want& want) sptr JsSelectionExtension::OnConnect(const AAFwk::Want& want) { + HILOG_INFO("JsSelectionExtension OnConnect begin."); + Extension::OnConnect(want); return nullptr; } @@ -137,26 +138,6 @@ void JsSelectionExtension::GetSrcPath(std::string& srcPath) void JsSelectionExtension::BindContext() { // TODO: - - // auto env = jsRuntime_.GetNapiEnv(); - // napi_value obj = jsObj_->GetNapiValue(); - // if (!CheckTypeForNapiValue(env, obj, napi_object)) { - // HILOG_ERROR("check type failed"); - // return; - // } - - // auto context = GetContext(); - // if (context == nullptr) { - // HILOG_ERROR("failed to get context!"); - // return; - // } - - // napi_value contextObj = CreateJsSelectionExtensionContext(env, context); - // auto contextRef = jsRuntime_.LoadSystemModule("SelectionExtensionContext", &contextObj, ARGC_ONE); - // if (!contextRef) { - // HILOG_ERROR("context is nullptr"); - // return; - // } } } // namespace OHOS::AbilityRuntime \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp index 4d7e0a9..0233a59 100644 --- a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp @@ -29,7 +29,7 @@ Extension* SelectionExtensionModuleLoader::Create(const std::unique_ptr std::map SelectionExtensionModuleLoader::GetParams() { // type means extension type in ExtensionAbilityType of extension_ability_info.h - return {{"type", "509"}, {"name", "SelectionExtensionAbility"}}; + return {{"type", "29"}, {"name", "SelectionExtensionAbility"}}; } extern "C" __attribute__((visibility("default"))) void* OHOS_EXTENSION_GetExtensionModule() -- Gitee From 31756e1200d76e4aa2e27e538e922cb5a4912e28 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Tue, 20 May 2025 17:24:44 +0800 Subject: [PATCH 22/93] =?UTF-8?q?=E9=80=89=E8=AF=8D=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/include/selection_service.h | 3 +- service/src/selection_service.cpp | 48 ++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index e42ff9e..5ec1010 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -50,7 +50,8 @@ typedef enum { SUB_WAIT_PRESS_DOWN = 1, SUB_WAIT_PRESS_MOVE = 2, SUB_WAIT_PRESS_UP = 3, - SUB_WAIT_CTRL = 4, + SUB_WAIT_CTRL_DOWN = 4, + SUB_WAIT_CTRL_UP = 5, } SelectInputSubState; class SelectionService : public SystemAbility, public SelectionServiceStub { diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index ba9a5b5..47d1cd3 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -262,28 +262,46 @@ void SelectionService::HandlePointEvent(int32_t type) #endif } -// foundation/multimodalinput/input/interfaces/native/innerkits/event/include/key_event.h void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { SELECTION_HILOGD("[SelectionService] into keyEvent"); + if (!ctrlSelectFlag) { + return; + } + + if (subSelectState != SUB_WAIT_CTRL_DOWN && subSelectState != SUB_WAIT_CTRL_UP) { + return; + } + int32_t keyCode = keyEvent->GetKeyCode(); - SELECTION_HILOGD("[SelectionService] keyId: %{public}d", keyCode); - if (keyCode == KeyEvent::KEYCODE_CTRL_LEFT || keyCode == KeyEvent::KEYCODE_CTRL_RIGHT) { - SELECTION_HILOGI("[SelectionService] Processed ctrl key."); - if (ctrlSelectFlag && curSelectState == SELECT_INPUT_WAIT_LEFT_MOVE && subSelectState == SUB_WAIT_CTRL) { + int32_t action = keyEvent->GetKeyAction(); + if (keyCode != KeyEvent::KEYCODE_CTRL_LEFT && keyCode != KeyEvent::KEYCODE_CTRL_RIGHT) { + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); + return; + } + SELECTION_HILOGI("[SelectionService] Processed ctrl key."); + if (subSelectState == SUB_WAIT_CTRL_DOWN && action == KeyEvent::KEY_ACTION_DOWN) { + subSelectState = SUB_WAIT_CTRL_UP; + return; + } else if (subSelectState == SUB_WAIT_CTRL_UP && action == KeyEvent::KEY_ACTION_UP) { + if (curSelectState == SELECT_INPUT_WAIT_LEFT_MOVE) { curSelectState = SELECT_INPUT_LEFT_MOVE; - subSelectState = SUB_INITIAL; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); - return; } - if (ctrlSelectFlag && curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK && subSelectState == SUB_WAIT_CTRL) { + if (curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK) { curSelectState = SELECT_INPUT_DOUBLE_CLICKED; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); - return; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); } + subSelectState = SUB_INITIAL; + return; + } else { + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); } - + return; } void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const @@ -296,7 +314,7 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv if (curSelectState == SELECT_INPUT_INITIAL && buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { return; } - if (subSelectState == SUB_WAIT_CTRL) { + if (subSelectState == SUB_WAIT_CTRL_DOWN || subSelectState == SUB_WAIT_CTRL_UP) { SELECTION_HILOGI("[SelectionService] pointerEvent: curSelectState == SELECT_INPUT_WAIT_CTRL. return."); curSelectState = SELECT_INPUT_INITIAL; subSelectState = SUB_INITIAL; @@ -374,7 +392,7 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptrGetPointerAction(); if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_CTRL; + subSelectState = SUB_WAIT_CTRL_DOWN; SELECTION_HILOGI("set subSelectState to SUB_WAIT_CTRL."); } else { curSelectState = SELECT_INPUT_LEFT_MOVE; @@ -403,7 +421,7 @@ void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr Date: Tue, 20 May 2025 20:40:28 +0800 Subject: [PATCH 23/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9README=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- README.md | 10 +++++++--- .../selection_extension/src/js_selection_extension.cpp | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fee8861..01a5191 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,13 @@ │ │ └── security │ │ └── selinux_adapter => 代码提交仓: https://gitee.com/sinall/security_selinux_adapter.git, selection_fwk分支 │ ├── foundation -│ │ └── systemabilitymgr -│ │ ├── samgr => 代码提交仓: https://gitee.com/sinall/systemabilitymgr_samgr.git, selection_fwk分支 -│ │ └── selection_fwk => 代码提交仓: https://gitee.com/sinall/selection_fwk.git, master分支 +│ │ ├──systemabilitymgr +│ │ │ ├── samgr => 代码提交仓: https://gitee.com/sinall/systemabilitymgr_samgr.git, selection_fwk分支 +│ │ │ └── selection_fwk => 代码提交仓: https://gitee.com/sinall/selection_fwk.git, master分支 +│ │ ├──bundlemanager +│ │ │ └── bundle_framework =>代码提交仓: https://gitee.com/sinall/bundlemanager_bundle_framework.git selection_fwk分支 +│ │ └──ability +│ │ └── ability_runtime => 代码提交仓: https://gitee.com/sinall/ability_ability_runtime.git, selection_fwk分支 │ ├── productdefine │ │ └── common => 代码提交仓: https://gitee.com/sinall/productdefine_common.git, selection_fwk分支 ``` diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index 1e101b7..437a629 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -40,6 +40,7 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor std::shared_ptr& handler, const sptr& token) { + HILOG_INFO("JsSelectionExtension Init begin."); SelectionExtension::Init(record, application, handler, token); std::string srcPath; GetSrcPath(srcPath); @@ -59,6 +60,7 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor return; } BindContext(); + HILOG_INFO("JsSelectionExtension Init end."); } void JsSelectionExtension::OnStart(const AAFwk::Want& want) -- Gitee From c1467a7f8ea56d214650b7dddfe164dcb480bd1c Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Wed, 21 May 2025 16:51:15 +0800 Subject: [PATCH 24/93] =?UTF-8?q?=E6=BB=91=E8=AF=8D=E5=A2=9E=E5=8A=A0ctrl?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/include/selection_service.h | 1 + service/src/selection_service.cpp | 98 +++++++++++++++++++++++------ 2 files changed, 81 insertions(+), 18 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 5ec1010..5dda29b 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -116,6 +116,7 @@ private: void InputWordBeginProcess(std::shared_ptr pointerEvent) const; void InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const; void InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const; + void FinishedWordSelection() const; void InjectCtrlC() const; static uint32_t curSelectState; static uint32_t subSelectState; diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 47d1cd3..2a59d7c 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -295,12 +295,12 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); } subSelectState = SUB_INITIAL; - return; } else { curSelectState = SELECT_INPUT_INITIAL; subSelectState = SUB_INITIAL; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); } + FinishedWordSelection(); return; } @@ -308,14 +308,17 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv { SELECTION_HILOGD("[SelectionService] into PointerEvent"); int32_t action = pointerEvent->GetPointerAction(); - int32_t buttonId = pointerEvent->GetButtonId(); + int32_t pointerId = pointerEvent->GetPointerId(); SELECTION_HILOGD("[SelectionService] pointerEvent: %{public}d", action); - SELECTION_HILOGD("[SelectionService] buttonId: %{public}d", buttonId); - if (curSelectState == SELECT_INPUT_INITIAL && buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { + SELECTION_HILOGD("[SelectionService] pointerId: %{public}d", pointerId); + if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { return; } - if (subSelectState == SUB_WAIT_CTRL_DOWN || subSelectState == SUB_WAIT_CTRL_UP) { + if ((subSelectState == SUB_WAIT_CTRL_DOWN || subSelectState == SUB_WAIT_CTRL_UP) + && (action != PointerEvent::POINTER_ACTION_MOVE)) { SELECTION_HILOGI("[SelectionService] pointerEvent: curSelectState == SELECT_INPUT_WAIT_CTRL. return."); + SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", action); + SELECTION_HILOGI("[SelectionService] pointerId: %{public}d", pointerId); curSelectState = SELECT_INPUT_INITIAL; subSelectState = SUB_INITIAL; return; @@ -342,14 +345,7 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv default: break; } - if (curSelectState == SELECT_INPUT_LEFT_MOVE || curSelectState == SELECT_INPUT_DOUBLE_CLICKED) { - // world selection action - SELECTION_HILOGI("[SelectionService] first, end word selection action."); - InjectCtrlC(); - SELECTION_HILOGI("[SelectionService] first, end inject ctrl + c."); - curSelectState = SELECT_INPUT_INITIAL; - } - + FinishedWordSelection(); return; } @@ -393,7 +389,7 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptrAddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + // std::vector downKey; + // downKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); + // downKey.push_back(KeyEvent::KEYCODE_C); + // keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + + // KeyEvent::KeyItem downItem[downKey.size()]; + // for (size_t i = 0; i < downKey.size(); i++) { + // downItem[i].SetKeyCode(downKey[i]); + // downItem[i].SetPressed(true); + // downItem[i].SetDownTime(500); + // keyDownEvent->AddPressedKeyItems(downItem[i]); + // } + // InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); + // 创建KeyEvent对象 + // auto keyEvent = KeyEvent::Create(); + + // // 设置Ctrl键按下 + // keyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入Ctrl按下 + + // // 设置C键按下 + // keyEvent->SetKeyCode(KeyEvent::KEYCODE_C); + // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入C按下 + + // // 设置C键释放 + // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_UP); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入C释放 + + // // 设置Ctrl键释放 + // keyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_UP); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入Ctrl释放 auto keyDownEvent = KeyEvent::Create(); keyDownEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); std::vector downKey; downKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); downKey.push_back(KeyEvent::KEYCODE_C); - keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - + KeyEvent::KeyItem downItem[downKey.size()]; for (size_t i = 0; i < downKey.size(); i++) { + keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); downItem[i].SetKeyCode(downKey[i]); downItem[i].SetPressed(true); downItem[i].SetDownTime(500); keyDownEvent->AddPressedKeyItems(downItem[i]); } InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); + + auto keyUpEvent = KeyEvent::Create(); + keyUpEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + std::vector upKey; + upKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); + upKey.push_back(KeyEvent::KEYCODE_C); + + KeyEvent::KeyItem upItem[upKey.size()]; + for (size_t i = 0; i < upKey.size(); i++) { + keyUpEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyUpEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + upItem[i].SetKeyCode(upKey[i]); + upItem[i].SetPressed(true); + upItem[i].SetDownTime(0); + keyUpEvent->RemoveReleasedKeyItems(upItem[i]); + } + InputManager::GetInstance()->SimulateInputEvent(keyUpEvent); } std::shared_ptr SelectionService::GetEventHandler() -- Gitee From b486e53833f50ba4ca18f3febb51276408c2bc48 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Wed, 21 May 2025 18:20:26 +0800 Subject: [PATCH 25/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0On=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- bundle.json | 3 +- common/selection_interface.h | 33 ++++++ frameworks/js/napi/selection_ability/BUILD.gn | 3 + .../js_selection_engine_setting.cpp | 109 ++++++++++++++++++ .../js_selection_engine_setting.h | 29 ++++- frameworks/native/selection_ability/BUILD.gn | 66 ++++++++--- .../selection_ability/ISelectionListener.idl | 17 +++ .../include/selection_listener_impl.h | 34 ++++++ .../src/selection_listener_impl.cpp | 28 +++++ service/BUILD.gn | 28 ++++- service/ISelectionService.idl | 4 + service/include/selection_service.h | 21 +--- service/libselection_service.map | 2 + service/src/selection_service.cpp | 79 ++++--------- 14 files changed, 359 insertions(+), 97 deletions(-) create mode 100644 common/selection_interface.h create mode 100644 frameworks/native/selection_ability/ISelectionListener.idl create mode 100644 frameworks/native/selection_ability/include/selection_listener_impl.h create mode 100644 frameworks/native/selection_ability/src/selection_listener_impl.cpp diff --git a/bundle.json b/bundle.json index 3ca62e5..e3b8500 100644 --- a/bundle.json +++ b/bundle.json @@ -47,7 +47,8 @@ "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile", "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native", - "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionengine_napi" + "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionengine_napi", + "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_ability:selection_ability" ], "inner_kits": [] } diff --git a/common/selection_interface.h b/common/selection_interface.h new file mode 100644 index 0000000..3474bb2 --- /dev/null +++ b/common/selection_interface.h @@ -0,0 +1,33 @@ +/* + * 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 SELECTION_INTERFACE_H +#define SELECTION_INTERFACE_H + +#include +#include +#include +#include + +namespace OHOS { +namespace SelectionFwk { +class SelectionInterface { +public: + virtual ~SelectionInterface() = default; + virtual int32_t OnSelectionEvent(const std::string &selectionData) = 0; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // SELECTION_INTERFACE_H \ No newline at end of file diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 6ec481b..921a3fb 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -37,6 +37,9 @@ ohos_shared_library("selectionengine_napi") { deps = [ "${selection_fwk_root_path}/common:selection_common", + "${selection_fwk_root_path}/service:selection_service_proxy", + "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_listener_proxy", + "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_ability", ] external_deps = [ diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 912979e..551026d 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -1,11 +1,16 @@ #include "js_selection_engine_setting.h" #include "event_checker.h" +#include "iservice_registry.h" #include "js_utils.h" +#include "callback_handler.h" #include "napi/native_node_api.h" +#include "selection_listener_impl.h" #include "selection_log.h" +#include "system_ability_definition.h" #include "util.h" +using namespace OHOS; using namespace OHOS::SelectionFwk; constexpr size_t ARGC_ONE = 1; @@ -15,6 +20,8 @@ const std::string JsSelectionEngineSetting::KDS_CLASS_NAME = "SelectionAbility"; thread_local napi_ref JsSelectionEngineSetting::KDSRef_ = nullptr; std::mutex JsSelectionEngineSetting::selectionMutex_; std::shared_ptr JsSelectionEngineSetting::selectionDelegate_{ nullptr }; +std::mutex JsSelectionEngineSetting::eventHandlerMutex_; +std::shared_ptr JsSelectionEngineSetting::handler_{ nullptr }; napi_value JsSelectionEngineSetting::GetSelectionAbility(napi_env env, napi_callback_info info) @@ -96,6 +103,25 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf return nullptr; } +sptr JsSelectionEngineSetting::GetSelectionSystemAbility() +{ + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + SELECTION_HILOGE("system ability manager is nullptr!"); + return nullptr; + } + + sptr systemAbility = nullptr; + systemAbility = systemAbilityManager->GetSystemAbility(SELECTION_FWK_SA_ID); + if (systemAbility == nullptr) { + SELECTION_HILOGE("get system ability is nullptr!"); + return nullptr; + } + + abilityManager_ = iface_cast(systemAbility); + return abilityManager_; +} + void JsSelectionEngineSetting::RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj) { @@ -115,6 +141,16 @@ void JsSelectionEngineSetting::RegisterListener(napi_value callback, std::string SELECTION_HILOGI("add %{public}s callbackObj into jsCbMap_.", type.c_str()); jsCbMap_[type].push_back(std::move(callbackObj)); + + auto proxy = GetSelectionSystemAbility(); + if (proxy == nullptr) { + SELECTION_HILOGE("selection system ability is nullptr!"); + return; + } + auto selectionInterface = GetJsSelectionEngineSetting(); + listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionInterface); + SELECTION_HILOGI("Begin to call SA RegisterListener"); + proxy->RegisterListener(listenerStub_->AsObject()); } void JsSelectionEngineSetting::UnRegisterListener(napi_value callback, std::string type) @@ -172,6 +208,10 @@ std::shared_ptr JsSelectionEngineSetting::GetJsSelecti selectionDelegate_ = delegate; } } + { + std::lock_guard lock(eventHandlerMutex_); + handler_ = AppExecFwk::EventHandler::Current(); + } return selectionDelegate_; } @@ -221,3 +261,72 @@ napi_value JsSelectionEngineSetting::InitProperty(napi_env env, napi_value expor NAPI_CALL(env, napi_set_named_property(env, exports, KDS_CLASS_NAME.c_str(), cons)); return exports; } + +std::shared_ptr JsSelectionEngineSetting::GetEventHandler() +{ + std::lock_guard lock(eventHandlerMutex_); + return handler_; +} + +std::shared_ptr JsSelectionEngineSetting::GetEntry(const std::string &type, + EntrySetter entrySetter) +{ + SELECTION_HILOGI("start, type: %{public}s", type.c_str()); + std::shared_ptr entry = nullptr; + { + std::lock_guard lock(mutex_); + if (jsCbMap_[type].empty()) { + SELECTION_HILOGI("%{public}s cb-vector is empty.", type.c_str()); + return nullptr; + } + entry = std::make_shared(jsCbMap_[type], type); + } + if (entrySetter != nullptr) { + entrySetter(*entry); + } + return entry; +} + +int32_t JsSelectionEngineSetting::OnSelectionEvent(const std::string &selectionData) +{ + SELECTION_HILOGI("OnSelectionEvent begin"); + std::string type = "selectionEvent"; + + if (selectionData.empty()) { + SELECTION_HILOGE("selectionData is empty"); + return 1; + } + + auto entry = GetEntry(type, [&selectionData](SelectionEntry &entry) { entry.text = selectionData; }); + if (entry == nullptr) { + SELECTION_HILOGE("failed to get uv entry!"); + return 1; + } + + auto eventHandler = GetEventHandler(); + if (eventHandler == nullptr) { + SELECTION_HILOGE("eventHandler is nullptr!"); + return 1; + } + + SELECTION_HILOGI("selectionData is [%{public}s]", selectionData.c_str()); + + + auto task = [entry]() { + auto getTextChangeProperty = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { + if (argc == 0) { + return false; + } + // 0 means the first param of callback. + napi_create_string_utf8(env, entry->text.c_str(), NAPI_AUTO_LENGTH, &args[0]); + return true; + }; + // 1 means callback has one param. + JsCallbackHandler::Traverse(entry->vecCopy, { 1, getTextChangeProperty }); + }; + eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); + + SELECTION_HILOGI("OnSelectionEvent end"); + return 0; +} + diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index c8cb30e..fea671d 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -21,13 +21,18 @@ #include #include +#include "callback_object.h" +#include "iremote_stub.h" +#include "iselection_listener.h" +#include "iselection_service.h" #include "napi/native_api.h" +#include "refbase.h" +#include "selection_interface.h" #include "util.h" -#include "callback_object.h" namespace OHOS { namespace SelectionFwk { -class JsSelectionEngineSetting { +class JsSelectionEngineSetting : public SelectionInterface{ public: JsSelectionEngineSetting() = default; ~JsSelectionEngineSetting() = default; @@ -37,13 +42,28 @@ public: static napi_value Subscribe(napi_env env, napi_callback_info info); static napi_value UnSubscribe(napi_env env, napi_callback_info info); static napi_value CreatePanel(napi_env env, napi_callback_info info); + int32_t OnSelectionEvent(const std::string &selectionData); private: + struct SelectionEntry { + std::vector> vecCopy; + std::string type; + std::string text; + SelectionEntry(const std::vector> &cbVec, const std::string &type) + : vecCopy(cbVec), type(type) + { + } + }; + static napi_value GetSEInstance(napi_env env, napi_callback_info info); static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); static std::shared_ptr GetJsSelectionEngineSetting(); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); + sptr GetSelectionSystemAbility(); + static std::shared_ptr GetEventHandler(); + using EntrySetter = std::function; + std::shared_ptr GetEntry(const std::string &type, EntrySetter entrySetter = nullptr); private: static const std::string KDS_CLASS_NAME; @@ -52,7 +72,10 @@ private: static std::mutex selectionMutex_; static std::shared_ptr selectionDelegate_; std::recursive_mutex mutex_; - + sptr listenerStub_ { nullptr }; + sptr abilityManager_ { nullptr }; + static std::mutex eventHandlerMutex_; + static std::shared_ptr handler_; }; } //SelectionFwk } //OHOS diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn index 00b6458..fe94f3f 100644 --- a/frameworks/native/selection_ability/BUILD.gn +++ b/frameworks/native/selection_ability/BUILD.gn @@ -12,33 +12,69 @@ # limitations under the License. import("//build/ohos.gni") +import("//build/config/components/idl_tool/idl.gni") +import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") -ohos_shared_library("selectionability") { - branch_protector_ret = "pac_ret" +config("selection_listener_config") { + include_dirs = [ + "include", + "../../../utils/include", + "${target_gen_dir}", + "${selection_fwk_root_path}/common", + ] +} + +idl_interface_sources = [ + "${target_gen_dir}/selection_listener_proxy.cpp", + "${target_gen_dir}/selection_listener_stub.cpp", +] + +idl_gen_interface("selection_listener_interface") { + src_idl = rebase_path("ISelectionListener.idl") + dst_file = string_join(",", idl_interface_sources) +} + +ohos_source_set("selection_listener_proxy") { sanitize = { - boundary_sanitize = true cfi = true cfi_cross_dso = true debug = false - integer_overflow = true - ubsan = true } - sources = [ - "src/selection_ability.cpp", - ] - include_dirs = [ - ".", - "../../../utils/include", "${target_gen_dir}", ] + public_configs = [":selection_listener_config"] + output_values = get_target_outputs(":selection_listener_interface") + sources = filter_include(output_values, [ "*_proxy.cpp" ]) + deps = [ ":selection_listener_interface" ] external_deps = [ + "c_utils:utils", "hilog:libhilog", - "napi:ace_napi", + "ipc:ipc_single", ] - - relative_install_dir = "module" - subsystem_name = "systemabilitymgr" part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" } + +ohos_shared_library("selection_ability") { + configs = [ ":selection_listener_config", ] + output_values = get_target_outputs(":selection_listener_interface") + + sources = [ + "src/selection_listener_impl.cpp", + ] + sources += filter_include(output_values, [ "*.cpp" ]) + deps = [ + ":selection_listener_interface", + ] + + external_deps = [ + "c_utils:utils", + "ipc:ipc_single", + "hilog:libhilog", + ] + + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} \ No newline at end of file diff --git a/frameworks/native/selection_ability/ISelectionListener.idl b/frameworks/native/selection_ability/ISelectionListener.idl new file mode 100644 index 0000000..2643dab --- /dev/null +++ b/frameworks/native/selection_ability/ISelectionListener.idl @@ -0,0 +1,17 @@ +/* + * 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. + */ +interface OHOS.SelectionFwk.ISelectionListener { + void OnSelectionChange([in] String text); +} diff --git a/frameworks/native/selection_ability/include/selection_listener_impl.h b/frameworks/native/selection_ability/include/selection_listener_impl.h new file mode 100644 index 0000000..1092461 --- /dev/null +++ b/frameworks/native/selection_ability/include/selection_listener_impl.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 SELECTION_LISTENER_IMPL_H +#define SELECTION_LISTENER_IMPL_H +#include "refbase.h" +#include "selection_listener_stub.h" +#include "selection_interface.h" + +namespace OHOS { +namespace SelectionFwk { +class SelectionListenerImpl : public SelectionListenerStub { +public: + SelectionListenerImpl(std::shared_ptr selectionI) : selectionI_(selectionI) {} + ~SelectionListenerImpl() override = default; + ErrCode OnSelectionChange(const std::string& text) override; +private: + std::shared_ptr selectionI_; +}; +} +} +#endif // SELECTION_LISTENER_IMPL_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp new file mode 100644 index 0000000..9b9f9b9 --- /dev/null +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -0,0 +1,28 @@ +/* + * 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 "selection_listener_impl.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { +ErrCode SelectionListenerImpl::OnSelectionChange(const std::string& text) +{ + SELECTION_HILOGI("Recveive selection data: %{public}s", text.c_str()); + selectionI_->OnSelectionEvent(text); + return 0; +} +} // namespace SelectionFramework +} // namespace OHOS \ No newline at end of file diff --git a/service/BUILD.gn b/service/BUILD.gn index 190e0f2..0300477 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -16,7 +16,7 @@ import("//build/config/components/idl_tool/idl.gni") import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") config("selection_sa_config") { - visibility = [ ":*" ] + # visibility = [ ":*" ] include_dirs = [ "include", "../utils/include", @@ -34,6 +34,29 @@ idl_gen_interface("selection_service_interface") { dst_file = string_join(",", idl_interface_sources) } +ohos_source_set("selection_service_proxy") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + include_dirs = [ + "${target_gen_dir}", + ] + + public_configs = [":selection_sa_config"] + output_values = get_target_outputs(":selection_service_interface") + sources = filter_include(output_values, [ "*_proxy.cpp" ]) + deps = [ ":selection_service_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} + ohos_shared_library("selection_service") { configs = [ ":selection_sa_config", ] shlib_type = "sa" @@ -46,7 +69,8 @@ ohos_shared_library("selection_service") { sources += filter_include(output_values, [ "*.cpp" ]) deps = [ ":selection_service_interface", - "${selection_fwk_root_path}/common:selection_common" + "${selection_fwk_root_path}/common:selection_common", + "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_listener_proxy", ] external_deps = [ diff --git a/service/ISelectionService.idl b/service/ISelectionService.idl index 5897a3d..c560d00 100644 --- a/service/ISelectionService.idl +++ b/service/ISelectionService.idl @@ -12,6 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +sequenceable OHOS.IRemoteObject; interface OHOS.SelectionFwk.ISelectionService { int AddVolume([in] int volume); + void RegisterListener([in] IRemoteObject listener); + void UnregisterListener([in] IRemoteObject listener); } \ No newline at end of file diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 5dda29b..e650201 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -20,6 +20,7 @@ #include #include "callback_object.h" +#include "iselection_listener.h" #include "selection_service_stub.h" #include "refbase.h" #include "system_ability.h" @@ -64,6 +65,8 @@ public: ~SelectionService(); ErrCode AddVolume(int32_t volume, int32_t& funcResult) override; + ErrCode RegisterListener(const sptr &listener) override; + ErrCode UnregisterListener(const sptr &listener) override; int32_t Dump(int32_t fd, const std::vector &args) override; int32_t StartNewAbility(const std::string& bundleName, const std::string& abilityName); void StopCurrentAbility(); @@ -73,22 +76,6 @@ protected: void HandleKeyEvent(int32_t keyCode); void HandlePointEvent(int32_t type); private: - - struct SelectionEntry { - std::vector> vecCopy; - std::string type; - std::string text; - SelectionEntry(const std::vector> &cbVec, const std::string &type) - : vecCopy(cbVec), type(type) - { - } - }; - - using EntrySetter = std::function; - int32_t OnSelectionEvent(std::string &selectionData); - std::shared_ptr GetEntry(const std::string &type, EntrySetter entrySetter = nullptr); - static std::shared_ptr GetEventHandler(); - void InputMonitorInit(); void InputMonitorCancel(); void WatchParams(); @@ -99,8 +86,6 @@ private: std::string currentAbilityName_ = ""; static sptr instance_; static std::shared_mutex adminLock_; - static std::mutex eventHandlerMutex_; - static std::shared_ptr handler_; }; class SelectionInputMonitor : public IInputEventConsumer { diff --git a/service/libselection_service.map b/service/libselection_service.map index 4f4d1a2..95bd01d 100644 --- a/service/libselection_service.map +++ b/service/libselection_service.map @@ -2,6 +2,8 @@ global: extern "C++" { OHOS::SelectionFwk::SelectionService::AddVolume*; + OHOS::SelectionFwk::SelectionService::RegisterListener*; + OHOS::SelectionFwk::SelectionService::UnregisterListener*; }; local: *; diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 2a59d7c..008121c 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -23,16 +23,16 @@ #include #include "parameter.h" #include +#include "common_event_manager.h" using namespace OHOS; using namespace OHOS::SelectionFwk; using namespace OHOS::MMI; +using namespace OHOS::EventFwk; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(SelectionService::GetInstance().GetRefPtr()); std::shared_mutex SelectionService::adminLock_; sptr SelectionService::instance_; -std::mutex SelectionService::eventHandlerMutex_; -std::shared_ptr SelectionService::handler_{ nullptr }; uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; uint32_t SelectionInputMonitor::subSelectState = SUB_INITIAL; @@ -72,6 +72,23 @@ ErrCode SelectionService::AddVolume(int32_t volume, int32_t& funcResult) return (volume + 1); } +ErrCode SelectionService::UnregisterListener(const sptr &listener) +{ + return 0; +} + +ErrCode SelectionService::RegisterListener(const sptr &listener) +{ + SELECTION_HILOGI("Begin to call SA RegisterListener"); + auto proxy = iface_cast(listener); + if (proxy == nullptr) { + SELECTION_HILOGE("RegisterListener: listener is nullptr"); + return -1; + } + proxy->OnSelectionChange("HELLO FANZHE"); + return 0; +} + int32_t SelectionService::Dump(int32_t fd, const std::vector &args) { dprintf(fd, "---------------------SelectionService::Dump--------------------\n"); @@ -205,11 +222,6 @@ void SelectionService::InputMonitorInit() InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); SELECTION_HILOGI("[SelectionService] input monitor init end"); } - - { - std::lock_guard lock(eventHandlerMutex_); - handler_ = AppExecFwk::EventHandler::Current(); - } } void SelectionService::InputMonitorCancel() @@ -345,6 +357,7 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv default: break; } + FinishedWordSelection(); return; } @@ -523,54 +536,4 @@ void SelectionInputMonitor::InjectCtrlC() const keyUpEvent->RemoveReleasedKeyItems(upItem[i]); } InputManager::GetInstance()->SimulateInputEvent(keyUpEvent); -} - -std::shared_ptr SelectionService::GetEventHandler() -{ - std::lock_guard lock(eventHandlerMutex_); - return handler_; -} - - -int32_t SelectionService::OnSelectionEvent(std::string &selectionData) -{ - SELECTION_HILOGI("OnSelectionEvent begin"); - std::string type = "selectionEvent"; - - if (selectionData.empty()) { - SELECTION_HILOGE("selectionData is empty"); - return 1; - } - - auto entry = GetEntry(type, [&selectionData](SelectionEntry &entry) { entry.text = selectionData; }); - if (entry == nullptr) { - SELECTION_HILOGE("failed to get uv entry!"); - return 1; - } - - auto eventHandler = GetEventHandler(); - if (eventHandler == nullptr) { - SELECTION_HILOGE("eventHandler is nullptr!"); - return 1; - } - - SELECTION_HILOGI("selectionData is [%{public}s]", selectionData.c_str()); - - - auto task = [entry]() { - auto getTextChangeProperty = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { - if (argc == 0) { - return false; - } - // 0 means the first param of callback. - napi_create_string_utf8(env, entry->text.c_str(), NAPI_AUTO_LENGTH, &args[0]); - return true; - }; - // 1 means callback has one param. - JsCallbackHandler::Traverse(entry->vecCopy, { 1, getTextChangeProperty }); - }; - eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); - - SELECTION_HILOGI("OnSelectionEvent end"); - return 0; -} +} \ No newline at end of file -- Gitee From ae438ae1b835fed809ab29d467c905ba06b5de97 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Fri, 23 May 2025 11:42:40 +0800 Subject: [PATCH 26/93] =?UTF-8?q?=E6=BB=91=E8=AF=8D=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8F=8C=E5=87=BB=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/include/selection_service.h | 17 ++-- service/src/selection_service.cpp | 151 +++++++++++++++++++++------- 2 files changed, 123 insertions(+), 45 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index e650201..f9360a7 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -33,7 +33,7 @@ constexpr const char *SYS_SELECTION_SWITCH_USERNAM = "persist.sys.selection.swit constexpr const char *SYS_SELECTION_TRIGGER_USERNAM = "persist.sys.selection.trigger.username"; constexpr const char *SYS_SELECTION_APP_USERNAM = "persist.sys.selection.app.username"; constexpr const char *SYS_SELECTION_TRIGGER_VAL = "ctrl"; -constexpr const uint32_t DOUBLE_CLICK_TIME = 400; +constexpr const uint32_t DOUBLE_CLICK_TIME = 500; typedef enum { SELECT_INPUT_INITIAL = 0, @@ -43,16 +43,15 @@ typedef enum { SELECT_INPUT_WAIT_DOUBLE_CLICK = 4, SELECT_INPUT_WAIT_TRIBLE_CLICK = 5, SELECT_INPUT_DOUBLE_CLICKED = 6, - + SELECT_INPUT_TRIPLE_CLICKED = 7, } SelectInputState; typedef enum { SUB_INITIAL = 0, - SUB_WAIT_PRESS_DOWN = 1, - SUB_WAIT_PRESS_MOVE = 2, - SUB_WAIT_PRESS_UP = 3, - SUB_WAIT_CTRL_DOWN = 4, - SUB_WAIT_CTRL_UP = 5, + SUB_WAIT_POINTER_ACTION_BUTTON_DOWN = 1, + SUB_WAIT_POINTER_ACTION_BUTTON_UP = 2, + SUB_WAIT_KEY_CTRL_DOWN = 3, + SUB_WAIT_KEY_CTRL_UP = 4, } SelectInputSubState; class SelectionService : public SystemAbility, public SelectionServiceStub { @@ -101,8 +100,12 @@ private: void InputWordBeginProcess(std::shared_ptr pointerEvent) const; void InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const; void InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const; + void InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const; + void InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const; void FinishedWordSelection() const; void InjectCtrlC() const; + void ResetProcess(std::shared_ptr pointerEvent) const; + void JudgeTripleClick() const; static uint32_t curSelectState; static uint32_t subSelectState; static int64_t lastClickTime; diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 008121c..f9d74ce 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -281,7 +281,7 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con return; } - if (subSelectState != SUB_WAIT_CTRL_DOWN && subSelectState != SUB_WAIT_CTRL_UP) { + if (subSelectState != SUB_WAIT_KEY_CTRL_DOWN && subSelectState != SUB_WAIT_KEY_CTRL_UP) { return; } @@ -294,17 +294,19 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con return; } SELECTION_HILOGI("[SelectionService] Processed ctrl key."); - if (subSelectState == SUB_WAIT_CTRL_DOWN && action == KeyEvent::KEY_ACTION_DOWN) { - subSelectState = SUB_WAIT_CTRL_UP; + if (subSelectState == SUB_WAIT_KEY_CTRL_DOWN && action == KeyEvent::KEY_ACTION_DOWN) { + subSelectState = SUB_WAIT_KEY_CTRL_UP; return; - } else if (subSelectState == SUB_WAIT_CTRL_UP && action == KeyEvent::KEY_ACTION_UP) { + } else if (subSelectState == SUB_WAIT_KEY_CTRL_UP && action == KeyEvent::KEY_ACTION_UP) { if (curSelectState == SELECT_INPUT_WAIT_LEFT_MOVE) { curSelectState = SELECT_INPUT_LEFT_MOVE; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); - } - if (curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK) { + } else if (curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK) { curSelectState = SELECT_INPUT_DOUBLE_CLICKED; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); + } else if (curSelectState == SELECT_INPUT_WAIT_TRIBLE_CLICK) { + curSelectState = SELECT_INPUT_TRIPLE_CLICKED; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); } subSelectState = SUB_INITIAL; } else { @@ -316,6 +318,13 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con return; } + void SelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const + { + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + OnInputEvent(pointerEvent); + } + void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { SELECTION_HILOGD("[SelectionService] into PointerEvent"); @@ -326,15 +335,6 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { return; } - if ((subSelectState == SUB_WAIT_CTRL_DOWN || subSelectState == SUB_WAIT_CTRL_UP) - && (action != PointerEvent::POINTER_ACTION_MOVE)) { - SELECTION_HILOGI("[SelectionService] pointerEvent: curSelectState == SELECT_INPUT_WAIT_CTRL. return."); - SELECTION_HILOGI("[SelectionService] pointerEvent: %{public}d", action); - SELECTION_HILOGI("[SelectionService] pointerId: %{public}d", pointerId); - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - return; - } SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); switch (curSelectState) @@ -350,10 +350,19 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv case SELECT_INPUT_WAIT_LEFT_MOVE: InputWordWaitLeftMoveProcess(pointerEvent); break; + case SELECT_INPUT_WAIT_DOUBLE_CLICK: InputWordWaitDoubleClickProcess(pointerEvent); break; + case SELECT_INPUT_DOUBLE_CLICKED: + InputWordJudgeTripleClickProcess(pointerEvent); + break; + + case SELECT_INPUT_WAIT_TRIBLE_CLICK: + InputWordWaitTripleClickProcess(pointerEvent); + break; + default: break; } @@ -386,11 +395,11 @@ void SelectionInputMonitor::InputWordBeginProcess(std::shared_ptr int32_t action = pointerEvent->GetPointerAction(); if (action == PointerEvent::POINTER_ACTION_MOVE) { curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; - subSelectState = SUB_WAIT_PRESS_UP; + subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); } else if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { curSelectState = SELECT_INPUT_WAIT_DOUBLE_CLICK; - subSelectState = SUB_WAIT_PRESS_DOWN; + subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_DOWN; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_DOUBLE_CLICK."); } return; @@ -401,16 +410,34 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptrGetPointerAction(); if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_CTRL_DOWN; - SELECTION_HILOGI("set subSelectState to SUB_WAIT_CTRL_DOWN."); + subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); } else { curSelectState = SELECT_INPUT_LEFT_MOVE; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_LEFT_MOVE."); } + } else if (action != PointerEvent::POINTER_ACTION_MOVE) { + SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); + ResetProcess(pointerEvent); } return; } +void SelectionInputMonitor::JudgeTripleClick() const +{ + auto curTime = GetCurrentTimeMillis(); + if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { + curSelectState = SELECT_INPUT_WAIT_TRIBLE_CLICK; + subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_TRIBLE_CLICK."); + } else { + curSelectState = SELECT_INPUT_WORD_BEGIN; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); + } + lastClickTime = curTime; +} + void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); @@ -421,45 +448,93 @@ void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (subSelectState == SUB_INITIAL && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + SELECTION_HILOGI("Begin JudgeTripleClick."); + JudgeTripleClick(); + } else { + SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); + ResetProcess(pointerEvent); + } +} + +void SelectionInputMonitor::InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + int32_t buttonId = pointerEvent->GetButtonId(); + if (buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL."); + return; + } + if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_UP) { + if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + if (ctrlSelectFlag) { + subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); + } else { + curSelectState = SELECT_INPUT_TRIPLE_CLICKED; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_TRIPLE_CLICKED."); + } + } else if (action != PointerEvent::POINTER_ACTION_MOVE) { + SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); + ResetProcess(pointerEvent); + } + return; + } +} + void SelectionInputMonitor::FinishedWordSelection() const { - if (curSelectState == SELECT_INPUT_LEFT_MOVE || curSelectState == SELECT_INPUT_DOUBLE_CLICKED) { + if (curSelectState == SELECT_INPUT_LEFT_MOVE || curSelectState == SELECT_INPUT_DOUBLE_CLICKED || + curSelectState == SELECT_INPUT_TRIPLE_CLICKED) { // world selection action SELECTION_HILOGI("[SelectionService] first, end word selection action."); InjectCtrlC(); SELECTION_HILOGI("[SelectionService] first, end inject ctrl + c."); - curSelectState = SELECT_INPUT_INITIAL; + if (curSelectState != SELECT_INPUT_DOUBLE_CLICKED) { + curSelectState = SELECT_INPUT_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); + } } return; } -- Gitee From 7c1e19c6d9c996478fc49c48aca0d5cc37a68fe6 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Fri, 23 May 2025 14:14:33 +0800 Subject: [PATCH 27/93] =?UTF-8?q?=E5=AE=8C=E5=96=84On=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- service/include/selection_service.h | 3 +++ service/src/selection_service.cpp | 35 ++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index f9360a7..eee06f6 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -69,6 +69,7 @@ public: int32_t Dump(int32_t fd, const std::vector &args) override; int32_t StartNewAbility(const std::string& bundleName, const std::string& abilityName); void StopCurrentAbility(); + sptr GetListener(); protected: void OnStart() override; void OnStop() override; @@ -85,6 +86,8 @@ private: std::string currentAbilityName_ = ""; static sptr instance_; static std::shared_mutex adminLock_; + mutable std::mutex mutex_; + sptr listenerStub_ { nullptr }; }; class SelectionInputMonitor : public IInputEventConsumer { diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index f9d74ce..b3da23e 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -77,15 +77,31 @@ ErrCode SelectionService::UnregisterListener(const sptr &listener return 0; } +sptr SelectionService::GetListenerStub() const { + std::lock_guard lock(mutex_); + return listenerStub_; +} + ErrCode SelectionService::RegisterListener(const sptr &listener) { - SELECTION_HILOGI("Begin to call SA RegisterListener"); - auto proxy = iface_cast(listener); - if (proxy == nullptr) { - SELECTION_HILOGE("RegisterListener: listener is nullptr"); - return -1; + SELECTION_HILOGD("Begin to call SA RegisterListener"); + if (listener == nullptr) { + SELECTION_HILOGE("RegisterListener: Input listener is nullptr."); + return 1; } - proxy->OnSelectionChange("HELLO FANZHE"); + + auto listenerStub = iface_cast(listener); + if (listenerStub == nullptr) { + SELECTION_HILOGE("RegisterListener: Failed to cast listener to ISelectionListener."); + return 1; + } + + if (listenerStub_ && listenerStub_ == listenerStub) { + SELECTION_HILOGW("RegisterListener: Listener already registered."); + return 0; + } + + listenerStub_ = listenerStub; return 0; } @@ -535,6 +551,13 @@ void SelectionInputMonitor::FinishedWordSelection() const curSelectState = SELECT_INPUT_INITIAL; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); } + + // send selection data + sptr listener = SelectionService::GetInstance().GetListenerStub(); + if (listener == nullptr) { + SELECTION_HILOGE("get listener is null") + } + listener->OnSelectionChange("HELLO FANZHE"); } return; } -- Gitee From 74dbcb4a996637a1da0deaec75ffd7e91783212b Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Fri, 23 May 2025 11:42:40 +0800 Subject: [PATCH 28/93] =?UTF-8?q?=E6=BB=91=E8=AF=8D=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8F=8C=E5=87=BB=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/src/selection_service.cpp | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index b3da23e..ef91720 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -457,13 +457,6 @@ void SelectionInputMonitor::JudgeTripleClick() const void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - int32_t buttonId = pointerEvent->GetButtonId(); - if (buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL."); - return; - } if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { auto curTime = GetCurrentTimeMillis(); if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { @@ -514,13 +507,6 @@ void SelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - int32_t buttonId = pointerEvent->GetButtonId(); - if (buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL."); - return; - } if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_UP) { if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { if (ctrlSelectFlag) { @@ -531,7 +517,10 @@ void SelectionInputMonitor::InputWordWaitTripleClickProcess(std::shared_ptr Date: Mon, 26 May 2025 09:05:09 +0800 Subject: [PATCH 29/93] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- service/src/selection_service.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index ef91720..c177b15 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -77,7 +77,7 @@ ErrCode SelectionService::UnregisterListener(const sptr &listener return 0; } -sptr SelectionService::GetListenerStub() const { +sptr SelectionService::GetListener() { std::lock_guard lock(mutex_); return listenerStub_; } @@ -542,9 +542,9 @@ void SelectionInputMonitor::FinishedWordSelection() const } // send selection data - sptr listener = SelectionService::GetInstance().GetListenerStub(); + sptr listener = SelectionService::GetInstance()->GetListener(); if (listener == nullptr) { - SELECTION_HILOGE("get listener is null") + SELECTION_HILOGE("get listener is null"); } listener->OnSelectionChange("HELLO FANZHE"); } -- Gitee From 0d89ae896b5b4e04d155d4796bbe98e1c2d2928d Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Mon, 26 May 2025 09:26:15 +0800 Subject: [PATCH 30/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0OnConnect=E3=80=81OnDis?= =?UTF-8?q?connect?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../src/js_selection_extension.cpp | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index 437a629..af0efe2 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -18,6 +18,7 @@ #include "js_runtime_utils.h" #include "napi/native_api.h" #include "napi_common_want.h" +#include "napi_remote_object.h" namespace OHOS::AbilityRuntime { namespace { @@ -40,7 +41,7 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor std::shared_ptr& handler, const sptr& token) { - HILOG_INFO("JsSelectionExtension Init begin."); + HILOG_INFO("%{public}s start.", __func__); SelectionExtension::Init(record, application, handler, token); std::string srcPath; GetSrcPath(srcPath); @@ -60,12 +61,12 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor return; } BindContext(); - HILOG_INFO("JsSelectionExtension Init end."); + HILOG_INFO("%{public}s end.", __func__); } void JsSelectionExtension::OnStart(const AAFwk::Want& want) { - HILOG_INFO("JsSelectionExtension OnStart begin."); + HILOG_INFO("%{public}s start.", __func__); Extension::OnStart(want); napi_env env = jsRuntime_.GetNapiEnv(); napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); @@ -76,12 +77,32 @@ void JsSelectionExtension::OnStart(const AAFwk::Want& want) sptr JsSelectionExtension::OnConnect(const AAFwk::Want& want) { - HILOG_INFO("JsSelectionExtension OnConnect begin."); + HILOG_INFO("%{public}s start.", __func__); + HandleScope handleScope(jsRuntime_); Extension::OnConnect(want); - return nullptr; + napi_env env = jsRuntime_.GetNapiEnv(); + napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); + napi_value argv[] = {napiWant}; + napi_value result = CallObjectMethod("onConnect", argv, ARGC_ONE); + auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, result); + if (remoteObj == nullptr) { + HILOG_ERROR("remoteObj nullptr."); + } + HILOG_INFO("%{public}s end.", __func__); + return remoteObj; } -void JsSelectionExtension::OnDisconnect(const AAFwk::Want& want) {} +void JsSelectionExtension::OnDisconnect(const AAFwk::Want& want) +{ + HILOG_INFO("%{public}s start.", __func__); + HandleScope handleScope(jsRuntime_); + Extension::OnDisconnect(want); + napi_env env = jsRuntime_.GetNapiEnv(); + napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); + napi_value argv[] = {napiWant}; + CallObjectMethod("onDisconnect", argv, ARGC_ONE); + HILOG_INFO("%{public}s end.", __func__); +} void JsSelectionExtension::OnStop() {} @@ -94,7 +115,6 @@ napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const return nullptr; } - HandleScope handleScope(jsRuntime_); napi_env env = jsRuntime_.GetNapiEnv(); napi_value obj = jsObj_->GetNapiValue(); if (obj == nullptr) { @@ -108,11 +128,12 @@ napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const HILOG_ERROR("failed to get '%{public}s' from JsSelectionExtension object!", methodName); return nullptr; } - HILOG_INFO("JsSelectionExtension::CallFunction(%{public}s), success.", methodName); napi_value result = nullptr; if (napi_call_function(env, obj, method, argc, argv, &result) != napi_ok) { + HILOG_ERROR("JsSelectionExtension::CallFunction(%{public}s), failed.", methodName); return nullptr; } + HILOG_INFO("JsSelectionExtension::CallFunction(%{public}s), success.", methodName); return result; } -- Gitee From d66cb340760c13638830f09d857f5227ed27bdb0 Mon Sep 17 00:00:00 2001 From: xying6 Date: Mon, 26 May 2025 09:59:47 +0800 Subject: [PATCH 31/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=9F=E5=91=BD?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- etc/para/selection.para | 2 +- service/include/selection_service.h | 20 +++++++++--- service/src/selection_service.cpp | 47 ++++++++++++++++------------- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/etc/para/selection.para b/etc/para/selection.para index 7eb6fb9..34d5bc9 100644 --- a/etc/para/selection.para +++ b/etc/para/selection.para @@ -13,4 +13,4 @@ persist.sys.selection.switch.username = off persist.sys.selection.trigger.username = ctrl -persist.sys.selection.app.username = com.hm.youdao +persist.sys.selection.app.username = com.hm.youdao/ExtensionAbility diff --git a/service/include/selection_service.h b/service/include/selection_service.h index eee06f6..2f1367e 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -19,6 +19,7 @@ #include #include +#include "ability_connect_callback_stub.h" #include "callback_object.h" #include "iselection_listener.h" #include "selection_service_stub.h" @@ -54,6 +55,17 @@ typedef enum { SUB_WAIT_KEY_CTRL_UP = 4, } SelectInputSubState; +class SelectionExtensionAbilityConnection : public OHOS::AAFwk::AbilityConnectionStub { +public: + SelectionExtensionAbilityConnection() = default; + ~SelectionExtensionAbilityConnection() = default; + void OnAbilityConnectDone( + const OHOS::AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override; + void OnAbilityDisconnectDone(const OHOS::AppExecFwk::ElementName &element, int resultCode) override; +private: + sptr remoteObject_; +}; + class SelectionService : public SystemAbility, public SelectionServiceStub { DECLARE_SYSTEM_ABILITY(SelectionService); @@ -67,8 +79,8 @@ public: ErrCode RegisterListener(const sptr &listener) override; ErrCode UnregisterListener(const sptr &listener) override; int32_t Dump(int32_t fd, const std::vector &args) override; - int32_t StartNewAbility(const std::string& bundleName, const std::string& abilityName); - void StopCurrentAbility(); + int32_t ConnectNewExtAbility(const std::string& bundleName, const std::string& abilityName); + void DisconnectCurrentExtAbility(); sptr GetListener(); protected: void OnStart() override; @@ -81,13 +93,11 @@ private: void WatchParams(); int32_t inputMonitorId_ {-1}; - std::mutex abilityMutex_; - std::string currentBundleName_ = ""; - std::string currentAbilityName_ = ""; static sptr instance_; static std::shared_mutex adminLock_; mutable std::mutex mutex_; sptr listenerStub_ { nullptr }; + sptr connectInner_ {nullptr}; }; class SelectionInputMonitor : public IInputEventConsumer { diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index c177b15..02ab015 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -27,6 +27,7 @@ using namespace OHOS; using namespace OHOS::SelectionFwk; +using namespace OHOS::AppExecFwk; using namespace OHOS::MMI; using namespace OHOS::EventFwk; @@ -39,6 +40,19 @@ uint32_t SelectionInputMonitor::subSelectState = SUB_INITIAL; int64_t SelectionInputMonitor::lastClickTime = 0; bool SelectionInputMonitor::ctrlSelectFlag = false; +void SelectionExtensionAbilityConnection::OnAbilityConnectDone( + const ElementName &element, const sptr &remoteObject, int resultCode) +{ + SELECTION_HILOGI("OnAbilityConnectDone, bundle = %{public}s, ability = %{public}s, resultCode = %{public}d", + element.GetBundleName().c_str(), element.GetAbilityName().c_str(), resultCode); +} +void SelectionExtensionAbilityConnection::OnAbilityDisconnectDone(const ElementName &element, int resultCode) +{ + SELECTION_HILOGI("OnAbilityDisconnectDone, bundle = %{public}s,ability = %{public}s, resultCode = %{public}d", + element.GetBundleName().c_str(), element.GetAbilityName().c_str(), resultCode); + remoteObject_ = nullptr; +} + sptr SelectionService::GetInstance() { if (instance_ == nullptr) { @@ -139,43 +153,34 @@ static void WatchTriggerMode(const char *key, const char *value, void *context) } } -void SelectionService::StopCurrentAbility() +void SelectionService::DisconnectCurrentExtAbility() { - std::lock_guard lock(abilityMutex_); - if (currentBundleName_.empty() || currentAbilityName_.empty()) { - SELECTION_HILOGD("No ability running"); + SELECTION_HILOGD("Disconnect current extensionAbility"); + if (connectInner_ == nullptr) { + SELECTION_HILOGE("connectInner_ is null"); return; } - SELECTION_HILOGD("Stop current ability: %{public}s/%{public}s", currentBundleName_.c_str(), - currentAbilityName_.c_str()); - AAFwk::Want want; - want.SetElementName(currentBundleName_, currentAbilityName_); - int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->StopExtensionAbility(want, nullptr); + int32_t ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(connectInner_); if (ret != ERR_OK) { - SELECTION_HILOGE("StopServiceAbility failed, ret: %{public}d", ret); + SELECTION_HILOGE("DisconnectServiceAbility failed, ret: %{public}d", ret); return; } - - currentBundleName_.clear(); - currentAbilityName_.clear(); } -int32_t SelectionService::StartNewAbility( const std::string& bundleName, const std::string& abilityName) +int32_t SelectionService::ConnectNewExtAbility( const std::string& bundleName, const std::string& abilityName) { SELECTION_HILOGD("Start new SelectionExtension, bundleName:%{public}s, abilityName:%{public}s", bundleName.c_str(), abilityName.c_str()); AAFwk::Want want; want.SetElementName(bundleName, abilityName); + connectInner_ = new(std::nothrow) SelectionExtensionAbilityConnection(); - auto ret = AAFwk::AbilityManagerClient::GetInstance()->StartExtensionAbility(want, nullptr); + auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, connectInner_, -1); if (ret != 0) { SELECTION_HILOGE("StartExtensionAbility failed %{public}d", ret); return ret; } - - currentBundleName_ = bundleName; - currentAbilityName_ = abilityName; SELECTION_HILOGD("StartExtensionAbility success"); return 0; } @@ -199,8 +204,8 @@ static void WatchAppSwitch(const char *key, const char *value, void *context) const std::string bundleName = appInfo.substr(0, pos); const std::string extName = appInfo.substr(pos + 1); SELECTION_HILOGD("bundleName: %{public}s, extName: %{public}s", bundleName.c_str(), extName.c_str()); - selectionService->StopCurrentAbility(); - auto ret = selectionService->StartNewAbility(bundleName, extName); + selectionService->DisconnectCurrentExtAbility(); + auto ret = selectionService->ConnectNewExtAbility(bundleName, extName); SELECTION_HILOGD("StartExtensionAbility ret = %{public}d", ret); } @@ -623,4 +628,4 @@ void SelectionInputMonitor::InjectCtrlC() const keyUpEvent->RemoveReleasedKeyItems(upItem[i]); } InputManager::GetInstance()->SimulateInputEvent(keyUpEvent); -} \ No newline at end of file +} -- Gitee From a117e3ac0bef372295dbe684267621df343c1cc3 Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Mon, 26 May 2025 12:01:09 +0800 Subject: [PATCH 32/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9extension=20type?= =?UTF-8?q?=E5=80=BC=E4=B8=BA46?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../src/selection_extension_module_loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp index 0233a59..c60c1cd 100644 --- a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp @@ -29,7 +29,7 @@ Extension* SelectionExtensionModuleLoader::Create(const std::unique_ptr std::map SelectionExtensionModuleLoader::GetParams() { // type means extension type in ExtensionAbilityType of extension_ability_info.h - return {{"type", "29"}, {"name", "SelectionExtensionAbility"}}; + return {{"type", "46"}, {"name", "SelectionExtensionAbility"}}; } extern "C" __attribute__((visibility("default"))) void* OHOS_EXTENSION_GetExtensionModule() -- Gitee From 082e6512ab90aaf9dabaac7ff1d1812ce7da741e Mon Sep 17 00:00:00 2001 From: fanzhe Date: Mon, 26 May 2025 14:56:31 +0800 Subject: [PATCH 33/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9C=8D=E5=8A=A1Publi?= =?UTF-8?q?sh=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- service/src/selection_service.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 02ab015..1e0e6e4 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -221,7 +221,7 @@ void SelectionService::WatchParams() void SelectionService::OnStart() { SELECTION_HILOGI("[SelectionService][OnStart]begin"); - Publish(this); + Publish(SelectionService::GetInstance()); InputMonitorInit(); WatchParams(); SELECTION_HILOGI("[SelectionService][OnStart]end"); @@ -550,6 +550,7 @@ void SelectionInputMonitor::FinishedWordSelection() const sptr listener = SelectionService::GetInstance()->GetListener(); if (listener == nullptr) { SELECTION_HILOGE("get listener is null"); + return; } listener->OnSelectionChange("HELLO FANZHE"); } -- Gitee From f1241a4972b63af0bdc12d5bbf91d649f7929443 Mon Sep 17 00:00:00 2001 From: lixiaojuan Date: Mon, 26 May 2025 19:52:52 +0800 Subject: [PATCH 34/93] =?UTF-8?q?off=20selectionEvent=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../selection_ability/js_selection_engine_setting.cpp | 8 ++++++++ service/src/selection_service.cpp | 1 + 2 files changed, 9 insertions(+) diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 551026d..75c3ffc 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -178,6 +178,14 @@ void JsSelectionEngineSetting::UnRegisterListener(napi_value callback, std::stri if (jsCbMap_[type].empty()) { jsCbMap_.erase(type); } + + auto proxy = GetSelectionSystemAbility(); + if (proxy == nullptr || listenerStub_ == nullptr) { + SELECTION_HILOGE("selection system ability or listenerStub_ is nullptr!"); + return; + } + proxy->UnregisterListener(listenerStub_->AsObject()); + listenerStub_ = nullptr; } napi_value JsSelectionEngineSetting::GetSEInstance(napi_env env, napi_callback_info info) diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 1e0e6e4..e650203 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -88,6 +88,7 @@ ErrCode SelectionService::AddVolume(int32_t volume, int32_t& funcResult) ErrCode SelectionService::UnregisterListener(const sptr &listener) { + listenerStub_ = nullptr; return 0; } -- Gitee From 3f9ad50aedf0ba70b55c475a71c62bea4c2e92f3 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Tue, 27 May 2025 15:02:27 +0800 Subject: [PATCH 35/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0selection=20context?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 1 + .../napi/selection_extension_context/BUILD.gn | 61 ++++++++ .../selection_extension_context.js | 29 ++++ .../selection_extension_context_module.cpp | 55 ++++++++ .../native/selection_extension/BUILD.gn | 7 +- .../include/js_selection_extension.h | 3 +- .../include/js_selection_extension_context.h | 27 ++++ .../include/selection_extension_context.h | 28 ++++ .../include/selection_extension_hilog.h | 66 +++++++++ .../src/js_selection_extension.cpp | 98 ++++++++++++- .../src/js_selection_extension_context.cpp | 131 ++++++++++++++++++ .../src/selection_extension.cpp | 2 + .../src/selection_extension_context.cpp | 29 +++- 13 files changed, 528 insertions(+), 9 deletions(-) create mode 100644 frameworks/js/napi/selection_extension_context/BUILD.gn create mode 100644 frameworks/js/napi/selection_extension_context/selection_extension_context.js create mode 100644 frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp create mode 100644 frameworks/native/selection_extension/include/js_selection_extension_context.h create mode 100644 frameworks/native/selection_extension/include/selection_extension_hilog.h create mode 100644 frameworks/native/selection_extension/src/js_selection_extension_context.cpp diff --git a/bundle.json b/bundle.json index e3b8500..55c0b61 100644 --- a/bundle.json +++ b/bundle.json @@ -46,6 +46,7 @@ "//foundation/systemabilitymgr/selection_fwk/service:selection_service", "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile", "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", + "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_context:selectionextensioncontext_napi", "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native", "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionengine_napi", "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_ability:selection_ability" diff --git a/frameworks/js/napi/selection_extension_context/BUILD.gn b/frameworks/js/napi/selection_extension_context/BUILD.gn new file mode 100644 index 0000000..bbb99c2 --- /dev/null +++ b/frameworks/js/napi/selection_extension_context/BUILD.gn @@ -0,0 +1,61 @@ +# 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/config/components/ets_frontend/es2abc_config.gni") + +import("//build/ohos.gni") + +es2abc_gen_abc("gen_selection_extension_context_abc") { + src_js = rebase_path("selection_extension_context.js") + dst_file = rebase_path(target_out_dir + "/selection_extension_context.abc") + in_puts = [ "selection_extension_context.js" ] + out_puts = [ target_out_dir + "/selection_extension_context.abc" ] + extra_args = [ "--module" ] +} + +gen_js_obj("selection_extension_context_js") { + input = "selection_extension_context.js" + output = target_out_dir + "/selection_extension_context.o" +} + +gen_js_obj("selection_extension_context_abc") { + input = + get_label_info(":gen_selection_extension_context_abc", + "target_out_dir") + "/selection_extension_context.abc" + output = target_out_dir + "/selection_extension_context_abc.o" + dep = ":gen_selection_extension_context_abc" +} + +ohos_shared_library("selectionextensioncontext_napi") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + sources = [ "selection_extension_context_module.cpp" ] + + deps = [ + ":selection_extension_context_abc", + ":selection_extension_context_js", + ] + + external_deps = [ "napi:ace_napi" ] + + relative_install_dir = "module" + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/frameworks/js/napi/selection_extension_context/selection_extension_context.js b/frameworks/js/napi/selection_extension_context/selection_extension_context.js new file mode 100644 index 0000000..2d65b3a --- /dev/null +++ b/frameworks/js/napi/selection_extension_context/selection_extension_context.js @@ -0,0 +1,29 @@ +/* + * 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. + */ + +const ExtensionContext = requireNapi('application.ExtensionContext'); + +class SelectionExtensionContext extends ExtensionContext { + constructor(obj) { + super(obj); + this.extensionAbilityInfo = obj.extensionAbilityInfo; + } + + startAbility(want) { + return this.__context_impl__.startAbility(want); + } +} + +export default SelectionExtensionContext; \ No newline at end of file diff --git a/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp b/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp new file mode 100644 index 0000000..9db1fa9 --- /dev/null +++ b/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp @@ -0,0 +1,55 @@ +/* + * 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 "native_engine/native_engine.h" + +extern const char _binary_selection_extension_context_js_start[]; +extern const char _binary_selection_extension_context_js_end[]; +extern const char _binary_selection_extension_context_abc_start[]; +extern const char _binary_selection_extension_context_abc_end[]; + +static napi_module g_ExtensionContextModule = { + .nm_version = 0, + .nm_filename = "libselectionextensioncontext_napi.so/selection_extension_context.js", + .nm_modname = "SelectionExtensionContext", +}; + +extern "C" __attribute__((constructor)) void NAPI_SelectionExtensionContext_AutoRegister() +{ + napi_module_register(&g_ExtensionContextModule); +} + +extern "C" __attribute__((visibility("default"))) void NAPI_SelectionExtensionContext_GetJSCode( + const char **buf, int *bufLen) +{ + if (buf != nullptr) { + *buf = _binary_selection_extension_context_js_start; + } + if (bufLen != nullptr) { + *bufLen = _binary_selection_extension_context_js_end - _binary_selection_extension_context_js_start; + } +} + +// ability_context JS register +extern "C" __attribute__((visibility("default"))) void NAPI_SelectionExtensionContext_GetABCCode( + const char **buf, int *buflen) +{ + if (buf != nullptr) { + *buf = _binary_selection_extension_context_abc_start; + } + if (buflen != nullptr) { + *buflen = _binary_selection_extension_context_abc_end - _binary_selection_extension_context_abc_start; + } +} diff --git a/frameworks/native/selection_extension/BUILD.gn b/frameworks/native/selection_extension/BUILD.gn index 140c15e..35fa0f5 100644 --- a/frameworks/native/selection_extension/BUILD.gn +++ b/frameworks/native/selection_extension/BUILD.gn @@ -32,7 +32,8 @@ ohos_shared_library("selection_extension_ability_native") { ] include_dirs = [ - "include" + "include", + "${selection_fwk_root_path}/utils/include", ] sources = [ @@ -40,11 +41,12 @@ ohos_shared_library("selection_extension_ability_native") { "src/selection_extension_context.cpp", "src/selection_extension_module_loader.cpp", "src/js_selection_extension.cpp", + "src/js_selection_extension_context.cpp", ] deps = [ - + "${selection_fwk_root_path}/common:selection_common" ] external_deps = [ @@ -52,6 +54,7 @@ ohos_shared_library("selection_extension_ability_native") { "ability_runtime:ability_connect_callback_stub", "ability_runtime:ability_context_native", "ability_runtime:ability_manager", + "ability_runtime:ability_start_options", "ability_runtime:abilitykit_native", "ability_runtime:app_context", "ability_runtime:extensionkit_native", diff --git a/frameworks/native/selection_extension/include/js_selection_extension.h b/frameworks/native/selection_extension/include/js_selection_extension.h index cba8c63..932e11c 100644 --- a/frameworks/native/selection_extension/include/js_selection_extension.h +++ b/frameworks/native/selection_extension/include/js_selection_extension.h @@ -82,12 +82,11 @@ public: private: napi_value CallObjectMethod(const char* methodName, const napi_value* argv = nullptr, size_t argc = 0); void GetSrcPath(std::string& srcPath); - void BindContext(); + void BindContext(napi_env env, napi_value obj); private: JsRuntime& jsRuntime_; std::unique_ptr jsObj_; - std::shared_ptr shellContextRef_ = nullptr; }; } // namespace OHOS::AbilityRuntime diff --git a/frameworks/native/selection_extension/include/js_selection_extension_context.h b/frameworks/native/selection_extension/include/js_selection_extension_context.h new file mode 100644 index 0000000..c79ee90 --- /dev/null +++ b/frameworks/native/selection_extension/include/js_selection_extension_context.h @@ -0,0 +1,27 @@ +/* + * 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 JS_SELECTION_EXTENSION_CONTEXT_H +#define JS_SELECTION_EXTENSION_CONTEXT_H + +#include +#include "native_engine/native_engine.h" +#include "selection_extension_context.h" + +namespace OHOS::AbilityRuntime { +napi_value CreateJsSelectionExtensionContext(napi_env env, std::shared_ptr context); +} + +#endif // JS_SELECTION_EXTENSION_CONTEXT_H diff --git a/frameworks/native/selection_extension/include/selection_extension_context.h b/frameworks/native/selection_extension/include/selection_extension_context.h index 3299c1a..80ab383 100644 --- a/frameworks/native/selection_extension/include/selection_extension_context.h +++ b/frameworks/native/selection_extension/include/selection_extension_context.h @@ -17,6 +17,7 @@ #define SELECTION_EXTENSION_CONTEXT_H #include "extension_context.h" +#include "start_options.h" #include "want.h" namespace OHOS::AbilityRuntime { @@ -24,6 +25,33 @@ class SelectionExtensionContext : public ExtensionContext { public: SelectionExtensionContext() = default; virtual ~SelectionExtensionContext() = default; + + /** + * @brief Starts a new ability. + * An ability using the AbilityInfo.AbilityType.INPUTMETHOD or + * AbilityInfo.AbilityType.PAGE template uses this method to start a specific + * ability. The system locates the target ability from installed abilities + * based on the value of the want parameter and then starts it. You can + * specify the ability to start using the want parameter. + * + * @param want Indicates the Want containing information about the target + * ability to start. + * + * @return errCode ERR_OK on success, others on failure. + */ + ErrCode StartAbility(const AAFwk::Want& want) const; + ErrCode StartAbility(const AAFwk::Want& want, const AAFwk::StartOptions& startOptions) const; + + static const size_t CONTEXT_TYPE_ID; + +protected: + bool IsContext(size_t contextTypeId) override + { + return contextTypeId == CONTEXT_TYPE_ID || ExtensionContext::IsContext(contextTypeId); + } + +private: + static int ILLEGAL_REQUEST_CODE; }; } // namespace OHOS::AbilityRuntime #endif // SELECTION_EXTENSION_CONTEXT_H diff --git a/frameworks/native/selection_extension/include/selection_extension_hilog.h b/frameworks/native/selection_extension/include/selection_extension_hilog.h new file mode 100644 index 0000000..53952bb --- /dev/null +++ b/frameworks/native/selection_extension/include/selection_extension_hilog.h @@ -0,0 +1,66 @@ +/* + * 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 SELECTION_LOG_H +#define SELECTION_LOG_H +#include "hilog/log.h" + +#ifdef HILOG_FATAL +#undef HILOG_FATAL +#endif + +#ifdef HILOG_ERROR +#undef HILOG_ERROR +#endif + +#ifdef HILOG_WARN +#undef HILOG_WARN +#endif + +#ifdef HILOG_INFO +#undef HILOG_INFO +#endif + +#ifdef HILOG_DEBUG +#undef HILOG_DEBUG +#endif + +#ifndef SE_LOG_DOMAIN +#define SE_LOG_DOMAIN 0xD002902 +#endif + +#ifndef SE_LOG_TAG +#define SE_LOG_TAG "SELECTION_EXT" +#endif + +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#define HILOG_FATAL(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, SE_LOG_DOMAIN, SE_LOG_TAG, \ + "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_ERROR(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, SE_LOG_DOMAIN, SE_LOG_TAG, \ + "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_WARN(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, SE_LOG_DOMAIN, SE_LOG_TAG, \ + "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_INFO(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, SE_LOG_DOMAIN, SE_LOG_TAG, \ + "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_DEBUG(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, SE_LOG_DOMAIN, SE_LOG_TAG, \ + "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) + +#endif // SELECTION_LOG_H \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index af0efe2..a2eb2f2 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -16,15 +16,58 @@ #include "js_selection_extension.h" #include "js_runtime.h" #include "js_runtime_utils.h" +#include "js_selection_extension_context.h" #include "napi/native_api.h" #include "napi_common_want.h" #include "napi_remote_object.h" +#include "selection_extension_hilog.h" namespace OHOS::AbilityRuntime { namespace { constexpr size_t ARGC_ONE = 1; } +napi_value AttachSelectionExtensionContext(napi_env env, void* value, void*) +{ + HILOG_INFO("AttachSelectionExtensionContext start."); + if (value == nullptr) { + HILOG_WARN("parameter is invalid."); + return nullptr; + } + auto ptr = reinterpret_cast*>(value)->lock(); + if (ptr == nullptr) { + HILOG_WARN("context is invalid."); + return nullptr; + } + napi_value object = CreateJsSelectionExtensionContext(env, ptr); + auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "SelectionExtensionContext", &object, 1); + if (systemModule == nullptr) { + HILOG_ERROR("failed to load system module by engine!"); + return nullptr; + } + auto contextObj = systemModule->GetNapiValue(); + napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachSelectionExtensionContext, value, + nullptr); + auto workContext = new (std::nothrow) std::weak_ptr(ptr); + if (workContext == nullptr) { + HILOG_ERROR("workContext is nullptr!"); + return nullptr; + } + napi_status status = napi_wrap( + env, contextObj, workContext, + [](napi_env, void* data, void*) { + HILOG_INFO("finalizer for weak_ptr input method extension context is called."); + delete static_cast*>(data); + }, + nullptr, nullptr); + if (status != napi_ok) { + HILOG_ERROR("SelectionExtensionContext wrap failed: %{public}d!", status); + delete workContext; + return nullptr; + } + return object; +} + JsSelectionExtension::JsSelectionExtension(JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {} JsSelectionExtension::~JsSelectionExtension() { @@ -60,7 +103,14 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor HILOG_ERROR("failed to init jsObj_!"); return; } - BindContext(); + + napi_env env = jsRuntime_.GetNapiEnv(); + napi_value obj = jsObj_->GetNapiValue(); + if (obj == nullptr) { + HILOG_ERROR("failed to get JsSelectionExtension object!"); + return; + } + BindContext(env, obj); HILOG_INFO("%{public}s end.", __func__); } @@ -86,7 +136,7 @@ sptr JsSelectionExtension::OnConnect(const AAFwk::Want& want) napi_value result = CallObjectMethod("onConnect", argv, ARGC_ONE); auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, result); if (remoteObj == nullptr) { - HILOG_ERROR("remoteObj nullptr."); + HILOG_ERROR("remoteObj is nullptr."); } HILOG_INFO("%{public}s end.", __func__); return remoteObj; @@ -158,9 +208,49 @@ void JsSelectionExtension::GetSrcPath(std::string& srcPath) } } -void JsSelectionExtension::BindContext() +void JsSelectionExtension::BindContext(napi_env env, napi_value obj) { - // TODO: + HILOG_INFO("%{public}s start.", __func__); + auto context = GetContext(); + if (context == nullptr) { + HILOG_ERROR("failed to get context!"); + return; + } + HILOG_DEBUG("JsSelectionExtension::Init CreateJsSelectionExtensionContext."); + napi_value contextObj = CreateJsSelectionExtensionContext(env, context); + auto shellContextRef = jsRuntime_.LoadSystemModule("SelectionExtensionContext", &contextObj, ARGC_ONE); + if (shellContextRef == nullptr) { + HILOG_ERROR("shellContextRef is nullptr!"); + return; + } + contextObj = shellContextRef->GetNapiValue(); + if (contextObj == nullptr) { + HILOG_ERROR("failed to get input method extension native object!"); + return; + } + auto workContext = new (std::nothrow) std::weak_ptr(context); + if (workContext == nullptr) { + HILOG_ERROR("workContext is nullptr!"); + return; + } + napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachSelectionExtensionContext, + workContext, nullptr); + HILOG_DEBUG("JsSelectionExtension::Init Bind."); + context->Bind(jsRuntime_, shellContextRef.release()); + HILOG_DEBUG("JsSelectionExtension::SetProperty."); + napi_set_named_property(env, obj, "context", contextObj); + napi_status status = napi_wrap( + env, contextObj, workContext, + [](napi_env, void* data, void*) { + HILOG_INFO("Finalizer for weak_ptr input method extension context is called."); + delete static_cast*>(data); + }, + nullptr, nullptr); + if (status != napi_ok) { + HILOG_ERROR("SelectionExtensionContext wrap failed: %{public}d", status); + delete workContext; + } + HILOG_INFO("%{public}s end.", __func__); } } // namespace OHOS::AbilityRuntime \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp new file mode 100644 index 0000000..91caea8 --- /dev/null +++ b/frameworks/native/selection_extension/src/js_selection_extension_context.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 "js_selection_extension_context.h" + +#include "js_error_utils.h" +#include "js_extension_context.h" +#include "js_runtime.h" +#include "js_runtime_utils.h" +#include "js_utils.h" +#include "napi_common_start_options.h" +#include "napi_common_want.h" +#include "selection_extension_hilog.h" +#include "start_options.h" + +namespace OHOS::AbilityRuntime { +using namespace OHOS::SelectionFwk; +namespace { +constexpr int32_t INDEX_ZERO = 0; +constexpr int32_t INDEX_ONE = 1; +constexpr int32_t ERROR_CODE_ONE = 1; +constexpr size_t ARGC_ONE = 1; +constexpr size_t ARGC_TWO = 2; +constexpr size_t ARGC_THREE = 3; + +class JsSelectionExtensionContext final { +public: + explicit JsSelectionExtensionContext(const std::shared_ptr& context) : context_(context) + { + // HILOG_INFO(LOG_CORE, "JsSelectionExtensionContext::JsSelectionExtensionContext is called."); + } + JsSelectionExtensionContext() = default; + ~JsSelectionExtensionContext() = default; + + static void Finalizer(napi_env env, void* data, void* hint) + { + // HILOG_INFO("JsSelectionExtensionContext::Finalizer is called."); + std::unique_ptr(static_cast(data)); + } + + static napi_value StartAbility(napi_env env, napi_callback_info info) + { + GET_CB_INFO_AND_CALL(env, info, JsSelectionExtensionContext, OnStartAbility); + } + +private: + std::weak_ptr context_; + + napi_value OnStartAbility(napi_env env, size_t argc, napi_value* argv) + { + // HILOG_INFO("SelectionExtensionContext OnStartAbility."); + // only support one or two or three params + PARAM_CHECK_RETURN(env, argc == ARGC_ONE || argc == ARGC_TWO || argc == ARGC_THREE, + "number of param should in [1,3]", TYPE_NONE, CreateJsUndefined(env)); + PARAM_CHECK_RETURN(env, JsUtil::GetType(env, argv[0]) == napi_object, "param want type must be Want", TYPE_NONE, + JsUtil::Const::Null(env)); + decltype(argc) unwrapArgc = 0; + AAFwk::Want want; + OHOS::AppExecFwk::UnwrapWant(env, argv[INDEX_ZERO], want); + // HILOG_INFO("%{public}s bundleName: %{public}s abilityName: %{public}s.", __func__, want.GetBundle().c_str(), + // want.GetElement().GetAbilityName().c_str()); + unwrapArgc++; + AAFwk::StartOptions startOptions; + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[INDEX_ONE], &valueType); + if (argc > ARGC_ONE && valueType == napi_object) { + // HILOG_INFO("OnStartAbility start options is used."); + AppExecFwk::UnwrapStartOptions(env, argv[INDEX_ONE], startOptions); + unwrapArgc++; + } + napi_value lastParam = argc > unwrapArgc ? argv[unwrapArgc] : nullptr; + napi_value result = nullptr; + std::unique_ptr napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result); + auto asyncTask = [weak = context_, want, startOptions, unwrapArgc, env, task = napiAsyncTask.get()]() { + // HILOG_INFO("startAbility start."); + auto context = weak.lock(); + if (context == nullptr) { + // HILOG_WRAN("context is released."); + task->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "Context is released")); + delete task; + return; + } + ErrCode errcode = ERR_OK; + (unwrapArgc == 1) ? errcode = context->StartAbility(want) + : errcode = context->StartAbility(want, startOptions); + if (errcode == 0) { + task->Resolve(env, CreateJsUndefined(env)); + } else { + task->Reject(env, CreateJsErrorByNativeErr(env, errcode)); + } + delete task; + }; + if (napi_send_event(env, asyncTask, napi_eprio_high) != napi_status::napi_ok) { + napiAsyncTask->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "send event failed")); + } else { + napiAsyncTask.release(); + } + return result; + } +}; +} // namespace + +napi_value CreateJsSelectionExtensionContext(napi_env env, std::shared_ptr context) +{ + // HILOG_INFO(LOG_CORE, "CreateJsSelectionExtensionContext begin"); + std::shared_ptr abilityInfo = nullptr; + if (context) { + abilityInfo = context->GetAbilityInfo(); + } + + napi_value objValue = CreateJsExtensionContext(env, context, abilityInfo); + std::unique_ptr jsContext = std::make_unique(context); + napi_wrap(env, objValue, jsContext.release(), JsSelectionExtensionContext::Finalizer, nullptr, nullptr); + + const char* moduleName = "JsSelectionExtensionContext"; + BindNativeFunction(env, objValue, "StartAbility", moduleName, JsSelectionExtensionContext::StartAbility); + return objValue; +} +} // namespace OHOS::AbilityRuntime diff --git a/frameworks/native/selection_extension/src/selection_extension.cpp b/frameworks/native/selection_extension/src/selection_extension.cpp index 09ff3e0..d21eee8 100644 --- a/frameworks/native/selection_extension/src/selection_extension.cpp +++ b/frameworks/native/selection_extension/src/selection_extension.cpp @@ -16,6 +16,7 @@ #include "selection_extension.h" #include "js_selection_extension.h" #include "runtime.h" +#include "selection_extension_hilog.h" namespace OHOS::AbilityRuntime { using namespace OHOS::AppExecFwk; @@ -27,6 +28,7 @@ SelectionExtension* SelectionExtension::Create(const std::unique_ptr& r } switch (runtime->GetLanguage()) { case Runtime::Language::JS: + HILOG_INFO("Create JsSelectionExtension"); return JsSelectionExtension::Create(runtime); default: return new SelectionExtension(); diff --git a/frameworks/native/selection_extension/src/selection_extension_context.cpp b/frameworks/native/selection_extension/src/selection_extension_context.cpp index c584c14..d7f6c97 100644 --- a/frameworks/native/selection_extension/src/selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_context.cpp @@ -14,7 +14,34 @@ */ #include "selection_extension_context.h" +#include "ability_manager_client.h" +#include "selection_extension_hilog.h" namespace OHOS::AbilityRuntime { +const size_t SelectionExtensionContext::CONTEXT_TYPE_ID(std::hash {}("SelectionExtensionContext")); +int32_t SelectionExtensionContext::ILLEGAL_REQUEST_CODE(-1); -} \ No newline at end of file +ErrCode SelectionExtensionContext::StartAbility(const AAFwk::Want& want) const +{ + HILOG_DEBUG("%{public}s begin.", __func__); + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, ILLEGAL_REQUEST_CODE); + HILOG_DEBUG("%{public}s ret=%{public}d", __func__, err); + if (err != ERR_OK) { + HILOG_ERROR("SelectionExtensionContext::StartAbility failed: %{public}d", err); + } + return err; +} + +ErrCode SelectionExtensionContext::StartAbility(const AAFwk::Want& want, const AAFwk::StartOptions& startOptions) const +{ + HILOG_DEBUG("%{public}s start.", __func__); + ErrCode err = + AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_, ILLEGAL_REQUEST_CODE); + HILOG_DEBUG("%{public}s ret=%{public}d", __func__, err); + if (err != ERR_OK) { + HILOG_ERROR("InputMethodExtensionContext::StartAbility failed: %{public}d", err); + } + return err; +} + +} // namespace OHOS::AbilityRuntime \ No newline at end of file -- Gitee From 1adf66b526b6ddf4d6e00ab3caa365d16caa406c Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Wed, 28 May 2025 09:25:14 +0800 Subject: [PATCH 36/93] =?UTF-8?q?=E6=B3=A8=E5=85=A5ctrl=20c=E4=B8=B4?= =?UTF-8?q?=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/src/selection_service.cpp | 108 +++++++++++++----------------- 1 file changed, 47 insertions(+), 61 deletions(-) diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index e650203..4f025eb 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -240,6 +240,7 @@ void SelectionService::InputMonitorInit() SELECTION_HILOGI("[SelectionService] input monitor init"); std::shared_ptr inputMonitor = std::make_shared(); if (inputMonitorId_ < 0) { + sleep(30); inputMonitorId_ = InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); SELECTION_HILOGI("[SelectionService] input monitor init end"); @@ -298,7 +299,6 @@ void SelectionService::HandlePointEvent(int32_t type) void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { - SELECTION_HILOGD("[SelectionService] into keyEvent"); if (!ctrlSelectFlag) { return; } @@ -349,11 +349,8 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { - SELECTION_HILOGD("[SelectionService] into PointerEvent"); int32_t action = pointerEvent->GetPointerAction(); int32_t pointerId = pointerEvent->GetPointerId(); - SELECTION_HILOGD("[SelectionService] pointerEvent: %{public}d", action); - SELECTION_HILOGD("[SelectionService] pointerId: %{public}d", pointerId); if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { return; } @@ -560,74 +557,63 @@ void SelectionInputMonitor::FinishedWordSelection() const void SelectionInputMonitor::InjectCtrlC() const { + // 创建KeyEvent对象 + auto keyEvent1 = KeyEvent::Create(); + + // 设置Ctrl键按下 + keyEvent1->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyEvent1->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + InputManager::GetInstance()->SimulateInputEvent(keyEvent1); + + // 设置C键按下 + auto keyEvent2 = KeyEvent::Create(); + keyEvent2->SetKeyCode(KeyEvent::KEYCODE_C); + keyEvent2->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + InputManager::GetInstance()->SimulateInputEvent(keyEvent2); + + // 设置C键释放 + auto keyEvent3 = KeyEvent::Create(); + keyEvent3->SetKeyCode(KeyEvent::KEYCODE_C); + keyEvent3->SetKeyAction(KeyEvent::KEY_ACTION_UP); + InputManager::GetInstance()->SimulateInputEvent(keyEvent3); + + // 设置Ctrl键释放 + auto keyEvent4 = KeyEvent::Create(); + keyEvent4->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyEvent4->SetKeyAction(KeyEvent::KEY_ACTION_UP); + InputManager::GetInstance()->SimulateInputEvent(keyEvent4); + // auto keyDownEvent = KeyEvent::Create(); // keyDownEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); // std::vector downKey; // downKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); // downKey.push_back(KeyEvent::KEYCODE_C); - // keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - + // KeyEvent::KeyItem downItem[downKey.size()]; // for (size_t i = 0; i < downKey.size(); i++) { + // keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); // downItem[i].SetKeyCode(downKey[i]); // downItem[i].SetPressed(true); // downItem[i].SetDownTime(500); // keyDownEvent->AddPressedKeyItems(downItem[i]); // } // InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); - // 创建KeyEvent对象 - // auto keyEvent = KeyEvent::Create(); - - // // 设置Ctrl键按下 - // keyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入Ctrl按下 - - // // 设置C键按下 - // keyEvent->SetKeyCode(KeyEvent::KEYCODE_C); - // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入C按下 - - // // 设置C键释放 - // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_UP); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入C释放 - - // // 设置Ctrl键释放 - // keyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_UP); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent); // 注入Ctrl释放 - auto keyDownEvent = KeyEvent::Create(); - keyDownEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - std::vector downKey; - downKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); - downKey.push_back(KeyEvent::KEYCODE_C); - - KeyEvent::KeyItem downItem[downKey.size()]; - for (size_t i = 0; i < downKey.size(); i++) { - keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - downItem[i].SetKeyCode(downKey[i]); - downItem[i].SetPressed(true); - downItem[i].SetDownTime(500); - keyDownEvent->AddPressedKeyItems(downItem[i]); - } - InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); - - auto keyUpEvent = KeyEvent::Create(); - keyUpEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - std::vector upKey; - upKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); - upKey.push_back(KeyEvent::KEYCODE_C); - - KeyEvent::KeyItem upItem[upKey.size()]; - for (size_t i = 0; i < upKey.size(); i++) { - keyUpEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - keyUpEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - upItem[i].SetKeyCode(upKey[i]); - upItem[i].SetPressed(true); - upItem[i].SetDownTime(0); - keyUpEvent->RemoveReleasedKeyItems(upItem[i]); - } - InputManager::GetInstance()->SimulateInputEvent(keyUpEvent); + + // auto keyUpEvent = KeyEvent::Create(); + // keyUpEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + // std::vector upKey; + // upKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); + // upKey.push_back(KeyEvent::KEYCODE_C); + + // KeyEvent::KeyItem upItem[upKey.size()]; + // for (size_t i = 0; i < upKey.size(); i++) { + // keyUpEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // keyUpEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + // upItem[i].SetKeyCode(upKey[i]); + // upItem[i].SetPressed(true); + // upItem[i].SetDownTime(0); + // keyUpEvent->RemoveReleasedKeyItems(upItem[i]); + // } + // InputManager::GetInstance()->SimulateInputEvent(keyUpEvent); } -- Gitee From 1de8bb1d90d9b787a1b0cf22980759df78513cb0 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Wed, 28 May 2025 14:14:11 +0800 Subject: [PATCH 37/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0selectionData=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- common/selection_interface.h | 60 ++++++++++++++++++- .../js_selection_engine_setting.cpp | 46 +++++++++----- .../js_selection_engine_setting.h | 5 +- .../selection_ability/ISelectionListener.idl | 5 +- .../include/selection_listener_impl.h | 2 +- .../src/selection_listener_impl.cpp | 18 +++++- service/src/selection_service.cpp | 11 +++- 7 files changed, 121 insertions(+), 26 deletions(-) diff --git a/common/selection_interface.h b/common/selection_interface.h index 3474bb2..3ff6c3d 100644 --- a/common/selection_interface.h +++ b/common/selection_interface.h @@ -20,13 +20,71 @@ #include #include #include +#include "parcel.h" namespace OHOS { namespace SelectionFwk { + +struct SelectionData { + std::string text { "" }; + int32_t cursorStartPos = 0; + int32_t cursorEndPos = 0; + uint32_t windowId = 0; + uint32_t bundleID = 0; +}; + +struct SelectionDataInner : public Parcelable { + std::string text { "" }; + int32_t cursorStartPos = 0; + int32_t cursorEndPos = 0; + uint32_t windowId = 0; + uint32_t bundleID = 0; + + bool ReadFromParcel(Parcel &in) + { + text = in.ReadString(); + cursorEndPos = in.ReadInt32(); + cursorEndPos = in.ReadInt32(); + windowId = in.ReadUint32(); + bundleID = in.ReadUint32(); + return true; + } + + bool Marshalling(Parcel &out) const + { + if (!out.WriteString(text)) { + return false; + } + if (!out.WriteInt32(cursorStartPos)) { + return false; + } + if (!out.WriteInt32(cursorEndPos)) { + return false; + } + if (!out.WriteUint32(windowId)) { + return false; + } + if (!out.WriteUint32(bundleID)) { + return false; + } + return true; + } + + static SelectionDataInner *Unmarshalling(Parcel &in) + { + SelectionDataInner *data = new (std::nothrow) SelectionDataInner(); + if (data && !data->ReadFromParcel(in)) { + delete data; + data = nullptr; + } + return data; + } +}; + class SelectionInterface { public: virtual ~SelectionInterface() = default; - virtual int32_t OnSelectionEvent(const std::string &selectionData) = 0; + virtual int32_t OnSelectionEvent(const SelectionData &selectionData) = 0; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 75c3ffc..24142e9 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -46,7 +46,7 @@ napi_value JsSelectionEngineSetting::Subscribe(napi_env env, napi_callback_info SELECTION_HILOGE("subscribe failed, type: %{public}s!", type.c_str()); return nullptr; } - SELECTION_HILOGE("subscribe type: %{public}s.", type.c_str()); + SELECTION_HILOGI("subscribe type: %{public}s.", type.c_str()); auto engine = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); if (engine == nullptr) { return nullptr; @@ -149,6 +149,10 @@ void JsSelectionEngineSetting::RegisterListener(napi_value callback, std::string } auto selectionInterface = GetJsSelectionEngineSetting(); listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionInterface); + if (listenerStub_ == nullptr) { + SELECTION_HILOGE("listenerStub_ is nullptr!"); + return; + } SELECTION_HILOGI("Begin to call SA RegisterListener"); proxy->RegisterListener(listenerStub_->AsObject()); } @@ -295,19 +299,27 @@ std::shared_ptr JsSelectionEngineSetti return entry; } -int32_t JsSelectionEngineSetting::OnSelectionEvent(const std::string &selectionData) +napi_value JsSelectionEngineSetting::Write(napi_env env, const SelectionData &selectionData) +{ + napi_value jsObject = nullptr; + napi_create_object(env, &jsObject); + auto ret = JsUtil::Object::WriteProperty(env, jsObject, "bundleId", selectionData.bundleID); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "winID", selectionData.windowId); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "cursorEndPos", selectionData.cursorEndPos); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "cursorStartPos", selectionData.cursorStartPos); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "text", selectionData.text); + SELECTION_HILOGD("write selectionData into object, ret=%{public}s", ret ? "true" : "false"); + return ret ? jsObject : JsUtil::Const::Null(env); +} + +int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionData &selectionData) { SELECTION_HILOGI("OnSelectionEvent begin"); std::string type = "selectionEvent"; - if (selectionData.empty()) { - SELECTION_HILOGE("selectionData is empty"); - return 1; - } - - auto entry = GetEntry(type, [&selectionData](SelectionEntry &entry) { entry.text = selectionData; }); + auto entry = GetEntry(type, [&selectionData](SelectionEntry &entry) {entry.selectionData = selectionData; }); if (entry == nullptr) { - SELECTION_HILOGE("failed to get uv entry!"); + SELECTION_HILOGE("failed to get SelectionEntry entry!"); return 1; } @@ -317,23 +329,25 @@ int32_t JsSelectionEngineSetting::OnSelectionEvent(const std::string &selectionD return 1; } - SELECTION_HILOGI("selectionData is [%{public}s]", selectionData.c_str()); - - + SELECTION_HILOGI("selection text is [%{public}s]", entry->selectionData.text.c_str()); auto task = [entry]() { - auto getTextChangeProperty = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { + auto paramGetter = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { if (argc == 0) { return false; } + napi_value jsObject = Write(env, entry->selectionData); + if (jsObject == JsUtil::Const::Null(env)) { + SELECTION_HILOGE("jsObject is nullptr!"); + return false; + } // 0 means the first param of callback. - napi_create_string_utf8(env, entry->text.c_str(), NAPI_AUTO_LENGTH, &args[0]); + args[0] = jsObject; return true; }; // 1 means callback has one param. - JsCallbackHandler::Traverse(entry->vecCopy, { 1, getTextChangeProperty }); + JsCallbackHandler::Traverse(entry->vecCopy, { 1, paramGetter }); }; eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); - SELECTION_HILOGI("OnSelectionEvent end"); return 0; } diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index fea671d..3cbaaec 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -42,13 +42,13 @@ public: static napi_value Subscribe(napi_env env, napi_callback_info info); static napi_value UnSubscribe(napi_env env, napi_callback_info info); static napi_value CreatePanel(napi_env env, napi_callback_info info); - int32_t OnSelectionEvent(const std::string &selectionData); + int32_t OnSelectionEvent(const SelectionData &selectionData); private: struct SelectionEntry { std::vector> vecCopy; std::string type; - std::string text; + SelectionData selectionData; SelectionEntry(const std::vector> &cbVec, const std::string &type) : vecCopy(cbVec), type(type) { @@ -57,6 +57,7 @@ private: static napi_value GetSEInstance(napi_env env, napi_callback_info info); static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); + static napi_value Write(napi_env env, const SelectionData &selectionData); static std::shared_ptr GetJsSelectionEngineSetting(); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); diff --git a/frameworks/native/selection_ability/ISelectionListener.idl b/frameworks/native/selection_ability/ISelectionListener.idl index 2643dab..cc112a1 100644 --- a/frameworks/native/selection_ability/ISelectionListener.idl +++ b/frameworks/native/selection_ability/ISelectionListener.idl @@ -12,6 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +sequenceable selection_interface..OHOS.SelectionFwk.SelectionDataInner; + interface OHOS.SelectionFwk.ISelectionListener { - void OnSelectionChange([in] String text); + void OnSelectionChange([in] SelectionDataInner selectionDataInner); } diff --git a/frameworks/native/selection_ability/include/selection_listener_impl.h b/frameworks/native/selection_ability/include/selection_listener_impl.h index 1092461..bd4d0b8 100644 --- a/frameworks/native/selection_ability/include/selection_listener_impl.h +++ b/frameworks/native/selection_ability/include/selection_listener_impl.h @@ -25,7 +25,7 @@ class SelectionListenerImpl : public SelectionListenerStub { public: SelectionListenerImpl(std::shared_ptr selectionI) : selectionI_(selectionI) {} ~SelectionListenerImpl() override = default; - ErrCode OnSelectionChange(const std::string& text) override; + ErrCode OnSelectionChange(const SelectionDataInner& selectionDataInner) override; private: std::shared_ptr selectionI_; }; diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index 9b9f9b9..0894fcc 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -18,10 +18,22 @@ namespace OHOS { namespace SelectionFwk { -ErrCode SelectionListenerImpl::OnSelectionChange(const std::string& text) + +static void CopySelectionData(const SelectionDataInner& src, SelectionData& dst) +{ + dst.text = src.text; + dst.cursorStartPos = src.cursorStartPos; + dst.cursorEndPos = src.cursorEndPos; + dst.windowId = src.windowId; + dst.bundleID = src.bundleID; +} + +ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionDataInner& selectionDataInner) { - SELECTION_HILOGI("Recveive selection data: %{public}s", text.c_str()); - selectionI_->OnSelectionEvent(text); + SELECTION_HILOGI("Recveive selection data: %{public}s", selectionDataInner.text.c_str()); + SelectionData selectionData; + CopySelectionData(selectionDataInner, selectionData); + selectionI_->OnSelectionEvent(selectionData); return 0; } } // namespace SelectionFramework diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 4f025eb..e0d4133 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -24,6 +24,7 @@ #include "parameter.h" #include #include "common_event_manager.h" +#include "selection_interface.h" using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -99,7 +100,7 @@ sptr SelectionService::GetListener() { ErrCode SelectionService::RegisterListener(const sptr &listener) { - SELECTION_HILOGD("Begin to call SA RegisterListener"); + SELECTION_HILOGI("Enter RegisterListener"); if (listener == nullptr) { SELECTION_HILOGE("RegisterListener: Input listener is nullptr."); return 1; @@ -550,7 +551,13 @@ void SelectionInputMonitor::FinishedWordSelection() const SELECTION_HILOGE("get listener is null"); return; } - listener->OnSelectionChange("HELLO FANZHE"); + SelectionDataInner data; + data.text = "Hello, world!"; + data.cursorStartPos = 0; + data.cursorEndPos = 13; + data.windowId = 1001; + data.bundleID = 2002; + listener->OnSelectionChange(data); } return; } -- Gitee From cf058ef3a34bbd37dbc0b6f7d8c3c408c7233c5e Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Wed, 28 May 2025 14:23:36 +0800 Subject: [PATCH 38/93] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/src/selection_service.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index e0d4133..7f6352d 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -350,7 +350,6 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { - int32_t action = pointerEvent->GetPointerAction(); int32_t pointerId = pointerEvent->GetPointerId(); if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { return; -- Gitee From 0071afd233d8b69784c3ae3f80f6aaac684f7536 Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Mon, 26 May 2025 17:11:17 +0800 Subject: [PATCH 39/93] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0creat?= =?UTF-8?q?ePanel=E6=8E=A5=E5=8F=A3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 7 +- common/js_utils.cpp | 24 + common/js_utils.h | 2 +- etc/init/selection_service.cfg | 3 +- frameworks/common/concurrent_map.h | 302 ++++++++++ frameworks/js/napi/selection_ability/BUILD.gn | 10 + .../js/napi/selection_ability/js_panel.cpp | 136 +++++ .../js/napi/selection_ability/js_panel.h | 121 ++++ .../js_selection_engine_setting.cpp | 73 ++- .../js_selection_engine_setting.h | 27 + .../selection_ability/panel_listener_impl.cpp | 215 +++++++ .../selection_ability/panel_listener_impl.h | 75 +++ .../js/napi/selection_client/async_call.cpp | 244 ++++++++ .../js/napi/selection_client/async_call.h | 147 +++++ .../selection_client/js_selection_utils.cpp | 568 ++++++++++++++++++ .../selection_client/js_selection_utils.h | 197 ++++++ .../js/napi/selection_client/js_utils.cpp.bak | 567 +++++++++++++++++ .../js/napi/selection_client/js_utils.h.bak | 195 ++++++ frameworks/native/selection_ability/BUILD.gn | 20 + .../include/actions/action.h | 69 +++ .../include/actions/action_wait.h | 88 +++ .../selection_ability/include/panel_info.h | 77 +++ .../include/selection_ability.h | 60 ++ .../include/selection_panel.h | 66 ++ .../selection_ability/include/task_manager.h | 90 +++ .../selection_ability/include/tasks/task.h | 107 ++++ .../include/tasks/task_ams.h | 53 ++ .../include/tasks/task_inner.h | 32 + .../include/tasks/task_ssa.h | 190 ++++++ .../src/selection_ability.cpp | 121 ++++ .../selection_ability/src/selection_panel.cpp | 176 ++++++ .../selection_ability/src/task_manager.cpp | 282 +++++++++ .../selection_ability/src/tasks/task.cpp | 171 ++++++ 33 files changed, 4510 insertions(+), 5 deletions(-) create mode 100644 frameworks/common/concurrent_map.h create mode 100644 frameworks/js/napi/selection_ability/panel_listener_impl.cpp create mode 100644 frameworks/js/napi/selection_ability/panel_listener_impl.h create mode 100644 frameworks/js/napi/selection_client/async_call.cpp create mode 100644 frameworks/js/napi/selection_client/async_call.h create mode 100644 frameworks/js/napi/selection_client/js_selection_utils.cpp create mode 100644 frameworks/js/napi/selection_client/js_selection_utils.h create mode 100644 frameworks/js/napi/selection_client/js_utils.cpp.bak create mode 100644 frameworks/js/napi/selection_client/js_utils.h.bak create mode 100644 frameworks/native/selection_ability/include/actions/action.h create mode 100644 frameworks/native/selection_ability/include/actions/action_wait.h create mode 100644 frameworks/native/selection_ability/include/panel_info.h create mode 100644 frameworks/native/selection_ability/include/task_manager.h create mode 100644 frameworks/native/selection_ability/include/tasks/task.h create mode 100644 frameworks/native/selection_ability/include/tasks/task_ams.h create mode 100644 frameworks/native/selection_ability/include/tasks/task_inner.h create mode 100644 frameworks/native/selection_ability/include/tasks/task_ssa.h create mode 100644 frameworks/native/selection_ability/src/task_manager.cpp create mode 100644 frameworks/native/selection_ability/src/tasks/task.cpp diff --git a/bundle.json b/bundle.json index 55c0b61..91e484a 100644 --- a/bundle.json +++ b/bundle.json @@ -32,7 +32,12 @@ "ability_base", "ability_runtime", "window_manager", - "resource_management" + "resource_management", + "graphic_2d", + "bundle_framework", + "ffrt", + + "config_policy" ], "third_party": [ ] diff --git a/common/js_utils.cpp b/common/js_utils.cpp index a4d691e..936c704 100644 --- a/common/js_utils.cpp +++ b/common/js_utils.cpp @@ -230,6 +230,7 @@ void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info) napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &out) { + SELECTION_HILOGD("napi_value -> int32_t "); napi_valuetype type = napi_undefined; napi_status status = napi_typeof(env, in, &type); CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); @@ -303,6 +304,29 @@ napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &ty return napi_generic_failure; } +// napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out) +// { +// SELECTION_HILOGD("napi_value -> PanelInfo "); +// napi_value propType = nullptr; +// napi_status status = napi_get_named_property(env, in, "type", &propType); +// CHECK_RETURN((status == napi_ok), "no property type ", status); +// int32_t panelType = 0; +// status = GetValue(env, propType, panelType); +// CHECK_RETURN((status == napi_ok), "no value of type ", status); + +// // PanelFlag is optional, defaults to FLG_FIXED when empty. +// int32_t panelFlag = static_cast(PanelFlag::FLG_FIXED); +// napi_value panelFlagObj = nullptr; +// status = napi_get_named_property(env, in, "flag", &panelFlagObj); +// if (status == napi_ok) { +// JsUtils::GetValue(env, panelFlagObj, panelFlag); +// } + +// out.panelType = PanelType(panelType); +// out.panelFlag = PanelFlag(panelFlag); +// return napi_ok; +// } + napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out) { return napi_create_string_utf8(env, in.c_str(), in.size(), &out); diff --git a/common/js_utils.h b/common/js_utils.h index e98d419..8fc629b 100644 --- a/common/js_utils.h +++ b/common/js_utils.h @@ -164,7 +164,7 @@ public: static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); - + // static napi_status GetValue(napi_env env, napi_value in, PanelInfo &out); static napi_status GetValue(napi_env env, napi_value in, std::vector &out); diff --git a/etc/init/selection_service.cfg b/etc/init/selection_service.cfg index 0f753fb..163c4b9 100644 --- a/etc/init/selection_service.cfg +++ b/etc/init/selection_service.cfg @@ -12,7 +12,8 @@ "ohos.permission.INPUT_MONITORING", "ohos.permission.GET_RUNNING_INFO", "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", - "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT" + "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT", + "ohos.permission.SYSTEM_FLOAT_WINDOW" ], "permission_acls" : ["ohos.permission.INPUT_MONITORING"], "caps" : [], diff --git a/frameworks/common/concurrent_map.h b/frameworks/common/concurrent_map.h new file mode 100644 index 0000000..44a6ccc --- /dev/null +++ b/frameworks/common/concurrent_map.h @@ -0,0 +1,302 @@ +/* + * 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_SELECTION_FWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#define OHOS_SELECTION_FWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#include +#include +#include +namespace OHOS { +template +class ConcurrentMap { + template + static _First First(); + +public: + using map_type = typename std::map<_Key, _Tp>; + using filter_type = typename std::function; + using key_type = typename std::map<_Key, _Tp>::key_type; + using mapped_type = typename std::map<_Key, _Tp>::mapped_type; + using value_type = typename std::map<_Key, _Tp>::value_type; + using size_type = typename std::map<_Key, _Tp>::size_type; + using reference = typename std::map<_Key, _Tp>::reference; + using const_reference = typename std::map<_Key, _Tp>::const_reference; + + ConcurrentMap() = default; + ~ConcurrentMap() + { + Clear(); + } + + ConcurrentMap(const ConcurrentMap &other) + { + operator=(std::move(other)); + } + + ConcurrentMap &operator=(const ConcurrentMap &other) noexcept + { + if (this == &other) { + return *this; + } + auto tmp = other.Clone(); + std::lock_guard lock(mutex_); + entries_ = std::move(tmp); + return *this; + } + + ConcurrentMap(ConcurrentMap &&other) noexcept + { + operator=(std::move(other)); + } + + ConcurrentMap &operator=(ConcurrentMap &&other) noexcept + { + if (this == &other) { + return *this; + } + auto tmp = other.Steal(); + std::lock_guard lock(mutex_); + entries_ = std::move(tmp); + return *this; + } + + bool Emplace() noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.emplace(); + return it.second; + } + + template + typename std::enable_if()), filter_type>, bool>::type Emplace( + _Args &&...args) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.emplace(std::forward<_Args>(args)...); + return it.second; + } + + template + typename std::enable_if, bool>::type Emplace(const _Filter &filter, + _Args &&...args) noexcept + { + std::lock_guard lock(mutex_); + if (!filter(entries_)) { + return false; + } + auto it = entries_.emplace(std::forward<_Args>(args)...); + return it.second; + } + + std::pair Find(const key_type &key) const noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + return std::pair{ false, mapped_type() }; + } + + return std::pair{ true, it->second }; + } + + bool Contains(const key_type &key) const noexcept + { + std::lock_guard lock(mutex_); + return (entries_.find(key) != entries_.end()); + } + + template + bool InsertOrAssign(const key_type &key, _Obj &&obj) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.insert_or_assign(key, std::forward<_Obj>(obj)); + return it.second; + } + + bool Insert(const key_type &key, const mapped_type &value) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.insert(value_type{ key, value }); + return it.second; + } + + size_type Erase(const key_type &key) noexcept + { + std::lock_guard lock(mutex_); + return entries_.erase(key); + } + + void Clear() noexcept + { + std::lock_guard lock(mutex_); + return entries_.clear(); + } + + bool Empty() const noexcept + { + std::lock_guard lock(mutex_); + return entries_.empty(); + } + + size_type Size() const noexcept + { + std::lock_guard lock(mutex_); + return entries_.size(); + } + + // The action`s return true means meeting the erase condition + // The action`s return false means not meeting the erase condition + size_type EraseIf(const std::function &action) noexcept + { + if (action == nullptr) { + return 0; + } + std::lock_guard lock(mutex_); +#if __cplusplus > 201703L + auto count = std::erase_if(entries_, + [&action](value_type &value) -> bool { return action(value.first, value.second); }); +#else + auto count = entries_.size(); + for (auto it = entries_.begin(); it != entries_.end();) { + if (action((*it).first, (*it).second)) { + it = entries_.erase(it); + } else { + ++it; + } + } + count -= entries_.size(); +#endif + return count; + } + + void ForEach(const std::function &action) + { + if (action == nullptr) { + return; + } + std::lock_guard lock(mutex_); + for (auto &[key, value] : entries_) { + if (action(key, value)) { + break; + } + } + } + + void ForEachCopies(const std::function &action) + { + if (action == nullptr) { + return; + } + auto entries = Clone(); + for (auto &[key, value] : entries) { + if (action(key, value)) { + break; + } + } + } + + // The action's return value means that the element is keep in map or not; true means keeping, false means removing. + bool Compute(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + auto result = entries_.emplace(key, mapped_type()); + it = result.second ? result.first : entries_.end(); + } + if (it == entries_.end()) { + return false; + } + if (!action(it->first, it->second)) { + entries_.erase(key); + } + return true; + } + + // The action's return value means that the element is keep in map or not; true means keeping, false means removing. + bool ComputeIfPresent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + return false; + } + if (!action(key, it->second)) { + entries_.erase(key); + } + return true; + } + + bool ComputeIfAbsent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it != entries_.end()) { + return false; + } + entries_.emplace(key, action(key)); + return true; + } + + bool ComputeIfAbsent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it != entries_.end()) { + return false; + } + auto result = entries_.emplace(key, mapped_type()); + it = result.second ? result.first : entries_.end(); + if (it == entries_.end()) { + return false; + } + if (!action(it->first, it->second)) { + entries_.erase(key); + return false; + } + return true; + } + +private: + std::map<_Key, _Tp> Steal() noexcept + { + std::lock_guard lock(mutex_); + return std::move(entries_); + } + + std::map<_Key, _Tp> Clone() const noexcept + { + std::lock_guard lock(mutex_); + return entries_; + } + +private: + mutable std::recursive_mutex mutex_; + std::map<_Key, _Tp> entries_; +}; +} // namespace OHOS +#endif // OHOS_SELECTION_FWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 921a3fb..d11f656 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -26,13 +26,20 @@ ohos_shared_library("selectionengine_napi") { } sources = [ "js_selection_engine_setting.cpp", + "panel_listener_impl.cpp", "selection_engine_module.cpp", + "js_panel.cpp", + "../selection_client/async_call.cpp", + "../selection_client/js_selection_utils.cpp", ] include_dirs = [ ".", "../../../../utils/include", "${target_gen_dir}", + "../../../native/selection_ability/include", + "../selection_client", + "../../../common", ] deps = [ @@ -57,6 +64,9 @@ ohos_shared_library("selectionengine_napi") { "window_manager:libwm_lite", "resource_management:global_resmgr", "ability_runtime:app_context", + "ffrt:libffrt", + "graphic_2d:librender_service_client", + "graphic_2d:window_animation", ] relative_install_dir = "module" diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index e69de29..5c15d37 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.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_panel.h" + +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "selection_log.h" +#include "panel_listener_impl.h" +// #include "utils.h" +// #include "selectionmethod_trace.h" + + +#include "selection_ability.h" + +namespace OHOS { +namespace SelectionFwk { +const std::string JsPanel::CLASS_NAME = "Panel"; +thread_local napi_ref JsPanel::panelConstructorRef_ = nullptr; +std::mutex JsPanel::panelConstructorMutex_; + +napi_value JsPanel::Init(napi_env env) +{ + SELECTION_HILOGI("JsPanel start."); + napi_value constructor = nullptr; + std::lock_guard lock(panelConstructorMutex_); + if (panelConstructorRef_ != nullptr) { + napi_status status = napi_get_reference_value(env, panelConstructorRef_, &constructor); + CHECK_RETURN(status == napi_ok, "failed to get jsPanel constructor.", nullptr); + return constructor; + } + const napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("show", Show), + + }; + NAPI_CALL(env, napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), JsNew, nullptr, + sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor)); + CHECK_RETURN(constructor != nullptr, "failed to define class!", nullptr); + NAPI_CALL(env, napi_create_reference(env, constructor, 1, &panelConstructorRef_)); + return constructor; +} + +napi_value JsPanel::JsNew(napi_env env, napi_callback_info info) +{ + SELECTION_HILOGD("create panel instance start."); + std::shared_ptr panelImpl = PanelListenerImpl::GetInstance(); + if (panelImpl != nullptr) { + SELECTION_HILOGD("set eventHandler."); + panelImpl->SetEventHandler(AppExecFwk::EventHandler::Current()); + } + JsPanel *panel = new (std::nothrow) JsPanel(); + CHECK_RETURN(panel != nullptr, "no memory for JsPanel!", nullptr); + auto finalize = [](napi_env env, void *data, void *hint) { + SELECTION_HILOGD("jsPanel finalize."); + auto *jsPanel = reinterpret_cast(data); + CHECK_RETURN_VOID(jsPanel != nullptr, "finalize nullptr!"); + jsPanel->GetNative() = nullptr; + delete jsPanel; + }; + napi_value thisVar = nullptr; + napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); + if (status != napi_ok) { + SELECTION_HILOGE("failed to get cb info: %{public}d!", status); + delete panel; + return nullptr; + } + status = napi_wrap(env, thisVar, panel, finalize, nullptr, nullptr); + if (status != napi_ok) { + SELECTION_HILOGE("failed to wrap: %{public}d!", status); + delete panel; + return nullptr; + } + return thisVar; +} + +JsPanel::~JsPanel() +{ + selectionPanel_ = nullptr; +} + +void JsPanel::SetNative(const std::shared_ptr &panel) +{ + selectionPanel_ = panel; +} + +napi_value JsPanel::Show(napi_env env, napi_callback_info info) +{ + SELECTION_HILOGI("cJsPanel---Show."); + // SelectionMethodSyncTrace tracer("JsPanel_Show"); + // auto ctxt = std::make_shared(env, info); + // auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + // ctxt->info = { std::chrono::system_clock::now(), JsEvent::SHOW }; + // jsQueue_.Push(ctxt->info); + // return napi_ok; + // }; + // auto exec = [ctxt](AsyncCall::Context *ctx) { + // jsQueue_.Wait(ctxt->info); + // if (ctxt->selectionPanel == nullptr) { + // SELECTION_HILOGE("selectionPanel is nullptr!"); + // jsQueue_.Pop(); + // return; + // } + // auto code = SelectionAbility::GetInstance()->ShowPanel(ctxt->selectionPanel); + // if (code == ErrorCode::NO_ERROR) { + // ctxt->SetState(napi_ok); + // jsQueue_.Pop(); + // return; + // } + // jsQueue_.Pop(); + // ctxt->SetErrorCode(code); + // }; + // ctxt->SetAction(std::move(input)); + // // 1 means JsAPI:show has 1 param at most. + // AsyncCall asyncCall(env, info, ctxt, 1); + // return asyncCall.Call(env, exec, "show"); + return nullptr; +} + +std::shared_ptr JsPanel::GetNative() +{ + return selectionPanel_; +} +} +} \ No newline at end of file diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index e69de29..29acde0 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -0,0 +1,121 @@ +/* + * 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 SELECTION_IMF_JSPANEL_H +#define SELECTION_IMF_JSPANEL_H + +#include "napi/native_api.h" +#include "selection_panel.h" +#include "async_call.h" +// #include "panel_common.h" +#include "panel_info.h" +// #include "ffrt_block_queue.h" +#include "event_checker.h" + + +#include +#include + +namespace OHOS { +namespace SelectionFwk { + +enum class JsEvent : uint32_t { + RESIZE = 0, + MOVE_TO, + ADJUST_PANEL_RECT, + UPDATE_REGION, + SHOW, + HIDE, + SET_UI_CONTENT, + GET_DISPLAYID, + SET_IMMERSIVE_MODE, + GET_IMMERSIVE_MODE, + EVENT_END, +}; + +struct JsEventInfo { + std::chrono::system_clock::time_point timestamp{}; + JsEvent event{ JsEvent::EVENT_END }; + bool operator==(const JsEventInfo &info) const + { + return (timestamp == info.timestamp && event == info.event); + } +}; + + + + +class JsPanel { +public: + JsPanel() = default; + ~JsPanel(); + static napi_value Init(napi_env env); + static napi_value Show(napi_env env, napi_callback_info info); + void SetNative(const std::shared_ptr &panel); + std::shared_ptr GetNative(); +private: + // struct PanelContentContext : public AsyncCall::Context { + // LayoutParams layoutParams = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; + // EnhancedLayoutParams enhancedLayoutParams; + // HotAreas hotAreas; + // std::vector hotArea; + // bool isEnhancedCall{ false }; + // PanelFlag panelFlag = PanelFlag::FLG_FIXED; + // std::string path = ""; + // uint32_t width = 0; + // uint32_t height = 0; + // int32_t x = 0; + // int32_t y = 0; + // uint64_t displayId = 0; + // std::shared_ptr selectionPanel = nullptr; + // std::shared_ptr contentStorage = nullptr; + // JsEventInfo info; + // PanelContentContext(napi_env env, napi_callback_info info) : Context(nullptr, nullptr) + // { + // napi_value self = nullptr; + // napi_status status = napi_get_cb_info(env, info, 0, nullptr, &self, nullptr); + // CHECK_RETURN_VOID((status == napi_ok) && (self != nullptr), "get callback info failed."); + // void *native = nullptr; + // status = napi_unwrap(env, self, &native); + // CHECK_RETURN_VOID((status == napi_ok) && (native != nullptr), "get jsPanel failed."); + // selectionPanel = reinterpret_cast(native)->GetNative(); + // }; + // PanelContentContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; + // napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override + // { + // CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); + // return Context::operator()(env, argc, argv, self); + // } + // napi_status operator()(napi_env env, napi_value *result) override + // { + // if (status_ != napi_ok) { + // output_ = nullptr; + // return status_; + // } + // return Context::operator()(env, result); + // } + // }; + + static napi_value JsNew(napi_env env, napi_callback_info info); + static const std::string CLASS_NAME; + static thread_local napi_ref panelConstructorRef_; + std::shared_ptr selectionPanel_ = nullptr; + static std::mutex panelConstructorMutex_; + // static FFRTBlockQueue jsQueue_; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif //SELECTION_IMF_JSPANEL_H diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 24142e9..5b0423c 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -2,6 +2,7 @@ #include "event_checker.h" #include "iservice_registry.h" +#include "selection_ability.h" #include "js_utils.h" #include "callback_handler.h" #include "napi/native_node_api.h" @@ -9,6 +10,9 @@ #include "selection_log.h" #include "system_ability_definition.h" #include "util.h" +#include "napi_base_context.h" +#include "js_panel.h" +#include "js_selection_utils.h" using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -96,11 +100,76 @@ napi_value JsSelectionEngineSetting::UnSubscribe(napi_env env, napi_callback_inf return result; } +napi_status JsSelectionEngineSetting::GetContext(napi_env env, napi_value in, + std::shared_ptr &context)//namespace AbilityRuntime待补充 +{ + bool stageMode = false; + napi_status status = OHOS::AbilityRuntime::IsStageContext(env, in, stageMode);//IsStageContext()待补充 + if (status != napi_ok || (!stageMode)) { + SELECTION_HILOGE("it's not in stage mode."); + return status; + } + context = OHOS::AbilityRuntime::GetStageModeContext(env, in);//GetStageModeContext()待补充 + if (context == nullptr) { + SELECTION_HILOGE("context is nullptr."); + return napi_generic_failure; + } + return napi_ok; +} + napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_info info) { - SELECTION_HILOGI("SelectionEngineSetting---CreatePanel"); + SELECTION_HILOGI("SelectionEngineSetting CreatePanel start."); + + auto ctxt = std::make_shared(); +//处理从JavaScript传入的参数验证和转换 + auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + PARAM_CHECK_RETURN(env, argc >= 2, "at least two parameters is required.", TYPE_NONE, napi_invalid_arg); + napi_valuetype valueType = napi_undefined; + // 0 means parameter of ctx + napi_typeof(env, argv[0], &valueType); + PARAM_CHECK_RETURN(env, valueType == napi_object, "ctx type must be BaseContext.", TYPE_NONE, napi_invalid_arg); + napi_status status = GetContext(env, argv[0], ctxt->context); + if (status != napi_ok) { + return status; + } + // 1 means parameter of info + napi_typeof(env, argv[1], &valueType); + PARAM_CHECK_RETURN(env, valueType == napi_object, "param info type must be PanelInfo.", TYPE_NONE, + napi_invalid_arg); + status = OHOS::SelectionFwk::JsSelectionUtils::GetValue(env, argv[1], ctxt->panelInfo);//参数解析失败,这个需要看下!!! + SELECTION_HILOGD( + "output js param panelInfo covert , type/flag: %{public}d/%{public}d.", static_cast(ctxt->panelInfo.panelType), static_cast(ctxt->panelInfo.panelFlag)); + PARAM_CHECK_RETURN(env, status == napi_ok, "js param info covert failed!", TYPE_NONE, napi_invalid_arg); + return status; + }; +//执行实际的面板创建操作 + auto exec = [ctxt](AsyncCall::Context *ctx) { + auto ret = SelectionAbility::GetInstance()->CreatePanel(ctxt->context, ctxt->panelInfo, ctxt->panel); + ctxt->SetErrorCode(ret); + CHECK_RETURN_VOID(ret == ErrorCode::NO_ERROR, "JsSelectionEngineSetting CreatePanel failed!"); + ctxt->SetState(napi_ok); + }; +//处理返回结果,创建JavaScript层的面板对象, + auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { + JsPanel *jsPanel = nullptr;//JsPanel类在Js_panel.h中声明定义 + napi_value constructor = JsPanel::Init(env);// 初始化JsPanel构造函数 + CHECK_RETURN(constructor != nullptr, "failed to get panel constructor!", napi_generic_failure); + + napi_status status = napi_new_instance(env, constructor, 0, nullptr, result); + CHECK_RETURN(status == napi_ok, "jsPanel new instance failed!", napi_generic_failure); + + status = napi_unwrap(env, *result, (void **)(&jsPanel)); + CHECK_RETURN((status == napi_ok) && (jsPanel != nullptr), "get jsPanel unwrap failed!", napi_generic_failure); + jsPanel->SetNative(ctxt->panel);//SetNative() 在js_panel.cpp实现 + return napi_ok; + }; - return nullptr; + ctxt->SetAction(std::move(input), std::move(output));// 设置上下文的操作函数SetAction() + // 3 means JsAPI:createPanel has 3 params at most. + AsyncCall asyncCall(env, info, ctxt, 3);// 创建异步调用对象(最多3个参数)AsyncCall + return asyncCall.Call(env, exec, "createPanel");// 执行异步调用asyncCall.Call() + // return nullptr;//测试时临时使用 } sptr JsSelectionEngineSetting::GetSelectionSystemAbility() diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index 3cbaaec..e67512e 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -29,6 +29,10 @@ #include "refbase.h" #include "selection_interface.h" #include "util.h" +#include "async_call.h" +#include "selection_panel.h" +#include "panel_info.h" +#include "context.h" namespace OHOS { namespace SelectionFwk { @@ -55,9 +59,32 @@ private: } }; + struct PanelContext : public AsyncCall::Context { + PanelInfo panelInfo = PanelInfo(); + std::shared_ptr panel = nullptr; + std::shared_ptr context = nullptr; + PanelContext() : Context(nullptr, nullptr){}; + PanelContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; + + napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override + { + CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); + return Context::operator()(env, argc, argv, self); + } + napi_status operator()(napi_env env, napi_value *result) override + { + if (status_ != napi_ok) { + output_ = nullptr; + return status_; + } + return Context::operator()(env, result); + } + }; + static napi_value GetSEInstance(napi_env env, napi_callback_info info); static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); static napi_value Write(napi_env env, const SelectionData &selectionData); + static napi_status GetContext(napi_env env, napi_value in, std::shared_ptr &context); static std::shared_ptr GetJsSelectionEngineSetting(); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp new file mode 100644 index 0000000..7325187 --- /dev/null +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -0,0 +1,215 @@ +/* + * 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 "panel_listener_impl.h" + +#include "callback_handler.h" +#include "js_utils.h" +#include "js_selection_utils.h" + +namespace OHOS { +namespace SelectionFwk { +std::shared_ptr PanelListenerImpl::instance_{ nullptr }; +std::mutex PanelListenerImpl::listenerMutex_; +std::shared_ptr PanelListenerImpl::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard lock(listenerMutex_); + if (instance_ == nullptr) { + instance_ = std::make_shared(); + } + } + return instance_; +} + +PanelListenerImpl::~PanelListenerImpl() {} + +// void PanelListenerImpl::Subscribe(uint32_t windowId, const std::string &type, +// std::shared_ptr cbObject) +// { +// callbacks_.Compute(windowId, +// [cbObject, &type](auto windowId, std::map> &cbs) { +// auto [it, insert] = cbs.try_emplace(type, cbObject); +// if (insert) { +// IMSA_HILOGI("start to subscribe type: %{public}s of windowId: %{public}u.", type.c_str(), windowId); +// } else { +// IMSA_HILOGD("type: %{public}s of windowId: %{public}u already subscribed.", type.c_str(), windowId); +// } +// return !cbs.empty(); +// }); +// } + +// void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId) +// { +// callbacks_.ComputeIfPresent(windowId, +// [&type](auto windowId, std::map> &cbs) { +// cbs.erase(type); +// return !cbs.empty(); +// }); +// } + +// void PanelListenerImpl::OnPanelStatus(uint32_t windowId, bool isShow) +// { +// std::string type = isShow ? "show" : "hide"; +// auto eventHandler = GetEventHandler(); +// if (eventHandler == nullptr) { +// IMSA_HILOGE("eventHandler is nullptr!"); +// return; +// } +// std::shared_ptr callBack = GetCallback(windowId, type); +// if (callBack == nullptr) { +// IMSA_HILOGE("callBack is nullptr!"); +// return; +// } +// auto entry = std::make_shared(callBack); +// IMSA_HILOGI("windowId = %{public}u, type = %{public}s", windowId, type.c_str()); +// auto task = [entry]() { +// JsCallbackHandler::Traverse({ entry->cbCopy }); +// }; +// eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); +// } + +// void PanelListenerImpl::OnSizeChange(uint32_t windowId, const WindowSize &size) +// { +// std::string type = "sizeChange"; +// auto eventHandler = GetEventHandler(); +// if (eventHandler == nullptr) { +// IMSA_HILOGE("eventHandler is nullptr!"); +// return; +// } +// std::shared_ptr callBack = GetCallback(windowId, type); +// if (callBack == nullptr) { +// return; +// } +// auto entry = std::make_shared(callBack); +// entry->size = size; +// IMSA_HILOGI("OnSizeChange start. windowId:%{public}u, w:%{public}u, h:%{public}u", windowId, size.width, +// size.height); +// auto task = [entry]() { +// auto gitWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { +// if (argc == 0) { +// return false; +// } +// napi_value windowSize = JsWindowSize::Write(env, entry->size); +// // 0 means the first param of callback. +// args[0] = { windowSize }; +// return true; +// }; +// JsCallbackHandler::Traverse({ entry->cbCopy }, { 1, gitWindowSizeParams }); +// }; +// eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); +// } + +// void PanelListenerImpl::OnSizeChange( +// uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) +// { +// std::string type = "sizeUpdate"; +// auto eventHandler = GetEventHandler(); +// if (eventHandler == nullptr) { +// IMSA_HILOGE("eventHandler is nullptr!"); +// return; +// } +// std::shared_ptr callBack = GetCallback(windowId, event); +// if (callBack == nullptr) { +// IMSA_HILOGE("callback is nullptr"); +// return; +// } +// auto entry = std::make_shared(callBack); +// entry->size = size; +// entry->keyboardArea = keyboardArea; +// IMSA_HILOGI("%{public}s start. windowId:%{public}u, windowSize[%{public}u/%{public}u], " +// "keyboardArea:[%{public}d/%{public}d/%{public}d/%{public}d]", +// event.c_str(), windowId, size.width, size.height, keyboardArea.top, keyboardArea.bottom, keyboardArea.left, +// keyboardArea.right); +// auto task = [entry]() { +// auto getWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { +// if (argc == 0) { +// return false; +// } +// napi_value windowSize = JsWindowSize::Write(env, entry->size); +// napi_value jsKeyboardArea = JsKeyboardArea::Write(env, entry->keyboardArea); +// args[0] = { windowSize }; +// args[1] = { jsKeyboardArea }; +// return true; +// }; +// // 2 means 'sizeChange' has 2 params +// JsCallbackHandler::Traverse({ entry->cbCopy }, { 2, getWindowSizeParams }); +// }; +// eventHandler->PostTask(task, event, 0, AppExecFwk::EventQueue::Priority::VIP); +// } + +void PanelListenerImpl::SetEventHandler(std::shared_ptr handler) +{ + std::unique_lock lock(eventHandlerMutex_); + handler_ = handler; +} + +// std::shared_ptr PanelListenerImpl::GetEventHandler() +// { +// std::shared_lock lock(eventHandlerMutex_); +// return handler_; +// } + +// std::shared_ptr PanelListenerImpl::GetCallback(uint32_t windowId, const std::string &type) +// { +// std::shared_ptr callBack = nullptr; +// callbacks_.ComputeIfPresent(windowId, [&type, &callBack](uint32_t id, auto callbacks) { +// auto it = callbacks.find(type); +// if (it == callbacks.end()) { +// return !callbacks.empty(); +// } +// callBack = it->second; +// return !callbacks.empty(); +// }); +// return callBack; +// } + +// napi_value JsWindowSize::Write(napi_env env, const WindowSize &nativeObject) +// { +// napi_value jsObject = nullptr; +// napi_create_object(env, &jsObject); +// bool ret = JsUtil::Object::WriteProperty(env, jsObject, "width", nativeObject.width); +// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", nativeObject.height); +// return ret ? jsObject : JsUtil::Const::Null(env); +// } + +// bool JsWindowSize::Read(napi_env env, napi_value jsObject, WindowSize &nativeObject) +// { +// auto ret = JsUtil::Object::ReadProperty(env, jsObject, "width", nativeObject.width); +// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "height", nativeObject.height); +// return ret; +// } + +// napi_value JsKeyboardArea::Write(napi_env env, const PanelAdjustInfo &nativeObject) +// { +// napi_value jsObject = nullptr; +// napi_create_object(env, &jsObject); +// bool ret = JsUtil::Object::WriteProperty(env, jsObject, "top", nativeObject.top); +// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "bottom", nativeObject.bottom); +// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "left", nativeObject.left); +// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "right", nativeObject.right); +// return ret ? jsObject : JsUtil::Const::Null(env); +// } + +// bool JsKeyboardArea::Read(napi_env env, napi_value jsObject, PanelAdjustInfo &nativeObject) +// { +// bool ret = JsUtil::Object::ReadProperty(env, jsObject, "top", nativeObject.top); +// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "bottom", nativeObject.bottom); +// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "left", nativeObject.left); +// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "right", nativeObject.right); +// return ret; +// } +} // namespace SelectionFwk +} // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.h b/frameworks/js/napi/selection_ability/panel_listener_impl.h new file mode 100644 index 0000000..9f29802 --- /dev/null +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.h @@ -0,0 +1,75 @@ +/* + * 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 SELECTON_FWK_PANEL_LISTENER_IMPL_H +#define SELECTON_FWK_PANEL_LISTENER_IMPL_H + +#include +#include +#include +#include + +// #include "concurrent_map.h" +#include "event_handler.h" +#include "selection_panel.h" +// #include "js_callback_object.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +// #include "panel_status_listener.h" + +namespace OHOS { +namespace SelectionFwk { +// struct JsWindowSize { +// static napi_value Write(napi_env env, const WindowSize &nativeObject); +// static bool Read(napi_env env, napi_value jsObject, WindowSize &nativeObject); +// }; +// struct JsKeyboardArea { +// static napi_value Write(napi_env env, const PanelAdjustInfo &nativeObject); +// static bool Read(napi_env env, napi_value jsObject, PanelAdjustInfo &nativeObject); +// }; +// class PanelListenerImpl : public PanelStatusListener { +class PanelListenerImpl { +public: + // struct UvEntry { + // WindowSize size; + // PanelAdjustInfo keyboardArea; + // std::shared_ptr cbCopy; + // explicit UvEntry(const std::shared_ptr &cb) : cbCopy(cb) + // { + // } + // }; + // using EntrySetter = std::function; + static std::shared_ptr GetInstance(); + ~PanelListenerImpl(); + // void OnPanelStatus(uint32_t windowId, bool isShow) override; + // void OnSizeChange(uint32_t windowId, const WindowSize &size) override; + // void OnSizeChange(uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, + // const std::string &event) override; + // void Subscribe(uint32_t windowId, const std::string &type, std::shared_ptr cbObject); + // void RemoveInfo(const std::string &type, uint32_t windowId); + void SetEventHandler(std::shared_ptr handler); + // std::shared_ptr GetCallback(uint32_t windowId, const std::string &type); + // std::shared_ptr GetEventHandler(); + + // ConcurrentMap>> callbacks_; + static std::mutex listenerMutex_; + static std::shared_ptr instance_; + mutable std::shared_mutex eventHandlerMutex_; + std::shared_ptr handler_; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif //SELECTON_FWK_PANEL_LISTENER_IMPL_H diff --git a/frameworks/js/napi/selection_client/async_call.cpp b/frameworks/js/napi/selection_client/async_call.cpp new file mode 100644 index 0000000..6f287b9 --- /dev/null +++ b/frameworks/js/napi/selection_client/async_call.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2021 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 "async_call.h" +#include +#include +#include +#include "selection_log.h" +#include "js_utils.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace SelectionFwk { +using namespace std::chrono; +constexpr size_t ARGC_MAX = 6; +constexpr int32_t MAX_WAIT_TIME = 100; // ms +static inline uint64_t GetTimeStamp() +{ + return duration_cast(system_clock::now().time_since_epoch()).count(); +} +AsyncCall::AsyncCall(napi_env env, napi_callback_info info, std::shared_ptr context, size_t maxParamCount) + : env_(env) +{ + context_ = new AsyncContext(); + NAPI_ASSERT_RETURN_VOID(env, context_ != nullptr, "context_ != nullptr"); + size_t argc = ARGC_MAX; + napi_value self = nullptr; + napi_value argv[ARGC_MAX] = { nullptr }; + NAPI_CALL_RETURN_VOID(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr)); + napi_valuetype valueType = napi_undefined; + argc = std::min(argc, maxParamCount); + if (argc > 0) { + napi_typeof(env, argv[argc - 1], &valueType); + if (valueType == napi_function) { + napi_create_reference(env, argv[argc - 1], 1, &context_->callback); + argc = argc - 1; + } + } + NAPI_CALL_RETURN_VOID(env, (*context)(env, argc, argv, self)); + context_->ctx = std::move(context); + napi_create_reference(env, self, 1, &context_->self); +} + +AsyncCall::~AsyncCall() +{ + if (context_ == nullptr) { + return; + } + + DeleteContext(env_, context_); +} + +napi_value AsyncCall::Call(napi_env env, Context::ExecAction exec, const std::string &resourceName) +{ + if (context_ == nullptr) { + SELECTION_HILOGE("context_ is nullptr!"); + return nullptr; + } + if (context_->ctx == nullptr) { + SELECTION_HILOGE("context_->ctx is nullptr!"); + return nullptr; + } + context_->ctx->exec_ = std::move(exec); + napi_value promise = nullptr; + if (context_->callback == nullptr) { + napi_create_promise(env, &context_->defer, &promise); + } else { + napi_get_undefined(env, &promise); + } + napi_async_work work = context_->work; + napi_value resource = nullptr; + std::string name = "IMF_" + resourceName; + napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &resource); + napi_create_async_work(env, nullptr, resource, AsyncCall::OnExecute, AsyncCall::OnComplete, context_, &work); + context_->work = work; + context_ = nullptr; + napi_queue_async_work_with_qos(env, work, napi_qos_user_initiated); + return promise; +} + +napi_value AsyncCall::Post(napi_env env, Context::ExecAction exec, std::shared_ptr queue, const char *func) +{ + if (context_ == nullptr || context_->ctx == nullptr || queue == nullptr) { + SELECTION_HILOGE("context is nullptr!"); + return nullptr; + } + context_->ctx->exec_ = std::move(exec); + napi_value promise = nullptr; + if (context_->callback == nullptr) { + napi_create_promise(env, &context_->defer, &promise); + } else { + napi_get_undefined(env, &promise); + } + napi_async_work work = context_->work; + napi_value resource = nullptr; + napi_create_string_utf8(env, func, NAPI_AUTO_LENGTH, &resource); + napi_create_async_work(env, nullptr, resource, AsyncCall::OnExecuteSeq, AsyncCall::OnComplete, context_, &work); + context_->work = work; + context_->queue = queue; + std::unique_lock lock(queue->queuesMutex_); + queue->taskQueue_.emplace(env, work, func); + if (!queue->isRunning) { + auto status = napi_queue_async_work_with_qos(env, work, napi_qos_user_initiated); + queue->isRunning = status == napi_ok; + if (status != napi_ok) { + SELECTION_HILOGE("async work failed.status:%{public}d, func:%{public}s!", status, func); + } + } + context_ = nullptr; + return promise; +} + +napi_value AsyncCall::SyncCall(napi_env env, AsyncCall::Context::ExecAction exec) +{ + if ((context_ == nullptr) || (context_->ctx == nullptr)) { + SELECTION_HILOGE("context_ or context_->ctx is nullptr!"); + return nullptr; + } + context_->ctx->exec_ = std::move(exec); + napi_value promise = nullptr; + if (context_->callback == nullptr) { + napi_create_promise(env, &context_->defer, &promise); + } else { + napi_get_undefined(env, &promise); + } + AsyncCall::OnExecute(env, context_); + AsyncCall::OnComplete(env, context_->ctx->status_, context_); + return promise; +} + +void AsyncCall::OnExecute(napi_env env, void *data) +{ + AsyncContext *context = reinterpret_cast(data); + if (context == nullptr || context->ctx == nullptr) { + SELECTION_HILOGE("context or context->ctx is nullptr!"); + return; + } + context->ctx->Exec(); +} + +void AsyncCall::OnExecuteSeq(napi_env env, void *data) +{ + OnExecute(env, data); + AsyncContext *context = reinterpret_cast(data); + if (context == nullptr || context->queue == nullptr) { + SELECTION_HILOGE("context or context->queue is nullptr!"); + return; + } + auto queue = context->queue; + std::unique_lock lock(queue->queuesMutex_); + if (!queue->taskQueue_.empty()) { + queue->taskQueue_.pop(); + } + queue->isRunning = !queue->taskQueue_.empty() && + napi_queue_async_work_with_qos(queue->taskQueue_.front().env, + queue->taskQueue_.front().work, napi_qos_user_initiated) == napi_ok; +} + +void AsyncCall::OnComplete(napi_env env, napi_status status, void *data) +{ + AsyncContext *context = reinterpret_cast(data); + napi_value output = nullptr; + if (context == nullptr || context->ctx == nullptr) { + SELECTION_HILOGE("context or context->ctx is nullptr!"); + return; + } + napi_status runStatus = (*context->ctx)(env, &output); + napi_value result[ARG_BUTT] = { 0 }; + if (status == napi_ok && runStatus == napi_ok) { + napi_get_undefined(env, &result[ARG_ERROR]); + if (output != nullptr) { + SELECTION_HILOGD("output != nullptr!"); + result[ARG_DATA] = output; + } else { + SELECTION_HILOGD("output is nullptr!"); + napi_get_undefined(env, &result[ARG_DATA]); + } + } else { + SELECTION_HILOGE("failed, [status:%{public}d, runStatus:%{public}d, errorCode:%{public}d, errMessage:%{public}s].", + status, runStatus, context->ctx->errorCode_, context->ctx->errMessage_.c_str()); + result[ARG_ERROR] = JsUtils::ToError(env, context->ctx->errorCode_, context->ctx->errMessage_); + napi_get_undefined(env, &result[ARG_DATA]); + } + if (context->defer != nullptr) { + if (status == napi_ok && runStatus == napi_ok) { + napi_resolve_deferred(env, context->defer, result[ARG_DATA]); + } else { + napi_reject_deferred(env, context->defer, result[ARG_ERROR]); + } + } else { + napi_value callback = nullptr; + napi_get_reference_value(env, context->callback, &callback); + napi_value returnValue; + napi_call_function(env, nullptr, callback, ARG_BUTT, result, &returnValue); + } + DeleteContext(env, context); +} + +void AsyncCall::DeleteContext(napi_env env, AsyncContext *context) +{ + if (env != nullptr) { + napi_delete_reference(env, context->callback); + napi_delete_reference(env, context->self); + napi_delete_async_work(env, context->work); + } + delete context; +} + +AsyncCall::InnerTask::InnerTask(napi_env env, napi_async_work work, const char *name) + : env(env), work(work), name(name), startTime(GetTimeStamp()) +{ +} + +AsyncCall::InnerTask::~InnerTask() +{ + auto endTime = GetTimeStamp(); + if (startTime > endTime) { + SELECTION_HILOGE("startTime:%{public}" PRIu64 ", endTime:%{public}" PRIu64, startTime, endTime); + return; + } + if (endTime - startTime > MAX_WAIT_TIME) { + SELECTION_HILOGW("async work timeout! func:%{public}s, startTime:%{public}" PRIu64 ", endTime:%{public}" PRIu64 + ", cost:%{public}" PRIu64 "ms", + name, startTime, endTime, endTime - startTime); + } else { + SELECTION_HILOGD("async work finished! func:%{public}s, startTime:%{public}" PRIu64 ", endTime:%{public}" PRIu64 + ", cost:%{public}" PRIu64 "ms", + name, startTime, endTime, endTime - startTime); + } +} +} // namespace SelectionFwk +} // namespace OHOS diff --git a/frameworks/js/napi/selection_client/async_call.h b/frameworks/js/napi/selection_client/async_call.h new file mode 100644 index 0000000..23f69f1 --- /dev/null +++ b/frameworks/js/napi/selection_client/async_call.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021 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 ASYN_CALL_H +#define ASYN_CALL_H + +#include +#include "cpp/mutex.h" +#include "selection_log.h" +#include "js_utils.h" +#include "ffrt.h" +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" + + +namespace OHOS { +namespace SelectionFwk { +class AsyncCall final { +public: + class Context { + public: + using InputAction = std::function; + using OutputAction = std::function; + using ExecAction = std::function; + Context(InputAction input, OutputAction output) : input_(std::move(input)), output_(std::move(output)){}; + virtual ~Context(){}; + void SetAction(InputAction input, OutputAction output = nullptr) + { + input_ = input; + output_ = output; + } + + void SetErrorCode(int32_t errorCode) + { + errorCode_ = errorCode; + } + + void SetErrorMessage(const std::string &errMessage) + { + errMessage_ = errMessage; + } + + void SetState(const napi_status &status) + { + status_ = status; + } + + void SetAction(OutputAction output) + { + SetAction(nullptr, std::move(output)); + } + + virtual napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) + { + if (input_ == nullptr) { + return napi_ok; + } + auto ret = input_(env, argc, argv, self); + input_ = nullptr; + return ret; + } + + virtual napi_status operator()(napi_env env, napi_value *result) + { + if (output_ == nullptr) { + *result = nullptr; + return napi_ok; + } + auto ret = output_(env, result); + output_ = nullptr; + return ret; + } + + virtual void Exec() + { + if (exec_ == nullptr) { + return; + } + exec_(this); + exec_ = nullptr; + }; + + protected: + friend class AsyncCall; + InputAction input_ = nullptr; + OutputAction output_ = nullptr; + ExecAction exec_ = nullptr; + napi_status status_ = napi_generic_failure; + int32_t errorCode_ = 0; + std::string errMessage_; + }; + + struct InnerTask { + InnerTask(napi_env env, napi_async_work work, const char *name); + ~InnerTask(); + napi_env env = nullptr; + napi_async_work work = nullptr; + const char *name = nullptr; + uint64_t startTime = 0; + }; + + struct TaskQueue { + ffrt::mutex queuesMutex_; + std::queue taskQueue_; + bool isRunning = false; + }; + + AsyncCall(napi_env env, napi_callback_info info, std::shared_ptr context, size_t maxParamCount); + ~AsyncCall(); + napi_value Call(napi_env env, Context::ExecAction exec = nullptr, const std::string &resourceName = "AsyncCall"); + napi_value Post(napi_env env, Context::ExecAction exec, std::shared_ptr queue, const char *func); + napi_value SyncCall(napi_env env, Context::ExecAction exec = nullptr); + +private: + enum Arg : int { ARG_ERROR, ARG_DATA, ARG_BUTT }; + static void OnExecute(napi_env env, void *data); + static void OnExecuteSeq(napi_env env, void *data); + static void OnComplete(napi_env env, napi_status status, void *data); + struct AsyncContext { + std::shared_ptr ctx = nullptr; + napi_ref callback = nullptr; + napi_ref self = nullptr; + napi_deferred defer = nullptr; + napi_async_work work = nullptr; + std::shared_ptr queue = nullptr; + }; + static void DeleteContext(napi_env env, AsyncContext *context); + + AsyncContext *context_ = nullptr; + napi_env env_ = nullptr; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // ASYNC_CALL_H \ No newline at end of file diff --git a/frameworks/js/napi/selection_client/js_selection_utils.cpp b/frameworks/js/napi/selection_client/js_selection_utils.cpp new file mode 100644 index 0000000..8e6c3af --- /dev/null +++ b/frameworks/js/napi/selection_client/js_selection_utils.cpp @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2022-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_selection_utils.h" +#include "panel_info.h" + +// #include "js_util.h" + +namespace OHOS { +namespace SelectionFwk { +constexpr int32_t STR_MAX_LENGTH = 4096; +constexpr size_t STR_TAIL_LENGTH = 1; +constexpr size_t ARGC_MAX = 6; +constexpr size_t ARGC_ONE = 1; +// const std::map JsUtils::ERROR_CODE_MAP = { +// { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER }, +// { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION }, +// { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION }, +// { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_EDITABLE }, +// { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED }, +// { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST }, +// { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER }, +// { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IME_START_INPUT_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME }, +// { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE }, +// { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, +// { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME }, +// { ErrorCode::ERROR_ENABLE_IME, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_NOT_CURRENT_IME, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_PANEL_NOT_FOUND, EXCEPTION_PANEL_NOT_FOUND }, +// { ErrorCode::ERROR_WINDOW_MANAGER, EXCEPTION_WINDOW_MANAGER }, +// { ErrorCode::ERROR_GET_TEXT_CONFIG, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE, EXCEPTION_PARAMCHECK }, +// { ErrorCode::ERROR_TEXT_LISTENER_ERROR, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED, EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED }, +// { ErrorCode::ERROR_INVALID_RANGE, EXCEPTION_PARAMCHECK }, +// { ErrorCode::ERROR_SECURITY_MODE_OFF, EXCEPTION_BASIC_MODE }, +// { ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST, EXCEPTION_REQUEST_NOT_ACCEPT }, +// { ErrorCode::ERROR_MESSAGE_HANDLER, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE, EXCEPTION_PARAMCHECK }, +// { ErrorCode::ERROR_INVALID_PANEL_TYPE, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, +// { ErrorCode::ERROR_INVALID_PANEL_FLAG, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, +// { ErrorCode::ERROR_IMA_CHANNEL_NULLPTR, EXCEPTION_IMCLIENT }, +// { ErrorCode::ERROR_IPC_REMOTE_NULLPTR, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMA_NULLPTR, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_INPUT_TYPE_NOT_FOUND, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_MALLOC_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_NULLPTR, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_IME_START_TIMEOUT, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS }, +// { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED }, +// }; + +// const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { +// { EXCEPTION_PERMISSION, "the permissions check fails." }, +// { EXCEPTION_SYSTEM_PERMISSION, "not system application." }, +// { EXCEPTION_PARAMCHECK, "the parameters check fails." }, +// { EXCEPTION_UNSUPPORTED, "capability not supported." }, +// { EXCEPTION_PACKAGEMANAGER, "bundle manager error." }, +// { EXCEPTION_IMENGINE, "input method engine error. Possible causes: 1.input method panel not created.\ +// 2.the input method application does not subscribe to related events." }, +// { EXCEPTION_IMCLIENT, "input method client error. Possible causes: 1.the edit box is not focused.\ +// 2.no edit box is bound to current input method application." }, +// { EXCEPTION_IME, "not an input method application." }, +// { EXCEPTION_CONFPERSIST, "configuration persistence error." }, +// { EXCEPTION_CONTROLLER, "input method controller error.\ +// Possible cause: create InputmethodController object failed." }, +// { EXCEPTION_SETTINGS, "input method setter error. Possible cause: create InputmethodSetting object failed." }, +// { EXCEPTION_IMMS, "input method manager service error. Possible cause: a system error, such as null pointer,\ +// IPC exception." }, +// { EXCEPTION_DETACHED, "input method client detached." }, +// { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." }, +// { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." }, +// { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." }, +// { EXCEPTION_WINDOW_MANAGER, "window manager service error." }, +// { EXCEPTION_BASIC_MODE, "the input method is basic mode." }, +// { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." }, +// { EXCEPTION_EDITABLE, "the edit mode need enable." }, +// { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." }, +// }; + +// const std::map JsUtils::PARAMETER_TYPE = { +// { TYPE_UNDEFINED, "napi_undefine." }, +// { TYPE_NULL, "napi_null." }, +// { TYPE_BOOLEAN, "napi_boolean." }, +// { TYPE_NUMBER, "napi_number." }, +// { TYPE_STRING, "napi_string." }, +// { TYPE_SYMBOL, "napi_symbol." }, +// { TYPE_OBJECT, "napi_object." }, +// { TYPE_FUNCTION, "napi_function." }, +// { TYPE_EXTERNAL, "napi_external." }, +// { TYPE_BIGINT, "napi_bigint." }, +// { TYPE_ARRAY_BUFFER, "ArrayBuffer." }, +// { TYPE_ARRAY, "napi_array." }, +// }; + +// void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type) +// { +// std::string errMsg = ToMessage(err); +// napi_value error; +// napi_value code; +// napi_value message; +// if (type == TypeCode::TYPE_NONE) { +// errMsg = errMsg + " " + msg; +// IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); +// } else { +// auto iter = PARAMETER_TYPE.find(type); +// if (iter != PARAMETER_TYPE.end()) { +// errMsg = errMsg + "The type of " + msg + " must be " + iter->second; +// IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); +// } +// } +// NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message)); +// NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error)); +// NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code)); +// NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code)); +// NAPI_CALL_RETURN_VOID(env, napi_throw(env, error)); +// } + +// napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg) +// { +// IMSA_HILOGD("ToError start"); +// napi_value errorObj; +// NAPI_CALL(env, napi_create_object(env, &errorObj)); +// napi_value errorCode = nullptr; +// NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode)); +// napi_value errorMessage = nullptr; +// std::string errMsg = ToMessage(Convert(code)) + " " + msg; +// NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errorMessage)); +// NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode)); +// NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage)); +// IMSA_HILOGD("ToError end"); +// return errorObj; +// } + +// int32_t JsUtils::Convert(int32_t code) +// { +// IMSA_HILOGD("Convert start."); +// auto iter = ERROR_CODE_MAP.find(code); +// if (iter != ERROR_CODE_MAP.end()) { +// IMSA_HILOGD("ErrorCode: %{public}d", iter->second); +// return iter->second; +// } +// IMSA_HILOGD("Convert end."); +// return ERROR_CODE_QUERY_FAILED; +// } + +// const std::string JsUtils::ToMessage(int32_t code) +// { +// IMSA_HILOGD("ToMessage start"); +// auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code); +// if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) { +// IMSA_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str()); +// return iter->second; +// } +// return "error is out of definition."; +// } +//SJM +// bool JsSelectionUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId) +// { +// if (copy == nullptr) { +// return value == nullptr; +// } + +// if (threadId != std::this_thread::get_id()) { +// SELECTION_HILOGD("napi_value can not be compared"); +// return false; +// } + +// napi_value copyValue = nullptr; +// napi_get_reference_value(env, copy, ©Value); + +// bool isEquals = false; +// napi_strict_equals(env, value, copyValue, &isEquals); +// SELECTION_HILOGD("value compare result: %{public}d", isEquals); +// return isEquals; +// } + +// void *JsSelectionUtils::GetNativeSelf(napi_env env, napi_callback_info info) +// { +// size_t argc = ARGC_MAX; +// void *native = nullptr; +// napi_value self = nullptr; +// napi_value argv[ARGC_MAX] = { nullptr }; +// napi_status status = napi_invalid_arg; +// napi_get_cb_info(env, info, &argc, argv, &self, nullptr); +// CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr); + +// status = napi_unwrap(env, self, &native); +// CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr); +// return native; +// } + +// napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, int32_t &out) +// { +// napi_valuetype type = napi_undefined; +// napi_status status = napi_typeof(env, in, &type); +// CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); +// return napi_get_value_int32(env, in, &out); +// } + +// /* napi_value <-> uint32_t */ +// napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, uint32_t &out) +// { +// napi_valuetype type = napi_undefined; +// napi_status status = napi_typeof(env, in, &type); +// CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); +// return napi_get_value_uint32(env, in, &out); +// }//SJM + +// napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out) +// { +// napi_valuetype type = napi_undefined; +// napi_status status = napi_typeof(env, in, &type); +// CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure); +// return napi_get_value_bool(env, in, &out); +// } + +// napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out) +// { +// napi_valuetype type = napi_undefined; +// napi_status status = napi_typeof(env, in, &type); +// CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure); +// return napi_get_value_double(env, in, &out); +// } + +// /* napi_value <-> std::string */ +// napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out) +// { +// IMSA_HILOGD("JsUtils get string value in."); +// napi_valuetype type = napi_undefined; +// napi_status status = napi_typeof(env, in, &type); +// CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure); + +// size_t maxLen = STR_MAX_LENGTH; +// status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen); +// if (maxLen <= 0) { +// return status; +// } +// IMSA_HILOGD("napi_value -> std::string get length %{public}zu", maxLen); +// char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH]; +// if (buf != nullptr) { +// size_t len = 0; +// status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len); +// if (status == napi_ok) { +// buf[len] = 0; +// out = std::string(buf); +// } +// delete[] buf; +// } else { +// status = napi_generic_failure; +// } +// return status; +// } + +// /* napi_value <-> std::unordered_map */ +// napi_status JsUtils::GetValue(napi_env env, napi_value in, std::unordered_map &out) +// { +// napi_valuetype type = napi_undefined; +// napi_status status = napi_typeof(env, in, &type); +// PARAM_CHECK_RETURN(env, type != napi_undefined, "param is undefined.", TYPE_NONE, napi_generic_failure); + +// napi_value keys = nullptr; +// napi_get_property_names(env, in, &keys); +// uint32_t arrLen = 0; +// status = napi_get_array_length(env, keys, &arrLen); +// if (status != napi_ok) { +// IMSA_HILOGE("napi_get_array_length error"); +// return status; +// } +// // 5 means max private command count. +// PARAM_CHECK_RETURN(env, arrLen <= 5 && arrLen > 0, "privateCommand must more than 0 and less than 5.", TYPE_NONE, +// napi_generic_failure); +// IMSA_HILOGD("length : %{public}u", arrLen); +// for (size_t iter = 0; iter < arrLen; ++iter) { +// napi_value key = nullptr; +// status = napi_get_element(env, keys, iter, &key); +// CHECK_RETURN(status == napi_ok, "napi_get_element error", status); + +// napi_value value = nullptr; +// status = napi_get_property(env, in, key, &value); +// CHECK_RETURN(status == napi_ok, "napi_get_property error", status); + +// std::string keyStr; +// status = GetValue(env, key, keyStr); +// CHECK_RETURN(status == napi_ok, "GetValue keyStr error", status); + +// PrivateDataValue privateCommand; +// status = GetValue(env, value, privateCommand); +// CHECK_RETURN(status == napi_ok, "GetValue privateCommand error", status); +// out.emplace(keyStr, privateCommand); +// } +// return status; +// } + +// napi_status JsUtils::GetValue(napi_env env, napi_value in, PrivateDataValue &out) +// { +// napi_valuetype valueType = napi_undefined; +// napi_status status = napi_typeof(env, in, &valueType); +// CHECK_RETURN(status == napi_ok, "napi_typeof error", napi_generic_failure); +// if (valueType == napi_string) { +// std::string privateDataStr; +// status = GetValue(env, in, privateDataStr); +// CHECK_RETURN(status == napi_ok, "GetValue napi_string error", napi_generic_failure); +// out.emplace(privateDataStr); +// } else if (valueType == napi_boolean) { +// bool privateDataBool = false; +// status = GetValue(env, in, privateDataBool); +// CHECK_RETURN(status == napi_ok, "GetValue napi_boolean error", napi_generic_failure); +// out.emplace(privateDataBool); +// } else if (valueType == napi_number) { +// int32_t privateDataInt = 0; +// status = GetValue(env, in, privateDataInt); +// CHECK_RETURN(status == napi_ok, "GetValue napi_number error", napi_generic_failure); +// out.emplace(privateDataInt); +// } else { +// PARAM_CHECK_RETURN(env, false, "value type must be string | boolean | number", TYPE_NONE, napi_generic_failure); +// } +// return status; +// } + +// napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out) +// { +// napi_valuetype valueType = napi_undefined; +// napi_status status = napi_typeof(env, in, &valueType); +// if ((status == napi_ok) && (valueType == napi_object)) { +// status = napi_get_named_property(env, in, type.c_str(), &out); +// return status; +// } +// return napi_generic_failure; +// } + +/* napi_value <-> PanelInfo */ +napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, PanelInfo &out) +{ + SELECTION_HILOGD("napi_value -> PanelInfo "); + napi_value propType = nullptr; + napi_status status = napi_get_named_property(env, in, "type", &propType); + CHECK_RETURN((status == napi_ok), "no property type ", status); + int32_t panelType = 0; + status = JsUtils::GetValue(env, propType, panelType); + CHECK_RETURN((status == napi_ok), "no value of type ", status); + + // PanelFlag is optional, defaults to FLG_FIXED when empty. + int32_t panelFlag = static_cast(PanelFlag::FLG_FIXED); + napi_value panelFlagObj = nullptr; + status = napi_get_named_property(env, in, "flag", &panelFlagObj); + if (status == napi_ok) { + JsUtils::GetValue(env, panelFlagObj, panelFlag);//JsSelectionUtils::GetValue(env, panelFlagObj, panelFlag); + } + + out.panelType = PanelType(panelType); + out.panelFlag = PanelFlag(panelFlag); + return napi_ok; +} + +// napi_value JsUtils::GetValue(napi_env env, const std::vector &in) +// { +// napi_value array = nullptr; +// uint32_t index = 0; +// napi_create_array(env, &array); +// if (array == nullptr) { +// IMSA_HILOGE("create array failed"); +// return array; +// } +// for (const auto &info : in) { +// napi_value jsInfo = GetValue(env, info); +// napi_set_element(env, array, index, jsInfo); +// ++index; +// } +// return array; +// } + +// napi_value JsUtils::GetValue(napi_env env, const InputWindowInfo &in) +// { +// napi_value info = nullptr; +// napi_create_object(env, &info); + +// napi_value name = nullptr; +// napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name); +// napi_set_named_property(env, info, "name", name); + +// napi_value left = nullptr; +// napi_create_int32(env, in.left, &left); +// napi_set_named_property(env, info, "left", left); + +// napi_value top = nullptr; +// napi_create_int32(env, in.top, &top); +// napi_set_named_property(env, info, "top", top); + +// napi_value width = nullptr; +// napi_create_uint32(env, in.width, &width); +// napi_set_named_property(env, info, "width", width); + +// napi_value height = nullptr; +// napi_create_uint32(env, in.height, &height); +// napi_set_named_property(env, info, "height", height); + +// return info; +// } + +// napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out) +// { +// return napi_create_string_utf8(env, in.c_str(), in.size(), &out); +// } + +// napi_value JsUtils::GetJsPrivateCommand(napi_env env, const std::unordered_map &in) +// { +// napi_value jsPrivateCommand = nullptr; +// NAPI_CALL(env, napi_create_object(env, &jsPrivateCommand)); +// for (const auto &iter : in) { +// size_t idx = iter.second.index(); +// napi_value value = nullptr; +// if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_STRING)) { +// auto stringValue = std::get_if(&iter.second); +// if (stringValue != nullptr) { +// NAPI_CALL(env, napi_create_string_utf8(env, (*stringValue).c_str(), (*stringValue).size(), &value)); +// } +// } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_BOOL)) { +// auto boolValue = std::get_if(&iter.second); +// if (boolValue != nullptr) { +// NAPI_CALL(env, napi_get_boolean(env, *boolValue, &value)); +// } +// } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_NUMBER)) { +// auto numberValue = std::get_if(&iter.second); +// if (numberValue != nullptr) { +// NAPI_CALL(env, napi_create_int32(env, *numberValue, &value)); +// } +// } +// NAPI_CALL(env, napi_set_named_property(env, jsPrivateCommand, iter.first.c_str(), value)); +// } +// return jsPrivateCommand; +// } + +// napi_value JsUtils::GetValue(napi_env env, const std::vector &in) +// { +// void *data = nullptr; +// napi_value arrayBuffer = nullptr; +// size_t length = in.size(); +// NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer)); +// // 0 means the size of data. +// CHECK_RETURN(length != 0, "Data size is 0.", arrayBuffer); +// if (memcpy_s(data, length, reinterpret_cast(in.data()), length) != 0) { +// return nullptr; +// } +// return arrayBuffer; +// } + +// napi_status JsUtils::GetValue(napi_env env, napi_value in, std::vector &out) +// { +// size_t length = 0; +// void *data = nullptr; +// auto status = napi_get_arraybuffer_info(env, in, &data, &length); +// if (status != napi_ok) { +// IMSA_HILOGE("Get ArrayBuffer info failed!"); +// return status; +// } +// if (data == nullptr && length == 0) { +// IMSA_HILOGE("Empty ArrayBuffer."); +// out.clear(); +// return napi_ok; +// } +// if (data == nullptr) { +// IMSA_HILOGE("ArrayBuffer data is nullptr!"); +// return napi_generic_failure; +// } +// IMSA_HILOGD("ArrayBuffer data size: %{public}zu.", length); +// out.assign(reinterpret_cast(data), reinterpret_cast(data) + length); +// return napi_ok; +// } + +// napi_status JsUtils::GetMessageHandlerCallbackParam(napi_value *argv, +// const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, size_t size) +// { +// if (argv == nullptr) { +// IMSA_HILOGE("argv is nullptr!."); +// return napi_generic_failure; +// } +// if (size < ARGC_ONE) { +// IMSA_HILOGE("argv size is less than 1!."); +// return napi_generic_failure; +// } +// if (jsMessageHandler == nullptr) { +// IMSA_HILOGE("jsMessageHandler is nullptr!."); +// return napi_generic_failure; +// } +// napi_value jsMsgId = nullptr; +// auto status = napi_create_string_utf8( +// jsMessageHandler->env_, arrayBuffer.msgId.c_str(), NAPI_AUTO_LENGTH, &jsMsgId); +// if (status != napi_ok) { +// IMSA_HILOGE("napi_create_string_utf8 failed!."); +// return napi_generic_failure; +// } +// // 0 means the first param index of callback. +// argv[0] = { jsMsgId }; +// if (arrayBuffer.jsArgc > ARGC_ONE) { +// napi_value jsMsgParam = JsUtils::GetValue(jsMessageHandler->env_, arrayBuffer.msgParam); +// if (jsMsgParam == nullptr) { +// IMSA_HILOGE("Get js messageParam object failed!."); +// return napi_generic_failure; +// } +// // 0 means the second param index of callback. +// argv[1] = { jsMsgParam }; +// } +// return napi_ok; +// } + +// napi_status JsUtils::GetValue(napi_env env, napi_value in, Rosen::Rect &out) +// { +// bool ret = JsUtil::Object::ReadProperty(env, in, "left", out.posX_); +// ret = ret && JsUtil::Object::ReadProperty(env, in, "top", out.posY_); +// ret = ret && JsUtil::Object::ReadProperty(env, in, "width", out.width_); +// ret = ret && JsUtil::Object::ReadProperty(env, in, "height", out.height_); +// return ret ? napi_ok : napi_generic_failure; +// } + +// napi_value JsUtils::GetValue(napi_env env, const Rosen::Rect &in) +// { +// napi_value jsObject = nullptr; +// napi_create_object(env, &jsObject); +// bool ret = JsUtil::Object::WriteProperty(env, jsObject, "left", in.posX_); +// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "top", in.posY_); +// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "width", in.width_); +// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", in.height_); +// return ret ? jsObject : JsUtil::Const::Null(env); +// } +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/selection_client/js_selection_utils.h b/frameworks/js/napi/selection_client/js_selection_utils.h new file mode 100644 index 0000000..c070aef --- /dev/null +++ b/frameworks/js/napi/selection_client/js_selection_utils.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2022-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 JS_SELECTION_UTILS_H +#define JS_SELECTION_UTILS_H + +#include + +#include "ability.h" +#include "selection_log.h" +#include "selection_panel.h" +// #include "selection_utils.h" +// #include "js_callback_object.h" +#include "util.h" +#include "js_utils.h" +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "string_ex.h" +#include "panel_info.h" + +using Ability = OHOS::AppExecFwk::Ability; +namespace OHOS { +namespace SelectionFwk { +// enum IMFErrorCode : int32_t { +// EXCEPTION_PERMISSION = 201, +// EXCEPTION_SYSTEM_PERMISSION = 202, +// EXCEPTION_PARAMCHECK = 401, +// EXCEPTION_UNSUPPORTED = 801, +// EXCEPTION_PACKAGEMANAGER = 12800001, +// EXCEPTION_IMENGINE = 12800002, +// EXCEPTION_IMCLIENT = 12800003, +// EXCEPTION_IME = 12800004, +// EXCEPTION_CONFPERSIST = 12800005, +// EXCEPTION_CONTROLLER = 12800006, +// EXCEPTION_SETTINGS = 12800007, +// EXCEPTION_IMMS = 12800008, +// EXCEPTION_DETACHED = 12800009, +// EXCEPTION_DEFAULTIME = 12800010, +// EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED = 12800011, +// EXCEPTION_PANEL_NOT_FOUND = 12800012, +// EXCEPTION_WINDOW_MANAGER = 12800013, +// EXCEPTION_BASIC_MODE = 12800014, +// EXCEPTION_REQUEST_NOT_ACCEPT = 12800015, +// EXCEPTION_EDITABLE = 12800016, +// EXCEPTION_INVALID_PANEL_TYPE_FLAG = 12800017, +// }; + +// enum TypeCode : int32_t { +// TYPE_NONE = 0, +// TYPE_UNDEFINED, +// TYPE_NULL, +// TYPE_BOOLEAN, +// TYPE_NUMBER, +// TYPE_STRING, +// TYPE_SYMBOL, +// TYPE_OBJECT, +// TYPE_FUNCTION, +// TYPE_EXTERNAL, +// TYPE_BIGINT, +// TYPE_ARRAY_BUFFER, +// TYPE_ARRAY, +// }; + +// /* check condition, return and logging if condition not true. */ +// #define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \ +// do { \ +// if (!(condition)) { \ +// JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ +// return retVal; \ +// } \ +// } while (0) + +// #define PARAM_CHECK_RETURN_VOID(env, condition, message, typeCode) \ +// do { \ +// if (!(condition)) { \ +// JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ +// return; \ +// } \ +// } while (0) + +// #define RESULT_CHECK_RETURN(env, condition, errCode, message, typeCode, retVal) \ +// do { \ +// if (!(condition)) { \ +// JsUtils::ThrowException(env, errCode, message, typeCode); \ +// return retVal; \ +// } \ +// } while (0) + +// #define RESULT_CHECK_RETURN_VOID(env, condition, errCode, message, typeCode) \ +// do { \ +// if (!(condition)) { \ +// JsUtils::ThrowException(env, errCode, message, typeCode); \ +// return; \ +// } \ +// } while (0) + +// /* check condition, return and logging. */ +// #define CHECK_RETURN_VOID(condition, message) \ +// do { \ +// if (!(condition)) { \ +// SELECTION_HILOGE("test (" #condition ") failed: " message); \ +// return; \ +// } \ +// } while (0) + +// /* check condition, return and logging. */ +// #define CHECK_RETURN(condition, message, retVal) \ +// do { \ +// if (!(condition)) { \ +// SELECTION_HILOGE("test (" #condition ") failed: " message); \ +// return retVal; \ +// } \ +// } while (0) + +// struct JsPropertyInfo { +// napi_valuetype type; +// TypeCode typeCode; +// std::string propertyName; +// }; + +class JsSelectionUtils { +public: + // static void ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type); + + // static napi_value ToError(napi_env env, int32_t code, const std::string &msg); + + // static int32_t Convert(int32_t code); + + // static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId);// + + // static void *GetNativeSelf(napi_env env, napi_callback_info info);// + + // static const std::string ToMessage(int32_t code); + + // template + // static bool ReadOptionalProperty(napi_env env, napi_value object, const JsPropertyInfo &jsPropInfo, T &value) + // { + // if (!JsUtil::HasProperty(env, object, jsPropInfo.propertyName.c_str())) { + // return false; + // } + // napi_value jsObject = nullptr; + // napi_get_named_property(env, object, jsPropInfo.propertyName.c_str(), &jsObject); + // PARAM_CHECK_RETURN(env, JsUtil::GetType(env, jsObject) == jsPropInfo.type, jsPropInfo.propertyName, + // jsPropInfo.typeCode, false); + // PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, jsObject, value) == napi_ok, + // "failed to convert " + jsPropInfo.propertyName, TYPE_NONE, false); + // return true; + // } + + // static napi_status GetValue(napi_env env, napi_value in, int32_t &out);// + // static napi_status GetValue(napi_env env, napi_value in, uint32_t &out);// + // static napi_status GetValue(napi_env env, napi_value in, bool &out); + // static napi_status GetValue(napi_env env, napi_value in, double &out); + // static napi_status GetValue(napi_env env, napi_value in, std::string &out); + // static napi_status GetValue(napi_env env, napi_value in, std::unordered_map &out); + // static napi_status GetValue(napi_env env, napi_value in, PrivateDataValue &out); + // static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); + static napi_status GetValue(napi_env env, napi_value in, PanelInfo &out); + // static napi_status GetValue(napi_env env, napi_value in, std::vector &out); + // static napi_status GetValue(napi_env env, napi_value in, Rosen::Rect &out); + // static napi_value GetValue(napi_env env, const std::vector &in); + // static napi_value GetValue(napi_env env, const InputWindowInfo &in); + // static napi_value GetValue(napi_env env, const Rosen::Rect &in); + // static napi_value GetJsPrivateCommand(napi_env env, const std::unordered_map &in); + // static napi_value GetValue(napi_env env, const std::vector &in); + // static napi_status GetValue(napi_env env, const std::string &in, napi_value &out); + // static napi_status GetMessageHandlerCallbackParam(napi_value *argv, + // const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, + // size_t size); + +private: + // static const std::map ERROR_CODE_MAP; + + // static const std::map ERROR_CODE_CONVERT_MESSAGE_MAP; + + // static const std::map PARAMETER_TYPE; + + // static constexpr int32_t ERROR_CODE_QUERY_FAILED = 1; + + // static constexpr uint8_t MAX_ARGMENT_COUNT = 10; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // JS_SELECTION_UTILS_H \ No newline at end of file diff --git a/frameworks/js/napi/selection_client/js_utils.cpp.bak b/frameworks/js/napi/selection_client/js_utils.cpp.bak new file mode 100644 index 0000000..1546d8f --- /dev/null +++ b/frameworks/js/napi/selection_client/js_utils.cpp.bak @@ -0,0 +1,567 @@ +/* + * Copyright (c) 2022-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_utils.h" + +#include "js_util.h" + +namespace OHOS { +namespace MiscServices { +constexpr int32_t STR_MAX_LENGTH = 4096; +constexpr size_t STR_TAIL_LENGTH = 1; +constexpr size_t ARGC_MAX = 6; +constexpr size_t ARGC_ONE = 1; +const std::map JsUtils::ERROR_CODE_MAP = { + { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER }, + { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION }, + { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION }, + { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_EDITABLE }, + { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED }, + { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS }, + { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS }, + { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS }, + { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST }, + { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER }, + { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS }, + { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IME_START_INPUT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME }, + { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE }, + { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME }, + { ErrorCode::ERROR_ENABLE_IME, EXCEPTION_IMMS }, + { ErrorCode::ERROR_NOT_CURRENT_IME, EXCEPTION_IMMS }, + { ErrorCode::ERROR_PANEL_NOT_FOUND, EXCEPTION_PANEL_NOT_FOUND }, + { ErrorCode::ERROR_WINDOW_MANAGER, EXCEPTION_WINDOW_MANAGER }, + { ErrorCode::ERROR_GET_TEXT_CONFIG, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_TEXT_LISTENER_ERROR, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED, EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED }, + { ErrorCode::ERROR_INVALID_RANGE, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_SECURITY_MODE_OFF, EXCEPTION_BASIC_MODE }, + { ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST, EXCEPTION_REQUEST_NOT_ACCEPT }, + { ErrorCode::ERROR_MESSAGE_HANDLER, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE, EXCEPTION_PARAMCHECK }, + { ErrorCode::ERROR_INVALID_PANEL_TYPE, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, + { ErrorCode::ERROR_INVALID_PANEL_FLAG, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, + { ErrorCode::ERROR_IMA_CHANNEL_NULLPTR, EXCEPTION_IMCLIENT }, + { ErrorCode::ERROR_IPC_REMOTE_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMA_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_INPUT_TYPE_NOT_FOUND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_MALLOC_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_START_TIMEOUT, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS }, + { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS }, + { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED }, +}; + +const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { + { EXCEPTION_PERMISSION, "the permissions check fails." }, + { EXCEPTION_SYSTEM_PERMISSION, "not system application." }, + { EXCEPTION_PARAMCHECK, "the parameters check fails." }, + { EXCEPTION_UNSUPPORTED, "capability not supported." }, + { EXCEPTION_PACKAGEMANAGER, "bundle manager error." }, + { EXCEPTION_IMENGINE, "input method engine error. Possible causes: 1.input method panel not created.\ + 2.the input method application does not subscribe to related events." }, + { EXCEPTION_IMCLIENT, "input method client error. Possible causes: 1.the edit box is not focused.\ + 2.no edit box is bound to current input method application." }, + { EXCEPTION_IME, "not an input method application." }, + { EXCEPTION_CONFPERSIST, "configuration persistence error." }, + { EXCEPTION_CONTROLLER, "input method controller error.\ + Possible cause: create InputmethodController object failed." }, + { EXCEPTION_SETTINGS, "input method setter error. Possible cause: create InputmethodSetting object failed." }, + { EXCEPTION_IMMS, "input method manager service error. Possible cause: a system error, such as null pointer,\ + IPC exception." }, + { EXCEPTION_DETACHED, "input method client detached." }, + { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." }, + { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." }, + { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." }, + { EXCEPTION_WINDOW_MANAGER, "window manager service error." }, + { EXCEPTION_BASIC_MODE, "the input method is basic mode." }, + { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." }, + { EXCEPTION_EDITABLE, "the edit mode need enable." }, + { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." }, +}; + +const std::map JsUtils::PARAMETER_TYPE = { + { TYPE_UNDEFINED, "napi_undefine." }, + { TYPE_NULL, "napi_null." }, + { TYPE_BOOLEAN, "napi_boolean." }, + { TYPE_NUMBER, "napi_number." }, + { TYPE_STRING, "napi_string." }, + { TYPE_SYMBOL, "napi_symbol." }, + { TYPE_OBJECT, "napi_object." }, + { TYPE_FUNCTION, "napi_function." }, + { TYPE_EXTERNAL, "napi_external." }, + { TYPE_BIGINT, "napi_bigint." }, + { TYPE_ARRAY_BUFFER, "ArrayBuffer." }, + { TYPE_ARRAY, "napi_array." }, +}; + +void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type) +{ + std::string errMsg = ToMessage(err); + napi_value error; + napi_value code; + napi_value message; + if (type == TypeCode::TYPE_NONE) { + errMsg = errMsg + " " + msg; + IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); + } else { + auto iter = PARAMETER_TYPE.find(type); + if (iter != PARAMETER_TYPE.end()) { + errMsg = errMsg + "The type of " + msg + " must be " + iter->second; + IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); + } + } + NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message)); + NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error)); + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code)); + NAPI_CALL_RETURN_VOID(env, napi_throw(env, error)); +} + +napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg) +{ + IMSA_HILOGD("ToError start"); + napi_value errorObj; + NAPI_CALL(env, napi_create_object(env, &errorObj)); + napi_value errorCode = nullptr; + NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode)); + napi_value errorMessage = nullptr; + std::string errMsg = ToMessage(Convert(code)) + " " + msg; + NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errorMessage)); + NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode)); + NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage)); + IMSA_HILOGD("ToError end"); + return errorObj; +} + +int32_t JsUtils::Convert(int32_t code) +{ + IMSA_HILOGD("Convert start."); + auto iter = ERROR_CODE_MAP.find(code); + if (iter != ERROR_CODE_MAP.end()) { + IMSA_HILOGD("ErrorCode: %{public}d", iter->second); + return iter->second; + } + IMSA_HILOGD("Convert end."); + return ERROR_CODE_QUERY_FAILED; +} + +const std::string JsUtils::ToMessage(int32_t code) +{ + IMSA_HILOGD("ToMessage start"); + auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code); + if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) { + IMSA_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str()); + return iter->second; + } + return "error is out of definition."; +} + +bool JsUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId) +{ + if (copy == nullptr) { + return value == nullptr; + } + + if (threadId != std::this_thread::get_id()) { + IMSA_HILOGD("napi_value can not be compared"); + return false; + } + + napi_value copyValue = nullptr; + napi_get_reference_value(env, copy, ©Value); + + bool isEquals = false; + napi_strict_equals(env, value, copyValue, &isEquals); + IMSA_HILOGD("value compare result: %{public}d", isEquals); + return isEquals; +} + +void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_MAX; + void *native = nullptr; + napi_value self = nullptr; + napi_value argv[ARGC_MAX] = { nullptr }; + napi_status status = napi_invalid_arg; + napi_get_cb_info(env, info, &argc, argv, &self, nullptr); + CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr); + + status = napi_unwrap(env, self, &native); + CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr); + return native; +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); + return napi_get_value_int32(env, in, &out); +} + +/* napi_value <-> uint32_t */ +napi_status JsUtils::GetValue(napi_env env, napi_value in, uint32_t &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); + return napi_get_value_uint32(env, in, &out); +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure); + return napi_get_value_bool(env, in, &out); +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure); + return napi_get_value_double(env, in, &out); +} + +/* napi_value <-> std::string */ +napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out) +{ + IMSA_HILOGD("JsUtils get string value in."); + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure); + + size_t maxLen = STR_MAX_LENGTH; + status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen); + if (maxLen <= 0) { + return status; + } + IMSA_HILOGD("napi_value -> std::string get length %{public}zu", maxLen); + char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH]; + if (buf != nullptr) { + size_t len = 0; + status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len); + if (status == napi_ok) { + buf[len] = 0; + out = std::string(buf); + } + delete[] buf; + } else { + status = napi_generic_failure; + } + return status; +} + +/* napi_value <-> std::unordered_map */ +napi_status JsUtils::GetValue(napi_env env, napi_value in, std::unordered_map &out) +{ + napi_valuetype type = napi_undefined; + napi_status status = napi_typeof(env, in, &type); + PARAM_CHECK_RETURN(env, type != napi_undefined, "param is undefined.", TYPE_NONE, napi_generic_failure); + + napi_value keys = nullptr; + napi_get_property_names(env, in, &keys); + uint32_t arrLen = 0; + status = napi_get_array_length(env, keys, &arrLen); + if (status != napi_ok) { + IMSA_HILOGE("napi_get_array_length error"); + return status; + } + // 5 means max private command count. + PARAM_CHECK_RETURN(env, arrLen <= 5 && arrLen > 0, "privateCommand must more than 0 and less than 5.", TYPE_NONE, + napi_generic_failure); + IMSA_HILOGD("length : %{public}u", arrLen); + for (size_t iter = 0; iter < arrLen; ++iter) { + napi_value key = nullptr; + status = napi_get_element(env, keys, iter, &key); + CHECK_RETURN(status == napi_ok, "napi_get_element error", status); + + napi_value value = nullptr; + status = napi_get_property(env, in, key, &value); + CHECK_RETURN(status == napi_ok, "napi_get_property error", status); + + std::string keyStr; + status = GetValue(env, key, keyStr); + CHECK_RETURN(status == napi_ok, "GetValue keyStr error", status); + + PrivateDataValue privateCommand; + status = GetValue(env, value, privateCommand); + CHECK_RETURN(status == napi_ok, "GetValue privateCommand error", status); + out.emplace(keyStr, privateCommand); + } + return status; +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, PrivateDataValue &out) +{ + napi_valuetype valueType = napi_undefined; + napi_status status = napi_typeof(env, in, &valueType); + CHECK_RETURN(status == napi_ok, "napi_typeof error", napi_generic_failure); + if (valueType == napi_string) { + std::string privateDataStr; + status = GetValue(env, in, privateDataStr); + CHECK_RETURN(status == napi_ok, "GetValue napi_string error", napi_generic_failure); + out.emplace(privateDataStr); + } else if (valueType == napi_boolean) { + bool privateDataBool = false; + status = GetValue(env, in, privateDataBool); + CHECK_RETURN(status == napi_ok, "GetValue napi_boolean error", napi_generic_failure); + out.emplace(privateDataBool); + } else if (valueType == napi_number) { + int32_t privateDataInt = 0; + status = GetValue(env, in, privateDataInt); + CHECK_RETURN(status == napi_ok, "GetValue napi_number error", napi_generic_failure); + out.emplace(privateDataInt); + } else { + PARAM_CHECK_RETURN(env, false, "value type must be string | boolean | number", TYPE_NONE, napi_generic_failure); + } + return status; +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out) +{ + napi_valuetype valueType = napi_undefined; + napi_status status = napi_typeof(env, in, &valueType); + if ((status == napi_ok) && (valueType == napi_object)) { + status = napi_get_named_property(env, in, type.c_str(), &out); + return status; + } + return napi_generic_failure; +} + +/* napi_value <-> PanelInfo */ +napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out) +{ + IMSA_HILOGD("napi_value -> PanelInfo "); + napi_value propType = nullptr; + napi_status status = napi_get_named_property(env, in, "type", &propType); + CHECK_RETURN((status == napi_ok), "no property type ", status); + int32_t panelType = 0; + status = GetValue(env, propType, panelType); + CHECK_RETURN((status == napi_ok), "no value of type ", status); + + // PanelFlag is optional, defaults to FLG_FIXED when empty. + int32_t panelFlag = static_cast(PanelFlag::FLG_FIXED); + napi_value panelFlagObj = nullptr; + status = napi_get_named_property(env, in, "flag", &panelFlagObj); + if (status == napi_ok) { + JsUtils::GetValue(env, panelFlagObj, panelFlag); + } + + out.panelType = PanelType(panelType); + out.panelFlag = PanelFlag(panelFlag); + return napi_ok; +} + +napi_value JsUtils::GetValue(napi_env env, const std::vector &in) +{ + napi_value array = nullptr; + uint32_t index = 0; + napi_create_array(env, &array); + if (array == nullptr) { + IMSA_HILOGE("create array failed"); + return array; + } + for (const auto &info : in) { + napi_value jsInfo = GetValue(env, info); + napi_set_element(env, array, index, jsInfo); + ++index; + } + return array; +} + +napi_value JsUtils::GetValue(napi_env env, const InputWindowInfo &in) +{ + napi_value info = nullptr; + napi_create_object(env, &info); + + napi_value name = nullptr; + napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name); + napi_set_named_property(env, info, "name", name); + + napi_value left = nullptr; + napi_create_int32(env, in.left, &left); + napi_set_named_property(env, info, "left", left); + + napi_value top = nullptr; + napi_create_int32(env, in.top, &top); + napi_set_named_property(env, info, "top", top); + + napi_value width = nullptr; + napi_create_uint32(env, in.width, &width); + napi_set_named_property(env, info, "width", width); + + napi_value height = nullptr; + napi_create_uint32(env, in.height, &height); + napi_set_named_property(env, info, "height", height); + + return info; +} + +napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out) +{ + return napi_create_string_utf8(env, in.c_str(), in.size(), &out); +} + +napi_value JsUtils::GetJsPrivateCommand(napi_env env, const std::unordered_map &in) +{ + napi_value jsPrivateCommand = nullptr; + NAPI_CALL(env, napi_create_object(env, &jsPrivateCommand)); + for (const auto &iter : in) { + size_t idx = iter.second.index(); + napi_value value = nullptr; + if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_STRING)) { + auto stringValue = std::get_if(&iter.second); + if (stringValue != nullptr) { + NAPI_CALL(env, napi_create_string_utf8(env, (*stringValue).c_str(), (*stringValue).size(), &value)); + } + } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_BOOL)) { + auto boolValue = std::get_if(&iter.second); + if (boolValue != nullptr) { + NAPI_CALL(env, napi_get_boolean(env, *boolValue, &value)); + } + } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_NUMBER)) { + auto numberValue = std::get_if(&iter.second); + if (numberValue != nullptr) { + NAPI_CALL(env, napi_create_int32(env, *numberValue, &value)); + } + } + NAPI_CALL(env, napi_set_named_property(env, jsPrivateCommand, iter.first.c_str(), value)); + } + return jsPrivateCommand; +} + +napi_value JsUtils::GetValue(napi_env env, const std::vector &in) +{ + void *data = nullptr; + napi_value arrayBuffer = nullptr; + size_t length = in.size(); + NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer)); + // 0 means the size of data. + CHECK_RETURN(length != 0, "Data size is 0.", arrayBuffer); + if (memcpy_s(data, length, reinterpret_cast(in.data()), length) != 0) { + return nullptr; + } + return arrayBuffer; +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, std::vector &out) +{ + size_t length = 0; + void *data = nullptr; + auto status = napi_get_arraybuffer_info(env, in, &data, &length); + if (status != napi_ok) { + IMSA_HILOGE("Get ArrayBuffer info failed!"); + return status; + } + if (data == nullptr && length == 0) { + IMSA_HILOGE("Empty ArrayBuffer."); + out.clear(); + return napi_ok; + } + if (data == nullptr) { + IMSA_HILOGE("ArrayBuffer data is nullptr!"); + return napi_generic_failure; + } + IMSA_HILOGD("ArrayBuffer data size: %{public}zu.", length); + out.assign(reinterpret_cast(data), reinterpret_cast(data) + length); + return napi_ok; +} + +napi_status JsUtils::GetMessageHandlerCallbackParam(napi_value *argv, + const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, size_t size) +{ + if (argv == nullptr) { + IMSA_HILOGE("argv is nullptr!."); + return napi_generic_failure; + } + if (size < ARGC_ONE) { + IMSA_HILOGE("argv size is less than 1!."); + return napi_generic_failure; + } + if (jsMessageHandler == nullptr) { + IMSA_HILOGE("jsMessageHandler is nullptr!."); + return napi_generic_failure; + } + napi_value jsMsgId = nullptr; + auto status = napi_create_string_utf8( + jsMessageHandler->env_, arrayBuffer.msgId.c_str(), NAPI_AUTO_LENGTH, &jsMsgId); + if (status != napi_ok) { + IMSA_HILOGE("napi_create_string_utf8 failed!."); + return napi_generic_failure; + } + // 0 means the first param index of callback. + argv[0] = { jsMsgId }; + if (arrayBuffer.jsArgc > ARGC_ONE) { + napi_value jsMsgParam = JsUtils::GetValue(jsMessageHandler->env_, arrayBuffer.msgParam); + if (jsMsgParam == nullptr) { + IMSA_HILOGE("Get js messageParam object failed!."); + return napi_generic_failure; + } + // 0 means the second param index of callback. + argv[1] = { jsMsgParam }; + } + return napi_ok; +} + +napi_status JsUtils::GetValue(napi_env env, napi_value in, Rosen::Rect &out) +{ + bool ret = JsUtil::Object::ReadProperty(env, in, "left", out.posX_); + ret = ret && JsUtil::Object::ReadProperty(env, in, "top", out.posY_); + ret = ret && JsUtil::Object::ReadProperty(env, in, "width", out.width_); + ret = ret && JsUtil::Object::ReadProperty(env, in, "height", out.height_); + return ret ? napi_ok : napi_generic_failure; +} + +napi_value JsUtils::GetValue(napi_env env, const Rosen::Rect &in) +{ + napi_value jsObject = nullptr; + napi_create_object(env, &jsObject); + bool ret = JsUtil::Object::WriteProperty(env, jsObject, "left", in.posX_); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "top", in.posY_); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "width", in.width_); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", in.height_); + return ret ? jsObject : JsUtil::Const::Null(env); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/selection_client/js_utils.h.bak b/frameworks/js/napi/selection_client/js_utils.h.bak new file mode 100644 index 0000000..0ae0a1a --- /dev/null +++ b/frameworks/js/napi/selection_client/js_utils.h.bak @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2022-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 INTERFACE_KITS_JS_UTILS_H +#define INTERFACE_KITS_JS_UTILS_H + +#include + +#include "ability.h" +#include "selection_log.h" +#include "selection_panel.h" +// #include "selection_utils.h" +#include "js_callback_object.h" +#include "js_util.h" +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" +#include "string_ex.h" + +using Ability = OHOS::AppExecFwk::Ability; +namespace OHOS { +namespace MiscServices { +enum IMFErrorCode : int32_t { + EXCEPTION_PERMISSION = 201, + EXCEPTION_SYSTEM_PERMISSION = 202, + EXCEPTION_PARAMCHECK = 401, + EXCEPTION_UNSUPPORTED = 801, + EXCEPTION_PACKAGEMANAGER = 12800001, + EXCEPTION_IMENGINE = 12800002, + EXCEPTION_IMCLIENT = 12800003, + EXCEPTION_IME = 12800004, + EXCEPTION_CONFPERSIST = 12800005, + EXCEPTION_CONTROLLER = 12800006, + EXCEPTION_SETTINGS = 12800007, + EXCEPTION_IMMS = 12800008, + EXCEPTION_DETACHED = 12800009, + EXCEPTION_DEFAULTIME = 12800010, + EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED = 12800011, + EXCEPTION_PANEL_NOT_FOUND = 12800012, + EXCEPTION_WINDOW_MANAGER = 12800013, + EXCEPTION_BASIC_MODE = 12800014, + EXCEPTION_REQUEST_NOT_ACCEPT = 12800015, + EXCEPTION_EDITABLE = 12800016, + EXCEPTION_INVALID_PANEL_TYPE_FLAG = 12800017, +}; + +enum TypeCode : int32_t { + TYPE_NONE = 0, + TYPE_UNDEFINED, + TYPE_NULL, + TYPE_BOOLEAN, + TYPE_NUMBER, + TYPE_STRING, + TYPE_SYMBOL, + TYPE_OBJECT, + TYPE_FUNCTION, + TYPE_EXTERNAL, + TYPE_BIGINT, + TYPE_ARRAY_BUFFER, + TYPE_ARRAY, +}; + +/* check condition, return and logging if condition not true. */ +#define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + return retVal; \ + } \ + } while (0) + +#define PARAM_CHECK_RETURN_VOID(env, condition, message, typeCode) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + return; \ + } \ + } while (0) + +#define RESULT_CHECK_RETURN(env, condition, errCode, message, typeCode, retVal) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, errCode, message, typeCode); \ + return retVal; \ + } \ + } while (0) + +#define RESULT_CHECK_RETURN_VOID(env, condition, errCode, message, typeCode) \ + do { \ + if (!(condition)) { \ + JsUtils::ThrowException(env, errCode, message, typeCode); \ + return; \ + } \ + } while (0) + +/* check condition, return and logging. */ +#define CHECK_RETURN_VOID(condition, message) \ + do { \ + if (!(condition)) { \ + IMSA_HILOGE("test (" #condition ") failed: " message); \ + return; \ + } \ + } while (0) + +/* check condition, return and logging. */ +#define CHECK_RETURN(condition, message, retVal) \ + do { \ + if (!(condition)) { \ + IMSA_HILOGE("test (" #condition ") failed: " message); \ + return retVal; \ + } \ + } while (0) + +struct JsPropertyInfo { + napi_valuetype type; + TypeCode typeCode; + std::string propertyName; +}; + +class JsUtils { +public: + static void ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type); + + static napi_value ToError(napi_env env, int32_t code, const std::string &msg); + + static int32_t Convert(int32_t code); + + static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId); + + static void *GetNativeSelf(napi_env env, napi_callback_info info); + + static const std::string ToMessage(int32_t code); + + template + static bool ReadOptionalProperty(napi_env env, napi_value object, const JsPropertyInfo &jsPropInfo, T &value) + { + if (!JsUtil::HasProperty(env, object, jsPropInfo.propertyName.c_str())) { + return false; + } + napi_value jsObject = nullptr; + napi_get_named_property(env, object, jsPropInfo.propertyName.c_str(), &jsObject); + PARAM_CHECK_RETURN(env, JsUtil::GetType(env, jsObject) == jsPropInfo.type, jsPropInfo.propertyName, + jsPropInfo.typeCode, false); + PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, jsObject, value) == napi_ok, + "failed to convert " + jsPropInfo.propertyName, TYPE_NONE, false); + return true; + } + + static napi_status GetValue(napi_env env, napi_value in, int32_t &out); + static napi_status GetValue(napi_env env, napi_value in, uint32_t &out); + static napi_status GetValue(napi_env env, napi_value in, bool &out); + static napi_status GetValue(napi_env env, napi_value in, double &out); + static napi_status GetValue(napi_env env, napi_value in, std::string &out); + static napi_status GetValue(napi_env env, napi_value in, std::unordered_map &out); + static napi_status GetValue(napi_env env, napi_value in, PrivateDataValue &out); + static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); + static napi_status GetValue(napi_env env, napi_value in, PanelInfo &out); + static napi_status GetValue(napi_env env, napi_value in, std::vector &out); + static napi_status GetValue(napi_env env, napi_value in, Rosen::Rect &out); + static napi_value GetValue(napi_env env, const std::vector &in); + static napi_value GetValue(napi_env env, const InputWindowInfo &in); + static napi_value GetValue(napi_env env, const Rosen::Rect &in); + static napi_value GetJsPrivateCommand(napi_env env, const std::unordered_map &in); + static napi_value GetValue(napi_env env, const std::vector &in); + static napi_status GetValue(napi_env env, const std::string &in, napi_value &out); + static napi_status GetMessageHandlerCallbackParam(napi_value *argv, + const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, + size_t size); + +private: + static const std::map ERROR_CODE_MAP; + + static const std::map ERROR_CODE_CONVERT_MESSAGE_MAP; + + static const std::map PARAMETER_TYPE; + + static constexpr int32_t ERROR_CODE_QUERY_FAILED = 1; + + static constexpr uint8_t MAX_ARGMENT_COUNT = 10; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // INTERFACE_KITS_JS_UTILS_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn index fe94f3f..e5d4905 100644 --- a/frameworks/native/selection_ability/BUILD.gn +++ b/frameworks/native/selection_ability/BUILD.gn @@ -21,6 +21,7 @@ config("selection_listener_config") { "../../../utils/include", "${target_gen_dir}", "${selection_fwk_root_path}/common", + "../../common", ] } @@ -62,7 +63,11 @@ ohos_shared_library("selection_ability") { output_values = get_target_outputs(":selection_listener_interface") sources = [ + "src/selection_ability.cpp", "src/selection_listener_impl.cpp", + "src/selection_panel.cpp", + "src/task_manager.cpp", + "src/tasks/task.cpp", ] sources += filter_include(output_values, [ "*.cpp" ]) deps = [ @@ -73,8 +78,23 @@ ohos_shared_library("selection_ability") { "c_utils:utils", "ipc:ipc_single", "hilog:libhilog", + "ability_base:configuration", + "ability_base:want", + "ability_runtime:ability_context_native", + "bundle_framework:appexecfwk_base", + "config_policy:configpolicy_util", + "eventhandler:libeventhandler", + "graphic_2d:librender_service_client", + "graphic_2d:window_animation", + "input:libmmi-client", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + "window_manager:libdm", + "window_manager:libwsutils", ] + public_external_deps = [ "window_manager:libwm" ] + part_name = "selectionfwk" subsystem_name = "systemabilitymgr" } \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/actions/action.h b/frameworks/native/selection_ability/include/actions/action.h new file mode 100644 index 0000000..62d913c --- /dev/null +++ b/frameworks/native/selection_ability/include/actions/action.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024-2024 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 FRAMEWORKS_SELECTION_ABILITY_INCLUDE_ACTIONS_ACTION_H +#define FRAMEWORKS_SELECTION_ABILITY_INCLUDE_ACTIONS_ACTION_H + +#include +#include + +namespace OHOS { +namespace SelectionFwk { + +enum RunningState : uint32_t { + RUNNING_STATE_IDLE = 0, + RUNNING_STATE_RUNNING, + RUNNING_STATE_PAUSED, + RUNNING_STATE_COMPLETED, + RUNNING_STATE_ERROR, +}; + +class Action { +public: + Action() = default; + Action(std::function func) : func_(func) { } + virtual ~Action() = default; + + virtual RunningState Execute() + { + if (state_ != RUNNING_STATE_IDLE) { + return RUNNING_STATE_ERROR; + } + + state_ = RUNNING_STATE_RUNNING; + if (func_) { + func_(); + } + state_ = RUNNING_STATE_COMPLETED; + return state_; + } + + virtual RunningState Resume(uint64_t resumeId) + { + return state_; + } + + RunningState GetState() const + { + return state_; + } + +protected: + RunningState state_ { RUNNING_STATE_IDLE }; + std::function func_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // FRAMEWORKS_SELECTION_ABILITY_INCLUDE_ACTIONS_ACTION_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/actions/action_wait.h b/frameworks/native/selection_ability/include/actions/action_wait.h new file mode 100644 index 0000000..b88cd86 --- /dev/null +++ b/frameworks/native/selection_ability/include/actions/action_wait.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2024-2024 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 FRAMEWORKS_SELECTION_ABILITY_INCLUDE_ACTIONS_ACTION_WAIT_H +#define FRAMEWORKS_SELECTION_ABILITY_INCLUDE_ACTIONS_ACTION_WAIT_H + +#include +#include + +#include "action.h" +#include "task_manager.h" +#include "tasks/task_inner.h" + +namespace OHOS { +namespace SelectionFwk { + +class ActionWait : public Action { +public: + using callback_t = std::function; + + ActionWait(uint64_t completeId, uint32_t timeoutMs) + : timeoutMs_(timeoutMs), completeId_(completeId), timeoutId_(Task::GetNextSeqId()) + { + } + + ActionWait(uint64_t completeId, uint32_t timeoutMs, callback_t onComplete, callback_t onTimeout) + : timeoutMs_(timeoutMs), completeId_(completeId), timeoutId_(Task::GetNextSeqId()), onComplete_(onComplete), + onTimeout_(onTimeout) + { + } + + ~ActionWait() = default; + + RunningState Execute() override + { + state_ = RUNNING_STATE_PAUSED; + // trigger timeout with delay + auto task = std::make_shared(timeoutId_); + TaskManager::GetInstance().PostTask(task, timeoutMs_); + return state_; + } + + RunningState Resume(uint64_t seqId) override + { + if (state_ != RUNNING_STATE_PAUSED) { + return RUNNING_STATE_ERROR; + } + + if (seqId == completeId_) { + if (onComplete_) { + onComplete_(); + } + state_ = RUNNING_STATE_COMPLETED; + return state_; + } + if (seqId == timeoutId_) { + if (onTimeout_) { + onTimeout_(); + } + state_ = RUNNING_STATE_COMPLETED; + return state_; + } + + return state_; + } + +private: + const uint32_t timeoutMs_; + const uint64_t completeId_; + const uint64_t timeoutId_; + std::function onComplete_; + std::function onTimeout_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // FRAMEWORKS_SELECTION_ABILITY_INCLUDE_ACTIONS_ACTION_WAIT_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/panel_info.h b/frameworks/native/selection_ability/include/panel_info.h new file mode 100644 index 0000000..7e93eec --- /dev/null +++ b/frameworks/native/selection_ability/include/panel_info.h @@ -0,0 +1,77 @@ +/* + * 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 SELECTION_FWK_PANEL_INFO_H +#define SELECTION_FWK_PANEL_INFO_H + +#include "parcel.h" + +namespace OHOS { +namespace SelectionFwk { +enum PanelType { + SOFT_KEYBOARD = 0, + STATUS_BAR, +}; + +enum PanelFlag { + FLG_FIXED = 0, + FLG_FLOATING, + FLG_CANDIDATE_COLUMN, +}; + +struct PanelInfo : public Parcelable { + PanelType panelType = SOFT_KEYBOARD; + PanelFlag panelFlag = FLG_FIXED; + + bool ReadFromParcel(Parcel &in) + { + int32_t panelTypeData = in.ReadInt32(); + int32_t panelFlagData = in.ReadInt32(); + panelType = static_cast(panelTypeData); + panelFlag = static_cast(panelFlagData); + return true; + } + bool Marshalling(Parcel &out) const + { + if (!out.WriteInt32(static_cast(panelType))) { + return false; + } + if (!out.WriteInt32(static_cast(panelFlag))) { + return false; + } + return true; + } + static PanelInfo *Unmarshalling(Parcel &in) + { + PanelInfo *data = new (std::nothrow) PanelInfo(); + if (data && !data->ReadFromParcel(in)) { + delete data; + data = nullptr; + } + return data; + } +}; + +enum class ImmersiveMode : int32_t { + NONE_IMMERSIVE = 0, + IMMERSIVE = 1, + LIGHT_IMMERSIVE = 2, + DARK_IMMERSIVE = 3, + END, +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // SELECTION_FWK_PANEL_INFO_H diff --git a/frameworks/native/selection_ability/include/selection_ability.h b/frameworks/native/selection_ability/include/selection_ability.h index e69de29..e9b80ea 100644 --- a/frameworks/native/selection_ability/include/selection_ability.h +++ b/frameworks/native/selection_ability/include/selection_ability.h @@ -0,0 +1,60 @@ +/* + * 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 FRAMEWORKS_SELECTION_ABILITY_INCLUDE_SELECTION_ABILITY_H +#define FRAMEWORKS_SELECTION_ABILITY_INCLUDE_SELECTION_ABILITY_H + +#include +#include +#include +#include "refbase.h" +#include "context.h" +#include "concurrent_map.h" +#include "selection_panel.h" +#include "panel_info.h" + +namespace OHOS { +namespace SelectionFwk{ +class SelectionAbility : public RefBase { +public: + SelectionAbility(); + ~SelectionAbility(); + static sptr GetInstance(); + int32_t CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo, + std::shared_ptr &selectionPanel); + void NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag); + +private: + static std::mutex instanceLock_; + static sptr instance_; + + std::mutex dataChannelLock_; + // std::shared_ptr dataChannelProxy_ = nullptr; + + + // std::shared_ptr GetInputDataChannelProxy(); + + void Initialize(); + + ConcurrentMap> panels_ {}; + // sptr coreStub_ { nullptr }; + // sptr agentStub_ { nullptr }; + + std::atomic_bool isShowAfterCreate_ { false }; + +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // FRAMEWORKS_SELECTION_ABILITY_INCLUDE_SELECTION_ABILITY_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index e69de29..47f45e5 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2023-2024 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 SELECTION_PANEL_H +#define SELECTION_PANEL_H + +#include +#include +#include +#include + +#include + +#include "panel_info.h" +#include "refbase.h" +#include "context.h" +#include "wm_common.h" +#include "window.h" +#include "ui/rs_surface_node.h" + +namespace OHOS { +namespace SelectionFwk { +class SelectionPanel { +public: + static constexpr uint32_t INVALID_WINDOW_ID = 0; + // using CallbackFunc = std::function; + SelectionPanel() = default; + ~SelectionPanel(); + int32_t CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo); + // void SetPanelHeightCallback(CallbackFunc heightCallback); + + uint32_t windowId_ = INVALID_WINDOW_ID; + +private: + std::string GeneratePanelName(); + int32_t SetPanelProperties(); + static uint32_t GenerateSequenceId(); + PanelType panelType_ = PanelType::STATUS_BAR;//待修改 + PanelFlag panelFlag_ = PanelFlag::FLG_FIXED;//待修改 + + sptr window_ = nullptr; + sptr winOption_ = nullptr; + + bool isScbEnable_ { false }; + + Rosen::KeyboardLayoutParams keyboardLayoutParams_; + static std::atomic sequenceId_; + uint32_t invalidGravityPercent = 0; + + // CallbackFunc panelHeightCallback_ = nullptr; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // SELECTION_PANEL_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/task_manager.h b/frameworks/native/selection_ability/include/task_manager.h new file mode 100644 index 0000000..93a4c93 --- /dev/null +++ b/frameworks/native/selection_ability/include/task_manager.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2024-2024 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 FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASK_MANAGER_H +#define FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASK_MANAGER_H + +#include +#include + +#include "actions/action.h" +#include "event_handler.h" +#include "tasks/task.h" + +namespace OHOS { +namespace SelectionFwk { + +using task_ptr_t = std::shared_ptr; +using action_ptr_t = std::unique_ptr; + +class TaskManager final { +private: + TaskManager(); + +public: + ~TaskManager() = default; + + TaskManager(const TaskManager &) = delete; + TaskManager(TaskManager &&) = delete; + TaskManager &operator=(const TaskManager &) = delete; + TaskManager &operator=(TaskManager &&) = delete; + + static TaskManager &GetInstance(); + + // Post a task to work thread + uint64_t PostTask(task_ptr_t task, uint32_t delayMs = 0); + + // Trigger task process async + void ProcessAsync(); + + // Resume paused task with seqId + void Complete(uint64_t seqId); + + // Pend an action to current task during executing + int32_t Pend(action_ptr_t action); + int32_t Pend(std::function); + + // Wait for task and execute + int32_t WaitExec(uint64_t seqId, uint32_t timeoutMs, std::function); + +private: + friend class SlectionAbility; + friend class TaskAmsInit; + void SetInited(bool flag); + +private: + void OnNewTask(task_ptr_t task); // Accept a new task + void Process(); // Process next task + void ProcessNextInnerTask(); // Process next inner task + void ProcessNextAmsTask(); // Process next AMS task + void ProcessNextImaTask(); // process next IMA task + void ProcessNextImsaTask(); // process next IMSA task + void ExecuteCurrentTask(); // Execute current task + + void Reset(); + +private: + bool inited_ { false }; + std::shared_ptr eventHandler_ { nullptr }; + + task_ptr_t curTask_ = { nullptr }; + std::list amsTasks_; + std::list imaTasks_; + std::list imsaTasks_; + std::list innerTasks_; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASK_MANAGER_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/tasks/task.h b/frameworks/native/selection_ability/include/tasks/task.h new file mode 100644 index 0000000..9099a33 --- /dev/null +++ b/frameworks/native/selection_ability/include/tasks/task.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2024-2024 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 FRAMEWORKS_SELECTON_ABILITY_INCLUDE_TASKS_TASK_H +#define FRAMEWORKS_SELECTON_ABILITY_INCLUDE_TASKS_TASK_H + +#include "actions/action.h" + +#include +#include + +namespace OHOS { +namespace SelectionFwk { + +enum SourceType : uint32_t { + SOURCE_TYPE_AMS = 0, + SOURCE_TYPE_IMA, + SOURCE_TYPE_IMSA, + SOURCE_TYPE_INNER, +}; + +#define TASK_TYPE_OFFSET(src) ((src)*10000) + +enum TaskType : uint32_t { + // Task from AMS + TASK_TYPE_AMS_BEGIN = TASK_TYPE_OFFSET(SOURCE_TYPE_AMS), + TASK_TYPE_AMS_INIT = TASK_TYPE_AMS_BEGIN, + TASK_TYPE_AMS_END = TASK_TYPE_AMS_INIT, + + // Task from IMA + TASK_TYPE_IMA_BEGIN = TASK_TYPE_OFFSET(SOURCE_TYPE_IMA), + TASK_TYPE_IMA_SHOW_PANEL = TASK_TYPE_IMA_BEGIN, + TASK_TYPE_IMA_HIDE_PANEL, + TASK_TYPE_IMA_END = TASK_TYPE_IMA_HIDE_PANEL, + + // Task from IMSA + TASK_TYPE_IMSA_BEGIN = TASK_TYPE_OFFSET(SOURCE_TYPE_IMSA), + TASK_TYPE_IMSA_START_INPUT = TASK_TYPE_IMSA_BEGIN, + TASK_TYPE_IMSA_STOP_INPUT, + TASK_TYPE_IMSA_SHOW_KEYBOARD, + TASK_TYPE_IMSA_HIDE_KEYBOARD, + TASK_TYPE_IMSA_CLIENT_INACTIVE, + TASK_TYPE_IMSA_INIT_INPUT_CTRL_CHANNEL, + TASK_TYPE_IMSA_CURSOR_UPDATE, + TASK_TYPE_IMSA_SEND_PRIVATE_COMMAND, + TASK_TYPE_IMSA_SELECTION_CHANGE, + TASK_TYPE_IMSA_ATTRIBUTE_CHANGE, + TASK_TYPE_IMSA_STOP_INPUT_SERVICE, + TASK_TYPE_IMSA_SET_SUBPROPERTY, + TASK_TYPE_IMSA_SET_CORE_AND_AGENT, + TASK_TYPE_IMSA_ADJUST_KEYBOARD, + TASK_TYPE_IMSA_END = TASK_TYPE_IMSA_ADJUST_KEYBOARD, + + // Task from inner + TASK_TYPE_RESUME, +}; + +class Task { +public: + explicit Task(TaskType t); + Task(TaskType t, uint64_t seqId); + virtual ~Task() = default; + + RunningState Execute(); + RunningState Resume(uint64_t resumeId); + + virtual RunningState OnTask(std::shared_ptr task); + + int32_t Pend(std::shared_ptr task); + int32_t Pend(std::unique_ptr action); + + TaskType GetType() const; + SourceType GetSourceType() const; + uint64_t GetSeqId() const; + RunningState GetState() const; + bool IsRunning() const; + const std::list> &GetActions() const; + + static uint64_t GetNextSeqId(); + +private: + RunningState ExecuteInner(); + +protected: + const TaskType type_; + RunningState state_ { RUNNING_STATE_IDLE }; + const uint64_t seqId_; + std::unique_ptr curAction_ { nullptr }; + std::list> actions_; + std::list> pendingActions_; +}; + +} // namespace SelectionFwk +} // namespace OHOS +#endif // FRAMEWORKS_SELECTON_ABILITY_INCLUDE_TASKS_TASK_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/tasks/task_ams.h b/frameworks/native/selection_ability/include/tasks/task_ams.h new file mode 100644 index 0000000..d0c336a --- /dev/null +++ b/frameworks/native/selection_ability/include/tasks/task_ams.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2024-2024 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 FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_AMS_H +#define FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_AMS_H + +#include "task.h" + +#include "actions/action_wait.h" +#include "global.h" +#include "task_manager.h" + +namespace OHOS { +namespace SelectionFwk { +const uint32_t AMS_INIT_TIMEOUT_MS = 5000; + +class TaskAmsInit : public Task { +public: + TaskAmsInit() : Task(TASK_TYPE_AMS_INIT) + { + auto action = std::make_unique(seqId_, AMS_INIT_TIMEOUT_MS, + std::bind(&TaskAmsInit::OnComplete, this), std::bind(&TaskAmsInit::OnTimeout, this)); + actions_.push_back(std::move(action)); + } + ~TaskAmsInit() = default; + +private: + void OnComplete() + { + SELECTION_HILOGI("TaskAmsInit::OnComplete"); + TaskManager::GetInstance().SetInited(true); + } + void OnTimeout() + { + SELECTION_HILOGW("TaskAmsInit::OnTimeout"); + } +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_AMS_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/tasks/task_inner.h b/frameworks/native/selection_ability/include/tasks/task_inner.h new file mode 100644 index 0000000..a2df33e --- /dev/null +++ b/frameworks/native/selection_ability/include/tasks/task_inner.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2024-2024 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 FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_INNER_H +#define FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_INNER_H + +#include "task.h" + +namespace OHOS { +namespace SelectionFwk { + +class TaskResume : public Task { +public: + explicit TaskResume(uint64_t seqId) : Task(TASK_TYPE_RESUME, seqId) { } + ~TaskResume() = default; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_INNER_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/tasks/task_ssa.h b/frameworks/native/selection_ability/include/tasks/task_ssa.h new file mode 100644 index 0000000..727ff39 --- /dev/null +++ b/frameworks/native/selection_ability/include/tasks/task_ssa.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2024-2024 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 FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_SSA_H +#define FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_SSA_H + +#include "task.h" + +#include "input_attribute.h" +#include "input_client_info.h" +#include "selection_ability.h" +#include "secelction_property.h" +#include "iremote_object.h" + +namespace OHOS { +namespace SelectionFwk { + +class TaskSsaStartInput : public Task { +public: + TaskSsaStartInput(const InputClientInfo &client, bool fromClient) : Task(TASK_TYPE_IMSA_START_INPUT) + { + auto func = [client, fromClient]() { + SelectionAbility::GetInstance()->StartInput(client, fromClient); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaStartInput() = default; +}; + +class TaskSsaStopInput : public Task { +public: + explicit TaskSsaStopInput(sptr channel, uint32_t sessionId) : Task(TASK_TYPE_IMSA_STOP_INPUT) + { + auto func = [channel, sessionId]() { + SelectionAbility::GetInstance()->StopInput(channel, sessionId); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaStopInput() = default; +}; + +class TaskSsaShowKeyboard : public Task { +public: + TaskSsaShowKeyboard(int32_t requestKeyboardReason = 0) : Task(TASK_TYPE_IMSA_SHOW_KEYBOARD) + { + auto func = [requestKeyboardReason]() { + SelectionAbility::GetInstance()->ShowKeyboard(requestKeyboardReason); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaShowKeyboard() = default; +}; + +class TaskSsaHideKeyboard : public Task { +public: + explicit TaskSsaHideKeyboard() : Task(TASK_TYPE_IMSA_HIDE_KEYBOARD) + { + auto func = []() { + SelectionAbility::GetInstance()->HideKeyboard(); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaHideKeyboard() = default; +}; + +class TaskSsaOnClientInactive : public Task { +public: + explicit TaskSsaOnClientInactive(sptr channel) : Task(TASK_TYPE_IMSA_CLIENT_INACTIVE) + { + auto func = [channel]() { + SelectionAbility::GetInstance()->OnClientInactive(channel); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaOnClientInactive() = default; +}; + +class TaskSsaInitInputCtrlChannel : public Task { +public: + explicit TaskSsaInitInputCtrlChannel(sptr channel) : Task(TASK_TYPE_IMSA_INIT_INPUT_CTRL_CHANNEL) + { + auto func = [channel]() { + SelectionAbility::GetInstance()->OnInitInputControlChannel(channel); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaInitInputCtrlChannel() = default; +}; + +class TaskSsaOnCursorUpdate : public Task { +public: + TaskSsaOnCursorUpdate(int32_t x, int32_t y, int32_t h) : Task(TASK_TYPE_IMSA_CURSOR_UPDATE) + { + auto func = [x, y, h]() { + SelectionAbility::GetInstance()->OnCursorUpdate(x, y, h); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaOnCursorUpdate() = default; +}; + +class TaskSsaSendPrivateCommand : public Task { +public: + TaskSsaSendPrivateCommand(std::unordered_map privateCommand) + : Task(TASK_TYPE_IMSA_SEND_PRIVATE_COMMAND) + { + auto func = [privateCommand]() { + SelectionAbility::GetInstance()->ReceivePrivateCommand(privateCommand); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaSendPrivateCommand() = default; +}; + +class TaskSsaOnSelectionChange : public Task { +public: + TaskSsaOnSelectionChange(std::u16string text, int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) + : Task(TASK_TYPE_IMSA_SELECTION_CHANGE) + { + auto func = [text, oldBegin, oldEnd, newBegin, newEnd]() { + SelectionAbility::GetInstance()->OnSelectionChange(text, oldBegin, oldEnd, newBegin, newEnd); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaOnSelectionChange() = default; +}; + +class TaskSsaAttributeChange : public Task { +public: + explicit TaskSsaAttributeChange(InputAttribute attr) : Task(TASK_TYPE_IMSA_ATTRIBUTE_CHANGE) + { + auto func = [attr]() { + SelectionAbility::GetInstance()->OnAttributeChange(attr); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaAttributeChange() = default; +}; + +class TaskSsaStopInputService : public Task { +public: + explicit TaskSsaStopInputService(bool isTerminateIme) : Task(TASK_TYPE_IMSA_STOP_INPUT_SERVICE) + { + auto func = [isTerminateIme]() { + SelectionAbility::GetInstance()->OnStopInputService(isTerminateIme); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaStopInputService() = default; +}; + +class TaskSsaOnSetSubProperty : public Task { +public: + explicit TaskSsaOnSetSubProperty(SubProperty prop) : Task(TASK_TYPE_IMSA_SET_SUBPROPERTY) + { + auto func = [prop]() { + SelectionAbility::GetInstance()->OnSetSubtype(prop); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaOnSetSubProperty() = default; +}; + +class TaskSsaSetCoreAndAgent : public Task { +public: + TaskSsaSetCoreAndAgent() : Task(TASK_TYPE_IMSA_SET_CORE_AND_AGENT) + { + auto func = []() { + SelectionAbility::GetInstance()->SetCoreAndAgent(); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskSsaSetCoreAndAgent() = default; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // FRAMEWORKS_SELECTION_ABILITY_INCLUDE_TASKS_TASK_SSA_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index e69de29..19c5dd9 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -0,0 +1,121 @@ +/* + * 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 "selection_ability.h" +#include "selection_panel.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { +sptr SelectionAbility::instance_; +std::mutex SelectionAbility::instanceLock_; + +SelectionAbility::SelectionAbility() { } + +SelectionAbility::~SelectionAbility() +{ + SELECTION_HILOGI("SelectionAbility::~SelectionAbility."); +} + +sptr SelectionAbility::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + SELECTION_HILOGI("SelectionAbility need new SA."); + instance_ = new (std::nothrow) SelectionAbility(); + if (instance_ == nullptr) { + SELECTION_HILOGE("instance is nullptr!"); + return instance_; + } + instance_->Initialize(); + } + } + return instance_; +} + +void SelectionAbility::Initialize() +{ + SELECTION_HILOGD("SelectionAbility init."); + // sptr coreStub = new (std::nothrow) SelectionCoreServiceImpl();//核心功能,处理文本操作 + // if (coreStub == nullptr) { + // SELECTION_HILOGE("failed to create core!"); + // return; + // } + // sptr agentStub = new (std::nothrow) SelectionAgentServiceImpl();//服务代理,将核心功能暴露给外部,处理通信和事件分发, + // if (agentStub == nullptr) { + // SELECTION_HILOGE("failed to create agent!"); + // return; + // } + // agentStub_ = agentStub; + // coreStub_ = coreStub; +} + +int32_t SelectionAbility::CreatePanel(const std::shared_ptr &context, + const PanelInfo &panelInfo, std::shared_ptr &selectionPanel) +{ + // SELECTION_HILOGI("SelectionAbility start."); + SELECTION_HILOGI("SelectionAbility CreatePanel start."); +//设置面板高度回调(可暂设定为固定高度) + // auto panelHeightCallback = [this](uint32_t panelHeight, PanelFlag panelFlag) { + // NotifyKeyboardHeight(panelHeight, panelFlag);//NotifyKeyboardHeight()待实现 + // }; + + auto flag = panels_.ComputeIfAbsent(panelInfo.panelType, + [&panelInfo, &context, &selectionPanel]( + // [panelHeightCallback, &panelInfo, &context, &selectionPanel]( + const PanelType &panelType, std::shared_ptr &panel) { + selectionPanel = std::make_shared(); + // selectionPanel->SetPanelHeightCallback(panelHeightCallback); + auto ret = selectionPanel->CreatePanel(context, panelInfo); + if (ret == ErrorCode::NO_ERROR) { + panel = selectionPanel; + return true; + } + selectionPanel = nullptr; + return false; + });//前期测试可以指定flag为true,并调用CreatePanel,感觉还是得实现相关类和方法 + // if (flag && isShowAfterCreate_.load() && panelInfo.panelType == SOFT_KEYBOARD &&//SOFT_KEYBOARD是输入法的键盘类型,划词键盘应该怎么设置?? + // panelInfo.panelFlag != FLG_CANDIDATE_COLUMN) {//FLG_CANDIDATE_COLUMN候选列表框 + // isShowAfterCreate_.store(false); + // auto task = std::make_shared();//TaskImsaShowKeyboard待添加 + // TaskManager::GetInstance().PostTask(task);//同级目录待实现 + // } + return flag ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL; +} + +// void SelectionAbility::NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag) +// { +// auto channel = GetInputDataChannelProxy(); +// if (channel == nullptr) { +// SELECTION_HILOGE("channel is nullptr!"); +// return; +// } +// SELECTION_HILOGD("notify panel height: %{public}u, flag: %{public}d.", panelHeight, static_cast(panelFlag)); +// if (panelFlag != PanelFlag::FLG_FIXED) { +// channel->NotifyKeyboardHeight(0); +// return; +// } +// channel->NotifyKeyboardHeight(panelHeight); +// } + +// std::shared_ptr SelectionAbility::GetInputDataChannelProxy() +// { +// std::lock_guard lock(dataChannelLock_); +// return dataChannelProxy_; +// } + +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index e69de29..c59e76b 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2023-2024 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 "scene_board_judgement.h" + +#include "selection_panel.h" +#include "selection_log.h" + +#include "display_manager.h" + +namespace OHOS { +namespace SelectionFwk { +using WMError = OHOS::Rosen::WMError; +using WindowGravity = OHOS::Rosen::WindowGravity; +using WindowState = OHOS::Rosen::WindowState; +std::atomic SelectionPanel::sequenceId_ { 0 }; + +SelectionPanel::~SelectionPanel() = default; +int32_t SelectionPanel::CreatePanel( + const std::shared_ptr &context, const PanelInfo &panelInfo) +{ + SELECTION_HILOGI("SelectionPanel CreatePanel start."); + SELECTION_HILOGD( + "start, type/flag: %{public}d/%{public}d.", static_cast(panelType_), static_cast(panelFlag_)); + // panelType_ = panelInfo.panelType; + // panelFlag_ = panelInfo.panelFlag; + // winOption_ = new (std::nothrow) OHOS::Rosen::WindowOption(); + // if (winOption_ == nullptr) { + // return ErrorCode::ERROR_NULL_POINTER; + // } + // if (panelInfo.panelType == PanelType::STATUS_BAR) {//状态栏面板 + // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR);//窗口类型需要添加WINDOW_TYPE_SELECTION_FLOAT + // } else { + // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);//窗口类型需要添加WINDOW_TYPE_SELECTION_FLOAT + // } + // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DIALOG);//窗口类型需要确认 + // winOption_->SetWindowRect(OHOS::Rosen::Rect{10, 10, 80, 50}); + // WMError wmError = WMError::WM_OK; + // window_ = OHOS::Rosen::Window::Create(GeneratePanelName(), winOption_, context, wmError); + // if (wmError == WMError::WM_ERROR_INVALID_PERMISSION || wmError == WMError::WM_ERROR_NOT_SYSTEM_APP) { + // SELECTION_HILOGE("create window failed, permission denied, %{public}d!", wmError); + // return ErrorCode::ERROR_NOT_IME; + // } + // if (window_ == nullptr || wmError != WMError::WM_OK) { + // SELECTION_HILOGE("create window failed: %{public}d!", wmError); + // return ErrorCode::ERROR_OPERATE_PANEL; + // } + // isScbEnable_ = Rosen::SceneBoardJudgement::IsSceneBoardEnabled(); + // if (SetPanelProperties() != ErrorCode::NO_ERROR) { + // wmError = window_->Destroy(); + // SELECTION_HILOGI("destroy window end, wmError is %{public}d.", wmError); + // return ErrorCode::ERROR_OPERATE_PANEL; + // } + // windowId_ = window_->GetWindowId(); + // SELECTION_HILOGI("success, type/flag/windowId/isScbEnable_: %{public}d/%{public}d/%{public}u/%{public}d.", + // static_cast(panelType_), static_cast(panelFlag_), windowId_, isScbEnable_); + // // if (panelInfo.panelType == SOFT_KEYBOARD && isScbEnable_) {//软键盘+可用 + // // RegisterKeyboardPanelInfoChangeListener(); + // // } + // window_->RaiseToAppTop(); + // SELECTION_HILOGI("selectionPanel RaiseToAppTop 2."); + // window_->Resize(80, 50); + // window_->SetBackgroundColor("green"); + // window_->Show(); + // window_->Resize(80, 50); + // window_->SetBackgroundColor("green"); + // SELECTION_HILOGI("selectionPanel show."); + OHOS::Rosen::Rect baseWindowRect = { 150, 150, 400, 600 }; + sptr baseOp = new Rosen::WindowOption(); + baseOp->SetWindowType(Rosen::WindowType::WINDOW_TYPE_DYNAMIC); + baseOp->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING); + baseOp->SetWindowRect(baseWindowRect); + baseOp->SetZIndex(1980); + auto displayId = Rosen::DisplayManager::GetInstance().GetDefaultDisplayId(); + baseOp->SetDisplayId(displayId); + // baseOp->SetWindowZOrder(Rosen::WindowZOrder::TOP_MOST); + // baseOp->SetVisible(true); + SELECTION_HILOGE("After SetWindowRect"); + + sptr window = Rosen::Window::Create("Demo_SSW_BaseWindow", baseOp, nullptr); + if (!window) { + SELECTION_HILOGE("Window creation failed"); + return ErrorCode::NO_ERROR; + } + SELECTION_HILOGE("After Window::Create"); + auto error = window->Show(); + if (error != WMError::WM_OK) { + SELECTION_HILOGE("After Window::Show, error=%{public}d, WM_ERROR_INVALID_PARAM=%d", error, WM_ERROR_INVALID_PARAM); + } + // window->SetWindowFocus(); + // window->RaiseToTop(); + SELECTION_HILOGE("After Window::Show"); + return ErrorCode::NO_ERROR; +} + +std::string SelectionPanel::GeneratePanelName() +{ + uint32_t sequenceId = GenerateSequenceId(); + std::string windowName = panelType_ == SOFT_KEYBOARD ? "softKeyboard" + std::to_string(sequenceId) ://panelType类型:softKeyboard、statusBar + "statusBar" + std::to_string(sequenceId); + SELECTION_HILOGD("SelectionPanel, windowName: %{public}s.", windowName.c_str()); + return windowName; +} + +int32_t SelectionPanel::SetPanelProperties()//设置输入面板属性,根据面板类型和标志来配置窗口的位置属性 +{ + if (window_ == nullptr) { + SELECTION_HILOGE("window is nullptr!"); + return ErrorCode::ERROR_OPERATE_PANEL; + } + WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT;//浮动位置 + if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) {//软键盘+固定 + gravity = WindowGravity::WINDOW_GRAVITY_BOTTOM; + } else if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FLOATING) {//软键盘+浮动 + auto surfaceNode = window_->GetSurfaceNode(); + if (surfaceNode == nullptr) { + SELECTION_HILOGE("surfaceNode is nullptr!"); + return ErrorCode::ERROR_OPERATE_PANEL; + } + surfaceNode->SetFrameGravity(Rosen::Gravity::TOP_LEFT); + Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction(); + } else if (panelType_ == STATUS_BAR) {//状态栏面板 + auto surfaceNo = window_->GetSurfaceNode(); + if (surfaceNo == nullptr) { + SELECTION_HILOGE("surfaceNo is nullptr!"); + return ErrorCode::ERROR_OPERATE_PANEL; + } + surfaceNo->SetFrameGravity(Rosen::Gravity::TOP_LEFT); + Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction(); + return ErrorCode::NO_ERROR; + } + if (!isScbEnable_) {//非场景模式的重力设置------是什么东西,划词需要吗 + WMError wmError = window_->SetWindowGravity(gravity, invalidGravityPercent); + if (wmError != WMError::WM_OK) { + SELECTION_HILOGE("failed to set window gravity, wmError is %{public}d, start destroy window!", wmError); + return ErrorCode::ERROR_OPERATE_PANEL; + } + return ErrorCode::NO_ERROR; + } + keyboardLayoutParams_.gravity_ = gravity;//场景模式 + auto ret = window_->AdjustKeyboardLayout(keyboardLayoutParams_); + if (ret != WMError::WM_OK) { + SELECTION_HILOGE("SetWindowGravity failed, wmError is %{public}d, start destroy window!", ret); + return ErrorCode::ERROR_OPERATE_PANEL; + } + return ErrorCode::NO_ERROR; +} + +uint32_t SelectionPanel::GenerateSequenceId() +{ + uint32_t seqId = ++sequenceId_; + if (seqId == std::numeric_limits::max()) { + return ++sequenceId_; + } + return seqId; +} + +// void SelectionPanel::SetPanelHeightCallback(CallbackFunc heightCallback) +// { +// panelHeightCallback_ = std::move(heightCallback); +// } + +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/task_manager.cpp b/frameworks/native/selection_ability/src/task_manager.cpp new file mode 100644 index 0000000..fae65be --- /dev/null +++ b/frameworks/native/selection_ability/src/task_manager.cpp @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2024-2024 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 "task_manager.h" + +#include + +#include "actions/action.h" +#include "actions/action_wait.h" + +// #include "global.h" +#include "selection_log.h" + +#include "tasks/task.h" +#include "tasks/task_inner.h" + +namespace OHOS { +namespace SelectionFwk { + +static const std::string THREAD_NAME = "OS_imf_task_manager"; + +TaskManager::TaskManager() +{ + auto runner = AppExecFwk::EventRunner::Create(THREAD_NAME); + eventHandler_ = std::make_shared(runner); +} + +TaskManager &TaskManager::GetInstance() +{ + static TaskManager instance; + return instance; +} + +uint64_t TaskManager::PostTask(task_ptr_t task, uint32_t delayMs) +{ + if (!task) { + SELECTION_HILOGE("task is NULL!"); + return 0; + } + + auto func = std::bind(&TaskManager::OnNewTask, this, task); + eventHandler_->PostTask(func, __FUNCTION__, delayMs); + return task->GetSeqId(); +} + +void TaskManager::ProcessAsync() +{ + auto func = [=] { + Process(); + }; + eventHandler_->PostTask(func, __FUNCTION__); +} + +void TaskManager::Complete(uint64_t seqId) +{ + PostTask(std::make_shared(seqId)); +} + +int32_t TaskManager::Pend(action_ptr_t action) +{ + if (action == nullptr) { + SELECTION_HILOGE("curTask_ is NULL or not runing, pend failed!"); + return ErrorCode::ERROR_NULL_POINTER; + } + if (curTask_ == nullptr || !curTask_->IsRunning()) { + SELECTION_HILOGE("curTask_ is NULL or not runing, pend failed!"); + return ErrorCode::ERROR_TASK_MANAGER_PEND_FAILED; + } + return curTask_->Pend(std::move(action)); +} + +int32_t TaskManager::Pend(std::function func) +{ + return Pend(std::make_unique(func)); +} + +int32_t TaskManager::WaitExec(uint64_t seqId, uint32_t timeoutMs, std::function func) +{ + auto wait = std::make_unique(seqId, timeoutMs); + int32_t ret = Pend(std::move(wait)); + if (ret != ErrorCode::NO_ERROR) { + SELECTION_HILOGE("Pend ActionWait failed, ret=%{public}d", ret); + return ret; + } + + auto exec = std::make_unique(func); + ret = Pend(std::move(exec)); + if (ret != ErrorCode::NO_ERROR) { + SELECTION_HILOGE("Pend Action failed, ret=%{public}d", ret); + return ret; + } + return ErrorCode::NO_ERROR; +} + +void TaskManager::SetInited(bool flag) +{ + inited_ = flag; +} + +void TaskManager::OnNewTask(task_ptr_t task) +{ + if (task == nullptr) { + SELECTION_HILOGE("task is NULL!"); + return; + } + auto srcType = task->GetSourceType(); + switch (srcType) { + case SOURCE_TYPE_AMS: + amsTasks_.push_back(task); + break; + case SOURCE_TYPE_IMA: + imaTasks_.push_back(task); + break; + case SOURCE_TYPE_IMSA: + imsaTasks_.push_back(task); + break; + case SOURCE_TYPE_INNER: + innerTasks_.push_back(task); + break; + default: + SELECTION_HILOGE("task type %{public}d unknown!", srcType); + return; + } + Process(); +} + +void TaskManager::Process() +{ + ProcessNextInnerTask(); + ProcessNextAmsTask(); + ProcessNextImaTask(); + ProcessNextImsaTask(); +} + +void TaskManager::ProcessNextInnerTask() +{ + while (curTask_) { + // curTask_ is not NULL, it must be paused + // Loop through innerTasks_, try resume + if (innerTasks_.empty()) { + SELECTION_HILOGI("InnerTasks_ empty, return"); + return; + } + + auto task = innerTasks_.front(); + innerTasks_.pop_front(); + auto state = curTask_->OnTask(task); + if (state == RUNNING_STATE_COMPLETED) { + // current task completed + curTask_.reset(); + innerTasks_.clear(); + return; + } + if (state == RUNNING_STATE_PAUSED) { + // current task still paused, try next inner task + continue; + } + + // unreachable + SELECTION_HILOGE("Unexpected OnTask result %{public}d", state); + curTask_.reset(); + innerTasks_.clear(); + } +} + +void TaskManager::ProcessNextAmsTask() +{ + if (amsTasks_.empty()) { + return; + } + + // AMS task has higher priority. If curTask_ is valid and not from AMS, drop it + if (curTask_) { + if (curTask_->GetSourceType() == SOURCE_TYPE_AMS) { + return; + } + curTask_.reset(); + } + + while (!curTask_) { + if (amsTasks_.empty()) { + return; + } + curTask_ = amsTasks_.front(); + amsTasks_.pop_front(); + ExecuteCurrentTask(); + } +} + +void TaskManager::ProcessNextImaTask() +{ + if (imaTasks_.empty()) { + return; + } + + if (curTask_) { + // curTask_ must be paused here + while (!imaTasks_.empty()) { + auto task = imaTasks_.front(); + imaTasks_.pop_front(); + auto state = curTask_->OnTask(task); + if (state == RUNNING_STATE_COMPLETED) { + curTask_.reset(); + break; + } + } + } + + while (!curTask_) { + if (imaTasks_.empty()) { + return; + } + curTask_ = imaTasks_.front(); + imaTasks_.pop_front(); + ExecuteCurrentTask(); + } +} + +void TaskManager::ProcessNextImsaTask() +{ + if (!inited_) { + return; + } + + if (curTask_ || imsaTasks_.empty()) { + return; + } + + while (!curTask_) { + if (imsaTasks_.empty()) { + return; + } + curTask_ = imsaTasks_.front(); + imsaTasks_.pop_front(); + ExecuteCurrentTask(); + } +} + +void TaskManager::ExecuteCurrentTask() +{ + if (curTask_ == nullptr) { + return; + } + auto state = curTask_->Execute(); + if (state == RUNNING_STATE_COMPLETED) { + SELECTION_HILOGI("curTask_ completed"); + curTask_.reset(); + ProcessAsync(); + return; + } + if (state == RUNNING_STATE_PAUSED) { + SELECTION_HILOGI("curTask_ paused"); + return; + } + SELECTION_HILOGE("Unexpected Execute result %{public}u", state); + curTask_.reset(); +} + +void TaskManager::Reset() +{ + inited_ = false; + curTask_ = nullptr; + innerTasks_.clear(); + imaTasks_.clear(); + imsaTasks_.clear(); + amsTasks_.clear(); +} + +} // namespace SelectionFwk +} // namespace OHOS diff --git a/frameworks/native/selection_ability/src/tasks/task.cpp b/frameworks/native/selection_ability/src/tasks/task.cpp new file mode 100644 index 0000000..32ecc7c --- /dev/null +++ b/frameworks/native/selection_ability/src/tasks/task.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2024-2024 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 "tasks/task.h" + +// #include "global.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { + +Task::Task(TaskType type) : type_(type), seqId_(GetNextSeqId()) { } + +Task::Task(TaskType type, uint64_t seqId) : type_(type), seqId_(seqId) { } + +RunningState Task::Execute() +{ + if (state_ != RUNNING_STATE_IDLE) { + SELECTION_HILOGE("Task not runnable, state=%{public}u", state_); + return RUNNING_STATE_ERROR; + } + return ExecuteInner(); +} + +RunningState Task::Resume(uint64_t seqId) +{ + if (!curAction_) { + SELECTION_HILOGE("curAction_ is NULL, error!"); + return RUNNING_STATE_ERROR; + } + + if (state_ != RUNNING_STATE_PAUSED) { + SELECTION_HILOGE("state_ is %{public}u, do not need to resume", state_); + return RUNNING_STATE_ERROR; + } + + auto ret = curAction_->Resume(seqId); + if (ret == RUNNING_STATE_PAUSED) { // resume failed, return + return state_; + } + if (ret == RUNNING_STATE_COMPLETED) { // resume success, continue to execute + curAction_.reset(); + return ExecuteInner(); + } + + // unreachable + SELECTION_HILOGE("curAction_ resume return %{public}u, error!", ret); + return RUNNING_STATE_ERROR; +} + +RunningState Task::OnTask(std::shared_ptr task) +{ + if (task == nullptr) { + SELECTION_HILOGE("task is NULL, error!"); + return state_; + } + auto src = task->GetSourceType(); + if (src == SOURCE_TYPE_INNER) { + return Resume(task->GetSeqId()); + } + if (src == SOURCE_TYPE_IMA) { + Pend(task); + return state_; + } + return state_; +} + +TaskType Task::GetType() const +{ + return type_; +} + +SourceType Task::GetSourceType() const +{ + if (type_ >= TASK_TYPE_AMS_BEGIN && type_ <= TASK_TYPE_AMS_END) { + return SOURCE_TYPE_AMS; + } + if (type_ >= TASK_TYPE_IMA_BEGIN && type_ <= TASK_TYPE_IMA_END) { + return SOURCE_TYPE_IMA; + } + if (type_ >= TASK_TYPE_IMSA_BEGIN && type_ <= TASK_TYPE_IMSA_END) { + return SOURCE_TYPE_IMSA; + } + return SOURCE_TYPE_INNER; +} + +uint64_t Task::GetSeqId() const +{ + return seqId_; +} + +RunningState Task::GetState() const +{ + return state_; +} + +bool Task::IsRunning() const +{ + return state_ == RUNNING_STATE_RUNNING; +} + +const std::list> &Task::GetActions() const +{ + return actions_; +} + +uint64_t Task::GetNextSeqId() +{ + static std::atomic maxSeqId(1); + return maxSeqId.fetch_add(1); +} + +RunningState Task::ExecuteInner() +{ + state_ = RUNNING_STATE_RUNNING; + if (!pendingActions_.empty()) { + pendingActions_.splice(pendingActions_.end(), actions_); + actions_.swap(pendingActions_); + } + + while (!actions_.empty()) { + curAction_ = std::move(actions_.front()); + actions_.pop_front(); + + auto ret = curAction_->Execute(); + + // check pending tasks + if (!pendingActions_.empty()) { + pendingActions_.splice(pendingActions_.end(), actions_); + actions_.swap(pendingActions_); + } + + if (ret == RUNNING_STATE_COMPLETED) { + curAction_.reset(); + continue; + } + + state_ = RUNNING_STATE_PAUSED; + return state_; + } + state_ = RUNNING_STATE_COMPLETED; + return state_; +} + +int32_t Task::Pend(std::shared_ptr task) +{ + pendingActions_.splice(pendingActions_.end(), task->actions_); + actions_.swap(pendingActions_); + return ErrorCode::NO_ERROR; +} + +int32_t Task::Pend(std::unique_ptr action) +{ + pendingActions_.push_back(std::move(action)); + return ErrorCode::NO_ERROR; +} + +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file -- Gitee From d5516b67d44ff3935b780bd2581e856ab29833a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Wed, 28 May 2025 14:47:37 +0800 Subject: [PATCH 40/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0showPanel=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 1 - common/BUILD.gn | 3 +- common/concurrent_map.h | 302 +++++++++++++++++ common/ffrt_block_queue.h | 70 ++++ frameworks/js/napi/selection_ability/BUILD.gn | 2 + .../js/napi/selection_ability/js_panel.cpp | 184 +++++++++-- .../js/napi/selection_ability/js_panel.h | 92 +++--- .../selection_ability/panel_listener_impl.cpp | 307 ++++++++---------- .../selection_ability/panel_listener_impl.h | 75 +++-- frameworks/native/selection_ability/BUILD.gn | 12 +- .../selection_ability/include/panel_common.h | 96 ++++++ .../include/panel_status_listener.h | 35 ++ .../include/selection_ability.h | 12 +- .../include/selection_attribute.h | 148 +++++++++ .../include/selection_panel.h | 22 +- .../include/selection_window_info.h | 123 +++++++ .../src/selection_ability.cpp | 54 +++ .../selection_ability/src/selection_panel.cpp | 191 ++++++++++- selection_service.gni | 2 + 19 files changed, 1431 insertions(+), 300 deletions(-) create mode 100644 common/concurrent_map.h create mode 100644 common/ffrt_block_queue.h create mode 100644 frameworks/native/selection_ability/include/panel_common.h create mode 100644 frameworks/native/selection_ability/include/panel_status_listener.h create mode 100644 frameworks/native/selection_ability/include/selection_attribute.h create mode 100644 frameworks/native/selection_ability/include/selection_window_info.h diff --git a/bundle.json b/bundle.json index 91e484a..f225aec 100644 --- a/bundle.json +++ b/bundle.json @@ -36,7 +36,6 @@ "graphic_2d", "bundle_framework", "ffrt", - "config_policy" ], "third_party": [ diff --git a/common/BUILD.gn b/common/BUILD.gn index cb77afd..a202b79 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -39,7 +39,7 @@ ohos_static_library("selection_common") { "callback_object.cpp", "util.cpp", "selectionmethod_trace.cpp", - "js_utils.cpp" + "js_utils.cpp", ] ldflags = [ "-Wl,--exclude-libs=ALL" ] @@ -59,6 +59,7 @@ ohos_static_library("selection_common") { "ability_base:want", "ability_runtime:abilitykit_native", "ability_runtime:extensionkit_native", + "ffrt:libffrt", ] part_name = "selectionfwk" subsystem_name = "systemabilitymgr" diff --git a/common/concurrent_map.h b/common/concurrent_map.h new file mode 100644 index 0000000..eff3b24 --- /dev/null +++ b/common/concurrent_map.h @@ -0,0 +1,302 @@ +/* + * 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_SELECTION_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#define OHOS_SELECTION_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#include +#include +#include +namespace OHOS { +template +class ConcurrentMap { + template + static _First First(); + +public: + using map_type = typename std::map<_Key, _Tp>; + using filter_type = typename std::function; + using key_type = typename std::map<_Key, _Tp>::key_type; + using mapped_type = typename std::map<_Key, _Tp>::mapped_type; + using value_type = typename std::map<_Key, _Tp>::value_type; + using size_type = typename std::map<_Key, _Tp>::size_type; + using reference = typename std::map<_Key, _Tp>::reference; + using const_reference = typename std::map<_Key, _Tp>::const_reference; + + ConcurrentMap() = default; + ~ConcurrentMap() + { + Clear(); + } + + ConcurrentMap(const ConcurrentMap &other) + { + operator=(std::move(other)); + } + + ConcurrentMap &operator=(const ConcurrentMap &other) noexcept + { + if (this == &other) { + return *this; + } + auto tmp = other.Clone(); + std::lock_guard lock(mutex_); + entries_ = std::move(tmp); + return *this; + } + + ConcurrentMap(ConcurrentMap &&other) noexcept + { + operator=(std::move(other)); + } + + ConcurrentMap &operator=(ConcurrentMap &&other) noexcept + { + if (this == &other) { + return *this; + } + auto tmp = other.Steal(); + std::lock_guard lock(mutex_); + entries_ = std::move(tmp); + return *this; + } + + bool Emplace() noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.emplace(); + return it.second; + } + + template + typename std::enable_if()), filter_type>, bool>::type Emplace( + _Args &&...args) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.emplace(std::forward<_Args>(args)...); + return it.second; + } + + template + typename std::enable_if, bool>::type Emplace(const _Filter &filter, + _Args &&...args) noexcept + { + std::lock_guard lock(mutex_); + if (!filter(entries_)) { + return false; + } + auto it = entries_.emplace(std::forward<_Args>(args)...); + return it.second; + } + + std::pair Find(const key_type &key) const noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + return std::pair{ false, mapped_type() }; + } + + return std::pair{ true, it->second }; + } + + bool Contains(const key_type &key) const noexcept + { + std::lock_guard lock(mutex_); + return (entries_.find(key) != entries_.end()); + } + + template + bool InsertOrAssign(const key_type &key, _Obj &&obj) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.insert_or_assign(key, std::forward<_Obj>(obj)); + return it.second; + } + + bool Insert(const key_type &key, const mapped_type &value) noexcept + { + std::lock_guard lock(mutex_); + auto it = entries_.insert(value_type{ key, value }); + return it.second; + } + + size_type Erase(const key_type &key) noexcept + { + std::lock_guard lock(mutex_); + return entries_.erase(key); + } + + void Clear() noexcept + { + std::lock_guard lock(mutex_); + return entries_.clear(); + } + + bool Empty() const noexcept + { + std::lock_guard lock(mutex_); + return entries_.empty(); + } + + size_type Size() const noexcept + { + std::lock_guard lock(mutex_); + return entries_.size(); + } + + // The action`s return true means meeting the erase condition + // The action`s return false means not meeting the erase condition + size_type EraseIf(const std::function &action) noexcept + { + if (action == nullptr) { + return 0; + } + std::lock_guard lock(mutex_); +#if __cplusplus > 201703L + auto count = std::erase_if(entries_, + [&action](value_type &value) -> bool { return action(value.first, value.second); }); +#else + auto count = entries_.size(); + for (auto it = entries_.begin(); it != entries_.end();) { + if (action((*it).first, (*it).second)) { + it = entries_.erase(it); + } else { + ++it; + } + } + count -= entries_.size(); +#endif + return count; + } + + void ForEach(const std::function &action) + { + if (action == nullptr) { + return; + } + std::lock_guard lock(mutex_); + for (auto &[key, value] : entries_) { + if (action(key, value)) { + break; + } + } + } + + void ForEachCopies(const std::function &action) + { + if (action == nullptr) { + return; + } + auto entries = Clone(); + for (auto &[key, value] : entries) { + if (action(key, value)) { + break; + } + } + } + + // The action's return value means that the element is keep in map or not; true means keeping, false means removing. + bool Compute(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + auto result = entries_.emplace(key, mapped_type()); + it = result.second ? result.first : entries_.end(); + } + if (it == entries_.end()) { + return false; + } + if (!action(it->first, it->second)) { + entries_.erase(key); + } + return true; + } + + // The action's return value means that the element is keep in map or not; true means keeping, false means removing. + bool ComputeIfPresent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it == entries_.end()) { + return false; + } + if (!action(key, it->second)) { + entries_.erase(key); + } + return true; + } + + bool ComputeIfAbsent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it != entries_.end()) { + return false; + } + entries_.emplace(key, action(key)); + return true; + } + + bool ComputeIfAbsent(const key_type &key, const std::function &action) + { + if (action == nullptr) { + return false; + } + std::lock_guard lock(mutex_); + auto it = entries_.find(key); + if (it != entries_.end()) { + return false; + } + auto result = entries_.emplace(key, mapped_type()); + it = result.second ? result.first : entries_.end(); + if (it == entries_.end()) { + return false; + } + if (!action(it->first, it->second)) { + entries_.erase(key); + return false; + } + return true; + } + +private: + std::map<_Key, _Tp> Steal() noexcept + { + std::lock_guard lock(mutex_); + return std::move(entries_); + } + + std::map<_Key, _Tp> Clone() const noexcept + { + std::lock_guard lock(mutex_); + return entries_; + } + +private: + mutable std::recursive_mutex mutex_; + std::map<_Key, _Tp> entries_; +}; +} // namespace OHOS +#endif // OHOS_SELECTION_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H diff --git a/common/ffrt_block_queue.h b/common/ffrt_block_queue.h new file mode 100644 index 0000000..8823968 --- /dev/null +++ b/common/ffrt_block_queue.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 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_INPUTMETHOD_FFRT_BLOCK_QUEUE_H +#define OHOS_INPUTMETHOD_FFRT_BLOCK_QUEUE_H +#include + +#include "cpp/mutex.h" +#include "ffrt.h" + +namespace OHOS { +namespace SelectionFwk { +template class FFRTBlockQueue { +public: + explicit FFRTBlockQueue(uint32_t timeout) : timeout_(timeout) + { + } + + ~FFRTBlockQueue() = default; + + void Pop() + { + std::unique_lock lock(queuesMutex_); + queues_.pop(); + cv_.notify_all(); + } + + void Push(const T &data) + { + std::unique_lock lock(queuesMutex_); + queues_.push(data); + } + + void Wait(const T &data) + { + std::unique_lock lock(queuesMutex_); + cv_.wait_for(lock, std::chrono::milliseconds(timeout_), [&data, this]() { return data == queues_.front(); }); + } + + bool GetFront(T &data) + { + std::unique_lock lock(queuesMutex_); + if (queues_.empty()) { + return false; + } + data = queues_.front(); + return true; + } + +private: + const uint32_t timeout_; + ffrt::mutex queuesMutex_; + std::queue queues_; + ffrt::condition_variable cv_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // OHOS_INPUTMETHOD_FFRT_BLOCK_QUEUE_H diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index d11f656..225f1fe 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -49,6 +49,8 @@ ohos_shared_library("selectionengine_napi") { "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_ability", ] + cflags_cc = [ "-std=c++17" ] + external_deps = [ "ability_base:configuration", "ability_runtime:ability_context_native", diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 5c15d37..074a3c3 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -19,17 +19,19 @@ #include "napi/native_node_api.h" #include "selection_log.h" #include "panel_listener_impl.h" -// #include "utils.h" -// #include "selectionmethod_trace.h" +#include "js_utils.h" +#include "selectionmethod_trace.h" #include "selection_ability.h" namespace OHOS { namespace SelectionFwk { +constexpr int32_t MAX_WAIT_TIME = 10; const std::string JsPanel::CLASS_NAME = "Panel"; thread_local napi_ref JsPanel::panelConstructorRef_ = nullptr; std::mutex JsPanel::panelConstructorMutex_; +FFRTBlockQueue JsPanel::jsQueue_{ MAX_WAIT_TIME }; napi_value JsPanel::Init(napi_env env) { @@ -42,8 +44,10 @@ napi_value JsPanel::Init(napi_env env) return constructor; } const napi_property_descriptor properties[] = { + DECLARE_NAPI_FUNCTION("setUiContent", SetUiContent), DECLARE_NAPI_FUNCTION("show", Show), - + DECLARE_NAPI_FUNCTION("hide", Hide), + // DECLARE_NAPI_FUNCTION("startMoving", StartMoving), }; NAPI_CALL(env, napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), JsNew, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor)); @@ -95,42 +99,150 @@ void JsPanel::SetNative(const std::shared_ptr &panel) selectionPanel_ = panel; } -napi_value JsPanel::Show(napi_env env, napi_callback_info info) +std::shared_ptr JsPanel::GetNative() { - SELECTION_HILOGI("cJsPanel---Show."); - // SelectionMethodSyncTrace tracer("JsPanel_Show"); - // auto ctxt = std::make_shared(env, info); - // auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { - // ctxt->info = { std::chrono::system_clock::now(), JsEvent::SHOW }; - // jsQueue_.Push(ctxt->info); - // return napi_ok; - // }; - // auto exec = [ctxt](AsyncCall::Context *ctx) { - // jsQueue_.Wait(ctxt->info); - // if (ctxt->selectionPanel == nullptr) { - // SELECTION_HILOGE("selectionPanel is nullptr!"); - // jsQueue_.Pop(); - // return; - // } - // auto code = SelectionAbility::GetInstance()->ShowPanel(ctxt->selectionPanel); - // if (code == ErrorCode::NO_ERROR) { - // ctxt->SetState(napi_ok); - // jsQueue_.Pop(); - // return; - // } - // jsQueue_.Pop(); - // ctxt->SetErrorCode(code); - // }; - // ctxt->SetAction(std::move(input)); - // // 1 means JsAPI:show has 1 param at most. - // AsyncCall asyncCall(env, info, ctxt, 1); - // return asyncCall.Call(env, exec, "show"); - return nullptr; + return selectionPanel_; } -std::shared_ptr JsPanel::GetNative() +napi_value JsPanel::SetUiContent(napi_env env, napi_callback_info info) { - return selectionPanel_; + SELECTION_HILOGI("JsPanel start."); + auto ctxt = std::make_shared(env, info); + auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + napi_status status = napi_generic_failure; + PARAM_CHECK_RETURN(env, argc >= 1, "at least one parameter is required!", TYPE_NONE, status); + // 0 means the first param path + PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, argv[0], ctxt->path) == napi_ok, + "js param path covert failed, must be string!", TYPE_NONE, status); + // if type of argv[1] is object, we will get value of 'storage' from it. + // if (argc >= 2) { + // napi_valuetype valueType = napi_undefined; + // status = napi_typeof(env, argv[1], &valueType); + // CHECK_RETURN(status == napi_ok, "get valueType failed!", status); + // if (valueType == napi_object) { + // napi_ref storage = nullptr; + // napi_create_reference(env, argv[1], 1, &storage); + // auto contentStorage = (storage == nullptr) ? nullptr + // : std::shared_ptr( + // reinterpret_cast(storage)); + // ctxt->contentStorage = contentStorage; + // } + // } + ctxt->info = { std::chrono::system_clock::now(), JsEvent::SET_UI_CONTENT }; + jsQueue_.Push(ctxt->info); + return napi_ok; + }; + + auto exec = [ctxt](AsyncCall::Context *ctx) { ctxt->SetState(napi_ok); }; + auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { + jsQueue_.Wait(ctxt->info); + if (ctxt->selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr!"); + jsQueue_.Pop(); + return napi_generic_failure; + } + // auto code = ctxt->selectionPanel->SetUiContent(ctxt->path, env, ctxt->contentStorage); + auto code = ctxt->selectionPanel->SetUiContent(ctxt->path, env); + jsQueue_.Pop(); + if (code == ErrorCode::ERROR_PARAMETER_CHECK_FAILED) { + ctxt->SetErrorCode(code); + ctxt->SetErrorMessage("path should be a path to specific page."); + return napi_generic_failure; + } + return napi_ok; + }; + ctxt->SetAction(std::move(input), std::move(output)); + // 2 means JsAPI:setUiContent has 2 params at most. + AsyncCall asyncCall(env, info, ctxt, 2); + return asyncCall.Call(env, exec, "setUiContent"); } + +napi_value JsPanel::Show(napi_env env, napi_callback_info info) +{ + SelectionMethodSyncTrace tracer("JsPanel_Show"); + auto ctxt = std::make_shared(env, info); + auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + ctxt->info = { std::chrono::system_clock::now(), JsEvent::SHOW }; + jsQueue_.Push(ctxt->info); + return napi_ok; + }; + auto exec = [ctxt](AsyncCall::Context *ctx) { + jsQueue_.Wait(ctxt->info); + if (ctxt->selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr!"); + jsQueue_.Pop(); + return; + } + auto code = SelectionAbility::GetInstance()->ShowPanel(ctxt->selectionPanel); + if (code == ErrorCode::NO_ERROR) { + ctxt->SetState(napi_ok); + jsQueue_.Pop(); + return; + } + jsQueue_.Pop(); + ctxt->SetErrorCode(code); + }; + ctxt->SetAction(std::move(input)); + // 1 means JsAPI:show has 1 param at most. + AsyncCall asyncCall(env, info, ctxt, 1); + return asyncCall.Call(env, exec, "show"); } -} \ No newline at end of file + +napi_value JsPanel::Hide(napi_env env, napi_callback_info info) +{ + SelectionMethodSyncTrace tracer("JsPanel_Hide"); + auto ctxt = std::make_shared(env, info); + + auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + ctxt->info = { std::chrono::system_clock::now(), JsEvent::HIDE }; + jsQueue_.Push(ctxt->info); + return napi_ok; + }; + auto exec = [ctxt](AsyncCall::Context *ctx) { + jsQueue_.Wait(ctxt->info); + if (ctxt->selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr!"); + jsQueue_.Pop(); + return; + } + auto code = SelectionAbility::GetInstance()->HidePanel(ctxt->selectionPanel); + jsQueue_.Pop(); + if (code == ErrorCode::NO_ERROR) { + ctxt->SetState(napi_ok); + return; + } + ctxt->SetErrorCode(code); + }; + ctxt->SetAction(std::move(input)); + // 1 means JsAPI:hide has 1 param at most. + AsyncCall asyncCall(env, info, ctxt, 1); + return asyncCall.Call(env, exec, "panel.hide"); +} + +// napi_value JsPanel::StartMoving(napi_env env, napi_callback_info info) +// { +// napi_value self = nullptr; +// NAPI_CALL(env, napi_get_cb_info(env, info, 0, nullptr, &self, nullptr)); +// RESULT_CHECK_RETURN(env, (self != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), +// "", TYPE_NONE, JsUtil::Const::Null(env)); +// void *native = nullptr; +// NAPI_CALL(env, napi_unwrap(env, self, &native)); +// RESULT_CHECK_RETURN(env, (native != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), +// "", TYPE_NONE, JsUtil::Const::Null(env)); +// auto selectionPanel = reinterpret_cast(native)->GetNative(); +// if (selectionPanel == nullptr) { +// SELECTION_HILOGE("selectionPanel is nullptr!"); +// JsUtils::ThrowException(env, JsUtils::Convert(ErrorCode::ERROR_IME), +// "failed to start moving, selectionPanel is nullptr", TYPE_NONE); +// return JsUtil::Const::Null(env); +// } + +// auto ret = selectionPanel->StartMoving(); +// if (ret != ErrorCode::NO_ERROR) { +// JsUtils::ThrowException(env, JsUtils::Convert(ret), "failed to start moving", TYPE_NONE); +// } +// return JsUtil::Const::Null(env); +// } + +} // namespace SelectionFwk +} // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index 29acde0..c44ae04 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -19,10 +19,9 @@ #include "napi/native_api.h" #include "selection_panel.h" #include "async_call.h" -// #include "panel_common.h" +#include "panel_common.h" #include "panel_info.h" -// #include "ffrt_block_queue.h" -#include "event_checker.h" +#include "ffrt_block_queue.h" #include @@ -62,58 +61,61 @@ public: JsPanel() = default; ~JsPanel(); static napi_value Init(napi_env env); + static napi_value SetUiContent(napi_env env, napi_callback_info info); static napi_value Show(napi_env env, napi_callback_info info); + static napi_value Hide(napi_env env, napi_callback_info info); + // static napi_value StartMoving(napi_env env, napi_callback_info info); void SetNative(const std::shared_ptr &panel); std::shared_ptr GetNative(); private: - // struct PanelContentContext : public AsyncCall::Context { - // LayoutParams layoutParams = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; - // EnhancedLayoutParams enhancedLayoutParams; - // HotAreas hotAreas; - // std::vector hotArea; - // bool isEnhancedCall{ false }; - // PanelFlag panelFlag = PanelFlag::FLG_FIXED; - // std::string path = ""; - // uint32_t width = 0; - // uint32_t height = 0; - // int32_t x = 0; - // int32_t y = 0; - // uint64_t displayId = 0; - // std::shared_ptr selectionPanel = nullptr; - // std::shared_ptr contentStorage = nullptr; - // JsEventInfo info; - // PanelContentContext(napi_env env, napi_callback_info info) : Context(nullptr, nullptr) - // { - // napi_value self = nullptr; - // napi_status status = napi_get_cb_info(env, info, 0, nullptr, &self, nullptr); - // CHECK_RETURN_VOID((status == napi_ok) && (self != nullptr), "get callback info failed."); - // void *native = nullptr; - // status = napi_unwrap(env, self, &native); - // CHECK_RETURN_VOID((status == napi_ok) && (native != nullptr), "get jsPanel failed."); - // selectionPanel = reinterpret_cast(native)->GetNative(); - // }; - // PanelContentContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; - // napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override - // { - // CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); - // return Context::operator()(env, argc, argv, self); - // } - // napi_status operator()(napi_env env, napi_value *result) override - // { - // if (status_ != napi_ok) { - // output_ = nullptr; - // return status_; - // } - // return Context::operator()(env, result); - // } - // }; + struct PanelContentContext : public AsyncCall::Context { + LayoutParams layoutParams = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; + EnhancedLayoutParams enhancedLayoutParams; + HotAreas hotAreas; + std::vector hotArea; + bool isEnhancedCall{ false }; + PanelFlag panelFlag = PanelFlag::FLG_FIXED; + std::string path = ""; + uint32_t width = 0; + uint32_t height = 0; + int32_t x = 0; + int32_t y = 0; + uint64_t displayId = 0; + std::shared_ptr selectionPanel = nullptr; + std::shared_ptr contentStorage = nullptr; + JsEventInfo info; + PanelContentContext(napi_env env, napi_callback_info info) : Context(nullptr, nullptr) + { + napi_value self = nullptr; + napi_status status = napi_get_cb_info(env, info, 0, nullptr, &self, nullptr); + CHECK_RETURN_VOID((status == napi_ok) && (self != nullptr), "get callback info failed."); + void *native = nullptr; + status = napi_unwrap(env, self, &native); + CHECK_RETURN_VOID((status == napi_ok) && (native != nullptr), "get jsPanel failed."); + selectionPanel = reinterpret_cast(native)->GetNative(); + }; + PanelContentContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){}; + napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override + { + CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg); + return Context::operator()(env, argc, argv, self); + } + napi_status operator()(napi_env env, napi_value *result) override + { + if (status_ != napi_ok) { + output_ = nullptr; + return status_; + } + return Context::operator()(env, result); + } + }; static napi_value JsNew(napi_env env, napi_callback_info info); static const std::string CLASS_NAME; static thread_local napi_ref panelConstructorRef_; std::shared_ptr selectionPanel_ = nullptr; static std::mutex panelConstructorMutex_; - // static FFRTBlockQueue jsQueue_; + static FFRTBlockQueue jsQueue_; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp index 7325187..fef87ff 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -15,9 +15,9 @@ #include "panel_listener_impl.h" -#include "callback_handler.h" #include "js_utils.h" -#include "js_selection_utils.h" +#include "callback_handler.h" +#include "util.h" namespace OHOS { namespace SelectionFwk { @@ -36,180 +36,157 @@ std::shared_ptr PanelListenerImpl::GetInstance() PanelListenerImpl::~PanelListenerImpl() {} -// void PanelListenerImpl::Subscribe(uint32_t windowId, const std::string &type, -// std::shared_ptr cbObject) -// { -// callbacks_.Compute(windowId, -// [cbObject, &type](auto windowId, std::map> &cbs) { -// auto [it, insert] = cbs.try_emplace(type, cbObject); -// if (insert) { -// IMSA_HILOGI("start to subscribe type: %{public}s of windowId: %{public}u.", type.c_str(), windowId); -// } else { -// IMSA_HILOGD("type: %{public}s of windowId: %{public}u already subscribed.", type.c_str(), windowId); -// } -// return !cbs.empty(); -// }); -// } - -// void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId) -// { -// callbacks_.ComputeIfPresent(windowId, -// [&type](auto windowId, std::map> &cbs) { -// cbs.erase(type); -// return !cbs.empty(); -// }); -// } +void PanelListenerImpl::SetEventHandler(std::shared_ptr handler) +{ + std::unique_lock lock(eventHandlerMutex_); + handler_ = handler; +} -// void PanelListenerImpl::OnPanelStatus(uint32_t windowId, bool isShow) -// { -// std::string type = isShow ? "show" : "hide"; -// auto eventHandler = GetEventHandler(); -// if (eventHandler == nullptr) { -// IMSA_HILOGE("eventHandler is nullptr!"); -// return; -// } -// std::shared_ptr callBack = GetCallback(windowId, type); -// if (callBack == nullptr) { -// IMSA_HILOGE("callBack is nullptr!"); -// return; -// } -// auto entry = std::make_shared(callBack); -// IMSA_HILOGI("windowId = %{public}u, type = %{public}s", windowId, type.c_str()); -// auto task = [entry]() { -// JsCallbackHandler::Traverse({ entry->cbCopy }); -// }; -// eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); -// } +std::shared_ptr PanelListenerImpl::GetEventHandler() +{ + std::shared_lock lock(eventHandlerMutex_); + return handler_; +} -// void PanelListenerImpl::OnSizeChange(uint32_t windowId, const WindowSize &size) -// { -// std::string type = "sizeChange"; -// auto eventHandler = GetEventHandler(); -// if (eventHandler == nullptr) { -// IMSA_HILOGE("eventHandler is nullptr!"); -// return; -// } -// std::shared_ptr callBack = GetCallback(windowId, type); -// if (callBack == nullptr) { -// return; -// } -// auto entry = std::make_shared(callBack); -// entry->size = size; -// IMSA_HILOGI("OnSizeChange start. windowId:%{public}u, w:%{public}u, h:%{public}u", windowId, size.width, -// size.height); -// auto task = [entry]() { -// auto gitWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { -// if (argc == 0) { -// return false; -// } -// napi_value windowSize = JsWindowSize::Write(env, entry->size); -// // 0 means the first param of callback. -// args[0] = { windowSize }; -// return true; -// }; -// JsCallbackHandler::Traverse({ entry->cbCopy }, { 1, gitWindowSizeParams }); -// }; -// eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); -// } +void PanelListenerImpl::OnPanelStatus(uint32_t windowId, bool isShow) +{ + std::string type = isShow ? "show" : "hide"; + auto eventHandler = GetEventHandler(); + if (eventHandler == nullptr) { + SELECTION_HILOGE("eventHandler is nullptr!"); + return; + } + std::shared_ptr callBack = GetCallback(windowId, type); + if (callBack == nullptr) { + SELECTION_HILOGE("callBack is nullptr!"); + return; + } + auto entry = std::make_shared(callBack); + SELECTION_HILOGI("windowId = %{public}u, type = %{public}s", windowId, type.c_str()); + auto task = [entry]() { + SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }); + }; + eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); +} -// void PanelListenerImpl::OnSizeChange( -// uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) -// { -// std::string type = "sizeUpdate"; -// auto eventHandler = GetEventHandler(); -// if (eventHandler == nullptr) { -// IMSA_HILOGE("eventHandler is nullptr!"); -// return; -// } -// std::shared_ptr callBack = GetCallback(windowId, event); -// if (callBack == nullptr) { -// IMSA_HILOGE("callback is nullptr"); -// return; -// } -// auto entry = std::make_shared(callBack); -// entry->size = size; -// entry->keyboardArea = keyboardArea; -// IMSA_HILOGI("%{public}s start. windowId:%{public}u, windowSize[%{public}u/%{public}u], " -// "keyboardArea:[%{public}d/%{public}d/%{public}d/%{public}d]", -// event.c_str(), windowId, size.width, size.height, keyboardArea.top, keyboardArea.bottom, keyboardArea.left, -// keyboardArea.right); -// auto task = [entry]() { -// auto getWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { -// if (argc == 0) { -// return false; -// } -// napi_value windowSize = JsWindowSize::Write(env, entry->size); -// napi_value jsKeyboardArea = JsKeyboardArea::Write(env, entry->keyboardArea); -// args[0] = { windowSize }; -// args[1] = { jsKeyboardArea }; -// return true; -// }; -// // 2 means 'sizeChange' has 2 params -// JsCallbackHandler::Traverse({ entry->cbCopy }, { 2, getWindowSizeParams }); -// }; -// eventHandler->PostTask(task, event, 0, AppExecFwk::EventQueue::Priority::VIP); -// } +void PanelListenerImpl::OnSizeChange(uint32_t windowId, const WindowSize &size) +{ + std::string type = "sizeChange"; + auto eventHandler = GetEventHandler(); + if (eventHandler == nullptr) { + SELECTION_HILOGE("eventHandler is nullptr!"); + return; + } + std::shared_ptr callBack = GetCallback(windowId, type); + if (callBack == nullptr) { + return; + } + auto entry = std::make_shared(callBack); + entry->size = size; + SELECTION_HILOGI("OnSizeChange start. windowId:%{public}u, w:%{public}u, h:%{public}u", windowId, size.width, + size.height); + auto task = [entry]() { + auto gitWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { + if (argc == 0) { + return false; + } + napi_value windowSize = JsWindowSize::Write(env, entry->size); + // 0 means the first param of callback. + args[0] = { windowSize }; + return true; + }; + SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 1, gitWindowSizeParams }); + }; + eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); +} -void PanelListenerImpl::SetEventHandler(std::shared_ptr handler) +void PanelListenerImpl::OnSizeChange( + uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) { - std::unique_lock lock(eventHandlerMutex_); - handler_ = handler; + std::string type = "sizeUpdate"; + auto eventHandler = GetEventHandler(); + if (eventHandler == nullptr) { + SELECTION_HILOGE("eventHandler is nullptr!"); + return; + } + std::shared_ptr callBack = GetCallback(windowId, event); + if (callBack == nullptr) { + SELECTION_HILOGE("callback is nullptr"); + return; + } + auto entry = std::make_shared(callBack); + entry->size = size; + entry->keyboardArea = keyboardArea; + SELECTION_HILOGI("%{public}s start. windowId:%{public}u, windowSize[%{public}u/%{public}u], " + "keyboardArea:[%{public}d/%{public}d/%{public}d/%{public}d]", + event.c_str(), windowId, size.width, size.height, keyboardArea.top, keyboardArea.bottom, keyboardArea.left, + keyboardArea.right); + auto task = [entry]() { + auto getWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { + if (argc == 0) { + return false; + } + napi_value windowSize = JsWindowSize::Write(env, entry->size); + napi_value jsKeyboardArea = JsKeyboardArea::Write(env, entry->keyboardArea); + args[0] = { windowSize }; + args[1] = { jsKeyboardArea }; + return true; + }; + // 2 means 'sizeChange' has 2 params + SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 2, getWindowSizeParams }); + }; + eventHandler->PostTask(task, event, 0, AppExecFwk::EventQueue::Priority::VIP); } -// std::shared_ptr PanelListenerImpl::GetEventHandler() -// { -// std::shared_lock lock(eventHandlerMutex_); -// return handler_; -// } -// std::shared_ptr PanelListenerImpl::GetCallback(uint32_t windowId, const std::string &type) -// { -// std::shared_ptr callBack = nullptr; -// callbacks_.ComputeIfPresent(windowId, [&type, &callBack](uint32_t id, auto callbacks) { -// auto it = callbacks.find(type); -// if (it == callbacks.end()) { -// return !callbacks.empty(); -// } -// callBack = it->second; -// return !callbacks.empty(); -// }); -// return callBack; -// } +std::shared_ptr PanelListenerImpl::GetCallback(uint32_t windowId, const std::string &type) +{ + std::shared_ptr callBack = nullptr; + callbacks_.ComputeIfPresent(windowId, [&type, &callBack](uint32_t id, auto callbacks) { + auto it = callbacks.find(type); + if (it == callbacks.end()) { + return !callbacks.empty(); + } + callBack = it->second; + return !callbacks.empty(); + }); + return callBack; +} -// napi_value JsWindowSize::Write(napi_env env, const WindowSize &nativeObject) -// { -// napi_value jsObject = nullptr; -// napi_create_object(env, &jsObject); -// bool ret = JsUtil::Object::WriteProperty(env, jsObject, "width", nativeObject.width); -// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", nativeObject.height); -// return ret ? jsObject : JsUtil::Const::Null(env); -// } +napi_value JsWindowSize::Write(napi_env env, const WindowSize &nativeObject) +{ + napi_value jsObject = nullptr; + napi_create_object(env, &jsObject); + bool ret = SelectionFwk::JsUtil::Object::WriteProperty(env, jsObject, "width", nativeObject.width); + ret = ret && SelectionFwk::JsUtil::Object::WriteProperty(env, jsObject, "height", nativeObject.height); + return ret ? jsObject : SelectionFwk::JsUtil::Const::Null(env); +} -// bool JsWindowSize::Read(napi_env env, napi_value jsObject, WindowSize &nativeObject) -// { -// auto ret = JsUtil::Object::ReadProperty(env, jsObject, "width", nativeObject.width); -// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "height", nativeObject.height); -// return ret; -// } +bool JsWindowSize::Read(napi_env env, napi_value jsObject, WindowSize &nativeObject) +{ + auto ret = SelectionFwk::JsUtil::Object::ReadProperty(env, jsObject, "width", nativeObject.width); + ret = ret && SelectionFwk::JsUtil::Object::ReadProperty(env, jsObject, "height", nativeObject.height); + return ret; +} -// napi_value JsKeyboardArea::Write(napi_env env, const PanelAdjustInfo &nativeObject) -// { -// napi_value jsObject = nullptr; -// napi_create_object(env, &jsObject); -// bool ret = JsUtil::Object::WriteProperty(env, jsObject, "top", nativeObject.top); -// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "bottom", nativeObject.bottom); -// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "left", nativeObject.left); -// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "right", nativeObject.right); -// return ret ? jsObject : JsUtil::Const::Null(env); -// } +napi_value JsKeyboardArea::Write(napi_env env, const PanelAdjustInfo &nativeObject) +{ + napi_value jsObject = nullptr; + napi_create_object(env, &jsObject); + bool ret = SelectionFwk::JsUtil::Object::WriteProperty(env, jsObject, "top", nativeObject.top); + ret = ret && SelectionFwk::JsUtil::Object::WriteProperty(env, jsObject, "bottom", nativeObject.bottom); + ret = ret && SelectionFwk::JsUtil::Object::WriteProperty(env, jsObject, "left", nativeObject.left); + ret = ret && SelectionFwk::JsUtil::Object::WriteProperty(env, jsObject, "right", nativeObject.right); + return ret ? jsObject : SelectionFwk::JsUtil::Const::Null(env); +} -// bool JsKeyboardArea::Read(napi_env env, napi_value jsObject, PanelAdjustInfo &nativeObject) -// { -// bool ret = JsUtil::Object::ReadProperty(env, jsObject, "top", nativeObject.top); -// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "bottom", nativeObject.bottom); -// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "left", nativeObject.left); -// ret = ret && JsUtil::Object::ReadProperty(env, jsObject, "right", nativeObject.right); -// return ret; -// } +bool JsKeyboardArea::Read(napi_env env, napi_value jsObject, PanelAdjustInfo &nativeObject) +{ + bool ret = SelectionFwk::JsUtil::Object::ReadProperty(env, jsObject, "top", nativeObject.top); + ret = ret && SelectionFwk::JsUtil::Object::ReadProperty(env, jsObject, "bottom", nativeObject.bottom); + ret = ret && SelectionFwk::JsUtil::Object::ReadProperty(env, jsObject, "left", nativeObject.left); + ret = ret && SelectionFwk::JsUtil::Object::ReadProperty(env, jsObject, "right", nativeObject.right); + return ret; +} } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.h b/frameworks/js/napi/selection_ability/panel_listener_impl.h index 9f29802..81c08c2 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.h +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.h @@ -13,63 +13,70 @@ * limitations under the License. */ -#ifndef SELECTON_FWK_PANEL_LISTENER_IMPL_H -#define SELECTON_FWK_PANEL_LISTENER_IMPL_H +#ifndef SELECTION_IMF_PANEL_LISTENER_IMPL_H +#define SELECTION_IMF_PANEL_LISTENER_IMPL_H #include +#include #include #include #include -// #include "concurrent_map.h" +#include "concurrent_map.h" #include "event_handler.h" #include "selection_panel.h" -// #include "js_callback_object.h" +#include "callback_object.h" #include "napi/native_api.h" #include "napi/native_node_api.h" -// #include "panel_status_listener.h" +#include "panel_status_listener.h" + namespace OHOS { namespace SelectionFwk { -// struct JsWindowSize { -// static napi_value Write(napi_env env, const WindowSize &nativeObject); -// static bool Read(napi_env env, napi_value jsObject, WindowSize &nativeObject); -// }; -// struct JsKeyboardArea { -// static napi_value Write(napi_env env, const PanelAdjustInfo &nativeObject); -// static bool Read(napi_env env, napi_value jsObject, PanelAdjustInfo &nativeObject); -// }; -// class PanelListenerImpl : public PanelStatusListener { -class PanelListenerImpl { + +struct JsWindowSize { + static napi_value Write(napi_env env, const WindowSize &nativeObject); + static bool Read(napi_env env, napi_value jsObject, WindowSize &nativeObject); +}; + +struct JsKeyboardArea { + static napi_value Write(napi_env env, const PanelAdjustInfo &nativeObject); + static bool Read(napi_env env, napi_value jsObject, PanelAdjustInfo &nativeObject); +}; + +class PanelListenerImpl : public PanelStatusListener { public: - // struct UvEntry { - // WindowSize size; - // PanelAdjustInfo keyboardArea; - // std::shared_ptr cbCopy; - // explicit UvEntry(const std::shared_ptr &cb) : cbCopy(cb) - // { - // } - // }; - // using EntrySetter = std::function; + +struct UvEntry { + WindowSize size; + PanelAdjustInfo keyboardArea; + std::shared_ptr cbCopy; + explicit UvEntry(const std::shared_ptr &cb) : cbCopy(cb) + { + } + }; + static std::shared_ptr GetInstance(); ~PanelListenerImpl(); - // void OnPanelStatus(uint32_t windowId, bool isShow) override; - // void OnSizeChange(uint32_t windowId, const WindowSize &size) override; - // void OnSizeChange(uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, - // const std::string &event) override; - // void Subscribe(uint32_t windowId, const std::string &type, std::shared_ptr cbObject); - // void RemoveInfo(const std::string &type, uint32_t windowId); + void SetEventHandler(std::shared_ptr handler); - // std::shared_ptr GetCallback(uint32_t windowId, const std::string &type); - // std::shared_ptr GetEventHandler(); + std::shared_ptr GetEventHandler(); + + void OnPanelStatus(uint32_t windowId, bool isShow) override; + void OnSizeChange(uint32_t windowId, const WindowSize &size) override; + void OnSizeChange(uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, + const std::string &event) override; + + std::shared_ptr GetCallback(uint32_t windowId, const std::string &type); - // ConcurrentMap>> callbacks_; static std::mutex listenerMutex_; static std::shared_ptr instance_; mutable std::shared_mutex eventHandlerMutex_; std::shared_ptr handler_; + + ConcurrentMap>> callbacks_; }; } // namespace SelectionFwk } // namespace OHOS -#endif //SELECTON_FWK_PANEL_LISTENER_IMPL_H +#endif //SELECTION_IMF_PANEL_LISTENER_IMPL_H diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn index e5d4905..6803b4c 100644 --- a/frameworks/native/selection_ability/BUILD.gn +++ b/frameworks/native/selection_ability/BUILD.gn @@ -21,7 +21,7 @@ config("selection_listener_config") { "../../../utils/include", "${target_gen_dir}", "${selection_fwk_root_path}/common", - "../../common", + "${selection_fwk_root_path}/frameworks/common", ] } @@ -59,6 +59,15 @@ ohos_source_set("selection_listener_proxy") { } ohos_shared_library("selection_ability") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } configs = [ ":selection_listener_config", ] output_values = get_target_outputs(":selection_listener_interface") @@ -71,6 +80,7 @@ ohos_shared_library("selection_ability") { ] sources += filter_include(output_values, [ "*.cpp" ]) deps = [ + "${selection_fwk_root_path}/common:selection_common", ":selection_listener_interface", ] diff --git a/frameworks/native/selection_ability/include/panel_common.h b/frameworks/native/selection_ability/include/panel_common.h new file mode 100644 index 0000000..5e4e33a --- /dev/null +++ b/frameworks/native/selection_ability/include/panel_common.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 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 INPUTMETHOD_IMF_PANEL_COMMON_H +#define INPUTMETHOD_IMF_PANEL_COMMON_H + +#include + +#include "wm_common.h" + +namespace OHOS { +namespace SelectionFwk { +struct WindowSize { + uint32_t width = 0; + uint32_t height = 0; +}; + +struct LayoutParams { + Rosen::Rect landscapeRect{ 0, 0, 0, 0 }; + Rosen::Rect portraitRect{ 0, 0, 0, 0 }; +}; + +struct HotArea { + std::vector keyboardHotArea; + std::vector panelHotArea; + static std::string ToString(const std::vector &areas) + { + std::string areasStr = "["; + for (const auto area : areas) { + areasStr.append(area.ToString()); + } + areasStr.append("]"); + return areasStr; + } +}; + +struct HotAreas { + HotArea landscape; + HotArea portrait; + bool isSet{ false }; +}; + +struct EnhancedLayoutParam { + Rosen::Rect rect{ 0, 0, 0, 0 }; + int32_t avoidY{ 0 }; + uint32_t avoidHeight{ 0 }; + inline std::string ToString() const + { + std::stringstream ss; + ss << "rect" << rect.ToString() << " avoidY " << avoidY << " avoidHeight " << avoidHeight; + return ss.str(); + } +}; + +struct EnhancedLayoutParams { + bool isFullScreen{ false }; + EnhancedLayoutParam portrait; + EnhancedLayoutParam landscape; +}; + +struct DisplaySize { + WindowSize portrait; + WindowSize landscape; +}; + +struct PanelAdjustInfo { + int32_t top{ 0 }; + int32_t left{ 0 }; + int32_t right{ 0 }; + int32_t bottom{ 0 }; + bool operator==(const PanelAdjustInfo &panelAdjust) const + { + return (top == panelAdjust.top && left == panelAdjust.left && right == panelAdjust.right + && bottom == panelAdjust.bottom); + } +}; + +struct FullPanelAdjustInfo { + PanelAdjustInfo portrait; + PanelAdjustInfo landscape; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif //INPUTMETHOD_IMF_PANEL_COMMON_H diff --git a/frameworks/native/selection_ability/include/panel_status_listener.h b/frameworks/native/selection_ability/include/panel_status_listener.h new file mode 100644 index 0000000..86a0f39 --- /dev/null +++ b/frameworks/native/selection_ability/include/panel_status_listener.h @@ -0,0 +1,35 @@ +/* + * 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 SELECTION_IMF_PANEL_STATUS_LISTENER_H +#define SELECTION_IMF_PANEL_STATUS_LISTENER_H +#include + +#include "panel_common.h" + +namespace OHOS { +namespace SelectionFwk { +class PanelStatusListener { +public: + virtual ~PanelStatusListener() {}; + virtual void OnPanelStatus(uint32_t windowId, bool isShow) = 0; + virtual void OnSizeChange(uint32_t windowId, const WindowSize &size) = 0; + virtual void OnSizeChange( + uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) = 0; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // SELECTION_IMF_PANEL_STATUS_LISTENER_H diff --git a/frameworks/native/selection_ability/include/selection_ability.h b/frameworks/native/selection_ability/include/selection_ability.h index e9b80ea..154bc72 100644 --- a/frameworks/native/selection_ability/include/selection_ability.h +++ b/frameworks/native/selection_ability/include/selection_ability.h @@ -34,24 +34,20 @@ public: static sptr GetInstance(); int32_t CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo, std::shared_ptr &selectionPanel); - void NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag); + int32_t ShowPanel(const std::shared_ptr &selectionPanel); + int32_t HidePanel(const std::shared_ptr &selectionPanel); + // void NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag); private: static std::mutex instanceLock_; static sptr instance_; std::mutex dataChannelLock_; - // std::shared_ptr dataChannelProxy_ = nullptr; - - - // std::shared_ptr GetInputDataChannelProxy(); + std::recursive_mutex keyboardCmdLock_; void Initialize(); ConcurrentMap> panels_ {}; - // sptr coreStub_ { nullptr }; - // sptr agentStub_ { nullptr }; - std::atomic_bool isShowAfterCreate_ { false }; }; diff --git a/frameworks/native/selection_ability/include/selection_attribute.h b/frameworks/native/selection_ability/include/selection_attribute.h new file mode 100644 index 0000000..fd89988 --- /dev/null +++ b/frameworks/native/selection_ability/include/selection_attribute.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2021 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 SERVICES_INCLUDE_INPUT_ATTRIBUTE_H +#define SERVICES_INCLUDE_INPUT_ATTRIBUTE_H + +#include +#include + +#include "parcel.h" + +namespace OHOS { +namespace SelectionFwk { + +struct InputAttribute { + static const int32_t PATTERN_TEXT = 0x00000001; + static const int32_t PATTERN_PASSWORD = 0x00000007; + static const int32_t PATTERN_PASSWORD_NUMBER = 0x00000008; + static const int32_t PATTERN_PASSWORD_SCREEN_LOCK = 0x00000009; + static const int32_t PATTERN_NEWPASSWORD = 0x0000000b; + int32_t inputPattern = 0; + int32_t enterKeyType = 0; + int32_t inputOption = 0; + bool isTextPreviewSupported { false }; + std::string bundleName { "" }; + int32_t immersiveMode = 0; + uint32_t windowId = 0; // for transfer + uint64_t callingDisplayId = 0; + + bool GetSecurityFlag() const + { + return inputPattern == PATTERN_PASSWORD || inputPattern == PATTERN_PASSWORD_SCREEN_LOCK || + PATTERN_PASSWORD_NUMBER == inputPattern || PATTERN_NEWPASSWORD == inputPattern; + } + + bool operator==(const InputAttribute &info) const + { + return inputPattern == info.inputPattern && enterKeyType == info.enterKeyType && + inputOption == info.inputOption && isTextPreviewSupported == info.isTextPreviewSupported; + } + + inline std::string ToString() const + { + std::stringstream ss; + ss << "[" << "inputPattern:" << inputPattern + << "enterKeyType:" << enterKeyType << "inputOption:" << inputOption + << "isTextPreviewSupported:" << isTextPreviewSupported << "bundleName:" << bundleName + << "immersiveMode:" << immersiveMode << "windowId:" << windowId + << "callingDisplayId:" << callingDisplayId << "]"; + return ss.str(); + } +}; + +struct InputAttributeInner : public Parcelable { + static const int32_t PATTERN_TEXT = 0x00000001; + static const int32_t PATTERN_PASSWORD = 0x00000007; + static const int32_t PATTERN_PASSWORD_NUMBER = 0x00000008; + static const int32_t PATTERN_PASSWORD_SCREEN_LOCK = 0x00000009; + static const int32_t PATTERN_NEWPASSWORD = 0x0000000b; + int32_t inputPattern = 0; + int32_t enterKeyType = 0; + int32_t inputOption = 0; + bool isTextPreviewSupported { false }; + std::string bundleName { "" }; + int32_t immersiveMode = 0; + uint32_t windowId = 0; // for transfer + uint64_t callingDisplayId = 0; + + bool ReadFromParcel(Parcel &in) + { + inputPattern = in.ReadInt32(); + enterKeyType = in.ReadInt32(); + inputOption = in.ReadInt32(); + isTextPreviewSupported = in.ReadBool(); + bundleName = in.ReadString(); + immersiveMode = in.ReadInt32(); + windowId = in.ReadUint32(); + callingDisplayId = in.ReadUint64(); + return true; + } + + bool Marshalling(Parcel &out) const + { + if (!out.WriteInt32(inputPattern)) { + return false; + } + if (!out.WriteInt32(enterKeyType)) { + return false; + } + if (!out.WriteInt32(inputOption)) { + return false; + } + if (!out.WriteBool(isTextPreviewSupported)) { + return false; + } + if (!out.WriteString(bundleName)) { + return false; + } + if (!out.WriteInt32(immersiveMode)) { + return false; + } + if (!out.WriteUint32(windowId)) { + return false; + } + if (!out.WriteUint64(callingDisplayId)) { + return false; + } + return true; + } + + static InputAttributeInner *Unmarshalling(Parcel &in) + { + InputAttributeInner *data = new (std::nothrow) InputAttributeInner(); + if (data && !data->ReadFromParcel(in)) { + delete data; + data = nullptr; + } + return data; + } + + bool operator==(const InputAttribute &info) const + { + return inputPattern == info.inputPattern && enterKeyType == info.enterKeyType && + inputOption == info.inputOption && isTextPreviewSupported == info.isTextPreviewSupported; + } + + bool GetSecurityFlag() const + { + return inputPattern == PATTERN_PASSWORD || inputPattern == PATTERN_PASSWORD_SCREEN_LOCK || + PATTERN_PASSWORD_NUMBER == inputPattern || PATTERN_NEWPASSWORD == inputPattern; + } +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // SERVICES_INCLUDE_INPUT_ATTRIBUTE_H diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 47f45e5..0289d0d 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -19,8 +19,8 @@ #include #include #include +#include #include - #include #include "panel_info.h" @@ -29,6 +29,8 @@ #include "wm_common.h" #include "window.h" #include "ui/rs_surface_node.h" +#include "selection_window_info.h" +#include "panel_status_listener.h" namespace OHOS { namespace SelectionFwk { @@ -40,6 +42,12 @@ public: ~SelectionPanel(); int32_t CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo); // void SetPanelHeightCallback(CallbackFunc heightCallback); + int32_t SetUiContent(const std::string &contentInfo, napi_env env); + int32_t ShowPanel(); + int32_t HidePanel(); + // int32_t StartMoving(); + bool IsShowing(); + bool IsHidden(); uint32_t windowId_ = INVALID_WINDOW_ID; @@ -47,18 +55,20 @@ private: std::string GeneratePanelName(); int32_t SetPanelProperties(); static uint32_t GenerateSequenceId(); + void PanelStatusChange(const SelectionWindowStatus &status); + PanelType panelType_ = PanelType::STATUS_BAR;//待修改 PanelFlag panelFlag_ = PanelFlag::FLG_FIXED;//待修改 - sptr window_ = nullptr; sptr winOption_ = nullptr; - bool isScbEnable_ { false }; - Rosen::KeyboardLayoutParams keyboardLayoutParams_; static std::atomic sequenceId_; uint32_t invalidGravityPercent = 0; - + std::atomic isWaitSetUiContent_ { true }; + std::shared_ptr panelStatusListener_ = nullptr; + bool showRegistered_ = false; + bool hideRegistered_ = false; // CallbackFunc panelHeightCallback_ = nullptr; }; } // namespace SelectionFwk diff --git a/frameworks/native/selection_ability/include/selection_window_info.h b/frameworks/native/selection_ability/include/selection_window_info.h new file mode 100644 index 0000000..72345bf --- /dev/null +++ b/frameworks/native/selection_ability/include/selection_window_info.h @@ -0,0 +1,123 @@ +/* + * 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 FRAMEWORKS_SELECTION_INCLUDE_SELECTION_WINDOW_INFO_H +#define FRAMEWORKS_SELECTION_INCLUDE_SELECTION_WINDOW_INFO_H + +#include +#include +#include "parcel.h" + +#include "panel_info.h" +namespace OHOS { +namespace SelectionFwk { +enum class SelectionWindowStatus : uint32_t { + SHOW, + HIDE, + NONE +}; + +struct SelectionWindowInfo : public Parcelable { + std::string name; // the name of inputWindow + int32_t left { 0 }; // the abscissa of the upper-left vertex of inputWindow + int32_t top { 0 }; // the ordinate of the upper-left vertex of inputWindow + uint32_t width { 0 }; // the width of inputWindow + uint32_t height { 0 }; // the height of inputWindow + + bool ReadFromParcel(Parcel &in) + { + name = in.ReadString(); + left = in.ReadInt32(); + top = in.ReadInt32(); + width = in.ReadUint32(); + height = in.ReadUint32(); + return true; + } + + bool Marshalling(Parcel &out) const + { + if (!out.WriteString(name)) { + return false; + } + if (!out.WriteInt32(left)) { + return false; + } + if (!out.WriteInt32(top)) { + return false; + } + if (!out.WriteUint32(width)) { + return false; + } + if (!out.WriteUint32(height)) { + return false; + } + return true; + } + + static SelectionWindowInfo *Unmarshalling(Parcel &in) + { + SelectionWindowInfo *data = new (std::nothrow) SelectionWindowInfo(); + if (data && !data->ReadFromParcel(in)) { + delete data; + data = nullptr; + } + return data; + } +}; + +struct ImeWindowInfo : public Parcelable { + PanelInfo panelInfo; + SelectionWindowInfo windowInfo; + + bool ReadFromParcel(Parcel &in) + { + std::unique_ptr pInfo(in.ReadParcelable()); + if (pInfo == nullptr) { + return false; + } + panelInfo = *pInfo; + + std::unique_ptr wInfo(in.ReadParcelable()); + if (wInfo == nullptr) { + return false; + } + windowInfo = *wInfo; + return true; + } + + bool Marshalling(Parcel &out) const + { + if (!out.WriteParcelable(&panelInfo)) { + return false; + } + if (!out.WriteParcelable(&windowInfo)) { + return false; + } + return true; + } + static ImeWindowInfo *Unmarshalling(Parcel &in) + { + ImeWindowInfo *data = new (std::nothrow) ImeWindowInfo(); + if (data && !data->ReadFromParcel(in)) { + delete data; + data = nullptr; + } + return data; + } +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // FRAMEWORKS_SELECTION_INCLUDE_SELECTION_WINDOW_INFO_H diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index 19c5dd9..661f5d0 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -14,6 +14,9 @@ */ #include "selection_ability.h" + +#include +#include #include "selection_panel.h" #include "selection_log.h" @@ -116,6 +119,57 @@ int32_t SelectionAbility::CreatePanel(const std::shared_ptr lock(dataChannelLock_); // return dataChannelProxy_; // } +int32_t SelectionAbility::ShowPanel(const std::shared_ptr &selectionpanel) +{ + std::lock_guard lock(keyboardCmdLock_); + if (selectionpanel == nullptr) { + return ErrorCode::ERROR_BAD_PARAMETERS; + } + + //面板标志flag(固定/浮动) trigger触发显示的原因(应用请求/输入法框架请求)不涉及 + // if (trigger == Trigger::IME_APP && GetInputDataChannelProxy() == nullptr) { + // IMSA_HILOGE("channel is nullptr!"); + // return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR; + // } + // if (flag == FLG_FIXED && selectionpanel->GetPanelType() == SOFT_KEYBOARD) { + // auto ret = selectionpanel->SetTextFieldAvoidInfo(positionY_, height_); + // if (ret != ErrorCode::NO_ERROR) { + // IMSA_HILOGE("failed to set keyBoard, ret: %{public}d!", ret); + // } + // } + // auto keyboardSize = selectionpanel->GetKeyboardSize(); + // SysPanelStatus sysPanelStatus = { inputType_, flag, keyboardSize.width, keyboardSize.height }; + // NotifyPanelStatus(selectionpanel->GetPanelType(), sysPanelStatus); + auto ret = selectionpanel->ShowPanel(); + // if (ret == ErrorCode::NO_ERROR) { + // PanelInfo info; + // info = selectionPanel; + // } + return ret; +} + +int32_t SelectionAbility::HidePanel(const std::shared_ptr &selectionpanel) +{ + if (selectionpanel == nullptr) { + return ErrorCode::ERROR_BAD_PARAMETERS; + } + auto ret = selectionpanel->HidePanel(); + if (ret != ErrorCode::NO_ERROR) { + SELECTION_HILOGD("failed, ret: %{public}d", ret); + return ret; + } + // PanelStatusInfo info; + // info.panelInfo.panelType = selectionpanel->GetPanelType(); + // info.panelInfo.panelFlag = flag; + // info.visible = false; + // info.trigger = trigger; + // info.sessionId = sessionId; + // NotifyPanelStatusInfo(info); + // if (trigger == Trigger::IMF && selectionpanel->GetPanelType() == PanelType::SOFT_KEYBOARD) { + // FinishTextPreview(true); + // } + return ErrorCode::NO_ERROR; +} } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index c59e76b..88998a3 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -13,19 +13,27 @@ * limitations under the License. */ -#include "scene_board_judgement.h" - #include "selection_panel.h" -#include "selection_log.h" + +#include +#include +#include #include "display_manager.h" +#include "scene_board_judgement.h" +#include "selection_log.h" +#include "selectionmethod_trace.h" namespace OHOS { namespace SelectionFwk { using WMError = OHOS::Rosen::WMError; +using WindowState = OHOS::Rosen::WindowState; +using namespace Rosen; using WindowGravity = OHOS::Rosen::WindowGravity; using WindowState = OHOS::Rosen::WindowState; std::atomic SelectionPanel::sequenceId_ { 0 }; +constexpr int32_t MAXWAITTIME = 30; +constexpr int32_t WAITTIME = 10; SelectionPanel::~SelectionPanel() = default; int32_t SelectionPanel::CreatePanel( @@ -172,5 +180,182 @@ uint32_t SelectionPanel::GenerateSequenceId() // panelHeightCallback_ = std::move(heightCallback); // } +int32_t SelectionPanel::SetUiContent(const std::string &contentInfo, napi_env env) +{ + if (window_ == nullptr) { + SELECTION_HILOGE("window_ is nullptr, can not SetUiContent!"); + return ErrorCode::ERROR_NULL_POINTER; + } + WMError ret = WMError::WM_OK; + + window_->NapiSetUIContent(contentInfo, env, nullptr);//调用napi接口设置UI内容 + // if (storage == nullptr) { + // ret = window_->NapiSetUIContent(contentInfo, env, nullptr); + // } else { + // ret = window_->NapiSetUIContent(contentInfo, env, storage->GetNapiValue()); + // } + WMError wmError = window_->SetTransparent(true); + if (isWaitSetUiContent_) { + isWaitSetUiContent_ = false; + } + SELECTION_HILOGI("SetTransparent ret: %{public}u.", wmError); + SELECTION_HILOGI("NapiSetUIContent ret: %{public}d.", ret); + return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR; +} + +int32_t SelectionPanel::ShowPanel() +{ + SELECTION_HILOGD("SelectionPanel start."); + int32_t waitTime = 0; + while (isWaitSetUiContent_ && waitTime < MAXWAITTIME) { + std::this_thread::sleep_for(std::chrono::milliseconds(WAITTIME)); + waitTime += WAITTIME; + SELECTION_HILOGI("SelectionPanel show pannel waitTime %{public}d.", waitTime); + } + if (window_ == nullptr) { + SELECTION_HILOGE("window_ is nullptr!"); + return ErrorCode::ERROR_IMA_NULLPTR; + } + if (IsShowing()) { + SELECTION_HILOGI("panel already shown."); + return ErrorCode::NO_ERROR; + } + auto ret = WMError::WM_OK; + { + SelectionMethodSyncTrace tracer("SelectionPanel_ShowPanel"); + ret = window_->Show(); + } + if (ret != WMError::WM_OK) { + SELECTION_HILOGE("ShowPanel error, err = %{public}d", ret); + return ErrorCode::ERROR_OPERATE_PANEL; + } + SELECTION_HILOGI("Selection panel shown successfully."); + PanelStatusChange(SelectionWindowStatus::SHOW); + // if (!isScbEnable_) { + // PanelStatusChangeToImc(SelectionWindowStatus::SHOW, window_->GetRect());//通知输入法管理器或其他监听者 + // } + return ErrorCode::NO_ERROR; +} + + +bool SelectionPanel::IsShowing() +{ + if (window_ == nullptr) { + SELECTION_HILOGE("window_ is nullptr!"); + return ErrorCode::ERROR_NULL_POINTER; + } + auto windowState = window_->GetWindowState(); + if (windowState == WindowState::STATE_SHOWN) { + return true; + } + SELECTION_HILOGD("windowState: %{public}d.", static_cast(windowState)); + return false; +} + +void SelectionPanel::PanelStatusChange(const SelectionWindowStatus &status) +{ + if (status == SelectionWindowStatus::SHOW && showRegistered_ && panelStatusListener_ != nullptr) { + SELECTION_HILOGD("ShowPanel panelStatusListener_ is not nullptr."); + panelStatusListener_->OnPanelStatus(windowId_, true); + } + if (status == SelectionWindowStatus::HIDE && hideRegistered_ && panelStatusListener_ != nullptr) { + SELECTION_HILOGD("HidePanel panelStatusListener_ is not nullptr."); + panelStatusListener_->OnPanelStatus(windowId_, false); + } +} +// 用于处理输入法面板状态变化,并将相关信息通知给输入法服务代理。(当输入法面板的状态或位置发生变化时,当函数会被调用) +// void SelectionPanel::PanelStatusChangeToImc(const SelectionWindowStatus &status, const Rosen::Rect &rect) +// { +// ImeWindowInfo info; +// info.panelInfo.panelType = panelType_; +// info.panelInfo.panelFlag = panelFlag_; +// if (info.panelInfo.panelType != SOFT_KEYBOARD || info.panelInfo.panelFlag == FLG_CANDIDATE_COLUMN) { +// SELECTION_HILOGD("no need to deal."); +// return; +// } +// auto proxy = ImaUtils::GetImsaProxy();//通过IMSA(Input Method Service Agent)代理对象获取输入法系统能力==》OnDemandStartStopSa(涉及到与系统能力管理器的交互) +// if (proxy == nullptr) { +// SELECTION_HILOGE("proxy is nullptr!"); +// return; +// } +// std::string name = window_->GetWindowName() + "/" + std::to_string(window_->GetWindowId()); +// info.windowInfo.name = std::move(name); +// info.windowInfo.left = rect.posX_; +// info.windowInfo.top = rect.posY_; +// info.windowInfo.width = rect.width_; +// info.windowInfo.height = rect.height_; +// SELECTION_HILOGD("rect[%{public}d, %{public}d, %{public}u, %{public}u], status: %{public}d, " +// "panelFlag: %{public}d.", +// rect.posX_, rect.posY_, rect.width_, rect.height_, status, info.panelInfo.panelFlag); +// proxy->PanelStatusChange(static_cast(status), info); +// } + + +int32_t SelectionPanel::HidePanel() +{ + SELECTION_HILOGD("SelectionPanel start"); + if (window_ == nullptr) { + SELECTION_HILOGE("window_ is nullptr!"); + return ErrorCode::ERROR_NULL_POINTER; + } + if (IsHidden()) { + SELECTION_HILOGI("panel already hidden."); + return ErrorCode::NO_ERROR; + } + auto ret = WMError::WM_OK; + { + SelectionMethodSyncTrace tracer("SelectionPanel_HidePanel"); + ret = window_->Hide(); + } + if (ret != WMError::WM_OK) { + SELECTION_HILOGE("HidePanel error, err: %{public}d!", ret); + return ErrorCode::ERROR_OPERATE_PANEL; + } + SELECTION_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast(panelType_), + static_cast(panelFlag_)); + PanelStatusChange(SelectionWindowStatus::HIDE); + // if (!isScbEnable_) { + // PanelStatusChangeToImc(InputWindowStatus::HIDE, { 0, 0, 0, 0 }); + // } + return ErrorCode::NO_ERROR; +} + +bool SelectionPanel::IsHidden() +{ + auto windowState = window_->GetWindowState(); + if (windowState == WindowState::STATE_HIDDEN) { + return true; + } + SELECTION_HILOGD("windowState: %{public}d.", static_cast(windowState)); + return false; +} + +// int32_t SelectionPanel::StartMoving() +// { +// if (window_ == nullptr) { +// SELECTION_HILOGE("window_ is nullptr!"); +// return ErrorCode::ERROR_IME; +// } +// // if (panelType_ != STATUS_BAR) { +// // IMSA_HILOGE("SOFT_KEYBOARD panel can not move!"); +// // return ErrorCode::ERROR_INVALID_PANEL_TYPE; +// // } +// // if (panelFlag_ != FLG_FLOATING) { +// // IMSA_HILOGE("invalid panel flag: %{public}d", panelFlag_); +// // return ErrorCode::ERROR_INVALID_PANEL_FLAG; +// // } +// auto ret = window_->StartMoveWindow(); +// if (ret == WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT) { +// SELECTION_HILOGE("window manager service not support error ret = %{public}d.", ret); +// return ErrorCode::ERROR_DEVICE_UNSUPPORTED; +// } +// if (ret != WmErrorCode::WM_OK) { +// SELECTION_HILOGE("window manager service error ret = %{public}d.", ret); +// return ErrorCode::ERROR_WINDOW_MANAGER; +// } +// SELECTION_HILOGI("StartMoving success!"); +// return ErrorCode::NO_ERROR; +// } + } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/selection_service.gni b/selection_service.gni index 8cdad4c..d189fd4 100644 --- a/selection_service.gni +++ b/selection_service.gni @@ -27,4 +27,6 @@ word_selection_part_name = "word_selection" selection_fwk_root_path = "//foundation/systemabilitymgr/selection_fwk" +selection_path = "//commonlibrary/c_utils" + system_type = "default" \ No newline at end of file -- Gitee From 3cda4d1ef7765b07735780421a4a5e1e2d193298 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Wed, 28 May 2025 09:46:19 +0800 Subject: [PATCH 41/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9startAbility=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../native/selection_extension/BUILD.gn | 4 -- .../include/selection_extension_context.h | 12 ++--- .../include/selection_extension_hilog.h | 31 ++++++------ .../src/js_selection_extension_context.cpp | 47 ++++++------------- .../src/selection_extension.cpp | 4 +- .../src/selection_extension_context.cpp | 12 ----- 6 files changed, 37 insertions(+), 73 deletions(-) diff --git a/frameworks/native/selection_extension/BUILD.gn b/frameworks/native/selection_extension/BUILD.gn index 35fa0f5..039b5e6 100644 --- a/frameworks/native/selection_extension/BUILD.gn +++ b/frameworks/native/selection_extension/BUILD.gn @@ -51,13 +51,9 @@ ohos_shared_library("selection_extension_ability_native") { external_deps = [ "ability_base:want", - "ability_runtime:ability_connect_callback_stub", "ability_runtime:ability_context_native", "ability_runtime:ability_manager", - "ability_runtime:ability_start_options", - "ability_runtime:abilitykit_native", "ability_runtime:app_context", - "ability_runtime:extensionkit_native", "ability_runtime:napi_common", "ability_runtime:runtime", "c_utils:utils", diff --git a/frameworks/native/selection_extension/include/selection_extension_context.h b/frameworks/native/selection_extension/include/selection_extension_context.h index 80ab383..6ea410f 100644 --- a/frameworks/native/selection_extension/include/selection_extension_context.h +++ b/frameworks/native/selection_extension/include/selection_extension_context.h @@ -28,19 +28,15 @@ public: /** * @brief Starts a new ability. - * An ability using the AbilityInfo.AbilityType.INPUTMETHOD or - * AbilityInfo.AbilityType.PAGE template uses this method to start a specific - * ability. The system locates the target ability from installed abilities - * based on the value of the want parameter and then starts it. You can - * specify the ability to start using the want parameter. + * An ability using the AbilityInfo.AbilityType.SERVICE or AbilityInfo.AbilityType.PAGE template uses this method + * to start a specific ability. The system locates the target ability from installed abilities based on the value + * of the want parameter and then starts it. You can specify the ability to start using the want parameter. * - * @param want Indicates the Want containing information about the target - * ability to start. + * @param want Indicates the Want containing information about the target ability to start. * * @return errCode ERR_OK on success, others on failure. */ ErrCode StartAbility(const AAFwk::Want& want) const; - ErrCode StartAbility(const AAFwk::Want& want, const AAFwk::StartOptions& startOptions) const; static const size_t CONTEXT_TYPE_ID; diff --git a/frameworks/native/selection_extension/include/selection_extension_hilog.h b/frameworks/native/selection_extension/include/selection_extension_hilog.h index 53952bb..2f911ee 100644 --- a/frameworks/native/selection_extension/include/selection_extension_hilog.h +++ b/frameworks/native/selection_extension/include/selection_extension_hilog.h @@ -47,20 +47,21 @@ #define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) -#define HILOG_FATAL(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, SE_LOG_DOMAIN, SE_LOG_TAG, \ - "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_ERROR(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, SE_LOG_DOMAIN, SE_LOG_TAG, \ - "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_WARN(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, SE_LOG_DOMAIN, SE_LOG_TAG, \ - "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_INFO(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, SE_LOG_DOMAIN, SE_LOG_TAG, \ - "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_DEBUG(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, SE_LOG_DOMAIN, SE_LOG_TAG, \ - "[%{public}s(%{public}s:%{public}d)]" fmt, __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_FATAL(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_ERROR(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_WARN(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_INFO(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define HILOG_DEBUG(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) + #endif // SELECTION_LOG_H \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp index 91caea8..fdfaa06 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp @@ -14,39 +14,33 @@ */ #include "js_selection_extension_context.h" - +#include "selection_extension_hilog.h" #include "js_error_utils.h" #include "js_extension_context.h" -#include "js_runtime.h" #include "js_runtime_utils.h" #include "js_utils.h" -#include "napi_common_start_options.h" #include "napi_common_want.h" -#include "selection_extension_hilog.h" -#include "start_options.h" namespace OHOS::AbilityRuntime { using namespace OHOS::SelectionFwk; + namespace { constexpr int32_t INDEX_ZERO = 0; -constexpr int32_t INDEX_ONE = 1; constexpr int32_t ERROR_CODE_ONE = 1; constexpr size_t ARGC_ONE = 1; -constexpr size_t ARGC_TWO = 2; -constexpr size_t ARGC_THREE = 3; class JsSelectionExtensionContext final { public: explicit JsSelectionExtensionContext(const std::shared_ptr& context) : context_(context) { - // HILOG_INFO(LOG_CORE, "JsSelectionExtensionContext::JsSelectionExtensionContext is called."); + HILOG_INFO("JsSelectionExtensionContext::JsSelectionExtensionContext is called."); } JsSelectionExtensionContext() = default; ~JsSelectionExtensionContext() = default; static void Finalizer(napi_env env, void* data, void* hint) { - // HILOG_INFO("JsSelectionExtensionContext::Finalizer is called."); + HILOG_INFO("JsSelectionExtensionContext::Finalizer is called."); std::unique_ptr(static_cast(data)); } @@ -60,41 +54,30 @@ private: napi_value OnStartAbility(napi_env env, size_t argc, napi_value* argv) { - // HILOG_INFO("SelectionExtensionContext OnStartAbility."); - // only support one or two or three params - PARAM_CHECK_RETURN(env, argc == ARGC_ONE || argc == ARGC_TWO || argc == ARGC_THREE, - "number of param should in [1,3]", TYPE_NONE, CreateJsUndefined(env)); + HILOG_INFO("SelectionExtensionContext OnStartAbility."); + // only support one params + PARAM_CHECK_RETURN(env, argc == ARGC_ONE, "number of param should in 1", TYPE_NONE, CreateJsUndefined(env)); PARAM_CHECK_RETURN(env, JsUtil::GetType(env, argv[0]) == napi_object, "param want type must be Want", TYPE_NONE, JsUtil::Const::Null(env)); decltype(argc) unwrapArgc = 0; AAFwk::Want want; OHOS::AppExecFwk::UnwrapWant(env, argv[INDEX_ZERO], want); - // HILOG_INFO("%{public}s bundleName: %{public}s abilityName: %{public}s.", __func__, want.GetBundle().c_str(), - // want.GetElement().GetAbilityName().c_str()); + HILOG_INFO("%{public}s bundleName: %{public}s abilityName: %{public}s.", __func__, want.GetBundle().c_str(), + want.GetElement().GetAbilityName().c_str()); unwrapArgc++; - AAFwk::StartOptions startOptions; - napi_valuetype valueType = napi_undefined; - napi_typeof(env, argv[INDEX_ONE], &valueType); - if (argc > ARGC_ONE && valueType == napi_object) { - // HILOG_INFO("OnStartAbility start options is used."); - AppExecFwk::UnwrapStartOptions(env, argv[INDEX_ONE], startOptions); - unwrapArgc++; - } napi_value lastParam = argc > unwrapArgc ? argv[unwrapArgc] : nullptr; napi_value result = nullptr; std::unique_ptr napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result); - auto asyncTask = [weak = context_, want, startOptions, unwrapArgc, env, task = napiAsyncTask.get()]() { - // HILOG_INFO("startAbility start."); + auto asyncTask = [weak = context_, want, unwrapArgc, env, task = napiAsyncTask.get()]() { + HILOG_INFO("startAbility start."); auto context = weak.lock(); if (context == nullptr) { - // HILOG_WRAN("context is released."); + HILOG_WARN("context is released."); task->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "Context is released")); delete task; return; } - ErrCode errcode = ERR_OK; - (unwrapArgc == 1) ? errcode = context->StartAbility(want) - : errcode = context->StartAbility(want, startOptions); + ErrCode errcode = (unwrapArgc == 1) ? context->StartAbility(want) : ERR_INVALID_VALUE; if (errcode == 0) { task->Resolve(env, CreateJsUndefined(env)); } else { @@ -114,7 +97,7 @@ private: napi_value CreateJsSelectionExtensionContext(napi_env env, std::shared_ptr context) { - // HILOG_INFO(LOG_CORE, "CreateJsSelectionExtensionContext begin"); + HILOG_INFO("CreateJsSelectionExtensionContext begin"); std::shared_ptr abilityInfo = nullptr; if (context) { abilityInfo = context->GetAbilityInfo(); @@ -125,7 +108,7 @@ napi_value CreateJsSelectionExtensionContext(napi_env env, std::shared_ptr& r } switch (runtime->GetLanguage()) { case Runtime::Language::JS: - HILOG_INFO("Create JsSelectionExtension"); + HILOG_INFO("create JsSelectionExtension"); return JsSelectionExtension::Create(runtime); default: return new SelectionExtension(); @@ -40,7 +40,7 @@ void SelectionExtension::Init(const std::shared_ptr& record, std::shared_ptr& handler, const sptr& token) { - HILOG_INFO("call SelectionExtension::Init"); + HILOG_INFO("call %{public}s", __func__); ExtensionBase::Init(record, application, handler, token); } diff --git a/frameworks/native/selection_extension/src/selection_extension_context.cpp b/frameworks/native/selection_extension/src/selection_extension_context.cpp index d7f6c97..5b0c24e 100644 --- a/frameworks/native/selection_extension/src/selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_context.cpp @@ -32,16 +32,4 @@ ErrCode SelectionExtensionContext::StartAbility(const AAFwk::Want& want) const return err; } -ErrCode SelectionExtensionContext::StartAbility(const AAFwk::Want& want, const AAFwk::StartOptions& startOptions) const -{ - HILOG_DEBUG("%{public}s start.", __func__); - ErrCode err = - AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, startOptions, token_, ILLEGAL_REQUEST_CODE); - HILOG_DEBUG("%{public}s ret=%{public}d", __func__, err); - if (err != ERR_OK) { - HILOG_ERROR("InputMethodExtensionContext::StartAbility failed: %{public}d", err); - } - return err; -} - } // namespace OHOS::AbilityRuntime \ No newline at end of file -- Gitee From 2c07e8911fad4fa2f5af51d94bacbb67f88e3834 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Thu, 29 May 2025 15:15:21 +0800 Subject: [PATCH 42/93] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E8=AF=84=E5=AE=A1?= =?UTF-8?q?=E6=84=8F=E8=A7=81=E4=BF=AE=E6=94=B9=E6=BB=91=E8=AF=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/include/selection_service.h | 32 +++++- service/src/selection_service.cpp | 167 ++++++++++++++-------------- 2 files changed, 116 insertions(+), 83 deletions(-) diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 2f1367e..1915d5b 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -42,7 +42,7 @@ typedef enum { SELECT_INPUT_WAIT_LEFT_MOVE = 2, SELECT_INPUT_LEFT_MOVE = 3, SELECT_INPUT_WAIT_DOUBLE_CLICK = 4, - SELECT_INPUT_WAIT_TRIBLE_CLICK = 5, + SELECT_INPUT_WAIT_TRIPLE_CLICK = 5, SELECT_INPUT_DOUBLE_CLICKED = 6, SELECT_INPUT_TRIPLE_CLICKED = 7, } SelectInputState; @@ -100,14 +100,40 @@ private: sptr connectInner_ {nullptr}; }; +class SelectionEventListener { +public: + virtual void OnTextSelected() { + }; + virtual ~SelectionEventListener() = default; +}; + +class DefaultSelectionEventListener : public SelectionEventListener { +public: + virtual void OnTextSelected(); + +private: + void InjectCtrlC() const; +}; + class SelectionInputMonitor : public IInputEventConsumer { public: + SelectionInputMonitor() + : selectionEventListener_(std::make_shared()) { + } + + SelectionInputMonitor(std::shared_ptr selectionEventListener) + : selectionEventListener_(selectionEventListener) { + } + + bool IsTextSelected() const; + virtual void OnInputEvent(std::shared_ptr keyEvent) const; virtual void OnInputEvent(std::shared_ptr pointerEvent) const; virtual void OnInputEvent(std::shared_ptr axisEvent) const; public: static bool ctrlSelectFlag; + private: void InputInitialProcess(std::shared_ptr pointerEvent) const; void InputWordBeginProcess(std::shared_ptr pointerEvent) const; @@ -116,12 +142,14 @@ private: void InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const; void InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const; void FinishedWordSelection() const; - void InjectCtrlC() const; void ResetProcess(std::shared_ptr pointerEvent) const; void JudgeTripleClick() const; + static uint32_t curSelectState; static uint32_t subSelectState; static int64_t lastClickTime; + + std::shared_ptr selectionEventListener_; }; } diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 7f6352d..f46ce37 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -239,7 +239,8 @@ void SelectionService::OnStop() void SelectionService::InputMonitorInit() { SELECTION_HILOGI("[SelectionService] input monitor init"); - std::shared_ptr inputMonitor = std::make_shared(); + std::shared_ptr inputMonitor = std::make_shared( + std::make_shared()); if (inputMonitorId_ < 0) { sleep(30); inputMonitorId_ = @@ -298,6 +299,35 @@ void SelectionService::HandlePointEvent(int32_t type) #endif } +void DefaultSelectionEventListener::OnTextSelected() +{ + SELECTION_HILOGI("End word selection action."); + InjectCtrlC(); + SELECTION_HILOGI("End Inject Ctrl + C."); + // send selection data + sptr listener = SelectionService::GetInstance()->GetListener(); + if (listener == nullptr) { + SELECTION_HILOGE("get listener is null"); + return; + } + SelectionDataInner data; + data.text = "Hello, world!"; + data.cursorStartPos = 0; + data.cursorEndPos = 13; + data.windowId = 1001; + data.bundleID = 2002; + listener->OnSelectionChange(data); + return; +} + +bool SelectionInputMonitor::IsTextSelected() const { + if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_DOUBLE_CLICKED && + curSelectState != SELECT_INPUT_TRIPLE_CLICKED) { + return false; + } + return true; +} + void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { if (!ctrlSelectFlag) { @@ -327,7 +357,7 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con } else if (curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK) { curSelectState = SELECT_INPUT_DOUBLE_CLICKED; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); - } else if (curSelectState == SELECT_INPUT_WAIT_TRIBLE_CLICK) { + } else if (curSelectState == SELECT_INPUT_WAIT_TRIPLE_CLICK) { curSelectState = SELECT_INPUT_TRIPLE_CLICKED; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); } @@ -378,7 +408,7 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv InputWordJudgeTripleClickProcess(pointerEvent); break; - case SELECT_INPUT_WAIT_TRIBLE_CLICK: + case SELECT_INPUT_WAIT_TRIPLE_CLICK: InputWordWaitTripleClickProcess(pointerEvent); break; @@ -446,9 +476,9 @@ void SelectionInputMonitor::JudgeTripleClick() const { auto curTime = GetCurrentTimeMillis(); if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { - curSelectState = SELECT_INPUT_WAIT_TRIBLE_CLICK; + curSelectState = SELECT_INPUT_WAIT_TRIPLE_CLICK; subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_TRIBLE_CLICK."); + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_TRIPLE_CLICK."); } else { curSelectState = SELECT_INPUT_WORD_BEGIN; subSelectState = SUB_INITIAL; @@ -510,58 +540,43 @@ void SelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_UP) { - if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { - if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_KEY_CTRL_DOWN; - SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); - } else { - curSelectState = SELECT_INPUT_TRIPLE_CLICKED; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_TRIPLE_CLICKED."); - } - } else if (action == PointerEvent::POINTER_ACTION_MOVE) { - curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); + if (subSelectState != SUB_WAIT_POINTER_ACTION_BUTTON_UP) { + return; + } + if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + if (ctrlSelectFlag) { + subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); } else { - SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); - ResetProcess(pointerEvent); + curSelectState = SELECT_INPUT_TRIPLE_CLICKED; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_TRIPLE_CLICKED."); } - return; + } else if (action == PointerEvent::POINTER_ACTION_MOVE) { + curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); + } else { + SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); + ResetProcess(pointerEvent); } + return; } void SelectionInputMonitor::FinishedWordSelection() const { - if (curSelectState == SELECT_INPUT_LEFT_MOVE || curSelectState == SELECT_INPUT_DOUBLE_CLICKED || - curSelectState == SELECT_INPUT_TRIPLE_CLICKED) { - // world selection action - SELECTION_HILOGI("[SelectionService] first, end word selection action."); - InjectCtrlC(); - SELECTION_HILOGI("[SelectionService] first, end inject ctrl + c."); - if (curSelectState != SELECT_INPUT_DOUBLE_CLICKED) { - curSelectState = SELECT_INPUT_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); - } - - // send selection data - sptr listener = SelectionService::GetInstance()->GetListener(); - if (listener == nullptr) { - SELECTION_HILOGE("get listener is null"); - return; - } - SelectionDataInner data; - data.text = "Hello, world!"; - data.cursorStartPos = 0; - data.cursorEndPos = 13; - data.windowId = 1001; - data.bundleID = 2002; - listener->OnSelectionChange(data); + if (!IsTextSelected()) { + return; } - return; + // world selection action + if (curSelectState != SELECT_INPUT_DOUBLE_CLICKED) { + curSelectState = SELECT_INPUT_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); + } + + selectionEventListener_->OnTextSelected(); } -void SelectionInputMonitor::InjectCtrlC() const +void DefaultSelectionEventListener::InjectCtrlC() const { // 创建KeyEvent对象 auto keyEvent1 = KeyEvent::Create(); @@ -569,57 +584,47 @@ void SelectionInputMonitor::InjectCtrlC() const // 设置Ctrl键按下 keyEvent1->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); keyEvent1->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + keyEvent1->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + KeyEvent::KeyItem item1; + item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + item1.SetPressed(true); + item1.SetDownTime(500); + keyEvent1->AddKeyItem(item1); InputManager::GetInstance()->SimulateInputEvent(keyEvent1); // 设置C键按下 auto keyEvent2 = KeyEvent::Create(); keyEvent2->SetKeyCode(KeyEvent::KEYCODE_C); keyEvent2->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + keyEvent2->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + KeyEvent::KeyItem item2; + item2.SetKeyCode(KeyEvent::KEYCODE_C); + item2.SetPressed(true); + item2.SetDownTime(500); + keyEvent2->AddKeyItem(item2); InputManager::GetInstance()->SimulateInputEvent(keyEvent2); // 设置C键释放 auto keyEvent3 = KeyEvent::Create(); keyEvent3->SetKeyCode(KeyEvent::KEYCODE_C); keyEvent3->SetKeyAction(KeyEvent::KEY_ACTION_UP); + keyEvent3->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + KeyEvent::KeyItem item3; + item3.SetKeyCode(KeyEvent::KEYCODE_C); + item3.SetPressed(true); + item3.SetDownTime(500); + keyEvent3->AddKeyItem(item3); InputManager::GetInstance()->SimulateInputEvent(keyEvent3); // 设置Ctrl键释放 auto keyEvent4 = KeyEvent::Create(); keyEvent4->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); keyEvent4->SetKeyAction(KeyEvent::KEY_ACTION_UP); + keyEvent4->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + KeyEvent::KeyItem item4; + item4.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + item4.SetPressed(true); + item4.SetDownTime(500); + keyEvent4->AddKeyItem(item4); InputManager::GetInstance()->SimulateInputEvent(keyEvent4); - - // auto keyDownEvent = KeyEvent::Create(); - // keyDownEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // std::vector downKey; - // downKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); - // downKey.push_back(KeyEvent::KEYCODE_C); - - // KeyEvent::KeyItem downItem[downKey.size()]; - // for (size_t i = 0; i < downKey.size(); i++) { - // keyDownEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // keyDownEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - // downItem[i].SetKeyCode(downKey[i]); - // downItem[i].SetPressed(true); - // downItem[i].SetDownTime(500); - // keyDownEvent->AddPressedKeyItems(downItem[i]); - // } - // InputManager::GetInstance()->SimulateInputEvent(keyDownEvent); - - // auto keyUpEvent = KeyEvent::Create(); - // keyUpEvent->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // std::vector upKey; - // upKey.push_back(KeyEvent::KEYCODE_CTRL_LEFT); - // upKey.push_back(KeyEvent::KEYCODE_C); - - // KeyEvent::KeyItem upItem[upKey.size()]; - // for (size_t i = 0; i < upKey.size(); i++) { - // keyUpEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // keyUpEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - // upItem[i].SetKeyCode(upKey[i]); - // upItem[i].SetPressed(true); - // upItem[i].SetDownTime(0); - // keyUpEvent->RemoveReleasedKeyItems(upItem[i]); - // } - // InputManager::GetInstance()->SimulateInputEvent(keyUpEvent); } -- Gitee From d37376e5689a172fb6c253cbe5f10ed7b69a8131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Thu, 29 May 2025 17:11:59 +0800 Subject: [PATCH 43/93] =?UTF-8?q?=E6=B7=BB=E5=8A=A0startMoving=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../js/napi/selection_ability/js_panel.cpp | 65 ++++++-------- .../js/napi/selection_ability/js_panel.h | 7 +- .../include/selection_ability.h | 2 - .../include/selection_panel.h | 2 +- .../src/selection_ability.cpp | 38 ++------- .../selection_ability/src/selection_panel.cpp | 85 +++++-------------- 6 files changed, 51 insertions(+), 148 deletions(-) diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 074a3c3..6b50d59 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -21,8 +21,6 @@ #include "panel_listener_impl.h" #include "js_utils.h" #include "selectionmethod_trace.h" - - #include "selection_ability.h" namespace OHOS { @@ -47,7 +45,7 @@ napi_value JsPanel::Init(napi_env env) DECLARE_NAPI_FUNCTION("setUiContent", SetUiContent), DECLARE_NAPI_FUNCTION("show", Show), DECLARE_NAPI_FUNCTION("hide", Hide), - // DECLARE_NAPI_FUNCTION("startMoving", StartMoving), + DECLARE_NAPI_FUNCTION("startMoving", StartMoving), }; NAPI_CALL(env, napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), JsNew, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor)); @@ -114,20 +112,6 @@ napi_value JsPanel::SetUiContent(napi_env env, napi_callback_info info) // 0 means the first param path PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, argv[0], ctxt->path) == napi_ok, "js param path covert failed, must be string!", TYPE_NONE, status); - // if type of argv[1] is object, we will get value of 'storage' from it. - // if (argc >= 2) { - // napi_valuetype valueType = napi_undefined; - // status = napi_typeof(env, argv[1], &valueType); - // CHECK_RETURN(status == napi_ok, "get valueType failed!", status); - // if (valueType == napi_object) { - // napi_ref storage = nullptr; - // napi_create_reference(env, argv[1], 1, &storage); - // auto contentStorage = (storage == nullptr) ? nullptr - // : std::shared_ptr( - // reinterpret_cast(storage)); - // ctxt->contentStorage = contentStorage; - // } - // } ctxt->info = { std::chrono::system_clock::now(), JsEvent::SET_UI_CONTENT }; jsQueue_.Push(ctxt->info); return napi_ok; @@ -141,7 +125,6 @@ napi_value JsPanel::SetUiContent(napi_env env, napi_callback_info info) jsQueue_.Pop(); return napi_generic_failure; } - // auto code = ctxt->selectionPanel->SetUiContent(ctxt->path, env, ctxt->contentStorage); auto code = ctxt->selectionPanel->SetUiContent(ctxt->path, env); jsQueue_.Pop(); if (code == ErrorCode::ERROR_PARAMETER_CHECK_FAILED) { @@ -219,30 +202,30 @@ napi_value JsPanel::Hide(napi_env env, napi_callback_info info) return asyncCall.Call(env, exec, "panel.hide"); } -// napi_value JsPanel::StartMoving(napi_env env, napi_callback_info info) -// { -// napi_value self = nullptr; -// NAPI_CALL(env, napi_get_cb_info(env, info, 0, nullptr, &self, nullptr)); -// RESULT_CHECK_RETURN(env, (self != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), -// "", TYPE_NONE, JsUtil::Const::Null(env)); -// void *native = nullptr; -// NAPI_CALL(env, napi_unwrap(env, self, &native)); -// RESULT_CHECK_RETURN(env, (native != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), -// "", TYPE_NONE, JsUtil::Const::Null(env)); -// auto selectionPanel = reinterpret_cast(native)->GetNative(); -// if (selectionPanel == nullptr) { -// SELECTION_HILOGE("selectionPanel is nullptr!"); -// JsUtils::ThrowException(env, JsUtils::Convert(ErrorCode::ERROR_IME), -// "failed to start moving, selectionPanel is nullptr", TYPE_NONE); -// return JsUtil::Const::Null(env); -// } +napi_value JsPanel::StartMoving(napi_env env, napi_callback_info info) +{ + napi_value self = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, 0, nullptr, &self, nullptr)); + RESULT_CHECK_RETURN(env, (self != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), + "", TYPE_NONE, JsUtil::Const::Null(env)); + void *native = nullptr; + NAPI_CALL(env, napi_unwrap(env, self, &native)); + RESULT_CHECK_RETURN(env, (native != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), + "", TYPE_NONE, JsUtil::Const::Null(env)); + auto selectionPanel = reinterpret_cast(native)->GetNative(); + if (selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr!"); + JsUtils::ThrowException(env, JsUtils::Convert(ErrorCode::ERROR_IME), + "failed to start moving, selectionPanel is nullptr", TYPE_NONE); + return JsUtil::Const::Null(env); + } -// auto ret = selectionPanel->StartMoving(); -// if (ret != ErrorCode::NO_ERROR) { -// JsUtils::ThrowException(env, JsUtils::Convert(ret), "failed to start moving", TYPE_NONE); -// } -// return JsUtil::Const::Null(env); -// } + auto ret = selectionPanel->StartMoving(); + if (ret != ErrorCode::NO_ERROR) { + JsUtils::ThrowException(env, JsUtils::Convert(ret), "failed to start moving", TYPE_NONE); + } + return JsUtil::Const::Null(env); +} } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index c44ae04..caf90f4 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -23,13 +23,11 @@ #include "panel_info.h" #include "ffrt_block_queue.h" - #include #include namespace OHOS { namespace SelectionFwk { - enum class JsEvent : uint32_t { RESIZE = 0, MOVE_TO, @@ -53,9 +51,6 @@ struct JsEventInfo { } }; - - - class JsPanel { public: JsPanel() = default; @@ -64,7 +59,7 @@ public: static napi_value SetUiContent(napi_env env, napi_callback_info info); static napi_value Show(napi_env env, napi_callback_info info); static napi_value Hide(napi_env env, napi_callback_info info); - // static napi_value StartMoving(napi_env env, napi_callback_info info); + static napi_value StartMoving(napi_env env, napi_callback_info info); void SetNative(const std::shared_ptr &panel); std::shared_ptr GetNative(); private: diff --git a/frameworks/native/selection_ability/include/selection_ability.h b/frameworks/native/selection_ability/include/selection_ability.h index 154bc72..b672237 100644 --- a/frameworks/native/selection_ability/include/selection_ability.h +++ b/frameworks/native/selection_ability/include/selection_ability.h @@ -43,8 +43,6 @@ private: static sptr instance_; std::mutex dataChannelLock_; - std::recursive_mutex keyboardCmdLock_; - void Initialize(); ConcurrentMap> panels_ {}; diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 0289d0d..6ad0922 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -45,7 +45,7 @@ public: int32_t SetUiContent(const std::string &contentInfo, napi_env env); int32_t ShowPanel(); int32_t HidePanel(); - // int32_t StartMoving(); + int32_t StartMoving(); bool IsShowing(); bool IsHidden(); diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index 661f5d0..4a14d58 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -119,33 +119,18 @@ int32_t SelectionAbility::CreatePanel(const std::shared_ptr lock(dataChannelLock_); // return dataChannelProxy_; // } + int32_t SelectionAbility::ShowPanel(const std::shared_ptr &selectionpanel) { - std::lock_guard lock(keyboardCmdLock_); if (selectionpanel == nullptr) { return ErrorCode::ERROR_BAD_PARAMETERS; } - - //面板标志flag(固定/浮动) trigger触发显示的原因(应用请求/输入法框架请求)不涉及 - // if (trigger == Trigger::IME_APP && GetInputDataChannelProxy() == nullptr) { - // IMSA_HILOGE("channel is nullptr!"); - // return ErrorCode::ERROR_IMA_CHANNEL_NULLPTR; - // } - // if (flag == FLG_FIXED && selectionpanel->GetPanelType() == SOFT_KEYBOARD) { - // auto ret = selectionpanel->SetTextFieldAvoidInfo(positionY_, height_); - // if (ret != ErrorCode::NO_ERROR) { - // IMSA_HILOGE("failed to set keyBoard, ret: %{public}d!", ret); - // } - // } - // auto keyboardSize = selectionpanel->GetKeyboardSize(); - // SysPanelStatus sysPanelStatus = { inputType_, flag, keyboardSize.width, keyboardSize.height }; - // NotifyPanelStatus(selectionpanel->GetPanelType(), sysPanelStatus); auto ret = selectionpanel->ShowPanel(); - // if (ret == ErrorCode::NO_ERROR) { - // PanelInfo info; - // info = selectionPanel; - // } - return ret; + if (ret != ErrorCode::NO_ERROR) { + SELECTION_HILOGD("failed, ret: %{public}d", ret); + return ret; + } + return ErrorCode::NO_ERROR; } int32_t SelectionAbility::HidePanel(const std::shared_ptr &selectionpanel) @@ -158,18 +143,7 @@ int32_t SelectionAbility::HidePanel(const std::shared_ptr &selec SELECTION_HILOGD("failed, ret: %{public}d", ret); return ret; } - // PanelStatusInfo info; - // info.panelInfo.panelType = selectionpanel->GetPanelType(); - // info.panelInfo.panelFlag = flag; - // info.visible = false; - // info.trigger = trigger; - // info.sessionId = sessionId; - // NotifyPanelStatusInfo(info); - // if (trigger == Trigger::IMF && selectionpanel->GetPanelType() == PanelType::SOFT_KEYBOARD) { - // FinishTextPreview(true); - // } return ErrorCode::NO_ERROR; } - } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index 88998a3..3001620 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -188,12 +188,7 @@ int32_t SelectionPanel::SetUiContent(const std::string &contentInfo, napi_env en } WMError ret = WMError::WM_OK; - window_->NapiSetUIContent(contentInfo, env, nullptr);//调用napi接口设置UI内容 - // if (storage == nullptr) { - // ret = window_->NapiSetUIContent(contentInfo, env, nullptr); - // } else { - // ret = window_->NapiSetUIContent(contentInfo, env, storage->GetNapiValue()); - // } + window_->NapiSetUIContent(contentInfo, env, nullptr); WMError wmError = window_->SetTransparent(true); if (isWaitSetUiContent_) { isWaitSetUiContent_ = false; @@ -231,13 +226,9 @@ int32_t SelectionPanel::ShowPanel() } SELECTION_HILOGI("Selection panel shown successfully."); PanelStatusChange(SelectionWindowStatus::SHOW); - // if (!isScbEnable_) { - // PanelStatusChangeToImc(SelectionWindowStatus::SHOW, window_->GetRect());//通知输入法管理器或其他监听者 - // } return ErrorCode::NO_ERROR; } - bool SelectionPanel::IsShowing() { if (window_ == nullptr) { @@ -263,33 +254,6 @@ void SelectionPanel::PanelStatusChange(const SelectionWindowStatus &status) panelStatusListener_->OnPanelStatus(windowId_, false); } } -// 用于处理输入法面板状态变化,并将相关信息通知给输入法服务代理。(当输入法面板的状态或位置发生变化时,当函数会被调用) -// void SelectionPanel::PanelStatusChangeToImc(const SelectionWindowStatus &status, const Rosen::Rect &rect) -// { -// ImeWindowInfo info; -// info.panelInfo.panelType = panelType_; -// info.panelInfo.panelFlag = panelFlag_; -// if (info.panelInfo.panelType != SOFT_KEYBOARD || info.panelInfo.panelFlag == FLG_CANDIDATE_COLUMN) { -// SELECTION_HILOGD("no need to deal."); -// return; -// } -// auto proxy = ImaUtils::GetImsaProxy();//通过IMSA(Input Method Service Agent)代理对象获取输入法系统能力==》OnDemandStartStopSa(涉及到与系统能力管理器的交互) -// if (proxy == nullptr) { -// SELECTION_HILOGE("proxy is nullptr!"); -// return; -// } -// std::string name = window_->GetWindowName() + "/" + std::to_string(window_->GetWindowId()); -// info.windowInfo.name = std::move(name); -// info.windowInfo.left = rect.posX_; -// info.windowInfo.top = rect.posY_; -// info.windowInfo.width = rect.width_; -// info.windowInfo.height = rect.height_; -// SELECTION_HILOGD("rect[%{public}d, %{public}d, %{public}u, %{public}u], status: %{public}d, " -// "panelFlag: %{public}d.", -// rect.posX_, rect.posY_, rect.width_, rect.height_, status, info.panelInfo.panelFlag); -// proxy->PanelStatusChange(static_cast(status), info); -// } - int32_t SelectionPanel::HidePanel() { @@ -314,9 +278,6 @@ int32_t SelectionPanel::HidePanel() SELECTION_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast(panelType_), static_cast(panelFlag_)); PanelStatusChange(SelectionWindowStatus::HIDE); - // if (!isScbEnable_) { - // PanelStatusChangeToImc(InputWindowStatus::HIDE, { 0, 0, 0, 0 }); - // } return ErrorCode::NO_ERROR; } @@ -330,32 +291,24 @@ bool SelectionPanel::IsHidden() return false; } -// int32_t SelectionPanel::StartMoving() -// { -// if (window_ == nullptr) { -// SELECTION_HILOGE("window_ is nullptr!"); -// return ErrorCode::ERROR_IME; -// } -// // if (panelType_ != STATUS_BAR) { -// // IMSA_HILOGE("SOFT_KEYBOARD panel can not move!"); -// // return ErrorCode::ERROR_INVALID_PANEL_TYPE; -// // } -// // if (panelFlag_ != FLG_FLOATING) { -// // IMSA_HILOGE("invalid panel flag: %{public}d", panelFlag_); -// // return ErrorCode::ERROR_INVALID_PANEL_FLAG; -// // } -// auto ret = window_->StartMoveWindow(); -// if (ret == WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT) { -// SELECTION_HILOGE("window manager service not support error ret = %{public}d.", ret); -// return ErrorCode::ERROR_DEVICE_UNSUPPORTED; -// } -// if (ret != WmErrorCode::WM_OK) { -// SELECTION_HILOGE("window manager service error ret = %{public}d.", ret); -// return ErrorCode::ERROR_WINDOW_MANAGER; -// } -// SELECTION_HILOGI("StartMoving success!"); -// return ErrorCode::NO_ERROR; -// } +int32_t SelectionPanel::StartMoving() +{ + if (window_ == nullptr) { + SELECTION_HILOGE("window_ is nullptr!"); + return ErrorCode::ERROR_IME; + } + auto ret = window_->StartMoveWindow(); + if (ret == WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT) { + SELECTION_HILOGE("window manager service not support error ret = %{public}d.", ret); + return ErrorCode::ERROR_DEVICE_UNSUPPORTED; + } + if (ret != WmErrorCode::WM_OK) { + SELECTION_HILOGE("window manager service error ret = %{public}d.", ret); + return ErrorCode::ERROR_WINDOW_MANAGER; + } + SELECTION_HILOGI("StartMoving success!"); + return ErrorCode::NO_ERROR; +} } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file -- Gitee From 62bac8536f8d75d636a8bf6de51a281e4a1cfbc5 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Thu, 29 May 2025 17:50:33 +0800 Subject: [PATCH 44/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0moveTo=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../js/napi/selection_ability/js_panel.cpp | 54 +++++++++++++++++++ .../js/napi/selection_ability/js_panel.h | 2 + .../include/selection_panel.h | 1 + .../selection_ability/src/selection_panel.cpp | 15 ++++++ 4 files changed, 72 insertions(+) diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 6b50d59..14b5b44 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -25,6 +25,7 @@ namespace OHOS { namespace SelectionFwk { +using namespace std::chrono; constexpr int32_t MAX_WAIT_TIME = 10; const std::string JsPanel::CLASS_NAME = "Panel"; thread_local napi_ref JsPanel::panelConstructorRef_ = nullptr; @@ -227,5 +228,58 @@ napi_value JsPanel::StartMoving(napi_env env, napi_callback_info info) return JsUtil::Const::Null(env); } +napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info) +{ + auto ctxt = std::make_shared(env, info); + auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + napi_status status = napi_generic_failure; + PARAM_CHECK_RETURN(env, argc > 1, "at least two parameters is required ", TYPE_NONE, status); + // 0 means the first param x + PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, argv[0], ctxt->x) == napi_ok, "x type must be number", + TYPE_NONE, status); + // 1 means the second param y + PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, argv[1], ctxt->y) == napi_ok, "y type must be number", + TYPE_NONE, status); + ctxt->info = { std::chrono::system_clock::now(), JsEvent::MOVE_TO }; + jsQueue_.Push(ctxt->info); + return napi_ok; + }; + + auto exec = [ctxt](AsyncCall::Context *ctx) { + int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); + jsQueue_.Wait(ctxt->info); + PrintEditorQueueInfoIfTimeout(start, ctxt->info); + if (ctxt->selectionPanel == nullptr) { + SELECTION_HILOGE("inputMethodPanel_ is nullptr!"); + jsQueue_.Pop(); + return; + } + auto code = ctxt->selectionPanel->MoveTo(ctxt->x, ctxt->y); + jsQueue_.Pop(); + if (code == ErrorCode::ERROR_PARAMETER_CHECK_FAILED) { + ctxt->SetErrorCode(code); + return; + } + ctxt->SetState(napi_ok); + }; + ctxt->SetAction(std::move(input)); + // 3 means JsAPI:moveTo has 3 params at most. + AsyncCall asyncCall(env, info, ctxt, 3); + return asyncCall.Call(env, exec, "moveTo"); +} + +void JsPanel::PrintEditorQueueInfoIfTimeout(int64_t start, const JsEventInfo ¤tInfo) +{ + int64_t end = duration_cast(system_clock::now().time_since_epoch()).count(); + if (end - start >= MAX_WAIT_TIME) { + JsEventInfo frontInfo; + auto ret = jsQueue_.GetFront(frontInfo); + int64_t frontTime = duration_cast(frontInfo.timestamp.time_since_epoch()).count(); + int64_t currentTime = duration_cast(currentInfo.timestamp.time_since_epoch()).count(); + SELECTION_HILOGI("ret:%{public}d,front[%{public}" PRId64 ",%{public}d],current[%{public}" PRId64 ",%{public}d]", ret, + frontTime, static_cast(frontInfo.event), currentTime, static_cast(currentInfo.event)); + } +} + } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index caf90f4..0591984 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -60,6 +60,7 @@ public: static napi_value Show(napi_env env, napi_callback_info info); static napi_value Hide(napi_env env, napi_callback_info info); static napi_value StartMoving(napi_env env, napi_callback_info info); + static napi_value MoveTo(napi_env env, napi_callback_info info); void SetNative(const std::shared_ptr &panel); std::shared_ptr GetNative(); private: @@ -106,6 +107,7 @@ private: }; static napi_value JsNew(napi_env env, napi_callback_info info); + static void PrintEditorQueueInfoIfTimeout(int64_t start, const JsEventInfo ¤tInfo); static const std::string CLASS_NAME; static thread_local napi_ref panelConstructorRef_; std::shared_ptr selectionPanel_ = nullptr; diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 6ad0922..7b4c931 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -46,6 +46,7 @@ public: int32_t ShowPanel(); int32_t HidePanel(); int32_t StartMoving(); + int32_t MoveTo(int32_t x, int32_t y); bool IsShowing(); bool IsHidden(); diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index 3001620..b0f05f9 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -310,5 +310,20 @@ int32_t SelectionPanel::StartMoving() return ErrorCode::NO_ERROR; } +int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) +{ + if (window_ == nullptr) { + SELECTION_HILOGE("window_ is nullptr!"); + return ErrorCode::ERROR_NULL_POINTER; + } + if (panelFlag_ == FLG_FIXED) { + SELECTION_HILOGE("FLG_FIXED panel can not moveTo!"); + return ErrorCode::NO_ERROR; + } + auto ret = window_->MoveTo(x, y); + SELECTION_HILOGI("x/y: %{public}d/%{public}d, ret = %{public}d", x, y, ret); + return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR; +} + } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file -- Gitee From 78265530d0b7c33b9b3d97d4a77b5cc526efc12f Mon Sep 17 00:00:00 2001 From: fanzhe Date: Fri, 30 May 2025 10:28:51 +0800 Subject: [PATCH 45/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- .../selection_ability/js_selection_engine_setting.cpp | 9 ++++----- .../selection_ability/src/selection_listener_impl.cpp | 4 ++++ service/src/selection_service.cpp | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 5b0423c..f619466 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -219,10 +219,10 @@ void JsSelectionEngineSetting::RegisterListener(napi_value callback, std::string auto selectionInterface = GetJsSelectionEngineSetting(); listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionInterface); if (listenerStub_ == nullptr) { - SELECTION_HILOGE("listenerStub_ is nullptr!"); + SELECTION_HILOGE("Failed to create SelectionListenerImpl instance."); return; } - SELECTION_HILOGI("Begin to call SA RegisterListener"); + SELECTION_HILOGI("Begin calling SA RegisterListener!"); proxy->RegisterListener(listenerStub_->AsObject()); } @@ -283,7 +283,7 @@ std::shared_ptr JsSelectionEngineSetting::GetJsSelecti if (selectionDelegate_ == nullptr) { auto delegate = std::make_shared(); if (delegate == nullptr) { - SELECTION_HILOGE("keyboard delegate is nullptr!"); + SELECTION_HILOGE("JsSelectionEngineSetting is nullptr!"); return nullptr; } selectionDelegate_ = delegate; @@ -383,7 +383,7 @@ napi_value JsSelectionEngineSetting::Write(napi_env env, const SelectionData &se int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionData &selectionData) { - SELECTION_HILOGI("OnSelectionEvent begin"); + SELECTION_HILOGD("OnSelectionEvent begin"); std::string type = "selectionEvent"; auto entry = GetEntry(type, [&selectionData](SelectionEntry &entry) {entry.selectionData = selectionData; }); @@ -417,7 +417,6 @@ int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionData &selectio JsCallbackHandler::Traverse(entry->vecCopy, { 1, paramGetter }); }; eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); - SELECTION_HILOGI("OnSelectionEvent end"); return 0; } diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index 0894fcc..df3d879 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -33,6 +33,10 @@ ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionDataInner& selec SELECTION_HILOGI("Recveive selection data: %{public}s", selectionDataInner.text.c_str()); SelectionData selectionData; CopySelectionData(selectionDataInner, selectionData); + if (selectionI_ == nullptr) { + SELECTION_HILOGI("selectionI_ is nullptr"); + return 1; + } selectionI_->OnSelectionEvent(selectionData); return 0; } diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index f46ce37..ab58a37 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -100,9 +100,9 @@ sptr SelectionService::GetListener() { ErrCode SelectionService::RegisterListener(const sptr &listener) { - SELECTION_HILOGI("Enter RegisterListener"); + SELECTION_HILOGD("Enter RegisterListener"); if (listener == nullptr) { - SELECTION_HILOGE("RegisterListener: Input listener is nullptr."); + SELECTION_HILOGE("RegisterListener: selection listener is nullptr."); return 1; } -- Gitee From 4d75f33acbcd8d76eb07c4c815d00468bc7b90f1 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Fri, 30 May 2025 17:42:14 +0800 Subject: [PATCH 46/93] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- bundle.json | 3 +- etc/init/selection_service.cfg | 5 +- service/BUILD.gn | 5 +- service/src/selection_service.cpp | 103 +++++++++++++----------------- 4 files changed, 52 insertions(+), 64 deletions(-) diff --git a/bundle.json b/bundle.json index f225aec..0171f57 100644 --- a/bundle.json +++ b/bundle.json @@ -36,7 +36,8 @@ "graphic_2d", "bundle_framework", "ffrt", - "config_policy" + "config_policy", + "screenlock_mgr" ], "third_party": [ ] diff --git a/etc/init/selection_service.cfg b/etc/init/selection_service.cfg index 163c4b9..9c1b471 100644 --- a/etc/init/selection_service.cfg +++ b/etc/init/selection_service.cfg @@ -10,12 +10,15 @@ "apl": "system_basic", "permission" : [ "ohos.permission.INPUT_MONITORING", + "ohos.permission.INJECT_INPUT_EVENT", "ohos.permission.GET_RUNNING_INFO", "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT", "ohos.permission.SYSTEM_FLOAT_WINDOW" ], - "permission_acls" : ["ohos.permission.INPUT_MONITORING"], + "permission_acls" : [ + "ohos.permission.INPUT_MONITORING" + ], "caps" : [], "secon" : "u:r:selection_service:s0" } diff --git a/service/BUILD.gn b/service/BUILD.gn index 0300477..1f8d5c4 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -78,12 +78,13 @@ ohos_shared_library("selection_service") { "ability_runtime:ability_manager", "c_utils:utils", "napi:ace_napi", + "hilog:libhilog", "ipc:ipc_single", "init:libbeget_proxy", - "hilog:libhilog", + "input:libmmi-client", "safwk:system_ability_fwk", "samgr:samgr_proxy", - "input:libmmi-client", + "screenlock_mgr:screenlock_client", ] part_name = "selectionfwk" diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index ab58a37..e1e63b7 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -25,6 +25,9 @@ #include #include "common_event_manager.h" #include "selection_interface.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "screenlock_manager.h" using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -242,7 +245,15 @@ void SelectionService::InputMonitorInit() std::shared_ptr inputMonitor = std::make_shared( std::make_shared()); if (inputMonitorId_ < 0) { - sleep(30); + auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + auto remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); + while (remoteObj == nullptr) + { + SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID failed. wait..."); + sleep(1); + remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); + } + SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID succeed."); inputMonitorId_ = InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); SELECTION_HILOGI("[SelectionService] input monitor init end"); @@ -261,42 +272,10 @@ void SelectionService::InputMonitorCancel() void SelectionService::HandleKeyEvent(int32_t keyCode) { -#ifdef HAS_MULTIMODALINPUT_INPUT_PART - SELECTION_HILOGI("[YMZ] keyCode: %{public}d", keyCode); - int64_t now = static_cast(time(nullptr)); - if (IsScreenOn()) { - this->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_BUTTON, false); - } else { - if (keyCode == KeyEvent::KEYCODE_F1) { - POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Wakeup by double click"); - std::string reason = "double click"; - reason.append(std::to_string(keyCode)); - this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK, reason); - } else if (keyCode >= KeyEvent::KEYCODE_0 && keyCode <= KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN) { - POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Wakeup by keyboard"); - std::string reason = "keyboard:"; - reason.append(std::to_string(keyCode)); - this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_KEYBOARD, reason); - } - } -#endif } void SelectionService::HandlePointEvent(int32_t type) { -#ifdef HAS_MULTIMODALINPUT_INPUT_PART - SELECTION_HILOGI("type: %{public}d", type); - int64_t now = static_cast(time(nullptr)); - if (this->IsScreenOn()) { - this->RefreshActivityInner(now, UserActivityType::USER_ACTIVITY_TYPE_ATTENTION, false); - } else { - if (type == PointerEvent::SOURCE_TYPE_MOUSE) { - std::string reason = "mouse click"; - POWER_HILOGI(FEATURE_WAKEUP, "[UL_POWER] Wakeup by mouse"); - this->WakeupDevice(now, WakeupDeviceType::WAKEUP_DEVICE_MOUSE, reason); - } - } -#endif } void DefaultSelectionEventListener::OnTextSelected() @@ -371,15 +350,13 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con return; } - void SelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const - { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - OnInputEvent(pointerEvent); - } - void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { + bool screenLockedFlag = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); + if (screenLockedFlag) { + SELECTION_HILOGD("It is not screen on."); + return; + } int32_t pointerId = pointerEvent->GetPointerId(); if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { return; @@ -425,6 +402,12 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) c SELECTION_HILOGI("[SelectionService] into axisEvent"); }; +void SelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const +{ + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + OnInputEvent(pointerEvent); +} void SelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const { @@ -585,11 +568,11 @@ void DefaultSelectionEventListener::InjectCtrlC() const keyEvent1->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); keyEvent1->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); keyEvent1->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - KeyEvent::KeyItem item1; - item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - item1.SetPressed(true); - item1.SetDownTime(500); - keyEvent1->AddKeyItem(item1); + // KeyEvent::KeyItem item1; + // item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // item1.SetPressed(true); + // item1.SetDownTime(500); + // keyEvent1->AddKeyItem(item1); InputManager::GetInstance()->SimulateInputEvent(keyEvent1); // 设置C键按下 @@ -597,11 +580,11 @@ void DefaultSelectionEventListener::InjectCtrlC() const keyEvent2->SetKeyCode(KeyEvent::KEYCODE_C); keyEvent2->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); keyEvent2->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - KeyEvent::KeyItem item2; - item2.SetKeyCode(KeyEvent::KEYCODE_C); - item2.SetPressed(true); - item2.SetDownTime(500); - keyEvent2->AddKeyItem(item2); + // KeyEvent::KeyItem item2; + // item2.SetKeyCode(KeyEvent::KEYCODE_C); + // item2.SetPressed(true); + // item2.SetDownTime(500); + // keyEvent2->AddKeyItem(item2); InputManager::GetInstance()->SimulateInputEvent(keyEvent2); // 设置C键释放 @@ -609,11 +592,11 @@ void DefaultSelectionEventListener::InjectCtrlC() const keyEvent3->SetKeyCode(KeyEvent::KEYCODE_C); keyEvent3->SetKeyAction(KeyEvent::KEY_ACTION_UP); keyEvent3->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - KeyEvent::KeyItem item3; - item3.SetKeyCode(KeyEvent::KEYCODE_C); - item3.SetPressed(true); - item3.SetDownTime(500); - keyEvent3->AddKeyItem(item3); + // KeyEvent::KeyItem item3; + // item3.SetKeyCode(KeyEvent::KEYCODE_C); + // item3.SetPressed(true); + // item3.SetDownTime(500); + // keyEvent3->AddKeyItem(item3); InputManager::GetInstance()->SimulateInputEvent(keyEvent3); // 设置Ctrl键释放 @@ -621,10 +604,10 @@ void DefaultSelectionEventListener::InjectCtrlC() const keyEvent4->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); keyEvent4->SetKeyAction(KeyEvent::KEY_ACTION_UP); keyEvent4->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - KeyEvent::KeyItem item4; - item4.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - item4.SetPressed(true); - item4.SetDownTime(500); - keyEvent4->AddKeyItem(item4); + // KeyEvent::KeyItem item4; + // item4.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // item4.SetPressed(true); + // item4.SetDownTime(500); + // keyEvent4->AddKeyItem(item4); InputManager::GetInstance()->SimulateInputEvent(keyEvent4); } -- Gitee From dcaf1fd60012aa29549bd760eb4e152e8a1a1da0 Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Fri, 30 May 2025 19:19:15 +0800 Subject: [PATCH 47/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0destroyPanel=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../js_selection_engine_setting.cpp | 70 ++- .../js_selection_engine_setting.h | 5 +- .../selection_client/js_selection_utils.cpp | 520 +----------------- .../selection_client/js_selection_utils.h | 154 ------ .../selection_ability/include/panel_common.h | 6 +- .../include/selection_ability.h | 2 +- .../include/selection_panel.h | 11 +- .../src/selection_ability.cpp | 49 +- .../selection_ability/src/selection_panel.cpp | 73 +-- .../selection_ability/src/tasks/task.cpp | 2 - 10 files changed, 122 insertions(+), 770 deletions(-) diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index f619466..6f0b07d 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -101,15 +101,15 @@ napi_value JsSelectionEngineSetting::UnSubscribe(napi_env env, napi_callback_inf } napi_status JsSelectionEngineSetting::GetContext(napi_env env, napi_value in, - std::shared_ptr &context)//namespace AbilityRuntime待补充 + std::shared_ptr &context) { bool stageMode = false; - napi_status status = OHOS::AbilityRuntime::IsStageContext(env, in, stageMode);//IsStageContext()待补充 + napi_status status = OHOS::AbilityRuntime::IsStageContext(env, in, stageMode); if (status != napi_ok || (!stageMode)) { SELECTION_HILOGE("it's not in stage mode."); return status; } - context = OHOS::AbilityRuntime::GetStageModeContext(env, in);//GetStageModeContext()待补充 + context = OHOS::AbilityRuntime::GetStageModeContext(env, in); if (context == nullptr) { SELECTION_HILOGE("context is nullptr."); return napi_generic_failure; @@ -122,7 +122,6 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf SELECTION_HILOGI("SelectionEngineSetting CreatePanel start."); auto ctxt = std::make_shared(); -//处理从JavaScript传入的参数验证和转换 auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { PARAM_CHECK_RETURN(env, argc >= 2, "at least two parameters is required.", TYPE_NONE, napi_invalid_arg); napi_valuetype valueType = napi_undefined; @@ -137,23 +136,23 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf napi_typeof(env, argv[1], &valueType); PARAM_CHECK_RETURN(env, valueType == napi_object, "param info type must be PanelInfo.", TYPE_NONE, napi_invalid_arg); - status = OHOS::SelectionFwk::JsSelectionUtils::GetValue(env, argv[1], ctxt->panelInfo);//参数解析失败,这个需要看下!!! + status = OHOS::SelectionFwk::JsSelectionUtils::GetValue(env, argv[1], ctxt->panelInfo); SELECTION_HILOGD( "output js param panelInfo covert , type/flag: %{public}d/%{public}d.", static_cast(ctxt->panelInfo.panelType), static_cast(ctxt->panelInfo.panelFlag)); PARAM_CHECK_RETURN(env, status == napi_ok, "js param info covert failed!", TYPE_NONE, napi_invalid_arg); return status; }; -//执行实际的面板创建操作 + auto exec = [ctxt](AsyncCall::Context *ctx) { auto ret = SelectionAbility::GetInstance()->CreatePanel(ctxt->context, ctxt->panelInfo, ctxt->panel); ctxt->SetErrorCode(ret); CHECK_RETURN_VOID(ret == ErrorCode::NO_ERROR, "JsSelectionEngineSetting CreatePanel failed!"); ctxt->SetState(napi_ok); }; -//处理返回结果,创建JavaScript层的面板对象, + auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { - JsPanel *jsPanel = nullptr;//JsPanel类在Js_panel.h中声明定义 - napi_value constructor = JsPanel::Init(env);// 初始化JsPanel构造函数 + JsPanel *jsPanel = nullptr; + napi_value constructor = JsPanel::Init(env); CHECK_RETURN(constructor != nullptr, "failed to get panel constructor!", napi_generic_failure); napi_status status = napi_new_instance(env, constructor, 0, nullptr, result); @@ -161,15 +160,57 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf status = napi_unwrap(env, *result, (void **)(&jsPanel)); CHECK_RETURN((status == napi_ok) && (jsPanel != nullptr), "get jsPanel unwrap failed!", napi_generic_failure); - jsPanel->SetNative(ctxt->panel);//SetNative() 在js_panel.cpp实现 + jsPanel->SetNative(ctxt->panel); return napi_ok; }; - ctxt->SetAction(std::move(input), std::move(output));// 设置上下文的操作函数SetAction() + ctxt->SetAction(std::move(input), std::move(output)); // 3 means JsAPI:createPanel has 3 params at most. - AsyncCall asyncCall(env, info, ctxt, 3);// 创建异步调用对象(最多3个参数)AsyncCall - return asyncCall.Call(env, exec, "createPanel");// 执行异步调用asyncCall.Call() - // return nullptr;//测试时临时使用 + AsyncCall asyncCall(env, info, ctxt, 3); + return asyncCall.Call(env, exec, "createPanel"); +} + +napi_value JsSelectionEngineSetting::DestroyPanel(napi_env env, napi_callback_info info) +{ + SELECTION_HILOGI("SelectionEngineSetting DestroyPanel start."); + auto ctxt = std::make_shared(); + auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + PARAM_CHECK_RETURN(env, argc >= 1, "at least one parameter is required!", TYPE_NONE, napi_invalid_arg); + napi_valuetype valueType = napi_undefined; + napi_typeof(env, argv[0], &valueType); + PARAM_CHECK_RETURN(env, valueType == napi_object, "param panel type must be SelectionPanel.", TYPE_NONE, + napi_invalid_arg); + bool isPanel = false; + napi_value constructor = JsPanel::Init(env); + CHECK_RETURN(constructor != nullptr, "failed to get panel constructor.", napi_invalid_arg); + napi_status status = napi_instanceof(env, argv[0], constructor, &isPanel); + CHECK_RETURN((status == napi_ok) && isPanel, "param verification failed, it's not expected panel instance!", + status); + JsPanel *jsPanel = nullptr; + status = napi_unwrap(env, argv[0], (void **)(&jsPanel)); + CHECK_RETURN((status == napi_ok) && (jsPanel != nullptr), "failed to unwrap JsPanel!", status); + ctxt->panel = jsPanel->GetNative(); + CHECK_RETURN((ctxt->panel != nullptr), "panel is nullptr!", napi_invalid_arg); + return status; + }; + + auto exec = [ctxt](AsyncCall::Context *ctx) { ctxt->SetState(napi_ok); }; + + auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { + CHECK_RETURN((ctxt->panel != nullptr), "panel is nullptr!", napi_generic_failure); + auto errCode = SelectionAbility::GetInstance()->DestroyPanel(ctxt->panel); + if (errCode != ErrorCode::NO_ERROR) { + SELECTION_HILOGE("DestroyPanel failed, errCode: %{public}d!", errCode); + return napi_generic_failure; + } + ctxt->panel = nullptr; + return napi_ok; + }; + + ctxt->SetAction(std::move(input), std::move(output)); + // 2 means JsAPI:destroyPanel has 2 params at most. + AsyncCall asyncCall(env, info, ctxt, 2); + return asyncCall.Call(env, exec, "destroyPanel"); } sptr JsSelectionEngineSetting::GetSelectionSystemAbility() @@ -333,6 +374,7 @@ napi_value JsSelectionEngineSetting::InitProperty(napi_env env, napi_value expor DECLARE_NAPI_FUNCTION("on", Subscribe), DECLARE_NAPI_FUNCTION("off", UnSubscribe), DECLARE_NAPI_FUNCTION("createPanel", CreatePanel), + DECLARE_NAPI_FUNCTION("destroyPanel", DestroyPanel), }; napi_value cons = nullptr; diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index e67512e..a478c6d 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -46,6 +46,7 @@ public: static napi_value Subscribe(napi_env env, napi_callback_info info); static napi_value UnSubscribe(napi_env env, napi_callback_info info); static napi_value CreatePanel(napi_env env, napi_callback_info info); + static napi_value DestroyPanel(napi_env env, napi_callback_info info); int32_t OnSelectionEvent(const SelectionData &selectionData); private: @@ -105,6 +106,6 @@ private: static std::mutex eventHandlerMutex_; static std::shared_ptr handler_; }; -} //SelectionFwk -} //OHOS +} // namespace SelectionFwk +} // namespace OHOS #endif //JS_SELECTION_ENGINE_SETTING_H diff --git a/frameworks/js/napi/selection_client/js_selection_utils.cpp b/frameworks/js/napi/selection_client/js_selection_utils.cpp index 8e6c3af..f240f11 100644 --- a/frameworks/js/napi/selection_client/js_selection_utils.cpp +++ b/frameworks/js/napi/selection_client/js_selection_utils.cpp @@ -16,359 +16,12 @@ #include "js_selection_utils.h" #include "panel_info.h" -// #include "js_util.h" - namespace OHOS { namespace SelectionFwk { constexpr int32_t STR_MAX_LENGTH = 4096; constexpr size_t STR_TAIL_LENGTH = 1; constexpr size_t ARGC_MAX = 6; constexpr size_t ARGC_ONE = 1; -// const std::map JsUtils::ERROR_CODE_MAP = { -// { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER }, -// { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION }, -// { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION }, -// { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_EDITABLE }, -// { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED }, -// { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST }, -// { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER }, -// { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IME_START_INPUT_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME }, -// { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE }, -// { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, -// { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME }, -// { ErrorCode::ERROR_ENABLE_IME, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_NOT_CURRENT_IME, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_PANEL_NOT_FOUND, EXCEPTION_PANEL_NOT_FOUND }, -// { ErrorCode::ERROR_WINDOW_MANAGER, EXCEPTION_WINDOW_MANAGER }, -// { ErrorCode::ERROR_GET_TEXT_CONFIG, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE, EXCEPTION_PARAMCHECK }, -// { ErrorCode::ERROR_TEXT_LISTENER_ERROR, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED, EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED }, -// { ErrorCode::ERROR_INVALID_RANGE, EXCEPTION_PARAMCHECK }, -// { ErrorCode::ERROR_SECURITY_MODE_OFF, EXCEPTION_BASIC_MODE }, -// { ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST, EXCEPTION_REQUEST_NOT_ACCEPT }, -// { ErrorCode::ERROR_MESSAGE_HANDLER, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE, EXCEPTION_PARAMCHECK }, -// { ErrorCode::ERROR_INVALID_PANEL_TYPE, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, -// { ErrorCode::ERROR_INVALID_PANEL_FLAG, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, -// { ErrorCode::ERROR_IMA_CHANNEL_NULLPTR, EXCEPTION_IMCLIENT }, -// { ErrorCode::ERROR_IPC_REMOTE_NULLPTR, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMA_NULLPTR, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_INPUT_TYPE_NOT_FOUND, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_MALLOC_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_NULLPTR, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_IME_START_TIMEOUT, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS }, -// { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED }, -// }; - -// const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { -// { EXCEPTION_PERMISSION, "the permissions check fails." }, -// { EXCEPTION_SYSTEM_PERMISSION, "not system application." }, -// { EXCEPTION_PARAMCHECK, "the parameters check fails." }, -// { EXCEPTION_UNSUPPORTED, "capability not supported." }, -// { EXCEPTION_PACKAGEMANAGER, "bundle manager error." }, -// { EXCEPTION_IMENGINE, "input method engine error. Possible causes: 1.input method panel not created.\ -// 2.the input method application does not subscribe to related events." }, -// { EXCEPTION_IMCLIENT, "input method client error. Possible causes: 1.the edit box is not focused.\ -// 2.no edit box is bound to current input method application." }, -// { EXCEPTION_IME, "not an input method application." }, -// { EXCEPTION_CONFPERSIST, "configuration persistence error." }, -// { EXCEPTION_CONTROLLER, "input method controller error.\ -// Possible cause: create InputmethodController object failed." }, -// { EXCEPTION_SETTINGS, "input method setter error. Possible cause: create InputmethodSetting object failed." }, -// { EXCEPTION_IMMS, "input method manager service error. Possible cause: a system error, such as null pointer,\ -// IPC exception." }, -// { EXCEPTION_DETACHED, "input method client detached." }, -// { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." }, -// { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." }, -// { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." }, -// { EXCEPTION_WINDOW_MANAGER, "window manager service error." }, -// { EXCEPTION_BASIC_MODE, "the input method is basic mode." }, -// { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." }, -// { EXCEPTION_EDITABLE, "the edit mode need enable." }, -// { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." }, -// }; - -// const std::map JsUtils::PARAMETER_TYPE = { -// { TYPE_UNDEFINED, "napi_undefine." }, -// { TYPE_NULL, "napi_null." }, -// { TYPE_BOOLEAN, "napi_boolean." }, -// { TYPE_NUMBER, "napi_number." }, -// { TYPE_STRING, "napi_string." }, -// { TYPE_SYMBOL, "napi_symbol." }, -// { TYPE_OBJECT, "napi_object." }, -// { TYPE_FUNCTION, "napi_function." }, -// { TYPE_EXTERNAL, "napi_external." }, -// { TYPE_BIGINT, "napi_bigint." }, -// { TYPE_ARRAY_BUFFER, "ArrayBuffer." }, -// { TYPE_ARRAY, "napi_array." }, -// }; - -// void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type) -// { -// std::string errMsg = ToMessage(err); -// napi_value error; -// napi_value code; -// napi_value message; -// if (type == TypeCode::TYPE_NONE) { -// errMsg = errMsg + " " + msg; -// IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); -// } else { -// auto iter = PARAMETER_TYPE.find(type); -// if (iter != PARAMETER_TYPE.end()) { -// errMsg = errMsg + "The type of " + msg + " must be " + iter->second; -// IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); -// } -// } -// NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message)); -// NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error)); -// NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code)); -// NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code)); -// NAPI_CALL_RETURN_VOID(env, napi_throw(env, error)); -// } - -// napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg) -// { -// IMSA_HILOGD("ToError start"); -// napi_value errorObj; -// NAPI_CALL(env, napi_create_object(env, &errorObj)); -// napi_value errorCode = nullptr; -// NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode)); -// napi_value errorMessage = nullptr; -// std::string errMsg = ToMessage(Convert(code)) + " " + msg; -// NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errorMessage)); -// NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode)); -// NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage)); -// IMSA_HILOGD("ToError end"); -// return errorObj; -// } - -// int32_t JsUtils::Convert(int32_t code) -// { -// IMSA_HILOGD("Convert start."); -// auto iter = ERROR_CODE_MAP.find(code); -// if (iter != ERROR_CODE_MAP.end()) { -// IMSA_HILOGD("ErrorCode: %{public}d", iter->second); -// return iter->second; -// } -// IMSA_HILOGD("Convert end."); -// return ERROR_CODE_QUERY_FAILED; -// } - -// const std::string JsUtils::ToMessage(int32_t code) -// { -// IMSA_HILOGD("ToMessage start"); -// auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code); -// if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) { -// IMSA_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str()); -// return iter->second; -// } -// return "error is out of definition."; -// } -//SJM -// bool JsSelectionUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId) -// { -// if (copy == nullptr) { -// return value == nullptr; -// } - -// if (threadId != std::this_thread::get_id()) { -// SELECTION_HILOGD("napi_value can not be compared"); -// return false; -// } - -// napi_value copyValue = nullptr; -// napi_get_reference_value(env, copy, ©Value); - -// bool isEquals = false; -// napi_strict_equals(env, value, copyValue, &isEquals); -// SELECTION_HILOGD("value compare result: %{public}d", isEquals); -// return isEquals; -// } - -// void *JsSelectionUtils::GetNativeSelf(napi_env env, napi_callback_info info) -// { -// size_t argc = ARGC_MAX; -// void *native = nullptr; -// napi_value self = nullptr; -// napi_value argv[ARGC_MAX] = { nullptr }; -// napi_status status = napi_invalid_arg; -// napi_get_cb_info(env, info, &argc, argv, &self, nullptr); -// CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr); - -// status = napi_unwrap(env, self, &native); -// CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr); -// return native; -// } - -// napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, int32_t &out) -// { -// napi_valuetype type = napi_undefined; -// napi_status status = napi_typeof(env, in, &type); -// CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); -// return napi_get_value_int32(env, in, &out); -// } - -// /* napi_value <-> uint32_t */ -// napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, uint32_t &out) -// { -// napi_valuetype type = napi_undefined; -// napi_status status = napi_typeof(env, in, &type); -// CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); -// return napi_get_value_uint32(env, in, &out); -// }//SJM - -// napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out) -// { -// napi_valuetype type = napi_undefined; -// napi_status status = napi_typeof(env, in, &type); -// CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure); -// return napi_get_value_bool(env, in, &out); -// } - -// napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out) -// { -// napi_valuetype type = napi_undefined; -// napi_status status = napi_typeof(env, in, &type); -// CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure); -// return napi_get_value_double(env, in, &out); -// } - -// /* napi_value <-> std::string */ -// napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out) -// { -// IMSA_HILOGD("JsUtils get string value in."); -// napi_valuetype type = napi_undefined; -// napi_status status = napi_typeof(env, in, &type); -// CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure); - -// size_t maxLen = STR_MAX_LENGTH; -// status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen); -// if (maxLen <= 0) { -// return status; -// } -// IMSA_HILOGD("napi_value -> std::string get length %{public}zu", maxLen); -// char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH]; -// if (buf != nullptr) { -// size_t len = 0; -// status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len); -// if (status == napi_ok) { -// buf[len] = 0; -// out = std::string(buf); -// } -// delete[] buf; -// } else { -// status = napi_generic_failure; -// } -// return status; -// } - -// /* napi_value <-> std::unordered_map */ -// napi_status JsUtils::GetValue(napi_env env, napi_value in, std::unordered_map &out) -// { -// napi_valuetype type = napi_undefined; -// napi_status status = napi_typeof(env, in, &type); -// PARAM_CHECK_RETURN(env, type != napi_undefined, "param is undefined.", TYPE_NONE, napi_generic_failure); - -// napi_value keys = nullptr; -// napi_get_property_names(env, in, &keys); -// uint32_t arrLen = 0; -// status = napi_get_array_length(env, keys, &arrLen); -// if (status != napi_ok) { -// IMSA_HILOGE("napi_get_array_length error"); -// return status; -// } -// // 5 means max private command count. -// PARAM_CHECK_RETURN(env, arrLen <= 5 && arrLen > 0, "privateCommand must more than 0 and less than 5.", TYPE_NONE, -// napi_generic_failure); -// IMSA_HILOGD("length : %{public}u", arrLen); -// for (size_t iter = 0; iter < arrLen; ++iter) { -// napi_value key = nullptr; -// status = napi_get_element(env, keys, iter, &key); -// CHECK_RETURN(status == napi_ok, "napi_get_element error", status); - -// napi_value value = nullptr; -// status = napi_get_property(env, in, key, &value); -// CHECK_RETURN(status == napi_ok, "napi_get_property error", status); - -// std::string keyStr; -// status = GetValue(env, key, keyStr); -// CHECK_RETURN(status == napi_ok, "GetValue keyStr error", status); - -// PrivateDataValue privateCommand; -// status = GetValue(env, value, privateCommand); -// CHECK_RETURN(status == napi_ok, "GetValue privateCommand error", status); -// out.emplace(keyStr, privateCommand); -// } -// return status; -// } - -// napi_status JsUtils::GetValue(napi_env env, napi_value in, PrivateDataValue &out) -// { -// napi_valuetype valueType = napi_undefined; -// napi_status status = napi_typeof(env, in, &valueType); -// CHECK_RETURN(status == napi_ok, "napi_typeof error", napi_generic_failure); -// if (valueType == napi_string) { -// std::string privateDataStr; -// status = GetValue(env, in, privateDataStr); -// CHECK_RETURN(status == napi_ok, "GetValue napi_string error", napi_generic_failure); -// out.emplace(privateDataStr); -// } else if (valueType == napi_boolean) { -// bool privateDataBool = false; -// status = GetValue(env, in, privateDataBool); -// CHECK_RETURN(status == napi_ok, "GetValue napi_boolean error", napi_generic_failure); -// out.emplace(privateDataBool); -// } else if (valueType == napi_number) { -// int32_t privateDataInt = 0; -// status = GetValue(env, in, privateDataInt); -// CHECK_RETURN(status == napi_ok, "GetValue napi_number error", napi_generic_failure); -// out.emplace(privateDataInt); -// } else { -// PARAM_CHECK_RETURN(env, false, "value type must be string | boolean | number", TYPE_NONE, napi_generic_failure); -// } -// return status; -// } - -// napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out) -// { -// napi_valuetype valueType = napi_undefined; -// napi_status status = napi_typeof(env, in, &valueType); -// if ((status == napi_ok) && (valueType == napi_object)) { -// status = napi_get_named_property(env, in, type.c_str(), &out); -// return status; -// } -// return napi_generic_failure; -// } /* napi_value <-> PanelInfo */ napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, PanelInfo &out) @@ -386,183 +39,12 @@ napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, PanelInfo &o napi_value panelFlagObj = nullptr; status = napi_get_named_property(env, in, "flag", &panelFlagObj); if (status == napi_ok) { - JsUtils::GetValue(env, panelFlagObj, panelFlag);//JsSelectionUtils::GetValue(env, panelFlagObj, panelFlag); + JsUtils::GetValue(env, panelFlagObj, panelFlag); } out.panelType = PanelType(panelType); out.panelFlag = PanelFlag(panelFlag); return napi_ok; } - -// napi_value JsUtils::GetValue(napi_env env, const std::vector &in) -// { -// napi_value array = nullptr; -// uint32_t index = 0; -// napi_create_array(env, &array); -// if (array == nullptr) { -// IMSA_HILOGE("create array failed"); -// return array; -// } -// for (const auto &info : in) { -// napi_value jsInfo = GetValue(env, info); -// napi_set_element(env, array, index, jsInfo); -// ++index; -// } -// return array; -// } - -// napi_value JsUtils::GetValue(napi_env env, const InputWindowInfo &in) -// { -// napi_value info = nullptr; -// napi_create_object(env, &info); - -// napi_value name = nullptr; -// napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name); -// napi_set_named_property(env, info, "name", name); - -// napi_value left = nullptr; -// napi_create_int32(env, in.left, &left); -// napi_set_named_property(env, info, "left", left); - -// napi_value top = nullptr; -// napi_create_int32(env, in.top, &top); -// napi_set_named_property(env, info, "top", top); - -// napi_value width = nullptr; -// napi_create_uint32(env, in.width, &width); -// napi_set_named_property(env, info, "width", width); - -// napi_value height = nullptr; -// napi_create_uint32(env, in.height, &height); -// napi_set_named_property(env, info, "height", height); - -// return info; -// } - -// napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out) -// { -// return napi_create_string_utf8(env, in.c_str(), in.size(), &out); -// } - -// napi_value JsUtils::GetJsPrivateCommand(napi_env env, const std::unordered_map &in) -// { -// napi_value jsPrivateCommand = nullptr; -// NAPI_CALL(env, napi_create_object(env, &jsPrivateCommand)); -// for (const auto &iter : in) { -// size_t idx = iter.second.index(); -// napi_value value = nullptr; -// if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_STRING)) { -// auto stringValue = std::get_if(&iter.second); -// if (stringValue != nullptr) { -// NAPI_CALL(env, napi_create_string_utf8(env, (*stringValue).c_str(), (*stringValue).size(), &value)); -// } -// } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_BOOL)) { -// auto boolValue = std::get_if(&iter.second); -// if (boolValue != nullptr) { -// NAPI_CALL(env, napi_get_boolean(env, *boolValue, &value)); -// } -// } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_NUMBER)) { -// auto numberValue = std::get_if(&iter.second); -// if (numberValue != nullptr) { -// NAPI_CALL(env, napi_create_int32(env, *numberValue, &value)); -// } -// } -// NAPI_CALL(env, napi_set_named_property(env, jsPrivateCommand, iter.first.c_str(), value)); -// } -// return jsPrivateCommand; -// } - -// napi_value JsUtils::GetValue(napi_env env, const std::vector &in) -// { -// void *data = nullptr; -// napi_value arrayBuffer = nullptr; -// size_t length = in.size(); -// NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer)); -// // 0 means the size of data. -// CHECK_RETURN(length != 0, "Data size is 0.", arrayBuffer); -// if (memcpy_s(data, length, reinterpret_cast(in.data()), length) != 0) { -// return nullptr; -// } -// return arrayBuffer; -// } - -// napi_status JsUtils::GetValue(napi_env env, napi_value in, std::vector &out) -// { -// size_t length = 0; -// void *data = nullptr; -// auto status = napi_get_arraybuffer_info(env, in, &data, &length); -// if (status != napi_ok) { -// IMSA_HILOGE("Get ArrayBuffer info failed!"); -// return status; -// } -// if (data == nullptr && length == 0) { -// IMSA_HILOGE("Empty ArrayBuffer."); -// out.clear(); -// return napi_ok; -// } -// if (data == nullptr) { -// IMSA_HILOGE("ArrayBuffer data is nullptr!"); -// return napi_generic_failure; -// } -// IMSA_HILOGD("ArrayBuffer data size: %{public}zu.", length); -// out.assign(reinterpret_cast(data), reinterpret_cast(data) + length); -// return napi_ok; -// } - -// napi_status JsUtils::GetMessageHandlerCallbackParam(napi_value *argv, -// const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, size_t size) -// { -// if (argv == nullptr) { -// IMSA_HILOGE("argv is nullptr!."); -// return napi_generic_failure; -// } -// if (size < ARGC_ONE) { -// IMSA_HILOGE("argv size is less than 1!."); -// return napi_generic_failure; -// } -// if (jsMessageHandler == nullptr) { -// IMSA_HILOGE("jsMessageHandler is nullptr!."); -// return napi_generic_failure; -// } -// napi_value jsMsgId = nullptr; -// auto status = napi_create_string_utf8( -// jsMessageHandler->env_, arrayBuffer.msgId.c_str(), NAPI_AUTO_LENGTH, &jsMsgId); -// if (status != napi_ok) { -// IMSA_HILOGE("napi_create_string_utf8 failed!."); -// return napi_generic_failure; -// } -// // 0 means the first param index of callback. -// argv[0] = { jsMsgId }; -// if (arrayBuffer.jsArgc > ARGC_ONE) { -// napi_value jsMsgParam = JsUtils::GetValue(jsMessageHandler->env_, arrayBuffer.msgParam); -// if (jsMsgParam == nullptr) { -// IMSA_HILOGE("Get js messageParam object failed!."); -// return napi_generic_failure; -// } -// // 0 means the second param index of callback. -// argv[1] = { jsMsgParam }; -// } -// return napi_ok; -// } - -// napi_status JsUtils::GetValue(napi_env env, napi_value in, Rosen::Rect &out) -// { -// bool ret = JsUtil::Object::ReadProperty(env, in, "left", out.posX_); -// ret = ret && JsUtil::Object::ReadProperty(env, in, "top", out.posY_); -// ret = ret && JsUtil::Object::ReadProperty(env, in, "width", out.width_); -// ret = ret && JsUtil::Object::ReadProperty(env, in, "height", out.height_); -// return ret ? napi_ok : napi_generic_failure; -// } - -// napi_value JsUtils::GetValue(napi_env env, const Rosen::Rect &in) -// { -// napi_value jsObject = nullptr; -// napi_create_object(env, &jsObject); -// bool ret = JsUtil::Object::WriteProperty(env, jsObject, "left", in.posX_); -// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "top", in.posY_); -// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "width", in.width_); -// ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", in.height_); -// return ret ? jsObject : JsUtil::Const::Null(env); -// } } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/selection_client/js_selection_utils.h b/frameworks/js/napi/selection_client/js_selection_utils.h index c070aef..ba314fa 100644 --- a/frameworks/js/napi/selection_client/js_selection_utils.h +++ b/frameworks/js/napi/selection_client/js_selection_utils.h @@ -21,8 +21,6 @@ #include "ability.h" #include "selection_log.h" #include "selection_panel.h" -// #include "selection_utils.h" -// #include "js_callback_object.h" #include "util.h" #include "js_utils.h" #include "napi/native_api.h" @@ -34,163 +32,11 @@ using Ability = OHOS::AppExecFwk::Ability; namespace OHOS { namespace SelectionFwk { -// enum IMFErrorCode : int32_t { -// EXCEPTION_PERMISSION = 201, -// EXCEPTION_SYSTEM_PERMISSION = 202, -// EXCEPTION_PARAMCHECK = 401, -// EXCEPTION_UNSUPPORTED = 801, -// EXCEPTION_PACKAGEMANAGER = 12800001, -// EXCEPTION_IMENGINE = 12800002, -// EXCEPTION_IMCLIENT = 12800003, -// EXCEPTION_IME = 12800004, -// EXCEPTION_CONFPERSIST = 12800005, -// EXCEPTION_CONTROLLER = 12800006, -// EXCEPTION_SETTINGS = 12800007, -// EXCEPTION_IMMS = 12800008, -// EXCEPTION_DETACHED = 12800009, -// EXCEPTION_DEFAULTIME = 12800010, -// EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED = 12800011, -// EXCEPTION_PANEL_NOT_FOUND = 12800012, -// EXCEPTION_WINDOW_MANAGER = 12800013, -// EXCEPTION_BASIC_MODE = 12800014, -// EXCEPTION_REQUEST_NOT_ACCEPT = 12800015, -// EXCEPTION_EDITABLE = 12800016, -// EXCEPTION_INVALID_PANEL_TYPE_FLAG = 12800017, -// }; - -// enum TypeCode : int32_t { -// TYPE_NONE = 0, -// TYPE_UNDEFINED, -// TYPE_NULL, -// TYPE_BOOLEAN, -// TYPE_NUMBER, -// TYPE_STRING, -// TYPE_SYMBOL, -// TYPE_OBJECT, -// TYPE_FUNCTION, -// TYPE_EXTERNAL, -// TYPE_BIGINT, -// TYPE_ARRAY_BUFFER, -// TYPE_ARRAY, -// }; - -// /* check condition, return and logging if condition not true. */ -// #define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \ -// do { \ -// if (!(condition)) { \ -// JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ -// return retVal; \ -// } \ -// } while (0) - -// #define PARAM_CHECK_RETURN_VOID(env, condition, message, typeCode) \ -// do { \ -// if (!(condition)) { \ -// JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ -// return; \ -// } \ -// } while (0) - -// #define RESULT_CHECK_RETURN(env, condition, errCode, message, typeCode, retVal) \ -// do { \ -// if (!(condition)) { \ -// JsUtils::ThrowException(env, errCode, message, typeCode); \ -// return retVal; \ -// } \ -// } while (0) - -// #define RESULT_CHECK_RETURN_VOID(env, condition, errCode, message, typeCode) \ -// do { \ -// if (!(condition)) { \ -// JsUtils::ThrowException(env, errCode, message, typeCode); \ -// return; \ -// } \ -// } while (0) - -// /* check condition, return and logging. */ -// #define CHECK_RETURN_VOID(condition, message) \ -// do { \ -// if (!(condition)) { \ -// SELECTION_HILOGE("test (" #condition ") failed: " message); \ -// return; \ -// } \ -// } while (0) - -// /* check condition, return and logging. */ -// #define CHECK_RETURN(condition, message, retVal) \ -// do { \ -// if (!(condition)) { \ -// SELECTION_HILOGE("test (" #condition ") failed: " message); \ -// return retVal; \ -// } \ -// } while (0) - -// struct JsPropertyInfo { -// napi_valuetype type; -// TypeCode typeCode; -// std::string propertyName; -// }; class JsSelectionUtils { public: - // static void ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type); - - // static napi_value ToError(napi_env env, int32_t code, const std::string &msg); - - // static int32_t Convert(int32_t code); - - // static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId);// - - // static void *GetNativeSelf(napi_env env, napi_callback_info info);// - - // static const std::string ToMessage(int32_t code); - - // template - // static bool ReadOptionalProperty(napi_env env, napi_value object, const JsPropertyInfo &jsPropInfo, T &value) - // { - // if (!JsUtil::HasProperty(env, object, jsPropInfo.propertyName.c_str())) { - // return false; - // } - // napi_value jsObject = nullptr; - // napi_get_named_property(env, object, jsPropInfo.propertyName.c_str(), &jsObject); - // PARAM_CHECK_RETURN(env, JsUtil::GetType(env, jsObject) == jsPropInfo.type, jsPropInfo.propertyName, - // jsPropInfo.typeCode, false); - // PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, jsObject, value) == napi_ok, - // "failed to convert " + jsPropInfo.propertyName, TYPE_NONE, false); - // return true; - // } - - // static napi_status GetValue(napi_env env, napi_value in, int32_t &out);// - // static napi_status GetValue(napi_env env, napi_value in, uint32_t &out);// - // static napi_status GetValue(napi_env env, napi_value in, bool &out); - // static napi_status GetValue(napi_env env, napi_value in, double &out); - // static napi_status GetValue(napi_env env, napi_value in, std::string &out); - // static napi_status GetValue(napi_env env, napi_value in, std::unordered_map &out); - // static napi_status GetValue(napi_env env, napi_value in, PrivateDataValue &out); - // static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); static napi_status GetValue(napi_env env, napi_value in, PanelInfo &out); - // static napi_status GetValue(napi_env env, napi_value in, std::vector &out); - // static napi_status GetValue(napi_env env, napi_value in, Rosen::Rect &out); - // static napi_value GetValue(napi_env env, const std::vector &in); - // static napi_value GetValue(napi_env env, const InputWindowInfo &in); - // static napi_value GetValue(napi_env env, const Rosen::Rect &in); - // static napi_value GetJsPrivateCommand(napi_env env, const std::unordered_map &in); - // static napi_value GetValue(napi_env env, const std::vector &in); - // static napi_status GetValue(napi_env env, const std::string &in, napi_value &out); - // static napi_status GetMessageHandlerCallbackParam(napi_value *argv, - // const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, - // size_t size); - -private: - // static const std::map ERROR_CODE_MAP; - - // static const std::map ERROR_CODE_CONVERT_MESSAGE_MAP; - - // static const std::map PARAMETER_TYPE; - - // static constexpr int32_t ERROR_CODE_QUERY_FAILED = 1; - // static constexpr uint8_t MAX_ARGMENT_COUNT = 10; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/native/selection_ability/include/panel_common.h b/frameworks/native/selection_ability/include/panel_common.h index 5e4e33a..03a1de3 100644 --- a/frameworks/native/selection_ability/include/panel_common.h +++ b/frameworks/native/selection_ability/include/panel_common.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef INPUTMETHOD_IMF_PANEL_COMMON_H -#define INPUTMETHOD_IMF_PANEL_COMMON_H +#ifndef SELECTION_FWK_PANEL_COMMON_H +#define SELECTION_FWK_PANEL_COMMON_H #include @@ -93,4 +93,4 @@ struct FullPanelAdjustInfo { }; } // namespace SelectionFwk } // namespace OHOS -#endif //INPUTMETHOD_IMF_PANEL_COMMON_H +#endif //SELECTION_FWK_PANEL_COMMON_H diff --git a/frameworks/native/selection_ability/include/selection_ability.h b/frameworks/native/selection_ability/include/selection_ability.h index b672237..77b0035 100644 --- a/frameworks/native/selection_ability/include/selection_ability.h +++ b/frameworks/native/selection_ability/include/selection_ability.h @@ -34,9 +34,9 @@ public: static sptr GetInstance(); int32_t CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo, std::shared_ptr &selectionPanel); + int32_t DestroyPanel(const std::shared_ptr &selectionPanel); int32_t ShowPanel(const std::shared_ptr &selectionPanel); int32_t HidePanel(const std::shared_ptr &selectionPanel); - // void NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag); private: static std::mutex instanceLock_; diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 7b4c931..590878f 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -23,6 +23,7 @@ #include #include +#include "panel_common.h" #include "panel_info.h" #include "refbase.h" #include "context.h" @@ -37,16 +38,16 @@ namespace SelectionFwk { class SelectionPanel { public: static constexpr uint32_t INVALID_WINDOW_ID = 0; - // using CallbackFunc = std::function; SelectionPanel() = default; ~SelectionPanel(); int32_t CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo); - // void SetPanelHeightCallback(CallbackFunc heightCallback); + int32_t DestroyPanel(); int32_t SetUiContent(const std::string &contentInfo, napi_env env); int32_t ShowPanel(); int32_t HidePanel(); int32_t StartMoving(); int32_t MoveTo(int32_t x, int32_t y); + PanelType GetPanelType(); bool IsShowing(); bool IsHidden(); @@ -58,8 +59,8 @@ private: static uint32_t GenerateSequenceId(); void PanelStatusChange(const SelectionWindowStatus &status); - PanelType panelType_ = PanelType::STATUS_BAR;//待修改 - PanelFlag panelFlag_ = PanelFlag::FLG_FIXED;//待修改 + PanelType panelType_ = PanelType::STATUS_BAR; + PanelFlag panelFlag_ = PanelFlag::FLG_FIXED; sptr window_ = nullptr; sptr winOption_ = nullptr; bool isScbEnable_ { false }; @@ -70,7 +71,7 @@ private: std::shared_ptr panelStatusListener_ = nullptr; bool showRegistered_ = false; bool hideRegistered_ = false; - // CallbackFunc panelHeightCallback_ = nullptr; + }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index 4a14d58..4ed5d6d 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -69,19 +69,12 @@ void SelectionAbility::Initialize() int32_t SelectionAbility::CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo, std::shared_ptr &selectionPanel) { - // SELECTION_HILOGI("SelectionAbility start."); SELECTION_HILOGI("SelectionAbility CreatePanel start."); -//设置面板高度回调(可暂设定为固定高度) - // auto panelHeightCallback = [this](uint32_t panelHeight, PanelFlag panelFlag) { - // NotifyKeyboardHeight(panelHeight, panelFlag);//NotifyKeyboardHeight()待实现 - // }; auto flag = panels_.ComputeIfAbsent(panelInfo.panelType, [&panelInfo, &context, &selectionPanel]( - // [panelHeightCallback, &panelInfo, &context, &selectionPanel]( const PanelType &panelType, std::shared_ptr &panel) { selectionPanel = std::make_shared(); - // selectionPanel->SetPanelHeightCallback(panelHeightCallback); auto ret = selectionPanel->CreatePanel(context, panelInfo); if (ret == ErrorCode::NO_ERROR) { panel = selectionPanel; @@ -89,36 +82,24 @@ int32_t SelectionAbility::CreatePanel(const std::shared_ptr();//TaskImsaShowKeyboard待添加 - // TaskManager::GetInstance().PostTask(task);//同级目录待实现 - // } + }); return flag ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL; } -// void SelectionAbility::NotifyKeyboardHeight(uint32_t panelHeight, PanelFlag panelFlag) -// { -// auto channel = GetInputDataChannelProxy(); -// if (channel == nullptr) { -// SELECTION_HILOGE("channel is nullptr!"); -// return; -// } -// SELECTION_HILOGD("notify panel height: %{public}u, flag: %{public}d.", panelHeight, static_cast(panelFlag)); -// if (panelFlag != PanelFlag::FLG_FIXED) { -// channel->NotifyKeyboardHeight(0); -// return; -// } -// channel->NotifyKeyboardHeight(panelHeight); -// } - -// std::shared_ptr SelectionAbility::GetInputDataChannelProxy() -// { -// std::lock_guard lock(dataChannelLock_); -// return dataChannelProxy_; -// } +int32_t SelectionAbility::DestroyPanel(const std::shared_ptr &selectionPanel) +{ + SELECTION_HILOGI("SelectionAbility DestroyPanel start."); + if (selectionPanel == nullptr) { + SELECTION_HILOGE("panel is nullptr!"); + return ErrorCode::ERROR_BAD_PARAMETERS; + } + auto ret = selectionPanel->DestroyPanel(); + if (ret == ErrorCode::NO_ERROR) { + PanelType panelType = selectionPanel->GetPanelType(); + panels_.Erase(panelType); + } + return ret; +} int32_t SelectionAbility::ShowPanel(const std::shared_ptr &selectionpanel) { diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index b0f05f9..85d964b 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -40,20 +40,15 @@ int32_t SelectionPanel::CreatePanel( const std::shared_ptr &context, const PanelInfo &panelInfo) { SELECTION_HILOGI("SelectionPanel CreatePanel start."); + panelType_ = panelInfo.panelType; + panelFlag_ = panelInfo.panelFlag; SELECTION_HILOGD( "start, type/flag: %{public}d/%{public}d.", static_cast(panelType_), static_cast(panelFlag_)); - // panelType_ = panelInfo.panelType; - // panelFlag_ = panelInfo.panelFlag; // winOption_ = new (std::nothrow) OHOS::Rosen::WindowOption(); // if (winOption_ == nullptr) { // return ErrorCode::ERROR_NULL_POINTER; // } - // if (panelInfo.panelType == PanelType::STATUS_BAR) {//状态栏面板 - // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR);//窗口类型需要添加WINDOW_TYPE_SELECTION_FLOAT - // } else { - // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);//窗口类型需要添加WINDOW_TYPE_SELECTION_FLOAT - // } - // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DIALOG);//窗口类型需要确认 + // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DYNAMIC); // winOption_->SetWindowRect(OHOS::Rosen::Rect{10, 10, 80, 50}); // WMError wmError = WMError::WM_OK; // window_ = OHOS::Rosen::Window::Create(GeneratePanelName(), winOption_, context, wmError); @@ -74,7 +69,7 @@ int32_t SelectionPanel::CreatePanel( // windowId_ = window_->GetWindowId(); // SELECTION_HILOGI("success, type/flag/windowId/isScbEnable_: %{public}d/%{public}d/%{public}u/%{public}d.", // static_cast(panelType_), static_cast(panelFlag_), windowId_, isScbEnable_); - // // if (panelInfo.panelType == SOFT_KEYBOARD && isScbEnable_) {//软键盘+可用 + // // if (panelInfo.panelType == SOFT_KEYBOARD && isScbEnable_) { // // RegisterKeyboardPanelInfoChangeListener(); // // } // window_->RaiseToAppTop(); @@ -87,51 +82,42 @@ int32_t SelectionPanel::CreatePanel( // SELECTION_HILOGI("selectionPanel show."); OHOS::Rosen::Rect baseWindowRect = { 150, 150, 400, 600 }; sptr baseOp = new Rosen::WindowOption(); - baseOp->SetWindowType(Rosen::WindowType::WINDOW_TYPE_DYNAMIC); - baseOp->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING); + baseOp->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); + baseOp->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FULLSCREEN); baseOp->SetWindowRect(baseWindowRect); baseOp->SetZIndex(1980); auto displayId = Rosen::DisplayManager::GetInstance().GetDefaultDisplayId(); baseOp->SetDisplayId(displayId); - // baseOp->SetWindowZOrder(Rosen::WindowZOrder::TOP_MOST); - // baseOp->SetVisible(true); - SELECTION_HILOGE("After SetWindowRect"); sptr window = Rosen::Window::Create("Demo_SSW_BaseWindow", baseOp, nullptr); if (!window) { SELECTION_HILOGE("Window creation failed"); return ErrorCode::NO_ERROR; } - SELECTION_HILOGE("After Window::Create"); - auto error = window->Show(); - if (error != WMError::WM_OK) { - SELECTION_HILOGE("After Window::Show, error=%{public}d, WM_ERROR_INVALID_PARAM=%d", error, WM_ERROR_INVALID_PARAM); - } - // window->SetWindowFocus(); - // window->RaiseToTop(); - SELECTION_HILOGE("After Window::Show"); - return ErrorCode::NO_ERROR; + window_ = window; + SELECTION_HILOGI("Window::Create Success"); + return 0; } std::string SelectionPanel::GeneratePanelName() { uint32_t sequenceId = GenerateSequenceId(); - std::string windowName = panelType_ == SOFT_KEYBOARD ? "softKeyboard" + std::to_string(sequenceId) ://panelType类型:softKeyboard、statusBar + std::string windowName = panelType_ == SOFT_KEYBOARD ? "softKeyboard" + std::to_string(sequenceId) : "statusBar" + std::to_string(sequenceId); SELECTION_HILOGD("SelectionPanel, windowName: %{public}s.", windowName.c_str()); return windowName; } -int32_t SelectionPanel::SetPanelProperties()//设置输入面板属性,根据面板类型和标志来配置窗口的位置属性 +int32_t SelectionPanel::SetPanelProperties() { if (window_ == nullptr) { SELECTION_HILOGE("window is nullptr!"); return ErrorCode::ERROR_OPERATE_PANEL; } - WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT;//浮动位置 - if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) {//软键盘+固定 + WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT; + if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) { gravity = WindowGravity::WINDOW_GRAVITY_BOTTOM; - } else if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FLOATING) {//软键盘+浮动 + } else if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FLOATING) { auto surfaceNode = window_->GetSurfaceNode(); if (surfaceNode == nullptr) { SELECTION_HILOGE("surfaceNode is nullptr!"); @@ -139,7 +125,7 @@ int32_t SelectionPanel::SetPanelProperties()//设置输入面板属性,根据 } surfaceNode->SetFrameGravity(Rosen::Gravity::TOP_LEFT); Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction(); - } else if (panelType_ == STATUS_BAR) {//状态栏面板 + } else if (panelType_ == STATUS_BAR) { auto surfaceNo = window_->GetSurfaceNode(); if (surfaceNo == nullptr) { SELECTION_HILOGE("surfaceNo is nullptr!"); @@ -149,7 +135,7 @@ int32_t SelectionPanel::SetPanelProperties()//设置输入面板属性,根据 Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction(); return ErrorCode::NO_ERROR; } - if (!isScbEnable_) {//非场景模式的重力设置------是什么东西,划词需要吗 + if (!isScbEnable_) { WMError wmError = window_->SetWindowGravity(gravity, invalidGravityPercent); if (wmError != WMError::WM_OK) { SELECTION_HILOGE("failed to set window gravity, wmError is %{public}d, start destroy window!", wmError); @@ -157,7 +143,7 @@ int32_t SelectionPanel::SetPanelProperties()//设置输入面板属性,根据 } return ErrorCode::NO_ERROR; } - keyboardLayoutParams_.gravity_ = gravity;//场景模式 + keyboardLayoutParams_.gravity_ = gravity; auto ret = window_->AdjustKeyboardLayout(keyboardLayoutParams_); if (ret != WMError::WM_OK) { SELECTION_HILOGE("SetWindowGravity failed, wmError is %{public}d, start destroy window!", ret); @@ -166,6 +152,21 @@ int32_t SelectionPanel::SetPanelProperties()//设置输入面板属性,根据 return ErrorCode::NO_ERROR; } +int32_t SelectionPanel::DestroyPanel() +{ + auto ret = HidePanel(); + if (ret != ErrorCode::NO_ERROR) { + SELECTION_HILOGE("SelectionPanel, hide panel failed, ret: %{public}d!", ret); + } + if (window_ == nullptr) { + SELECTION_HILOGE("window_ is nullptr!"); + return ErrorCode::ERROR_NULL_POINTER; + } + auto result = window_->Destroy(); + SELECTION_HILOGI("destroy ret: %{public}d", result); + return ErrorCode::NO_ERROR; +} + uint32_t SelectionPanel::GenerateSequenceId() { uint32_t seqId = ++sequenceId_; @@ -175,11 +176,6 @@ uint32_t SelectionPanel::GenerateSequenceId() return seqId; } -// void SelectionPanel::SetPanelHeightCallback(CallbackFunc heightCallback) -// { -// panelHeightCallback_ = std::move(heightCallback); -// } - int32_t SelectionPanel::SetUiContent(const std::string &contentInfo, napi_env env) { if (window_ == nullptr) { @@ -198,6 +194,11 @@ int32_t SelectionPanel::SetUiContent(const std::string &contentInfo, napi_env en return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR; } +PanelType SelectionPanel::GetPanelType() +{ + return panelType_; +} + int32_t SelectionPanel::ShowPanel() { SELECTION_HILOGD("SelectionPanel start."); diff --git a/frameworks/native/selection_ability/src/tasks/task.cpp b/frameworks/native/selection_ability/src/tasks/task.cpp index 32ecc7c..b75bc06 100644 --- a/frameworks/native/selection_ability/src/tasks/task.cpp +++ b/frameworks/native/selection_ability/src/tasks/task.cpp @@ -14,8 +14,6 @@ */ #include "tasks/task.h" - -// #include "global.h" #include "selection_log.h" namespace OHOS { -- Gitee From f4de8443c7cee1bd4e7aa01f528dc7ac4d6384f8 Mon Sep 17 00:00:00 2001 From: lixiaojuan Date: Tue, 3 Jun 2025 17:42:01 +0800 Subject: [PATCH 48/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=9B=B4=E6=96=B0maste?= =?UTF-8?q?r=E5=90=8Eselection=5Ffwk=E9=93=BE=E6=8E=A5=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98;=E5=A2=9E=E5=8A=A0moveTo=E7=BB=91?= =?UTF-8?q?=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- frameworks/js/napi/selection_ability/BUILD.gn | 1 + frameworks/js/napi/selection_ability/js_panel.cpp | 2 ++ frameworks/native/selection_ability/BUILD.gn | 1 + frameworks/native/selection_ability/src/selection_panel.cpp | 1 + 4 files changed, 5 insertions(+) diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 225f1fe..54cbc3e 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -67,6 +67,7 @@ ohos_shared_library("selectionengine_napi") { "resource_management:global_resmgr", "ability_runtime:app_context", "ffrt:libffrt", + "graphic_2d:librender_service_base", "graphic_2d:librender_service_client", "graphic_2d:window_animation", ] diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 14b5b44..2bb0c85 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -47,6 +47,7 @@ napi_value JsPanel::Init(napi_env env) DECLARE_NAPI_FUNCTION("show", Show), DECLARE_NAPI_FUNCTION("hide", Hide), DECLARE_NAPI_FUNCTION("startMoving", StartMoving), + DECLARE_NAPI_FUNCTION("moveTo", MoveTo), }; NAPI_CALL(env, napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), JsNew, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor)); @@ -230,6 +231,7 @@ napi_value JsPanel::StartMoving(napi_env env, napi_callback_info info) napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info) { + SELECTION_HILOGD("moveto start!"); auto ctxt = std::make_shared(env, info); auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { napi_status status = napi_generic_failure; diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn index 6803b4c..326dc15 100644 --- a/frameworks/native/selection_ability/BUILD.gn +++ b/frameworks/native/selection_ability/BUILD.gn @@ -94,6 +94,7 @@ ohos_shared_library("selection_ability") { "bundle_framework:appexecfwk_base", "config_policy:configpolicy_util", "eventhandler:libeventhandler", + "graphic_2d:librender_service_base", "graphic_2d:librender_service_client", "graphic_2d:window_animation", "input:libmmi-client", diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index 85d964b..a8cfd84 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -313,6 +313,7 @@ int32_t SelectionPanel::StartMoving() int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) { + SELECTION_HILOGD("moveto start!"); if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); return ErrorCode::ERROR_NULL_POINTER; -- Gitee From d8b7cad9b2937153545bfd7bfec4b06215b253e4 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Wed, 4 Jun 2025 15:46:29 +0800 Subject: [PATCH 49/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0panel=20on('show')?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/event_checker.cpp | 3 +- common/event_checker.h | 1 + .../js/napi/selection_ability/js_panel.cpp | 55 ++++++++++++++++++- .../js/napi/selection_ability/js_panel.h | 2 + .../selection_ability/panel_listener_impl.cpp | 25 +++++++++ .../selection_ability/panel_listener_impl.h | 2 + .../include/selection_panel.h | 2 + .../selection_ability/src/selection_panel.cpp | 36 ++++++++++++ .../src/js_selection_extension.cpp | 6 +- 9 files changed, 129 insertions(+), 3 deletions(-) diff --git a/common/event_checker.cpp b/common/event_checker.cpp index bdbc5e4..0dd1e5c 100644 --- a/common/event_checker.cpp +++ b/common/event_checker.cpp @@ -19,7 +19,8 @@ namespace OHOS { namespace SelectionFwk { const std::unordered_set EVENT_TYPES[static_cast(EventSubscribeModule::MODULE_END)] = { - [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionEvent", "selectionPanelEvent" } + [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionEvent", "selectionPanelEvent" }, + [static_cast(EventSubscribeModule::PANEL)] = { "show", "hide"} }; bool EventChecker::IsValidEventType(EventSubscribeModule module, const std::string &type) diff --git a/common/event_checker.h b/common/event_checker.h index 85a335e..82113c3 100644 --- a/common/event_checker.h +++ b/common/event_checker.h @@ -22,6 +22,7 @@ namespace SelectionFwk { enum class EventSubscribeModule : uint32_t { MODULE_BEGIN = 0, SELECTION_METHOD_ABILITY, + PANEL, MODULE_END, }; class EventChecker { diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 2bb0c85..5a47ac8 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -22,6 +22,7 @@ #include "js_utils.h" #include "selectionmethod_trace.h" #include "selection_ability.h" +#include "event_checker.h" namespace OHOS { namespace SelectionFwk { @@ -31,6 +32,7 @@ const std::string JsPanel::CLASS_NAME = "Panel"; thread_local napi_ref JsPanel::panelConstructorRef_ = nullptr; std::mutex JsPanel::panelConstructorMutex_; FFRTBlockQueue JsPanel::jsQueue_{ MAX_WAIT_TIME }; +constexpr size_t ARGC_MAX = 6; napi_value JsPanel::Init(napi_env env) { @@ -48,6 +50,7 @@ napi_value JsPanel::Init(napi_env env) DECLARE_NAPI_FUNCTION("hide", Hide), DECLARE_NAPI_FUNCTION("startMoving", StartMoving), DECLARE_NAPI_FUNCTION("moveTo", MoveTo), + DECLARE_NAPI_FUNCTION("on", Subscribe) }; NAPI_CALL(env, napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), JsNew, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor)); @@ -252,7 +255,7 @@ napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info) jsQueue_.Wait(ctxt->info); PrintEditorQueueInfoIfTimeout(start, ctxt->info); if (ctxt->selectionPanel == nullptr) { - SELECTION_HILOGE("inputMethodPanel_ is nullptr!"); + SELECTION_HILOGE("selectionPanel is nullptr!"); jsQueue_.Pop(); return; } @@ -283,5 +286,55 @@ void JsPanel::PrintEditorQueueInfoIfTimeout(int64_t start, const JsEventInfo &cu } } +napi_value JsPanel::Subscribe(napi_env env, napi_callback_info info) +{ + SELECTION_HILOGD("JsPanel start."); + size_t argc = ARGC_MAX; + napi_value argv[ARGC_MAX] = {nullptr}; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + std::string type; + // 2 means least param num. + if (argc < 2 || !JsUtil::GetValue(env, argv[0], type) || + !EventChecker::IsValidEventType(EventSubscribeModule::PANEL, type) || + JsUtil::GetType(env, argv[1]) != napi_function) { + SELECTION_HILOGE("subscribe failed, type: %{public}s!", type.c_str()); + return nullptr; + } + SELECTION_HILOGD("subscribe type: %{public}s.", type.c_str()); + std::shared_ptr observer = PanelListenerImpl::GetInstance(); + auto selectionPanel = UnwrapPanel(env, thisVar); + if (selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr!"); + return nullptr; + } + // 1 means the second param callback. + std::shared_ptr cbObject = std::make_shared( + env, argv[1], std::this_thread::get_id(), AppExecFwk::EventHandler::Current()); + observer->Subscribe(selectionPanel->windowId_, type, cbObject); + bool ret = selectionPanel->SetPanelStatusListener(observer, type); + if (!ret) { + SELECTION_HILOGE("failed to subscribe %{public}s!", type.c_str()); + observer->RemoveInfo(type, selectionPanel->windowId_); + } + napi_value result = nullptr; + napi_get_undefined(env, &result); + return result; +} + +std::shared_ptr JsPanel::UnwrapPanel(napi_env env, napi_value thisVar) +{ + void *native = nullptr; + napi_status status = napi_unwrap(env, thisVar, &native); + CHECK_RETURN((status == napi_ok && native != nullptr), "failed to unwrap!", nullptr); + auto jsPanel = reinterpret_cast(native); + if (jsPanel == nullptr) { + return nullptr; + } + auto selectionPanel = jsPanel->GetNative(); + CHECK_RETURN(selectionPanel != nullptr, "SelectionPanel is nullptr", nullptr); + return selectionPanel; +} + } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index 0591984..79c909a 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -61,6 +61,7 @@ public: static napi_value Hide(napi_env env, napi_callback_info info); static napi_value StartMoving(napi_env env, napi_callback_info info); static napi_value MoveTo(napi_env env, napi_callback_info info); + static napi_value Subscribe(napi_env env, napi_callback_info info); void SetNative(const std::shared_ptr &panel); std::shared_ptr GetNative(); private: @@ -107,6 +108,7 @@ private: }; static napi_value JsNew(napi_env env, napi_callback_info info); + static std::shared_ptr UnwrapPanel(napi_env env, napi_value thisVar); static void PrintEditorQueueInfoIfTimeout(int64_t start, const JsEventInfo ¤tInfo); static const std::string CLASS_NAME; static thread_local napi_ref panelConstructorRef_; diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp index fef87ff..75d9a3f 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -188,5 +188,30 @@ bool JsKeyboardArea::Read(napi_env env, napi_value jsObject, PanelAdjustInfo &na ret = ret && SelectionFwk::JsUtil::Object::ReadProperty(env, jsObject, "right", nativeObject.right); return ret; } + +void PanelListenerImpl::Subscribe(uint32_t windowId, const std::string &type, + std::shared_ptr cbObject) +{ + callbacks_.Compute(windowId, + [cbObject, &type](auto windowId, std::map> &cbs) { + auto [it, insert] = cbs.try_emplace(type, cbObject); + if (insert) { + SELECTION_HILOGI("start to subscribe type: %{public}s of windowId: %{public}u.", type.c_str(), windowId); + } else { + SELECTION_HILOGD("type: %{public}s of windowId: %{public}u already subscribed.", type.c_str(), windowId); + } + return !cbs.empty(); + }); +} + +void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId) +{ + callbacks_.ComputeIfPresent(windowId, + [&type](auto windowId, std::map> &cbs) { + cbs.erase(type); + return !cbs.empty(); + }); +} + } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.h b/frameworks/js/napi/selection_ability/panel_listener_impl.h index 81c08c2..6332d3e 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.h +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.h @@ -66,6 +66,8 @@ struct UvEntry { void OnSizeChange(uint32_t windowId, const WindowSize &size) override; void OnSizeChange(uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) override; + void Subscribe(uint32_t windowId, const std::string &type, std::shared_ptr cbObject); + void RemoveInfo(const std::string &type, uint32_t windowId); std::shared_ptr GetCallback(uint32_t windowId, const std::string &type); diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 590878f..ac8aac5 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -50,6 +50,7 @@ public: PanelType GetPanelType(); bool IsShowing(); bool IsHidden(); + bool SetPanelStatusListener(std::shared_ptr statusListener, const std::string &type); uint32_t windowId_ = INVALID_WINDOW_ID; @@ -58,6 +59,7 @@ private: int32_t SetPanelProperties(); static uint32_t GenerateSequenceId(); void PanelStatusChange(const SelectionWindowStatus &status); + bool MarkListener(const std::string &type, bool isRegister); PanelType panelType_ = PanelType::STATUS_BAR; PanelFlag panelFlag_ = PanelFlag::FLG_FIXED; diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index a8cfd84..85e1751 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -327,5 +327,41 @@ int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR; } +bool SelectionPanel::SetPanelStatusListener(std::shared_ptr statusListener, const std::string &type) +{ + if (!MarkListener(type, true)) { + return false; + } + SELECTION_HILOGD("type: %{public}s.", type.c_str()); + if (type == "show" || type == "hide") { + if (panelStatusListener_ == nullptr) { + SELECTION_HILOGD("panelStatusListener_ is nullptr, need to be set"); + panelStatusListener_ = std::move(statusListener); + } + if (window_ != nullptr) { + if (type == "show" && IsShowing()) { + panelStatusListener_->OnPanelStatus(windowId_, true); + } + if (type == "hide" && IsHidden()) { + panelStatusListener_->OnPanelStatus(windowId_, false); + } + } + } + return true; +} + +bool SelectionPanel::MarkListener(const std::string &type, bool isRegister) +{ + if (type == "show") { + showRegistered_ = isRegister; + } else if (type == "hide") { + hideRegistered_ = isRegister; + } else { + SELECTION_HILOGE("type error!"); + return false; + } + return true; +} + } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index a2eb2f2..7421ed2 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -154,7 +154,11 @@ void JsSelectionExtension::OnDisconnect(const AAFwk::Want& want) HILOG_INFO("%{public}s end.", __func__); } -void JsSelectionExtension::OnStop() {} +void JsSelectionExtension::OnStop() +{ + HILOG_INFO("%{public}s start.", __func__); + SelectionExtension::OnStop(); +} napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const napi_value* argv, size_t argc) { -- Gitee From 7ef986db88bb3294d5cc1434b60833265745527b Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Wed, 4 Jun 2025 17:24:51 +0800 Subject: [PATCH 50/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0unittest=E6=A1=86?= =?UTF-8?q?=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- bundle.json | 5 +- service/BUILD.gn | 3 +- service/include/selection_input_monitor.h | 100 +++++ service/include/selection_service.h | 72 --- service/src/selection_input_monitor.cpp | 423 ++++++++++++++++++ service/src/selection_service.cpp | 375 +--------------- test/unittest/BUILD.gn | 49 ++ .../unittest/selection_input_monitor_test.cpp | 95 ++++ 8 files changed, 687 insertions(+), 435 deletions(-) create mode 100644 service/include/selection_input_monitor.h create mode 100644 service/src/selection_input_monitor.cpp create mode 100644 test/unittest/BUILD.gn create mode 100644 test/unittest/selection_input_monitor_test.cpp diff --git a/bundle.json b/bundle.json index 0171f57..9a12f60 100644 --- a/bundle.json +++ b/bundle.json @@ -56,7 +56,10 @@ "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionengine_napi", "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_ability:selection_ability" ], - "inner_kits": [] + "inner_kits": [], + "test": [ + "//foundation/systemabilitymgr/selection_fwk/test/unittest:selection_service_unit_test" + ] } } } \ No newline at end of file diff --git a/service/BUILD.gn b/service/BUILD.gn index 1f8d5c4..b3a92dd 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -59,12 +59,11 @@ ohos_source_set("selection_service_proxy") { ohos_shared_library("selection_service") { configs = [ ":selection_sa_config", ] - shlib_type = "sa" - version_script = "libselection_service.map" output_values = get_target_outputs(":selection_service_interface") sources = [ "src/selection_service.cpp", + "src/selection_input_monitor.cpp", ] sources += filter_include(output_values, [ "*.cpp" ]) deps = [ diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h new file mode 100644 index 0000000..2464db3 --- /dev/null +++ b/service/include/selection_input_monitor.h @@ -0,0 +1,100 @@ +/* + * 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 SELECTION_INPUT_MONITOR_H +#define SELECTION_INPUT_MONITOR_H + +#include +#include + +namespace OHOS::SelectionFwk { +using namespace MMI; + +constexpr const uint32_t DOUBLE_CLICK_TIME = 500; + +typedef enum { + SELECT_INPUT_INITIAL = 0, + SELECT_INPUT_WORD_BEGIN = 1, + SELECT_INPUT_WAIT_LEFT_MOVE = 2, + SELECT_INPUT_LEFT_MOVE = 3, + SELECT_INPUT_WAIT_DOUBLE_CLICK = 4, + SELECT_INPUT_WAIT_TRIPLE_CLICK = 5, + SELECT_INPUT_DOUBLE_CLICKED = 6, + SELECT_INPUT_TRIPLE_CLICKED = 7, +} SelectInputState; + +typedef enum { + SUB_INITIAL = 0, + SUB_WAIT_POINTER_ACTION_BUTTON_DOWN = 1, + SUB_WAIT_POINTER_ACTION_BUTTON_UP = 2, + SUB_WAIT_KEY_CTRL_DOWN = 3, + SUB_WAIT_KEY_CTRL_UP = 4, +} SelectInputSubState; + +class SelectionEventListener { +public: + virtual void OnTextSelected() { + }; + virtual ~SelectionEventListener() = default; +}; + +class DefaultSelectionEventListener : public SelectionEventListener { +public: + virtual void OnTextSelected(); + +private: + void InjectCtrlC(); + void SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction); +}; + +class SelectionInputMonitor : public IInputEventConsumer { +public: + SelectionInputMonitor() + : selectionEventListener_(std::make_shared()) { + } + + SelectionInputMonitor(std::shared_ptr selectionEventListener) + : selectionEventListener_(selectionEventListener) { + } + + virtual void OnInputEvent(std::shared_ptr keyEvent) const; + virtual void OnInputEvent(std::shared_ptr pointerEvent) const; + virtual void OnInputEvent(std::shared_ptr axisEvent) const; + +public: + static bool ctrlSelectFlag; + static bool lastTextSelectedFlag; + +private: + void InputInitialProcess(std::shared_ptr pointerEvent) const; + void InputWordBeginProcess(std::shared_ptr pointerEvent) const; + void InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const; + void InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const; + void InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const; + void InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const; + void FinishedWordSelection() const; + void ResetProcess(std::shared_ptr pointerEvent) const; + void JudgeTripleClick() const; + bool IsTextSelected() const; + + static uint32_t curSelectState; + static uint32_t subSelectState; + static int64_t lastClickTime; + + std::shared_ptr selectionEventListener_; +}; +} + +#endif // SELECTION_INPUT_MONITOR_H \ No newline at end of file diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 1915d5b..41f24f7 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -34,26 +34,6 @@ constexpr const char *SYS_SELECTION_SWITCH_USERNAM = "persist.sys.selection.swit constexpr const char *SYS_SELECTION_TRIGGER_USERNAM = "persist.sys.selection.trigger.username"; constexpr const char *SYS_SELECTION_APP_USERNAM = "persist.sys.selection.app.username"; constexpr const char *SYS_SELECTION_TRIGGER_VAL = "ctrl"; -constexpr const uint32_t DOUBLE_CLICK_TIME = 500; - -typedef enum { - SELECT_INPUT_INITIAL = 0, - SELECT_INPUT_WORD_BEGIN = 1, - SELECT_INPUT_WAIT_LEFT_MOVE = 2, - SELECT_INPUT_LEFT_MOVE = 3, - SELECT_INPUT_WAIT_DOUBLE_CLICK = 4, - SELECT_INPUT_WAIT_TRIPLE_CLICK = 5, - SELECT_INPUT_DOUBLE_CLICKED = 6, - SELECT_INPUT_TRIPLE_CLICKED = 7, -} SelectInputState; - -typedef enum { - SUB_INITIAL = 0, - SUB_WAIT_POINTER_ACTION_BUTTON_DOWN = 1, - SUB_WAIT_POINTER_ACTION_BUTTON_UP = 2, - SUB_WAIT_KEY_CTRL_DOWN = 3, - SUB_WAIT_KEY_CTRL_UP = 4, -} SelectInputSubState; class SelectionExtensionAbilityConnection : public OHOS::AAFwk::AbilityConnectionStub { public: @@ -99,58 +79,6 @@ private: sptr listenerStub_ { nullptr }; sptr connectInner_ {nullptr}; }; - -class SelectionEventListener { -public: - virtual void OnTextSelected() { - }; - virtual ~SelectionEventListener() = default; -}; - -class DefaultSelectionEventListener : public SelectionEventListener { -public: - virtual void OnTextSelected(); - -private: - void InjectCtrlC() const; -}; - -class SelectionInputMonitor : public IInputEventConsumer { -public: - SelectionInputMonitor() - : selectionEventListener_(std::make_shared()) { - } - - SelectionInputMonitor(std::shared_ptr selectionEventListener) - : selectionEventListener_(selectionEventListener) { - } - - bool IsTextSelected() const; - - virtual void OnInputEvent(std::shared_ptr keyEvent) const; - virtual void OnInputEvent(std::shared_ptr pointerEvent) const; - virtual void OnInputEvent(std::shared_ptr axisEvent) const; - -public: - static bool ctrlSelectFlag; - -private: - void InputInitialProcess(std::shared_ptr pointerEvent) const; - void InputWordBeginProcess(std::shared_ptr pointerEvent) const; - void InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const; - void InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const; - void InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const; - void InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const; - void FinishedWordSelection() const; - void ResetProcess(std::shared_ptr pointerEvent) const; - void JudgeTripleClick() const; - - static uint32_t curSelectState; - static uint32_t subSelectState; - static int64_t lastClickTime; - - std::shared_ptr selectionEventListener_; -}; } #endif // SELECTION_SERVICE_H \ No newline at end of file diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp new file mode 100644 index 0000000..069ca1d --- /dev/null +++ b/service/src/selection_input_monitor.cpp @@ -0,0 +1,423 @@ +/* + * 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 "selection_service.h" + +#include "selection_log.h" +#include +#include "common_event_manager.h" +#include "selection_input_monitor.h" +#include "screenlock_manager.h" + +using namespace OHOS; +using namespace OHOS::SelectionFwk; +using namespace OHOS::AppExecFwk; +using namespace OHOS::MMI; +using namespace OHOS::EventFwk; + +uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; +uint32_t SelectionInputMonitor::subSelectState = SUB_INITIAL; +int64_t SelectionInputMonitor::lastClickTime = 0; +bool SelectionInputMonitor::ctrlSelectFlag = false; +bool SelectionInputMonitor::lastTextSelectedFlag = false; + + +static int64_t GetCurrentTimeMillis() { + auto now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + return std::chrono::duration_cast(duration).count(); +} + +void DefaultSelectionEventListener::OnTextSelected() +{ + SELECTION_HILOGI("End word selection action."); + InjectCtrlC(); + SELECTION_HILOGI("End Inject Ctrl + C."); + sptr listener = SelectionService::GetInstance()->GetListener(); + if (listener == nullptr) { + SELECTION_HILOGE("get listener is null"); + return; + } + SelectionDataInner data; + data.text = "Hello, world!"; + data.cursorStartPos = 0; + data.cursorEndPos = 13; + data.windowId = 1001; + data.bundleID = 2002; + listener->OnSelectionChange(data); + return; +} + +bool SelectionInputMonitor::IsTextSelected() const { + if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_DOUBLE_CLICKED && + curSelectState != SELECT_INPUT_TRIPLE_CLICKED) { + return false; + } + return true; +} + +void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const +{ + if (!ctrlSelectFlag) { + return; + } + + if (subSelectState != SUB_WAIT_KEY_CTRL_DOWN && subSelectState != SUB_WAIT_KEY_CTRL_UP) { + return; + } + + int32_t keyCode = keyEvent->GetKeyCode(); + int32_t action = keyEvent->GetKeyAction(); + if (keyCode != KeyEvent::KEYCODE_CTRL_LEFT && keyCode != KeyEvent::KEYCODE_CTRL_RIGHT) { + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); + return; + } + SELECTION_HILOGI("[SelectionService] Processed ctrl key."); + if (subSelectState == SUB_WAIT_KEY_CTRL_DOWN && action == KeyEvent::KEY_ACTION_DOWN) { + subSelectState = SUB_WAIT_KEY_CTRL_UP; + return; + } + + if (subSelectState == SUB_WAIT_KEY_CTRL_UP && action == KeyEvent::KEY_ACTION_UP) { + if (curSelectState == SELECT_INPUT_WAIT_LEFT_MOVE) { + curSelectState = SELECT_INPUT_LEFT_MOVE; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); + } else if (curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK) { + curSelectState = SELECT_INPUT_DOUBLE_CLICKED; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); + } else if (curSelectState == SELECT_INPUT_WAIT_TRIPLE_CLICK) { + curSelectState = SELECT_INPUT_TRIPLE_CLICKED; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); + } + subSelectState = SUB_INITIAL; + } else { + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); + } + FinishedWordSelection(); + return; +} + +void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const +{ + bool screenLockedFlag = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); + if (screenLockedFlag) { + SELECTION_HILOGD("It is not screen on."); + return; + } + // SELECTION_HILOGI("pointerEvent->windowId: %{public}d", pointerEvent->GetTargetWindowId()); + int32_t pointerId = pointerEvent->GetPointerId(); + PointerEvent::PointerItem pointerItem; + pointerEvent->GetPointerItem(pointerId, pointerItem); + // SELECTION_HILOGI("pointerItem, display: %{public}d, %{public}d, \ + // RawDxy: %{public}d, %{public}d. \ + // windows: %{public}d, %{public}d, windowId: %{public}d, deviceId: %{public}d", + // pointerItem.GetDisplayX(),pointerItem.GetDisplayY(), + // pointerItem.GetRawDx(),pointerItem.GetRawDy(), + // pointerItem.GetWindowX(), pointerItem.GetWindowY(), + // pointerItem.GetTargetWindowId(), pointerItem.GetDeviceId()); + if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { + // SELECTION_HILOGI("[SelectionService] into PointerEvent, pointerId = %{public}d. curSelectState: %{public}d", + // pointerId, curSelectState); + return; + } + SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); + + switch (curSelectState) + { + case SELECT_INPUT_INITIAL: + InputInitialProcess(pointerEvent); + break; + + case SELECT_INPUT_WORD_BEGIN: + InputWordBeginProcess(pointerEvent); + break; + + case SELECT_INPUT_WAIT_LEFT_MOVE: + InputWordWaitLeftMoveProcess(pointerEvent); + break; + + case SELECT_INPUT_WAIT_DOUBLE_CLICK: + InputWordWaitDoubleClickProcess(pointerEvent); + break; + + case SELECT_INPUT_DOUBLE_CLICKED: + InputWordJudgeTripleClickProcess(pointerEvent); + break; + + case SELECT_INPUT_WAIT_TRIPLE_CLICK: + InputWordWaitTripleClickProcess(pointerEvent); + break; + + default: + break; + } + + FinishedWordSelection(); + return; +} + +void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const +{ + SELECTION_HILOGI("[SelectionService] into axisEvent"); +}; + +void SelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const +{ + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + OnInputEvent(pointerEvent); +} + +void SelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + int32_t buttonId = pointerEvent->GetButtonId(); + if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && buttonId == PointerEvent::MOUSE_BUTTON_LEFT) { + curSelectState = SELECT_INPUT_WORD_BEGIN; + subSelectState = SUB_INITIAL; + lastClickTime = GetCurrentTimeMillis(); + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); + } + return; +} + +void SelectionInputMonitor::InputWordBeginProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (action == PointerEvent::POINTER_ACTION_MOVE) { + curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); + } else if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + curSelectState = SELECT_INPUT_WAIT_DOUBLE_CLICK; + subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_DOWN; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_DOUBLE_CLICK."); + } + return; +} + +void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + if (ctrlSelectFlag) { + subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); + } else { + curSelectState = SELECT_INPUT_LEFT_MOVE; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_LEFT_MOVE."); + } + } else if (action != PointerEvent::POINTER_ACTION_MOVE) { + SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); + ResetProcess(pointerEvent); + } + return; +} + +void SelectionInputMonitor::JudgeTripleClick() const +{ + auto curTime = GetCurrentTimeMillis(); + if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { + curSelectState = SELECT_INPUT_WAIT_TRIPLE_CLICK; + subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_TRIPLE_CLICK."); + } else { + curSelectState = SELECT_INPUT_WORD_BEGIN; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); + } + lastClickTime = curTime; +} + +void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + auto curTime = GetCurrentTimeMillis(); + if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { + subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_POINTER_ACTION_BUTTON_UP."); + } else { + curSelectState = SELECT_INPUT_WORD_BEGIN; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); + } + lastClickTime = curTime; + return; + } + if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_UP) { + if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + if (ctrlSelectFlag) { + subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); + } else { + curSelectState = SELECT_INPUT_DOUBLE_CLICKED; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_DOUBLE_CLICKED."); + } + } else if (action == PointerEvent::POINTER_ACTION_MOVE) { + curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); + } + return; + } + if (subSelectState == SUB_WAIT_KEY_CTRL_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + JudgeTripleClick(); + } + return; +} + +void SelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (subSelectState == SUB_INITIAL && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + SELECTION_HILOGI("Begin JudgeTripleClick."); + JudgeTripleClick(); + } else { + SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); + ResetProcess(pointerEvent); + } +} + +void SelectionInputMonitor::InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const +{ + int32_t action = pointerEvent->GetPointerAction(); + if (subSelectState != SUB_WAIT_POINTER_ACTION_BUTTON_UP) { + return; + } + if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { + if (ctrlSelectFlag) { + subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); + } else { + curSelectState = SELECT_INPUT_TRIPLE_CLICKED; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_TRIPLE_CLICKED."); + } + } else if (action == PointerEvent::POINTER_ACTION_MOVE) { + curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); + } else { + SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); + ResetProcess(pointerEvent); + } + return; +} + +void SelectionInputMonitor::FinishedWordSelection() const +{ + if (!IsTextSelected()) { + lastTextSelectedFlag = false; + return; + } + lastTextSelectedFlag = true; + // world selection action + if (curSelectState != SELECT_INPUT_DOUBLE_CLICKED) { + curSelectState = SELECT_INPUT_INITIAL; + SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); + } + + selectionEventListener_->OnTextSelected(); +} + +void DefaultSelectionEventListener::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) +{ + auto KeyEvent = KeyEvent::Create(); + KeyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + KeyEvent->SetKeyAction(keyAction); + KeyEvent::KeyItem item1, item2; + item1.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); + item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + item2.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); + item2.SetKeyCode(keyCode); + KeyEvent->AddKeyItem(item1); + KeyEvent->AddKeyItem(item2); + InputManager::GetInstance()->SimulateInputEvent(KeyEvent); +} + +void DefaultSelectionEventListener::InjectCtrlC() +{ + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + SimulateKeyWithCtrl(KeyEvent::KEYCODE_C, KeyEvent::KEY_ACTION_DOWN); + SimulateKeyWithCtrl(KeyEvent::KEYCODE_C, KeyEvent::KEY_ACTION_UP); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + // // 创建KeyEvent对象 + // auto keyEvent1 = KeyEvent::Create(); + + // // 设置Ctrl键按下 + // int deviceId = 100; + // int downTime = 104329296; + // keyEvent1->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + // keyEvent1->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // keyEvent1->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + // keyEvent1->SetDeviceId(deviceId); + // KeyEvent::KeyItem item1; + // item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // item1.SetPressed(true); + // item1.SetDeviceId(deviceId); + // item1.SetDownTime(downTime); + // keyEvent1->AddKeyItem(item1); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent1); + + // // 设置C键按下 + // auto keyEvent2 = KeyEvent::Create(); + // keyEvent2->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + // keyEvent2->SetKeyCode(KeyEvent::KEYCODE_C); + // keyEvent2->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + // keyEvent2->SetDeviceId(deviceId); + // KeyEvent::KeyItem item2; + // item2.SetKeyCode(KeyEvent::KEYCODE_C); + // item2.SetPressed(true); + // item2.SetDeviceId(deviceId); + // item2.SetUnicode(99); + // item2.SetDownTime(downTime); + // keyEvent2->AddKeyItem(item1); + // keyEvent2->AddKeyItem(item2); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent2); + + // // 设置C键释放 + // auto keyEvent3 = KeyEvent::Create(); + // keyEvent3->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + // keyEvent3->SetKeyCode(KeyEvent::KEYCODE_C); + // keyEvent3->SetKeyAction(KeyEvent::KEY_ACTION_UP); + // keyEvent3->SetDeviceId(deviceId); + // KeyEvent::KeyItem item3; + // item3.SetKeyCode(KeyEvent::KEYCODE_C); + // item3.SetPressed(false); + // item3.SetDeviceId(deviceId); + // item3.SetUnicode(99); + // item3.SetDownTime(downTime); + // keyEvent3->AddKeyItem(item1); + // keyEvent3->AddKeyItem(item3); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent3); + + // // 设置Ctrl键释放 + // auto keyEvent4 = KeyEvent::Create(); + // keyEvent4->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + // keyEvent4->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // keyEvent4->SetKeyAction(KeyEvent::KEY_ACTION_UP); + // keyEvent4->SetDeviceId(deviceId); + // KeyEvent::KeyItem item4; + // item4.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + // item4.SetPressed(false); + // item4.SetDeviceId(deviceId); + // item4.SetDownTime(downTime); + // keyEvent4->AddKeyItem(item4); + // InputManager::GetInstance()->SimulateInputEvent(keyEvent4); +} diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index e1e63b7..9614a03 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -24,10 +24,10 @@ #include "parameter.h" #include #include "common_event_manager.h" +#include "selection_input_monitor.h" #include "selection_interface.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" -#include "screenlock_manager.h" using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -39,11 +39,6 @@ const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(SelectionServ std::shared_mutex SelectionService::adminLock_; sptr SelectionService::instance_; -uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; -uint32_t SelectionInputMonitor::subSelectState = SUB_INITIAL; -int64_t SelectionInputMonitor::lastClickTime = 0; -bool SelectionInputMonitor::ctrlSelectFlag = false; - void SelectionExtensionAbilityConnection::OnAbilityConnectDone( const ElementName &element, const sptr &remoteObject, int resultCode) { @@ -130,12 +125,6 @@ int32_t SelectionService::Dump(int32_t fd, const std::vector &ar return OHOS::NO_ERROR; } -static int64_t GetCurrentTimeMillis() { - auto now = std::chrono::system_clock::now(); - auto duration = now.time_since_epoch(); - return std::chrono::duration_cast(duration).count(); -} - static void WatchParameterFunc(const char *key, const char *value, void *context) { (void)context; @@ -244,20 +233,20 @@ void SelectionService::InputMonitorInit() SELECTION_HILOGI("[SelectionService] input monitor init"); std::shared_ptr inputMonitor = std::make_shared( std::make_shared()); - if (inputMonitorId_ < 0) { - auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - auto remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); - while (remoteObj == nullptr) - { - SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID failed. wait..."); - sleep(1); - remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); - } - SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID succeed."); - inputMonitorId_ = - InputManager::GetInstance()->AddMonitor(std::static_pointer_cast(inputMonitor)); - SELECTION_HILOGI("[SelectionService] input monitor init end"); + if (inputMonitorId_ > 0) { + return; + } + + auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + auto remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); + while (remoteObj == nullptr) { + SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID failed. wait..."); + sleep(1); + remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); } + SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID succeed."); + inputMonitorId_ = InputManager::GetInstance()->AddMonitor(inputMonitor); + SELECTION_HILOGI("[SelectionService] input monitor init end"); } void SelectionService::InputMonitorCancel() @@ -276,338 +265,4 @@ void SelectionService::HandleKeyEvent(int32_t keyCode) void SelectionService::HandlePointEvent(int32_t type) { -} - -void DefaultSelectionEventListener::OnTextSelected() -{ - SELECTION_HILOGI("End word selection action."); - InjectCtrlC(); - SELECTION_HILOGI("End Inject Ctrl + C."); - // send selection data - sptr listener = SelectionService::GetInstance()->GetListener(); - if (listener == nullptr) { - SELECTION_HILOGE("get listener is null"); - return; - } - SelectionDataInner data; - data.text = "Hello, world!"; - data.cursorStartPos = 0; - data.cursorEndPos = 13; - data.windowId = 1001; - data.bundleID = 2002; - listener->OnSelectionChange(data); - return; -} - -bool SelectionInputMonitor::IsTextSelected() const { - if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_DOUBLE_CLICKED && - curSelectState != SELECT_INPUT_TRIPLE_CLICKED) { - return false; - } - return true; -} - -void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const -{ - if (!ctrlSelectFlag) { - return; - } - - if (subSelectState != SUB_WAIT_KEY_CTRL_DOWN && subSelectState != SUB_WAIT_KEY_CTRL_UP) { - return; - } - - int32_t keyCode = keyEvent->GetKeyCode(); - int32_t action = keyEvent->GetKeyAction(); - if (keyCode != KeyEvent::KEYCODE_CTRL_LEFT && keyCode != KeyEvent::KEYCODE_CTRL_RIGHT) { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); - return; - } - SELECTION_HILOGI("[SelectionService] Processed ctrl key."); - if (subSelectState == SUB_WAIT_KEY_CTRL_DOWN && action == KeyEvent::KEY_ACTION_DOWN) { - subSelectState = SUB_WAIT_KEY_CTRL_UP; - return; - } else if (subSelectState == SUB_WAIT_KEY_CTRL_UP && action == KeyEvent::KEY_ACTION_UP) { - if (curSelectState == SELECT_INPUT_WAIT_LEFT_MOVE) { - curSelectState = SELECT_INPUT_LEFT_MOVE; - SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); - } else if (curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK) { - curSelectState = SELECT_INPUT_DOUBLE_CLICKED; - SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); - } else if (curSelectState == SELECT_INPUT_WAIT_TRIPLE_CLICK) { - curSelectState = SELECT_INPUT_TRIPLE_CLICKED; - SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); - } - subSelectState = SUB_INITIAL; - } else { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); - } - FinishedWordSelection(); - return; -} - -void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const -{ - bool screenLockedFlag = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); - if (screenLockedFlag) { - SELECTION_HILOGD("It is not screen on."); - return; - } - int32_t pointerId = pointerEvent->GetPointerId(); - if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { - return; - } - SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); - - switch (curSelectState) - { - case SELECT_INPUT_INITIAL: - InputInitialProcess(pointerEvent); - break; - - case SELECT_INPUT_WORD_BEGIN: - InputWordBeginProcess(pointerEvent); - break; - - case SELECT_INPUT_WAIT_LEFT_MOVE: - InputWordWaitLeftMoveProcess(pointerEvent); - break; - - case SELECT_INPUT_WAIT_DOUBLE_CLICK: - InputWordWaitDoubleClickProcess(pointerEvent); - break; - - case SELECT_INPUT_DOUBLE_CLICKED: - InputWordJudgeTripleClickProcess(pointerEvent); - break; - - case SELECT_INPUT_WAIT_TRIPLE_CLICK: - InputWordWaitTripleClickProcess(pointerEvent); - break; - - default: - break; - } - - FinishedWordSelection(); - return; -} - -void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const -{ - SELECTION_HILOGI("[SelectionService] into axisEvent"); -}; - -void SelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const -{ - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - OnInputEvent(pointerEvent); -} - -void SelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const -{ - int32_t action = pointerEvent->GetPointerAction(); - int32_t buttonId = pointerEvent->GetButtonId(); - if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && buttonId == PointerEvent::MOUSE_BUTTON_LEFT) { - curSelectState = SELECT_INPUT_WORD_BEGIN; - subSelectState = SUB_INITIAL; - lastClickTime = GetCurrentTimeMillis(); - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); - } - return; -} - -void SelectionInputMonitor::InputWordBeginProcess(std::shared_ptr pointerEvent) const -{ - int32_t action = pointerEvent->GetPointerAction(); - if (action == PointerEvent::POINTER_ACTION_MOVE) { - curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); - } else if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { - curSelectState = SELECT_INPUT_WAIT_DOUBLE_CLICK; - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_DOWN; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_DOUBLE_CLICK."); - } - return; -} - -void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const -{ - int32_t action = pointerEvent->GetPointerAction(); - if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { - if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_KEY_CTRL_DOWN; - SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); - } else { - curSelectState = SELECT_INPUT_LEFT_MOVE; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_LEFT_MOVE."); - } - } else if (action != PointerEvent::POINTER_ACTION_MOVE) { - SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); - ResetProcess(pointerEvent); - } - return; -} - -void SelectionInputMonitor::JudgeTripleClick() const -{ - auto curTime = GetCurrentTimeMillis(); - if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { - curSelectState = SELECT_INPUT_WAIT_TRIPLE_CLICK; - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_TRIPLE_CLICK."); - } else { - curSelectState = SELECT_INPUT_WORD_BEGIN; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); - } - lastClickTime = curTime; -} - -void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const -{ - int32_t action = pointerEvent->GetPointerAction(); - if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { - auto curTime = GetCurrentTimeMillis(); - if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; - SELECTION_HILOGI("set subSelectState to SUB_WAIT_POINTER_ACTION_BUTTON_UP."); - } else { - curSelectState = SELECT_INPUT_WORD_BEGIN; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); - } - lastClickTime = curTime; - return; - } - if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_UP) { - if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { - if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_KEY_CTRL_DOWN; - SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); - } else { - curSelectState = SELECT_INPUT_DOUBLE_CLICKED; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_DOUBLE_CLICKED."); - } - } else if (action == PointerEvent::POINTER_ACTION_MOVE) { - curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); - } - return; - } - if (subSelectState == SUB_WAIT_KEY_CTRL_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { - JudgeTripleClick(); - } - return; -} - -void SelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const -{ - int32_t action = pointerEvent->GetPointerAction(); - if (subSelectState == SUB_INITIAL && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { - SELECTION_HILOGI("Begin JudgeTripleClick."); - JudgeTripleClick(); - } else { - SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); - ResetProcess(pointerEvent); - } -} - -void SelectionInputMonitor::InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const -{ - int32_t action = pointerEvent->GetPointerAction(); - if (subSelectState != SUB_WAIT_POINTER_ACTION_BUTTON_UP) { - return; - } - if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { - if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_KEY_CTRL_DOWN; - SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); - } else { - curSelectState = SELECT_INPUT_TRIPLE_CLICKED; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_TRIPLE_CLICKED."); - } - } else if (action == PointerEvent::POINTER_ACTION_MOVE) { - curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); - } else { - SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); - ResetProcess(pointerEvent); - } - return; -} - -void SelectionInputMonitor::FinishedWordSelection() const -{ - if (!IsTextSelected()) { - return; - } - // world selection action - if (curSelectState != SELECT_INPUT_DOUBLE_CLICKED) { - curSelectState = SELECT_INPUT_INITIAL; - SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); - } - - selectionEventListener_->OnTextSelected(); -} - -void DefaultSelectionEventListener::InjectCtrlC() const -{ - // 创建KeyEvent对象 - auto keyEvent1 = KeyEvent::Create(); - - // 设置Ctrl键按下 - keyEvent1->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - keyEvent1->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - keyEvent1->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // KeyEvent::KeyItem item1; - // item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // item1.SetPressed(true); - // item1.SetDownTime(500); - // keyEvent1->AddKeyItem(item1); - InputManager::GetInstance()->SimulateInputEvent(keyEvent1); - - // 设置C键按下 - auto keyEvent2 = KeyEvent::Create(); - keyEvent2->SetKeyCode(KeyEvent::KEYCODE_C); - keyEvent2->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - keyEvent2->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // KeyEvent::KeyItem item2; - // item2.SetKeyCode(KeyEvent::KEYCODE_C); - // item2.SetPressed(true); - // item2.SetDownTime(500); - // keyEvent2->AddKeyItem(item2); - InputManager::GetInstance()->SimulateInputEvent(keyEvent2); - - // 设置C键释放 - auto keyEvent3 = KeyEvent::Create(); - keyEvent3->SetKeyCode(KeyEvent::KEYCODE_C); - keyEvent3->SetKeyAction(KeyEvent::KEY_ACTION_UP); - keyEvent3->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // KeyEvent::KeyItem item3; - // item3.SetKeyCode(KeyEvent::KEYCODE_C); - // item3.SetPressed(true); - // item3.SetDownTime(500); - // keyEvent3->AddKeyItem(item3); - InputManager::GetInstance()->SimulateInputEvent(keyEvent3); - - // 设置Ctrl键释放 - auto keyEvent4 = KeyEvent::Create(); - keyEvent4->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - keyEvent4->SetKeyAction(KeyEvent::KEY_ACTION_UP); - keyEvent4->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // KeyEvent::KeyItem item4; - // item4.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // item4.SetPressed(true); - // item4.SetDownTime(500); - // keyEvent4->AddKeyItem(item4); - InputManager::GetInstance()->SimulateInputEvent(keyEvent4); -} +} \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn new file mode 100644 index 0000000..94024d4 --- /dev/null +++ b/test/unittest/BUILD.gn @@ -0,0 +1,49 @@ +# Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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/test.gni") +import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") + +module_out_path = "selection_fwk/selection_fwk" +ohos_unittest("selection_service_unit_test") { + module_out_path = module_out_path + include_dirs = [ + "./", + "${selection_fwk_root_path}/service/include", + "${selection_fwk_root_path}/utils/include", + ] + + sources = [ + "selection_input_monitor_test.cpp", + ] + deps = [ + "${selection_fwk_root_path}/service:selection_service", + ] + external_deps = [ + "ability_base:want", + "ability_runtime:ability_manager", + "c_utils:utils", + "googletest:gmock_main", + "googletest:gtest_main", + "napi:ace_napi", + "hilog:libhilog", + "ipc:ipc_single", + "init:libbeget_proxy", + "input:libmmi-client", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + "screenlock_mgr:screenlock_client", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp new file mode 100644 index 0000000..762ac11 --- /dev/null +++ b/test/unittest/selection_input_monitor_test.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022 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 "gtest/gtest.h" + +#define private public +#include "selection_input_monitor.h" +#include "screenlock_manager.h" + +namespace OHOS { +namespace SelectionFwk { + +using namespace testing::ext; + +class SelectionInputMonitorTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + std::shared_ptr inputMonitor = nullptr; +}; + +void SelectionInputMonitorTest::SetUpTestCase() +{ + std::cout << "SelectionInputMonitorTest SetUpTestCase" << std::endl; +} + +void SelectionInputMonitorTest::TearDownTestCase() +{ + std::cout << "SelectionInputMonitorTest TearDownTestCase" << std::endl; +} + +void SelectionInputMonitorTest::SetUp() +{ + std::cout << "SelectionInputMonitorTest SetUp" << std::endl; + inputMonitor = std::make_shared(std::make_shared()); +} + +void SelectionInputMonitorTest::TearDown() +{ + std::cout << "SelectionInputMonitorTest TearDown" << std::endl; +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) +{ + std::cout << " SelectInputMonitor001 start " << std::endl; + SelectionInputMonitor::ctrlSelectFlag = false; + SelectionInputMonitor::lastTextSelectedFlag = false; + + // bool screenLockedFlag = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); + // if (screenLockedFlag) { + // ASSERT_EQ(true, true); + // return; + // } + + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN); + inputMonitor->OnInputEvent(pointEvent); + + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE); + inputMonitor->OnInputEvent(pointEvent); + + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP); + inputMonitor->OnInputEvent(pointEvent); + + auto ret = inputMonitor->lastTextSelectedFlag; + ASSERT_EQ(ret, true); +} + +} +} \ No newline at end of file -- Gitee From 4ccf46216395e781ae883a12695325694c0568f8 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Wed, 4 Jun 2025 18:59:58 +0800 Subject: [PATCH 51/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9selectData=E5=AE=9A?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- common/selection_interface.h | 33 ++++++++++++++++++----- service/include/selection_input_monitor.h | 6 +++-- service/src/selection_input_monitor.cpp | 17 +++++++----- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/common/selection_interface.h b/common/selection_interface.h index 3ff6c3d..3785f8d 100644 --- a/common/selection_interface.h +++ b/common/selection_interface.h @@ -33,18 +33,30 @@ struct SelectionData { uint32_t bundleID = 0; }; +typedef enum { + MOVE_SELECTION = 0, + DOUBLE_CLICKED_SELECTION = 1, + TRIPLE_CLICKED_SELECTION = 2, +} SelectionType; + struct SelectionDataInner : public Parcelable { + SelectionType selectionType; std::string text { "" }; - int32_t cursorStartPos = 0; - int32_t cursorEndPos = 0; + int32_t startPosX = 0; + int32_t startPosY = 0; + int32_t endPosX = 0; + int32_t endPosY = 0; uint32_t windowId = 0; uint32_t bundleID = 0; bool ReadFromParcel(Parcel &in) { + selectionType = static_cast(in.ReadInt8()); text = in.ReadString(); - cursorEndPos = in.ReadInt32(); - cursorEndPos = in.ReadInt32(); + startPosX = in.ReadInt32(); + startPosY = in.ReadInt32(); + endPosX = in.ReadInt32(); + endPosY = in.ReadInt32(); windowId = in.ReadUint32(); bundleID = in.ReadUint32(); return true; @@ -52,13 +64,22 @@ struct SelectionDataInner : public Parcelable { bool Marshalling(Parcel &out) const { + if (!out.WriteInt8(static_cast(selectionType))) { + return false; + } if (!out.WriteString(text)) { return false; } - if (!out.WriteInt32(cursorStartPos)) { + if (!out.WriteInt32(startPosX)) { + return false; + } + if (!out.WriteInt32(startPosY)) { + return false; + } + if (!out.WriteInt32(endPosX)) { return false; } - if (!out.WriteInt32(cursorEndPos)) { + if (!out.WriteInt32(endPosY)) { return false; } if (!out.WriteUint32(windowId)) { diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h index 2464db3..5c50fb6 100644 --- a/service/include/selection_input_monitor.h +++ b/service/include/selection_input_monitor.h @@ -43,16 +43,18 @@ typedef enum { SUB_WAIT_KEY_CTRL_UP = 4, } SelectInputSubState; +struct SelectionDataInner; + class SelectionEventListener { public: - virtual void OnTextSelected() { + virtual void OnTextSelected(std::shared_ptr selectionData) { }; virtual ~SelectionEventListener() = default; }; class DefaultSelectionEventListener : public SelectionEventListener { public: - virtual void OnTextSelected(); + virtual void OnTextSelected(std::shared_ptr selectionData); private: void InjectCtrlC(); diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index 069ca1d..99d3119 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -40,7 +40,7 @@ static int64_t GetCurrentTimeMillis() { return std::chrono::duration_cast(duration).count(); } -void DefaultSelectionEventListener::OnTextSelected() +void DefaultSelectionEventListener::OnTextSelected(std::shared_ptr selectionData) { SELECTION_HILOGI("End word selection action."); InjectCtrlC(); @@ -51,9 +51,12 @@ void DefaultSelectionEventListener::OnTextSelected() return; } SelectionDataInner data; + data.selectionType = MOVE_SELECTION; data.text = "Hello, world!"; - data.cursorStartPos = 0; - data.cursorEndPos = 13; + data.startPosX = 0; + data.startPosY = 13; + data.endPosX = 0; + data.endPosY = 13; data.windowId = 1001; data.bundleID = 2002; listener->OnSelectionChange(data); @@ -120,14 +123,14 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv SELECTION_HILOGD("It is not screen on."); return; } - // SELECTION_HILOGI("pointerEvent->windowId: %{public}d", pointerEvent->GetTargetWindowId()); + SELECTION_HILOGI("pointerEvent->windowId: %{public}d", pointerEvent->GetTargetWindowId()); int32_t pointerId = pointerEvent->GetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); // SELECTION_HILOGI("pointerItem, display: %{public}d, %{public}d, \ // RawDxy: %{public}d, %{public}d. \ // windows: %{public}d, %{public}d, windowId: %{public}d, deviceId: %{public}d", - // pointerItem.GetDisplayX(),pointerItem.GetDisplayY(), + // pointerItem.GetDisplayX(),pointerItem.GetDisplayY(), // pointerItem.GetRawDx(),pointerItem.GetRawDy(), // pointerItem.GetWindowX(), pointerItem.GetWindowY(), // pointerItem.GetTargetWindowId(), pointerItem.GetDeviceId()); @@ -333,7 +336,9 @@ void SelectionInputMonitor::FinishedWordSelection() const SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); } - selectionEventListener_->OnTextSelected(); + std::shared_ptr selectionData = std::make_shared(); + + selectionEventListener_->OnTextSelected(selectionData); } void DefaultSelectionEventListener::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) -- Gitee From c36707276a8d716568d8941c48dee18e67a20db3 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Thu, 5 Jun 2025 09:14:38 +0800 Subject: [PATCH 52/93] =?UTF-8?q?=E6=B7=BB=E5=8A=A0off(hide)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- .../js/napi/selection_ability/js_panel.cpp | 36 ++++++++++++++++++- .../js/napi/selection_ability/js_panel.h | 1 + .../include/selection_panel.h | 3 ++ .../selection_ability/src/selection_panel.cpp | 24 +++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 5a47ac8..0df449b 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -50,7 +50,8 @@ napi_value JsPanel::Init(napi_env env) DECLARE_NAPI_FUNCTION("hide", Hide), DECLARE_NAPI_FUNCTION("startMoving", StartMoving), DECLARE_NAPI_FUNCTION("moveTo", MoveTo), - DECLARE_NAPI_FUNCTION("on", Subscribe) + DECLARE_NAPI_FUNCTION("on", Subscribe), + DECLARE_NAPI_FUNCTION("off", UnSubscribe) }; NAPI_CALL(env, napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), JsNew, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor)); @@ -322,6 +323,39 @@ napi_value JsPanel::Subscribe(napi_env env, napi_callback_info info) return result; } +napi_value JsPanel::UnSubscribe(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_MAX; + napi_value argv[ARGC_MAX] = { nullptr }; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + std::string type; + // 1 means least param num. + PARAM_CHECK_RETURN(env, argc >= 1, "at least one parameter is required!", TYPE_NONE, nullptr); + PARAM_CHECK_RETURN(env, JsUtil::GetValue(env, argv[0], type), "type must be string!", TYPE_NONE, nullptr); + PARAM_CHECK_RETURN(env, EventChecker::IsValidEventType(EventSubscribeModule::PANEL, type), + "type should be show/hide/sizeChange!", TYPE_NONE, nullptr); + // if the second param is not napi_function/napi_null/napi_undefined, return + auto paramType = JsUtil::GetType(env, argv[1]); + PARAM_CHECK_RETURN(env, (paramType == napi_function || paramType == napi_null || paramType == napi_undefined), + "callback should be function or null or undefined!", TYPE_NONE, nullptr); + // if the second param is napi_function, delete it, else delete all + argv[1] = paramType == napi_function ? argv[1] : nullptr; + + SELECTION_HILOGD("unsubscribe type: %{public}s.", type.c_str()); + std::shared_ptr observer = PanelListenerImpl::GetInstance(); + auto selectionPanel = UnwrapPanel(env, thisVar); + if (selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr!"); + return nullptr; + } + observer->RemoveInfo(type, selectionPanel->windowId_); + selectionPanel->ClearPanelListener(type); + napi_value result = nullptr; + napi_get_null(env, &result); + return result; +} + std::shared_ptr JsPanel::UnwrapPanel(napi_env env, napi_value thisVar) { void *native = nullptr; diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index 79c909a..93d2608 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -62,6 +62,7 @@ public: static napi_value StartMoving(napi_env env, napi_callback_info info); static napi_value MoveTo(napi_env env, napi_callback_info info); static napi_value Subscribe(napi_env env, napi_callback_info info); + static napi_value UnSubscribe(napi_env env, napi_callback_info info); void SetNative(const std::shared_ptr &panel); std::shared_ptr GetNative(); private: diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index ac8aac5..c8bcf9e 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -52,6 +52,9 @@ public: bool IsHidden(); bool SetPanelStatusListener(std::shared_ptr statusListener, const std::string &type); + void ClearPanelListener(const std::string &type); + int32_t GetWindowId(); + uint32_t windowId_ = INVALID_WINDOW_ID; private: diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index 85e1751..ab4e692 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -363,5 +363,29 @@ bool SelectionPanel::MarkListener(const std::string &type, bool isRegister) return true; } + +void SelectionPanel::ClearPanelListener(const std::string &type) +{ + if (!MarkListener(type, false)) { + return; + } + SELECTION_HILOGD("type: %{public}s.", type.c_str()); + if (panelStatusListener_ == nullptr) { + SELECTION_HILOGD("panelStatusListener_ not set, don't need to remove."); + return; + } + if (showRegistered_ || hideRegistered_) { + return; + } + panelStatusListener_ = nullptr; +} + +int32_t SelectionPanel::GetWindowId() +{ + std::lock_guard lock(windowMutex_); + return window_->GetWindowId(); + +} + } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file -- Gitee From 684232525027ed953e7b27ad1aaa078673affe8c Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Wed, 4 Jun 2025 19:40:55 +0800 Subject: [PATCH 53/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0selectData=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=A1=AB=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- common/selection_data_inner.h | 87 +++++++++++++++++++ common/selection_interface.h | 63 +------------- .../js_selection_engine_setting.cpp | 6 +- .../selection_ability/ISelectionListener.idl | 2 +- .../src/selection_listener_impl.cpp | 9 +- service/include/selection_input_monitor.h | 12 ++- service/src/selection_input_monitor.cpp | 74 ++++++++++++---- 7 files changed, 163 insertions(+), 90 deletions(-) create mode 100644 common/selection_data_inner.h diff --git a/common/selection_data_inner.h b/common/selection_data_inner.h new file mode 100644 index 0000000..1d8d62f --- /dev/null +++ b/common/selection_data_inner.h @@ -0,0 +1,87 @@ +/* + * 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 SELECTION_DATA_INNER +#define SELECTION_DATA_INNER + +#include +#include +#include +#include +#include "parcel.h" +#include "selection_interface.h" + +namespace OHOS { +namespace SelectionFwk { + +struct SelectionDataInner : public Parcelable { + SelectionData data; + + bool ReadFromParcel(Parcel &in) + { + data.selectionType = static_cast(in.ReadInt8()); + data.text = in.ReadString(); + data.startPosX = in.ReadInt32(); + data.startPosY = in.ReadInt32(); + data.endPosX = in.ReadInt32(); + data.endPosY = in.ReadInt32(); + data.windowId = in.ReadUint32(); + data.bundleID = in.ReadUint32(); + return true; + } + + bool Marshalling(Parcel &out) const + { + if (!out.WriteInt8(static_cast(data.selectionType))) { + return false; + } + if (!out.WriteString(data.text)) { + return false; + } + if (!out.WriteInt32(data.startPosX)) { + return false; + } + if (!out.WriteInt32(data.startPosY)) { + return false; + } + if (!out.WriteInt32(data.endPosX)) { + return false; + } + if (!out.WriteInt32(data.endPosY)) { + return false; + } + if (!out.WriteUint32(data.windowId)) { + return false; + } + if (!out.WriteUint32(data.bundleID)) { + return false; + } + return true; + } + + static SelectionDataInner *Unmarshalling(Parcel &in) + { + SelectionDataInner *data = new (std::nothrow) SelectionDataInner(); + if (data && !data->ReadFromParcel(in)) { + delete data; + data = nullptr; + } + return data; + } +}; + +} +} + +#endif \ No newline at end of file diff --git a/common/selection_interface.h b/common/selection_interface.h index 3785f8d..fb63c84 100644 --- a/common/selection_interface.h +++ b/common/selection_interface.h @@ -20,26 +20,17 @@ #include #include #include -#include "parcel.h" namespace OHOS { namespace SelectionFwk { -struct SelectionData { - std::string text { "" }; - int32_t cursorStartPos = 0; - int32_t cursorEndPos = 0; - uint32_t windowId = 0; - uint32_t bundleID = 0; -}; - typedef enum { MOVE_SELECTION = 0, DOUBLE_CLICKED_SELECTION = 1, TRIPLE_CLICKED_SELECTION = 2, } SelectionType; -struct SelectionDataInner : public Parcelable { +struct SelectionData { SelectionType selectionType; std::string text { "" }; int32_t startPosX = 0; @@ -48,58 +39,6 @@ struct SelectionDataInner : public Parcelable { int32_t endPosY = 0; uint32_t windowId = 0; uint32_t bundleID = 0; - - bool ReadFromParcel(Parcel &in) - { - selectionType = static_cast(in.ReadInt8()); - text = in.ReadString(); - startPosX = in.ReadInt32(); - startPosY = in.ReadInt32(); - endPosX = in.ReadInt32(); - endPosY = in.ReadInt32(); - windowId = in.ReadUint32(); - bundleID = in.ReadUint32(); - return true; - } - - bool Marshalling(Parcel &out) const - { - if (!out.WriteInt8(static_cast(selectionType))) { - return false; - } - if (!out.WriteString(text)) { - return false; - } - if (!out.WriteInt32(startPosX)) { - return false; - } - if (!out.WriteInt32(startPosY)) { - return false; - } - if (!out.WriteInt32(endPosX)) { - return false; - } - if (!out.WriteInt32(endPosY)) { - return false; - } - if (!out.WriteUint32(windowId)) { - return false; - } - if (!out.WriteUint32(bundleID)) { - return false; - } - return true; - } - - static SelectionDataInner *Unmarshalling(Parcel &in) - { - SelectionDataInner *data = new (std::nothrow) SelectionDataInner(); - if (data && !data->ReadFromParcel(in)) { - delete data; - data = nullptr; - } - return data; - } }; class SelectionInterface { diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 6f0b07d..a71b579 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -416,8 +416,10 @@ napi_value JsSelectionEngineSetting::Write(napi_env env, const SelectionData &se napi_create_object(env, &jsObject); auto ret = JsUtil::Object::WriteProperty(env, jsObject, "bundleId", selectionData.bundleID); ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "winID", selectionData.windowId); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "cursorEndPos", selectionData.cursorEndPos); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "cursorStartPos", selectionData.cursorStartPos); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosX", selectionData.startPosX); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosY", selectionData.startPosY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosX", selectionData.endPosX); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosY", selectionData.endPosY); ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "text", selectionData.text); SELECTION_HILOGD("write selectionData into object, ret=%{public}s", ret ? "true" : "false"); return ret ? jsObject : JsUtil::Const::Null(env); diff --git a/frameworks/native/selection_ability/ISelectionListener.idl b/frameworks/native/selection_ability/ISelectionListener.idl index cc112a1..1b8ce6e 100644 --- a/frameworks/native/selection_ability/ISelectionListener.idl +++ b/frameworks/native/selection_ability/ISelectionListener.idl @@ -13,7 +13,7 @@ * limitations under the License. */ -sequenceable selection_interface..OHOS.SelectionFwk.SelectionDataInner; +sequenceable selection_data_inner..OHOS.SelectionFwk.SelectionDataInner; interface OHOS.SelectionFwk.ISelectionListener { void OnSelectionChange([in] SelectionDataInner selectionDataInner); diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index df3d879..6ed0741 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -15,22 +15,19 @@ #include "selection_listener_impl.h" #include "selection_log.h" +#include "selection_data_inner.h" namespace OHOS { namespace SelectionFwk { static void CopySelectionData(const SelectionDataInner& src, SelectionData& dst) { - dst.text = src.text; - dst.cursorStartPos = src.cursorStartPos; - dst.cursorEndPos = src.cursorEndPos; - dst.windowId = src.windowId; - dst.bundleID = src.bundleID; + dst = src.data; } ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionDataInner& selectionDataInner) { - SELECTION_HILOGI("Recveive selection data: %{public}s", selectionDataInner.text.c_str()); + SELECTION_HILOGI("Recveive selection data: %{public}s", selectionDataInner.data.text.c_str()); SelectionData selectionData; CopySelectionData(selectionDataInner, selectionData); if (selectionI_ == nullptr) { diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h index 5c50fb6..7616c05 100644 --- a/service/include/selection_input_monitor.h +++ b/service/include/selection_input_monitor.h @@ -43,18 +43,18 @@ typedef enum { SUB_WAIT_KEY_CTRL_UP = 4, } SelectInputSubState; -struct SelectionDataInner; +struct SelectionData; class SelectionEventListener { public: - virtual void OnTextSelected(std::shared_ptr selectionData) { + virtual void OnTextSelected(std::shared_ptr selectionData) { }; virtual ~SelectionEventListener() = default; }; class DefaultSelectionEventListener : public SelectionEventListener { public: - virtual void OnTextSelected(std::shared_ptr selectionData); + virtual void OnTextSelected(std::shared_ptr selectionData); private: void InjectCtrlC(); @@ -65,10 +65,12 @@ class SelectionInputMonitor : public IInputEventConsumer { public: SelectionInputMonitor() : selectionEventListener_(std::make_shared()) { + selectionData_ = std::make_shared(); } SelectionInputMonitor(std::shared_ptr selectionEventListener) : selectionEventListener_(selectionEventListener) { + selectionData_ = std::make_shared(); } virtual void OnInputEvent(std::shared_ptr keyEvent) const; @@ -90,12 +92,16 @@ private: void ResetProcess(std::shared_ptr pointerEvent) const; void JudgeTripleClick() const; bool IsTextSelected() const; + void SaveSelectionStartInfo(std::shared_ptr pointerEvent) const; + void SaveSelectionEndInfo(std::shared_ptr pointerEvent) const; + void SaveSelectionType() const; static uint32_t curSelectState; static uint32_t subSelectState; static int64_t lastClickTime; std::shared_ptr selectionEventListener_; + std::shared_ptr selectionData_; }; } diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index 99d3119..96d9c5d 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -40,7 +40,7 @@ static int64_t GetCurrentTimeMillis() { return std::chrono::duration_cast(duration).count(); } -void DefaultSelectionEventListener::OnTextSelected(std::shared_ptr selectionData) +void DefaultSelectionEventListener::OnTextSelected(std::shared_ptr selectionData) { SELECTION_HILOGI("End word selection action."); InjectCtrlC(); @@ -50,16 +50,10 @@ void DefaultSelectionEventListener::OnTextSelected(std::shared_ptrOnSelectionChange(data); + selectionData->text = "Hello World."; // TODO modify + SelectionDataInner dataInner; + dataInner.data = *selectionData; + listener->OnSelectionChange(dataInner); return; } @@ -123,7 +117,8 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv SELECTION_HILOGD("It is not screen on."); return; } - SELECTION_HILOGI("pointerEvent->windowId: %{public}d", pointerEvent->GetTargetWindowId()); + SELECTION_HILOGI("pointerEvent->windowId: %{public}d, displayId: %{public}d", + pointerEvent->GetTargetWindowId(), pointerEvent->GetTargetDisplayId()); int32_t pointerId = pointerEvent->GetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); @@ -187,6 +182,51 @@ void SelectionInputMonitor::ResetProcess(std::shared_ptr pointerEv OnInputEvent(pointerEvent); } +void SelectionInputMonitor::SaveSelectionStartInfo(std::shared_ptr pointerEvent) const +{ + int32_t pointerId = pointerEvent->GetPointerId(); + PointerEvent::PointerItem pointerItem; + pointerEvent->GetPointerItem(pointerId, pointerItem); + selectionData_->startPosX = pointerItem.GetDisplayX(); + selectionData_->startPosY = pointerItem.GetDisplayY(); + selectionData_->endPosX = pointerItem.GetDisplayX(); + selectionData_->endPosY = pointerItem.GetDisplayY(); + selectionData_->windowId = pointerEvent->GetTargetWindowId(); + selectionData_->bundleID = 1; // TODO modify +} + +void SelectionInputMonitor::SaveSelectionEndInfo(std::shared_ptr pointerEvent) const +{ + if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_WAIT_LEFT_MOVE) { + return; + } + int32_t pointerId = pointerEvent->GetPointerId(); + PointerEvent::PointerItem pointerItem; + pointerEvent->GetPointerItem(pointerId, pointerItem); + selectionData_->endPosX = pointerItem.GetDisplayX(); + selectionData_->endPosY = pointerItem.GetDisplayY(); +} + +void SelectionInputMonitor::SaveSelectionType() const +{ + switch (curSelectState) { + case SELECT_INPUT_LEFT_MOVE: + selectionData_->selectionType = MOVE_SELECTION; + break; + + case SELECT_INPUT_DOUBLE_CLICKED: + selectionData_->selectionType = DOUBLE_CLICKED_SELECTION; + break; + + case SELECT_INPUT_TRIPLE_CLICKED: + selectionData_->selectionType = TRIPLE_CLICKED_SELECTION; + break; + + default: + break; + } +} + void SelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); @@ -195,6 +235,7 @@ void SelectionInputMonitor::InputInitialProcess(std::shared_ptr po curSelectState = SELECT_INPUT_WORD_BEGIN; subSelectState = SUB_INITIAL; lastClickTime = GetCurrentTimeMillis(); + SaveSelectionStartInfo(pointerEvent); SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); } return; @@ -226,6 +267,7 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr selectionData = std::make_shared(); - - selectionEventListener_->OnTextSelected(selectionData); + SaveSelectionType(); + selectionEventListener_->OnTextSelected(selectionData_); } void DefaultSelectionEventListener::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) -- Gitee From 2b74c15b78c59475214045af0f4859bcf4a87aaf Mon Sep 17 00:00:00 2001 From: fanzhe Date: Thu, 5 Jun 2025 10:26:37 +0800 Subject: [PATCH 54/93] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=B1=E7=84=A6?= =?UTF-8?q?=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- .../selection_ability/ISelectionListener.idl | 1 + .../include/selection_listener_impl.h | 1 + .../include/selection_panel.h | 9 ++-- .../src/selection_listener_impl.cpp | 24 ++++++++++ .../selection_ability/src/selection_panel.cpp | 3 +- service/BUILD.gn | 16 +++++++ .../include/focus_change_listener.h | 41 ++++++++++++++++ .../include/focus_monitor_manager.h | 35 ++++++++++++++ .../src/focus_change_listener.cpp | 46 ++++++++++++++++++ .../src/focus_monitor_manager.cpp | 48 +++++++++++++++++++ service/include/selection_service.h | 3 ++ service/src/selection_service.cpp | 21 ++++++++ 12 files changed, 243 insertions(+), 5 deletions(-) create mode 100644 service/focus_monitor/include/focus_change_listener.h create mode 100644 service/focus_monitor/include/focus_monitor_manager.h create mode 100644 service/focus_monitor/src/focus_change_listener.cpp create mode 100644 service/focus_monitor/src/focus_monitor_manager.cpp diff --git a/frameworks/native/selection_ability/ISelectionListener.idl b/frameworks/native/selection_ability/ISelectionListener.idl index 1b8ce6e..5d4cb29 100644 --- a/frameworks/native/selection_ability/ISelectionListener.idl +++ b/frameworks/native/selection_ability/ISelectionListener.idl @@ -17,4 +17,5 @@ sequenceable selection_data_inner..OHOS.SelectionFwk.SelectionDataInner; interface OHOS.SelectionFwk.ISelectionListener { void OnSelectionChange([in] SelectionDataInner selectionDataInner); + void FocusChange([in] int windowID); } diff --git a/frameworks/native/selection_ability/include/selection_listener_impl.h b/frameworks/native/selection_ability/include/selection_listener_impl.h index bd4d0b8..5819eda 100644 --- a/frameworks/native/selection_ability/include/selection_listener_impl.h +++ b/frameworks/native/selection_ability/include/selection_listener_impl.h @@ -26,6 +26,7 @@ public: SelectionListenerImpl(std::shared_ptr selectionI) : selectionI_(selectionI) {} ~SelectionListenerImpl() override = default; ErrCode OnSelectionChange(const SelectionDataInner& selectionDataInner) override; + ErrCode FocusChange(int32_t windowID)override; private: std::shared_ptr selectionI_; }; diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index c8bcf9e..3c8bf62 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -51,7 +51,6 @@ public: bool IsShowing(); bool IsHidden(); bool SetPanelStatusListener(std::shared_ptr statusListener, const std::string &type); - void ClearPanelListener(const std::string &type); int32_t GetWindowId(); @@ -64,9 +63,11 @@ private: void PanelStatusChange(const SelectionWindowStatus &status); bool MarkListener(const std::string &type, bool isRegister); - PanelType panelType_ = PanelType::STATUS_BAR; - PanelFlag panelFlag_ = PanelFlag::FLG_FIXED; - sptr window_ = nullptr; + + PanelType panelType_ = PanelType::STATUS_BAR;//待修改 + PanelFlag panelFlag_ = PanelFlag::FLG_FIXED;//待修改 + static std::mutex windowMutex_; + static sptr window_; sptr winOption_ = nullptr; bool isScbEnable_ { false }; Rosen::KeyboardLayoutParams keyboardLayoutParams_; diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index 6ed0741..834f408 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -16,6 +16,8 @@ #include "selection_listener_impl.h" #include "selection_log.h" #include "selection_data_inner.h" +#include "selection_panel.h" + namespace OHOS { namespace SelectionFwk { @@ -37,5 +39,27 @@ ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionDataInner& selec selectionI_->OnSelectionEvent(selectionData); return 0; } + +ErrCode SelectionListenerImpl::FocusChange(int32_t windowID) +{ + SELECTION_HILOGI("Recveive windowID: %{public}d", windowID); + if (selectionI_ == nullptr) { + SELECTION_HILOGI("selectionI_ is nullptr"); + return 1; + } + + auto selectionPanel = std::make_shared(); + if (selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr"); + return 1; + } + int32_t panelWindowID = selectionPanel->GetWindowId(); + if (windowID != panelWindowID) { + SELECTION_HILOGI("selectionPanel is UnFocus"); + selectionPanel->HidePanel(); + } + return 0; +} + } // namespace SelectionFramework } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index ab4e692..b4f286b 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -34,6 +34,8 @@ using WindowState = OHOS::Rosen::WindowState; std::atomic SelectionPanel::sequenceId_ { 0 }; constexpr int32_t MAXWAITTIME = 30; constexpr int32_t WAITTIME = 10; +sptr SelectionPanel::window_ {nullptr}; +std::mutex SelectionPanel::windowMutex_; SelectionPanel::~SelectionPanel() = default; int32_t SelectionPanel::CreatePanel( @@ -363,7 +365,6 @@ bool SelectionPanel::MarkListener(const std::string &type, bool isRegister) return true; } - void SelectionPanel::ClearPanelListener(const std::string &type) { if (!MarkListener(type, false)) { diff --git a/service/BUILD.gn b/service/BUILD.gn index b3a92dd..bf3705d 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -61,9 +61,15 @@ ohos_shared_library("selection_service") { configs = [ ":selection_sa_config", ] output_values = get_target_outputs(":selection_service_interface") + include_dirs = [ + "./focus_monitor/include", + ] + sources = [ "src/selection_service.cpp", "src/selection_input_monitor.cpp", + "./focus_monitor/src/focus_change_listener.cpp", + "./focus_monitor/src/focus_monitor_manager.cpp", ] sources += filter_include(output_values, [ "*.cpp" ]) deps = [ @@ -84,8 +90,18 @@ ohos_shared_library("selection_service") { "safwk:system_ability_fwk", "samgr:samgr_proxy", "screenlock_mgr:screenlock_client", + "input:libmmi-client", + "window_manager:libdm_lite", + "window_manager:libwsutils", ] + if (window_manager_use_sceneboard) { + external_deps += [ "window_manager:libwm_lite" ] + defines += [ "SCENE_BOARD_ENABLE" ] + } else { + external_deps += [ "window_manager:libwm" ] + } + part_name = "selectionfwk" subsystem_name = "systemabilitymgr" } \ No newline at end of file diff --git a/service/focus_monitor/include/focus_change_listener.h b/service/focus_monitor/include/focus_change_listener.h new file mode 100644 index 0000000..5807667 --- /dev/null +++ b/service/focus_monitor/include/focus_change_listener.h @@ -0,0 +1,41 @@ +/* + * 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 SELECTION_FOCUS_CHANGE_LISTENER_H +#define SELECTION_FOCUS_CHANGE_LISTENER_H + +#include "focus_monitor_manager.h" +#ifdef SCENE_BOARD_ENABLE +#include "window_manager_lite.h" +#else +#include "window_manager.h" +#endif + +namespace OHOS { +namespace SelectionFwk { +class FocusChangedListener : public Rosen::IFocusChangedListener { +public: + explicit FocusChangedListener(const FocusHandle &handle) : focusHandle_(handle){}; + ~FocusChangedListener() = default; + void OnFocused(const sptr &focusChangeInfo) override; + void OnUnfocused(const sptr &focusChangeInfo) override; + +private: + FocusHandle focusHandle_ = nullptr; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // SELECTION_FOCUS_CHANGE_LISTENER_H diff --git a/service/focus_monitor/include/focus_monitor_manager.h b/service/focus_monitor/include/focus_monitor_manager.h new file mode 100644 index 0000000..9068ad8 --- /dev/null +++ b/service/focus_monitor/include/focus_monitor_manager.h @@ -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. + */ + +#ifndef SELECTION_FOCUS_MONITOR_MANAGER_H +#define SELECTION_FOCUS_MONITOR_MANAGER_H + +#include + +namespace OHOS { +namespace SelectionFwk { +using FocusHandle = std::function; +class FocusMonitorManager { +public: + static FocusMonitorManager &GetInstance(); + void RegisterFocusChangedListener(const FocusHandle &handle); + +private: + FocusMonitorManager() = default; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // SELECTION_FOCUS_MONITOR_MANAGER_H diff --git a/service/focus_monitor/src/focus_change_listener.cpp b/service/focus_monitor/src/focus_change_listener.cpp new file mode 100644 index 0000000..e662e43 --- /dev/null +++ b/service/focus_monitor/src/focus_change_listener.cpp @@ -0,0 +1,46 @@ +/* + * 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 "focus_change_listener.h" + +#include + +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { +void FocusChangedListener::OnFocused(const sptr &focusChangeInfo) +{ + if (focusChangeInfo == nullptr || focusHandle_ == nullptr) { + SELECTION_HILOGE("error nullptr"); + return; + } + SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64 " pid: %{public}d, uid: %{public}d", + focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_); + focusHandle_(true, focusChangeInfo->windowId_); +} + +void FocusChangedListener::OnUnfocused(const sptr &focusChangeInfo) +{ + if (focusChangeInfo == nullptr || focusHandle_ == nullptr) { + SELECTION_HILOGE("error nullptr"); + return; + } + SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64 " pid: %{public}d, uid: %{public}d", + focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_); + focusHandle_(false, focusChangeInfo->windowId_); +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/service/focus_monitor/src/focus_monitor_manager.cpp b/service/focus_monitor/src/focus_monitor_manager.cpp new file mode 100644 index 0000000..76ad5eb --- /dev/null +++ b/service/focus_monitor/src/focus_monitor_manager.cpp @@ -0,0 +1,48 @@ +/* + * 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 "focus_change_listener.h" +#include "selection_log.h" +#ifdef SCENE_BOARD_ENABLE +#include "window_manager_lite.h" +#else +#include "window_manager.h" +#endif + +namespace OHOS { +namespace SelectionFwk { +using namespace Rosen; +FocusMonitorManager &FocusMonitorManager::GetInstance() +{ + static FocusMonitorManager focusMonitorManager; + return focusMonitorManager; +} + +void FocusMonitorManager::RegisterFocusChangedListener(const FocusHandle &handle) +{ + sptr listener = new (std::nothrow) FocusChangedListener(handle); + if (listener == nullptr) { + SELECTION_HILOGE("failed to create listener"); + return; + } +#ifdef SCENE_BOARD_ENABLE + WMError ret = WindowManagerLite::GetInstance().RegisterFocusChangedListener(listener); +#else + WMError ret = WindowManager::GetInstance().RegisterFocusChangedListener(listener); +#endif + SELECTION_HILOGI("register focus changed listener ret: %{public}d", ret); +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 41f24f7..e16ab71 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -71,6 +71,9 @@ private: void InputMonitorInit(); void InputMonitorCancel(); void WatchParams(); + void InitFocusChangedMonitor(); + void HandleFocusChanged(bool isOnFocused, uint32_t windowId); + int32_t inputMonitorId_ {-1}; static sptr instance_; diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 9614a03..2abba2e 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -28,6 +28,9 @@ #include "selection_interface.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" +#include "screenlock_manager.h" +#include "focus_monitor_manager.h" + using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -218,6 +221,7 @@ void SelectionService::OnStart() Publish(SelectionService::GetInstance()); InputMonitorInit(); WatchParams(); + InitFocusChangedMonitor(); SELECTION_HILOGI("[SelectionService][OnStart]end"); } @@ -259,6 +263,23 @@ void SelectionService::InputMonitorCancel() } } +void SelectionService::InitFocusChangedMonitor() +{ + SELECTION_HILOGI("[SelectionService] init focus changed monitor"); + FocusMonitorManager::GetInstance().RegisterFocusChangedListener( + [this](bool isOnFocused, uint32_t windowId) { + HandleFocusChanged(isOnFocused, windowId); + }); +} + +void SelectionService::HandleFocusChanged(bool isOnFocused, uint32_t windowId) +{ + SELECTION_HILOGI("[SelectionService] handle focus changed"); + if (!isOnFocused) { + listenerStub_->FocusChange(windowId); + } +} + void SelectionService::HandleKeyEvent(int32_t keyCode) { } -- Gitee From c24c038e2c71c3b5b9d3408e5c71f224f23b02d8 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Thu, 5 Jun 2025 11:05:56 +0800 Subject: [PATCH 55/93] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/src/selection_input_monitor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index 96d9c5d..fbd6f80 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -117,8 +117,8 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv SELECTION_HILOGD("It is not screen on."); return; } - SELECTION_HILOGI("pointerEvent->windowId: %{public}d, displayId: %{public}d", - pointerEvent->GetTargetWindowId(), pointerEvent->GetTargetDisplayId()); + // SELECTION_HILOGD("pointerEvent->windowId: %{public}d, displayId: %{public}d", + // pointerEvent->GetTargetWindowId(), pointerEvent->GetTargetDisplayId()); int32_t pointerId = pointerEvent->GetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); -- Gitee From 85b9b63aebb9163900c1bae963b8f7bae0a7fe1e Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Thu, 5 Jun 2025 16:33:47 +0800 Subject: [PATCH 56/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/event_checker.cpp | 4 +- .../include/selection_extension_hilog.h | 67 ---------------- .../src/js_selection_extension.cpp | 79 ++++++++++--------- .../src/js_selection_extension_context.cpp | 18 ++--- .../src/selection_extension.cpp | 6 +- .../src/selection_extension_context.cpp | 8 +- utils/include/selection_log.h | 28 ++++--- 7 files changed, 75 insertions(+), 135 deletions(-) delete mode 100644 frameworks/native/selection_extension/include/selection_extension_hilog.h diff --git a/common/event_checker.cpp b/common/event_checker.cpp index 0dd1e5c..4543b72 100644 --- a/common/event_checker.cpp +++ b/common/event_checker.cpp @@ -19,8 +19,8 @@ namespace OHOS { namespace SelectionFwk { const std::unordered_set EVENT_TYPES[static_cast(EventSubscribeModule::MODULE_END)] = { - [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionEvent", "selectionPanelEvent" }, - [static_cast(EventSubscribeModule::PANEL)] = { "show", "hide"} + [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionEvent", "selectionPanelEvent" }, + [static_cast(EventSubscribeModule::PANEL)] = { "show", "hide" } }; bool EventChecker::IsValidEventType(EventSubscribeModule module, const std::string &type) diff --git a/frameworks/native/selection_extension/include/selection_extension_hilog.h b/frameworks/native/selection_extension/include/selection_extension_hilog.h deleted file mode 100644 index 2f911ee..0000000 --- a/frameworks/native/selection_extension/include/selection_extension_hilog.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 SELECTION_LOG_H -#define SELECTION_LOG_H -#include "hilog/log.h" - -#ifdef HILOG_FATAL -#undef HILOG_FATAL -#endif - -#ifdef HILOG_ERROR -#undef HILOG_ERROR -#endif - -#ifdef HILOG_WARN -#undef HILOG_WARN -#endif - -#ifdef HILOG_INFO -#undef HILOG_INFO -#endif - -#ifdef HILOG_DEBUG -#undef HILOG_DEBUG -#endif - -#ifndef SE_LOG_DOMAIN -#define SE_LOG_DOMAIN 0xD002902 -#endif - -#ifndef SE_LOG_TAG -#define SE_LOG_TAG "SELECTION_EXT" -#endif - -#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) - -#define HILOG_FATAL(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_ERROR(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_WARN(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_INFO(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) -#define HILOG_DEBUG(fmt, ...) \ - ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, SE_LOG_DOMAIN, SE_LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) - - -#endif // SELECTION_LOG_H \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index 7421ed2..cd2b021 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -20,7 +20,7 @@ #include "napi/native_api.h" #include "napi_common_want.h" #include "napi_remote_object.h" -#include "selection_extension_hilog.h" +#include "selection_log.h" namespace OHOS::AbilityRuntime { namespace { @@ -29,20 +29,20 @@ constexpr size_t ARGC_ONE = 1; napi_value AttachSelectionExtensionContext(napi_env env, void* value, void*) { - HILOG_INFO("AttachSelectionExtensionContext start."); + SELECTION_HILOGI("AttachSelectionExtensionContext start."); if (value == nullptr) { - HILOG_WARN("parameter is invalid."); + SELECTION_HILOGW("parameter is invalid."); return nullptr; } auto ptr = reinterpret_cast*>(value)->lock(); if (ptr == nullptr) { - HILOG_WARN("context is invalid."); + SELECTION_HILOGW("context is invalid."); return nullptr; } napi_value object = CreateJsSelectionExtensionContext(env, ptr); auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "SelectionExtensionContext", &object, 1); if (systemModule == nullptr) { - HILOG_ERROR("failed to load system module by engine!"); + SELECTION_HILOGE("failed to load system module by engine!"); return nullptr; } auto contextObj = systemModule->GetNapiValue(); @@ -50,18 +50,18 @@ napi_value AttachSelectionExtensionContext(napi_env env, void* value, void*) nullptr); auto workContext = new (std::nothrow) std::weak_ptr(ptr); if (workContext == nullptr) { - HILOG_ERROR("workContext is nullptr!"); + SELECTION_HILOGE("workContext is nullptr!"); return nullptr; } napi_status status = napi_wrap( env, contextObj, workContext, [](napi_env, void* data, void*) { - HILOG_INFO("finalizer for weak_ptr input method extension context is called."); + SELECTION_HILOGI("finalizer for weak_ptr input method extension context is called."); delete static_cast*>(data); }, nullptr, nullptr); if (status != napi_ok) { - HILOG_ERROR("SelectionExtensionContext wrap failed: %{public}d!", status); + SELECTION_HILOGE("SelectionExtensionContext wrap failed: %{public}d!", status); delete workContext; return nullptr; } @@ -84,50 +84,51 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor std::shared_ptr& handler, const sptr& token) { - HILOG_INFO("%{public}s start.", __func__); + SELECTION_HILOGI("%{public}s start.", __func__); SelectionExtension::Init(record, application, handler, token); std::string srcPath; GetSrcPath(srcPath); if (srcPath.empty()) { - HILOG_ERROR("failed to get srcPath!"); + SELECTION_HILOGE("failed to get srcPath!"); return; } std::string moduleName(Extension::abilityInfo_->moduleName); moduleName.append("::").append(abilityInfo_->name); - HILOG_INFO("JsSelectionExtension, module: %{public}s, srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str()); + SELECTION_HILOGI("JsSelectionExtension, module: %{public}s, srcPath:%{public}s.", moduleName.c_str(), + srcPath.c_str()); HandleScope handleScope(jsRuntime_); jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath, abilityInfo_->compileMode == CompileMode::ES_MODULE); if (jsObj_ == nullptr) { - HILOG_ERROR("failed to init jsObj_!"); + SELECTION_HILOGE("failed to init jsObj_!"); return; } napi_env env = jsRuntime_.GetNapiEnv(); napi_value obj = jsObj_->GetNapiValue(); if (obj == nullptr) { - HILOG_ERROR("failed to get JsSelectionExtension object!"); + SELECTION_HILOGE("failed to get JsSelectionExtension object!"); return; } BindContext(env, obj); - HILOG_INFO("%{public}s end.", __func__); + SELECTION_HILOGI("%{public}s end.", __func__); } void JsSelectionExtension::OnStart(const AAFwk::Want& want) { - HILOG_INFO("%{public}s start.", __func__); + SELECTION_HILOGI("%{public}s start.", __func__); Extension::OnStart(want); napi_env env = jsRuntime_.GetNapiEnv(); napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); napi_value argv[] = {napiWant}; CallObjectMethod("onCreate", argv, ARGC_ONE); - HILOG_INFO("%{public}s end.", __func__); + SELECTION_HILOGI("%{public}s end.", __func__); } sptr JsSelectionExtension::OnConnect(const AAFwk::Want& want) { - HILOG_INFO("%{public}s start.", __func__); + SELECTION_HILOGI("%{public}s start.", __func__); HandleScope handleScope(jsRuntime_); Extension::OnConnect(want); napi_env env = jsRuntime_.GetNapiEnv(); @@ -136,58 +137,58 @@ sptr JsSelectionExtension::OnConnect(const AAFwk::Want& want) napi_value result = CallObjectMethod("onConnect", argv, ARGC_ONE); auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, result); if (remoteObj == nullptr) { - HILOG_ERROR("remoteObj is nullptr."); + SELECTION_HILOGE("remoteObj is nullptr."); } - HILOG_INFO("%{public}s end.", __func__); + SELECTION_HILOGI("%{public}s end.", __func__); return remoteObj; } void JsSelectionExtension::OnDisconnect(const AAFwk::Want& want) { - HILOG_INFO("%{public}s start.", __func__); + SELECTION_HILOGI("%{public}s start.", __func__); HandleScope handleScope(jsRuntime_); Extension::OnDisconnect(want); napi_env env = jsRuntime_.GetNapiEnv(); napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); napi_value argv[] = {napiWant}; CallObjectMethod("onDisconnect", argv, ARGC_ONE); - HILOG_INFO("%{public}s end.", __func__); + SELECTION_HILOGI("%{public}s end.", __func__); } void JsSelectionExtension::OnStop() { - HILOG_INFO("%{public}s start.", __func__); + SELECTION_HILOGI("%{public}s start.", __func__); SelectionExtension::OnStop(); } napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const napi_value* argv, size_t argc) { - HILOG_INFO("JsSelectionExtension::CallObjectMethod(%{public}s), start.", methodName); + SELECTION_HILOGI("JsSelectionExtension::CallObjectMethod(%{public}s), start.", methodName); if (jsObj_ == nullptr) { - HILOG_ERROR("not found JsSelectionExtension.js."); + SELECTION_HILOGE("not found JsSelectionExtension.js."); return nullptr; } napi_env env = jsRuntime_.GetNapiEnv(); napi_value obj = jsObj_->GetNapiValue(); if (obj == nullptr) { - HILOG_ERROR("failed to get JsSelectionExtension object!"); + SELECTION_HILOGE("failed to get JsSelectionExtension object!"); return nullptr; } napi_value method = nullptr; napi_get_named_property(env, obj, methodName, &method); if (method == nullptr) { - HILOG_ERROR("failed to get '%{public}s' from JsSelectionExtension object!", methodName); + SELECTION_HILOGE("failed to get '%{public}s' from JsSelectionExtension object!", methodName); return nullptr; } napi_value result = nullptr; if (napi_call_function(env, obj, method, argc, argv, &result) != napi_ok) { - HILOG_ERROR("JsSelectionExtension::CallFunction(%{public}s), failed.", methodName); + SELECTION_HILOGE("JsSelectionExtension::CallFunction(%{public}s), failed.", methodName); return nullptr; } - HILOG_INFO("JsSelectionExtension::CallFunction(%{public}s), success.", methodName); + SELECTION_HILOGI("JsSelectionExtension::CallFunction(%{public}s), success.", methodName); return result; } @@ -214,47 +215,47 @@ void JsSelectionExtension::GetSrcPath(std::string& srcPath) void JsSelectionExtension::BindContext(napi_env env, napi_value obj) { - HILOG_INFO("%{public}s start.", __func__); + SELECTION_HILOGI("%{public}s start.", __func__); auto context = GetContext(); if (context == nullptr) { - HILOG_ERROR("failed to get context!"); + SELECTION_HILOGE("failed to get context!"); return; } - HILOG_DEBUG("JsSelectionExtension::Init CreateJsSelectionExtensionContext."); + SELECTION_HILOGD("JsSelectionExtension::Init CreateJsSelectionExtensionContext."); napi_value contextObj = CreateJsSelectionExtensionContext(env, context); auto shellContextRef = jsRuntime_.LoadSystemModule("SelectionExtensionContext", &contextObj, ARGC_ONE); if (shellContextRef == nullptr) { - HILOG_ERROR("shellContextRef is nullptr!"); + SELECTION_HILOGE("shellContextRef is nullptr!"); return; } contextObj = shellContextRef->GetNapiValue(); if (contextObj == nullptr) { - HILOG_ERROR("failed to get input method extension native object!"); + SELECTION_HILOGE("failed to get input method extension native object!"); return; } auto workContext = new (std::nothrow) std::weak_ptr(context); if (workContext == nullptr) { - HILOG_ERROR("workContext is nullptr!"); + SELECTION_HILOGE("workContext is nullptr!"); return; } napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachSelectionExtensionContext, workContext, nullptr); - HILOG_DEBUG("JsSelectionExtension::Init Bind."); + SELECTION_HILOGD("JsSelectionExtension::Init Bind."); context->Bind(jsRuntime_, shellContextRef.release()); - HILOG_DEBUG("JsSelectionExtension::SetProperty."); + SELECTION_HILOGD("JsSelectionExtension::SetProperty."); napi_set_named_property(env, obj, "context", contextObj); napi_status status = napi_wrap( env, contextObj, workContext, [](napi_env, void* data, void*) { - HILOG_INFO("Finalizer for weak_ptr input method extension context is called."); + SELECTION_HILOGI("Finalizer for weak_ptr input method extension context is called."); delete static_cast*>(data); }, nullptr, nullptr); if (status != napi_ok) { - HILOG_ERROR("SelectionExtensionContext wrap failed: %{public}d", status); + SELECTION_HILOGE("SelectionExtensionContext wrap failed: %{public}d", status); delete workContext; } - HILOG_INFO("%{public}s end.", __func__); + SELECTION_HILOGI("%{public}s end.", __func__); } } // namespace OHOS::AbilityRuntime \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp index fdfaa06..d0f46ab 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp @@ -14,12 +14,12 @@ */ #include "js_selection_extension_context.h" -#include "selection_extension_hilog.h" #include "js_error_utils.h" #include "js_extension_context.h" #include "js_runtime_utils.h" #include "js_utils.h" #include "napi_common_want.h" +#include "selection_log.h" namespace OHOS::AbilityRuntime { using namespace OHOS::SelectionFwk; @@ -33,14 +33,14 @@ class JsSelectionExtensionContext final { public: explicit JsSelectionExtensionContext(const std::shared_ptr& context) : context_(context) { - HILOG_INFO("JsSelectionExtensionContext::JsSelectionExtensionContext is called."); + SELECTION_HILOGI("JsSelectionExtensionContext::JsSelectionExtensionContext is called."); } JsSelectionExtensionContext() = default; ~JsSelectionExtensionContext() = default; static void Finalizer(napi_env env, void* data, void* hint) { - HILOG_INFO("JsSelectionExtensionContext::Finalizer is called."); + SELECTION_HILOGI("JsSelectionExtensionContext::Finalizer is called."); std::unique_ptr(static_cast(data)); } @@ -54,7 +54,7 @@ private: napi_value OnStartAbility(napi_env env, size_t argc, napi_value* argv) { - HILOG_INFO("SelectionExtensionContext OnStartAbility."); + SELECTION_HILOGI("SelectionExtensionContext OnStartAbility."); // only support one params PARAM_CHECK_RETURN(env, argc == ARGC_ONE, "number of param should in 1", TYPE_NONE, CreateJsUndefined(env)); PARAM_CHECK_RETURN(env, JsUtil::GetType(env, argv[0]) == napi_object, "param want type must be Want", TYPE_NONE, @@ -62,17 +62,17 @@ private: decltype(argc) unwrapArgc = 0; AAFwk::Want want; OHOS::AppExecFwk::UnwrapWant(env, argv[INDEX_ZERO], want); - HILOG_INFO("%{public}s bundleName: %{public}s abilityName: %{public}s.", __func__, want.GetBundle().c_str(), - want.GetElement().GetAbilityName().c_str()); + SELECTION_HILOGI("%{public}s bundleName: %{public}s abilityName: %{public}s.", __func__, + want.GetBundle().c_str(), want.GetElement().GetAbilityName().c_str()); unwrapArgc++; napi_value lastParam = argc > unwrapArgc ? argv[unwrapArgc] : nullptr; napi_value result = nullptr; std::unique_ptr napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result); auto asyncTask = [weak = context_, want, unwrapArgc, env, task = napiAsyncTask.get()]() { - HILOG_INFO("startAbility start."); + SELECTION_HILOGI("startAbility start."); auto context = weak.lock(); if (context == nullptr) { - HILOG_WARN("context is released."); + SELECTION_HILOGW("context is released."); task->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "Context is released")); delete task; return; @@ -97,7 +97,7 @@ private: napi_value CreateJsSelectionExtensionContext(napi_env env, std::shared_ptr context) { - HILOG_INFO("CreateJsSelectionExtensionContext begin"); + SELECTION_HILOGI("CreateJsSelectionExtensionContext begin"); std::shared_ptr abilityInfo = nullptr; if (context) { abilityInfo = context->GetAbilityInfo(); diff --git a/frameworks/native/selection_extension/src/selection_extension.cpp b/frameworks/native/selection_extension/src/selection_extension.cpp index bf9a38f..ef5991e 100644 --- a/frameworks/native/selection_extension/src/selection_extension.cpp +++ b/frameworks/native/selection_extension/src/selection_extension.cpp @@ -16,7 +16,7 @@ #include "selection_extension.h" #include "js_selection_extension.h" #include "runtime.h" -#include "selection_extension_hilog.h" +#include "selection_log.h" namespace OHOS::AbilityRuntime { using namespace OHOS::AppExecFwk; @@ -28,7 +28,7 @@ SelectionExtension* SelectionExtension::Create(const std::unique_ptr& r } switch (runtime->GetLanguage()) { case Runtime::Language::JS: - HILOG_INFO("create JsSelectionExtension"); + SELECTION_HILOGI("create JsSelectionExtension"); return JsSelectionExtension::Create(runtime); default: return new SelectionExtension(); @@ -40,7 +40,7 @@ void SelectionExtension::Init(const std::shared_ptr& record, std::shared_ptr& handler, const sptr& token) { - HILOG_INFO("call %{public}s", __func__); + SELECTION_HILOGI("call %{public}s", __func__); ExtensionBase::Init(record, application, handler, token); } diff --git a/frameworks/native/selection_extension/src/selection_extension_context.cpp b/frameworks/native/selection_extension/src/selection_extension_context.cpp index 5b0c24e..d0163c7 100644 --- a/frameworks/native/selection_extension/src/selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_context.cpp @@ -15,7 +15,7 @@ #include "selection_extension_context.h" #include "ability_manager_client.h" -#include "selection_extension_hilog.h" +#include "selection_log.h" namespace OHOS::AbilityRuntime { const size_t SelectionExtensionContext::CONTEXT_TYPE_ID(std::hash {}("SelectionExtensionContext")); @@ -23,11 +23,11 @@ int32_t SelectionExtensionContext::ILLEGAL_REQUEST_CODE(-1); ErrCode SelectionExtensionContext::StartAbility(const AAFwk::Want& want) const { - HILOG_DEBUG("%{public}s begin.", __func__); + SELECTION_HILOGD("%{public}s begin.", __func__); ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, ILLEGAL_REQUEST_CODE); - HILOG_DEBUG("%{public}s ret=%{public}d", __func__, err); + SELECTION_HILOGD("%{public}s ret=%{public}d", __func__, err); if (err != ERR_OK) { - HILOG_ERROR("SelectionExtensionContext::StartAbility failed: %{public}d", err); + SELECTION_HILOGE("SelectionExtensionContext::StartAbility failed: %{public}d", err); } return err; } diff --git a/utils/include/selection_log.h b/utils/include/selection_log.h index 82fdd8f..6f8a1f0 100644 --- a/utils/include/selection_log.h +++ b/utils/include/selection_log.h @@ -31,17 +31,23 @@ extern "C" { #define SELETION_DEBUG_ENABLE 0 #endif -#define FILENAME (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) -#define HILOG_PRINT(func, fmt, args...) \ - do { \ - func(LOG_CORE, "{%{public}s:%{public}d %{public}s()} " fmt, FILENAME, __LINE__, __FUNCTION__, ##args); \ - } while (false) - -#define SELECTION_HILOGD(fmt, ...) HILOG_PRINT(HILOG_DEBUG, fmt, ##__VA_ARGS__) -#define SELECTION_HILOGI(fmt, ...) HILOG_PRINT(HILOG_INFO, fmt, ##__VA_ARGS__) -#define SELECTION_HILOGW(fmt, ...) HILOG_PRINT(HILOG_WARN, fmt, ##__VA_ARGS__) -#define SELECTION_HILOGE(fmt, ...) HILOG_PRINT(HILOG_ERROR, fmt, ##__VA_ARGS__) -#define SELECTION_HILOGF(fmt, ...) HILOG_PRINT(HILOG_FATAL, fmt, ##__VA_ARGS__) +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) + +#define SELECTION_HILOGF(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define SELECTION_HILOGE(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define SELECTION_HILOGW(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define SELECTION_HILOGI(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) +#define SELECTION_HILOGD(fmt, ...) \ + ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ + __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) namespace ErrorCode { // Error Code definition in the input method management system -- Gitee From 1a2a8109a590133f897f1a65981ddcb523dd6e56 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Fri, 6 Jun 2025 15:07:45 +0800 Subject: [PATCH 57/93] =?UTF-8?q?=E6=95=B4=E6=94=B9=E9=80=89=E8=AF=8D?= =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- common/selection_data_inner.h | 33 ++- common/selection_interface.h | 15 +- .../js_selection_engine_setting.cpp | 26 +-- .../js_selection_engine_setting.h | 6 +- .../selection_ability/ISelectionListener.idl | 4 +- .../include/selection_listener_impl.h | 2 +- .../src/selection_listener_impl.cpp | 12 +- service/include/selection_input_monitor.h | 70 +++---- service/src/selection_input_monitor.cpp | 193 +++++++++++------- service/src/selection_service.cpp | 17 +- test/unittest/BUILD.gn | 1 + .../unittest/selection_input_monitor_test.cpp | 184 ++++++++--------- 12 files changed, 310 insertions(+), 253 deletions(-) diff --git a/common/selection_data_inner.h b/common/selection_data_inner.h index 1d8d62f..290467a 100644 --- a/common/selection_data_inner.h +++ b/common/selection_data_inner.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "parcel.h" #include "selection_interface.h" @@ -25,24 +26,23 @@ namespace OHOS { namespace SelectionFwk { -struct SelectionDataInner : public Parcelable { - SelectionData data; +struct SelectionInfoData : public Parcelable { + SelectionInfo data; - bool ReadFromParcel(Parcel &in) - { + bool ReadFromParcel(Parcel &in) { data.selectionType = static_cast(in.ReadInt8()); data.text = in.ReadString(); data.startPosX = in.ReadInt32(); data.startPosY = in.ReadInt32(); data.endPosX = in.ReadInt32(); data.endPosY = in.ReadInt32(); + data.displayId = in.ReadUint32(); data.windowId = in.ReadUint32(); - data.bundleID = in.ReadUint32(); + data.bundleName = in.ReadString(); return true; } - bool Marshalling(Parcel &out) const - { + bool Marshalling(Parcel &out) const { if (!out.WriteInt8(static_cast(data.selectionType))) { return false; } @@ -61,24 +61,35 @@ struct SelectionDataInner : public Parcelable { if (!out.WriteInt32(data.endPosY)) { return false; } + if (!out.WriteUint32(data.displayId)) { + return false; + } if (!out.WriteUint32(data.windowId)) { return false; } - if (!out.WriteUint32(data.bundleID)) { + if (!out.WriteString(data.bundleName)) { return false; } return true; } - static SelectionDataInner *Unmarshalling(Parcel &in) - { - SelectionDataInner *data = new (std::nothrow) SelectionDataInner(); + static SelectionInfoData *Unmarshalling(Parcel &in) { + SelectionInfoData *data = new (std::nothrow) SelectionInfoData(); if (data && !data->ReadFromParcel(in)) { delete data; data = nullptr; } return data; } + + std::string ToString() const { + std::ostringstream oss; + oss << "SelectionInfo { selectionType: " << data.selectionType << ", text: \"" << data.text << "\" \ + startPosX: " << data.startPosX << ", startPosY: " << data.startPosY << ", endPosX: " << data.endPosX << ",\ + endPosY: " << data.endPosY << ", displayId: " << data.displayId << ", windowId: " << data.windowId << + ", bundleName: " << data.bundleName << "}"; + return oss.str(); + } }; } diff --git a/common/selection_interface.h b/common/selection_interface.h index fb63c84..ebda748 100644 --- a/common/selection_interface.h +++ b/common/selection_interface.h @@ -25,26 +25,27 @@ namespace OHOS { namespace SelectionFwk { typedef enum { - MOVE_SELECTION = 0, - DOUBLE_CLICKED_SELECTION = 1, - TRIPLE_CLICKED_SELECTION = 2, + MOVE_SELECTION = 1, + DOUBLE_CLICKED_SELECTION = 2, + TRIPLE_CLICKED_SELECTION = 3, } SelectionType; -struct SelectionData { +struct SelectionInfo { SelectionType selectionType; - std::string text { "" }; + std::string text = ""; int32_t startPosX = 0; int32_t startPosY = 0; int32_t endPosX = 0; int32_t endPosY = 0; + uint32_t displayId = 0; uint32_t windowId = 0; - uint32_t bundleID = 0; + std::string bundleName = ""; }; class SelectionInterface { public: virtual ~SelectionInterface() = default; - virtual int32_t OnSelectionEvent(const SelectionData &selectionData) = 0; + virtual int32_t OnSelectionEvent(const SelectionInfo &selectionInfo) = 0; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index a71b579..a239f78 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -410,27 +410,27 @@ std::shared_ptr JsSelectionEngineSetti return entry; } -napi_value JsSelectionEngineSetting::Write(napi_env env, const SelectionData &selectionData) +napi_value JsSelectionEngineSetting::Write(napi_env env, const SelectionInfo &selectionInfo) { napi_value jsObject = nullptr; napi_create_object(env, &jsObject); - auto ret = JsUtil::Object::WriteProperty(env, jsObject, "bundleId", selectionData.bundleID); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "winID", selectionData.windowId); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosX", selectionData.startPosX); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosY", selectionData.startPosY); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosX", selectionData.endPosX); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosY", selectionData.endPosY); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "text", selectionData.text); - SELECTION_HILOGD("write selectionData into object, ret=%{public}s", ret ? "true" : "false"); + auto ret = JsUtil::Object::WriteProperty(env, jsObject, "bundleName", selectionInfo.bundleName); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "winID", selectionInfo.windowId); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosX", selectionInfo.startPosX); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosY", selectionInfo.startPosY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosX", selectionInfo.endPosX); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosY", selectionInfo.endPosY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "text", selectionInfo.text); + SELECTION_HILOGD("write selectionInfo into object, ret=%{public}s", ret ? "true" : "false"); return ret ? jsObject : JsUtil::Const::Null(env); } -int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionData &selectionData) +int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionInfo &selectionInfo) { SELECTION_HILOGD("OnSelectionEvent begin"); std::string type = "selectionEvent"; - auto entry = GetEntry(type, [&selectionData](SelectionEntry &entry) {entry.selectionData = selectionData; }); + auto entry = GetEntry(type, [&selectionInfo](SelectionEntry &entry) {entry.selectionInfo = selectionInfo; }); if (entry == nullptr) { SELECTION_HILOGE("failed to get SelectionEntry entry!"); return 1; @@ -442,13 +442,13 @@ int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionData &selectio return 1; } - SELECTION_HILOGI("selection text is [%{public}s]", entry->selectionData.text.c_str()); + SELECTION_HILOGI("selection text is [%{public}s]", entry->selectionInfo.text.c_str()); auto task = [entry]() { auto paramGetter = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { if (argc == 0) { return false; } - napi_value jsObject = Write(env, entry->selectionData); + napi_value jsObject = Write(env, entry->selectionInfo); if (jsObject == JsUtil::Const::Null(env)) { SELECTION_HILOGE("jsObject is nullptr!"); return false; diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index a478c6d..6a27a54 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -47,13 +47,13 @@ public: static napi_value UnSubscribe(napi_env env, napi_callback_info info); static napi_value CreatePanel(napi_env env, napi_callback_info info); static napi_value DestroyPanel(napi_env env, napi_callback_info info); - int32_t OnSelectionEvent(const SelectionData &selectionData); + int32_t OnSelectionEvent(const SelectionInfo &selectionInfo); private: struct SelectionEntry { std::vector> vecCopy; std::string type; - SelectionData selectionData; + SelectionInfo selectionInfo; SelectionEntry(const std::vector> &cbVec, const std::string &type) : vecCopy(cbVec), type(type) { @@ -84,7 +84,7 @@ private: static napi_value GetSEInstance(napi_env env, napi_callback_info info); static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); - static napi_value Write(napi_env env, const SelectionData &selectionData); + static napi_value Write(napi_env env, const SelectionInfo &selectionInfo); static napi_status GetContext(napi_env env, napi_value in, std::shared_ptr &context); static std::shared_ptr GetJsSelectionEngineSetting(); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); diff --git a/frameworks/native/selection_ability/ISelectionListener.idl b/frameworks/native/selection_ability/ISelectionListener.idl index 5d4cb29..afbeafb 100644 --- a/frameworks/native/selection_ability/ISelectionListener.idl +++ b/frameworks/native/selection_ability/ISelectionListener.idl @@ -13,9 +13,9 @@ * limitations under the License. */ -sequenceable selection_data_inner..OHOS.SelectionFwk.SelectionDataInner; +sequenceable selection_data_inner..OHOS.SelectionFwk.SelectionInfoData; interface OHOS.SelectionFwk.ISelectionListener { - void OnSelectionChange([in] SelectionDataInner selectionDataInner); + void OnSelectionChange([in] SelectionInfoData selectionInfoData); void FocusChange([in] int windowID); } diff --git a/frameworks/native/selection_ability/include/selection_listener_impl.h b/frameworks/native/selection_ability/include/selection_listener_impl.h index 5819eda..833bf2d 100644 --- a/frameworks/native/selection_ability/include/selection_listener_impl.h +++ b/frameworks/native/selection_ability/include/selection_listener_impl.h @@ -25,7 +25,7 @@ class SelectionListenerImpl : public SelectionListenerStub { public: SelectionListenerImpl(std::shared_ptr selectionI) : selectionI_(selectionI) {} ~SelectionListenerImpl() override = default; - ErrCode OnSelectionChange(const SelectionDataInner& selectionDataInner) override; + ErrCode OnSelectionChange(const SelectionInfoData& SelectionInfoData) override; ErrCode FocusChange(int32_t windowID)override; private: std::shared_ptr selectionI_; diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index 834f408..094b84c 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -22,21 +22,21 @@ namespace OHOS { namespace SelectionFwk { -static void CopySelectionData(const SelectionDataInner& src, SelectionData& dst) +static void CopySelectionData(const SelectionInfoData& src, SelectionInfo& dst) { dst = src.data; } -ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionDataInner& selectionDataInner) +ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionInfoData& selectionInfoData) { - SELECTION_HILOGI("Recveive selection data: %{public}s", selectionDataInner.data.text.c_str()); - SelectionData selectionData; - CopySelectionData(selectionDataInner, selectionData); + SELECTION_HILOGI("Recveive selection data: %{public}s", selectionInfoData.data.text.c_str()); + SelectionInfo selectionInfo; + CopySelectionData(selectionInfoData, selectionInfo); if (selectionI_ == nullptr) { SELECTION_HILOGI("selectionI_ is nullptr"); return 1; } - selectionI_->OnSelectionEvent(selectionData); + selectionI_->OnSelectionEvent(selectionInfo); return 0; } diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h index 7616c05..ad95e27 100644 --- a/service/include/selection_input_monitor.h +++ b/service/include/selection_input_monitor.h @@ -18,7 +18,7 @@ #include #include - +#include "selection_interface.h" namespace OHOS::SelectionFwk { using namespace MMI; @@ -43,43 +43,21 @@ typedef enum { SUB_WAIT_KEY_CTRL_UP = 4, } SelectInputSubState; -struct SelectionData; - -class SelectionEventListener { -public: - virtual void OnTextSelected(std::shared_ptr selectionData) { - }; - virtual ~SelectionEventListener() = default; -}; - -class DefaultSelectionEventListener : public SelectionEventListener { -public: - virtual void OnTextSelected(std::shared_ptr selectionData); - -private: - void InjectCtrlC(); - void SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction); -}; - -class SelectionInputMonitor : public IInputEventConsumer { +class BaseSelectionInputMonitor : public IInputEventConsumer { public: - SelectionInputMonitor() - : selectionEventListener_(std::make_shared()) { - selectionData_ = std::make_shared(); - } - - SelectionInputMonitor(std::shared_ptr selectionEventListener) - : selectionEventListener_(selectionEventListener) { - selectionData_ = std::make_shared(); + BaseSelectionInputMonitor() { } virtual void OnInputEvent(std::shared_ptr keyEvent) const; virtual void OnInputEvent(std::shared_ptr pointerEvent) const; virtual void OnInputEvent(std::shared_ptr axisEvent) const; + void ResetState() const; + bool IsTextSelected() const; + const SelectionInfo& GetSelectionInfo() const; + public: static bool ctrlSelectFlag; - static bool lastTextSelectedFlag; private: void InputInitialProcess(std::shared_ptr pointerEvent) const; @@ -91,18 +69,40 @@ private: void FinishedWordSelection() const; void ResetProcess(std::shared_ptr pointerEvent) const; void JudgeTripleClick() const; - bool IsTextSelected() const; void SaveSelectionStartInfo(std::shared_ptr pointerEvent) const; void SaveSelectionEndInfo(std::shared_ptr pointerEvent) const; void SaveSelectionType() const; + bool IsSelectionDone() const; - static uint32_t curSelectState; - static uint32_t subSelectState; - static int64_t lastClickTime; +private: + mutable uint32_t curSelectState = SELECT_INPUT_INITIAL; + mutable uint32_t subSelectState = SUB_INITIAL; + mutable int64_t lastClickTime = 0; + + mutable bool isTextSelected_ = false; + mutable SelectionInfo selectionInfo_; +}; + +class SelectionInputMonitor : public IInputEventConsumer { +public: + SelectionInputMonitor() { + delegate_ = std::make_shared(); + } + + virtual void OnInputEvent(std::shared_ptr keyEvent) const; + virtual void OnInputEvent(std::shared_ptr pointerEvent) const; + virtual void OnInputEvent(std::shared_ptr axisEvent) const; + +private: + void FinishedWordSelection() const; + void OnSelectionTriggered() const; + void InjectCtrlC() const; + void SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) const; - std::shared_ptr selectionEventListener_; - std::shared_ptr selectionData_; +private: + std::shared_ptr delegate_; }; + } #endif // SELECTION_INPUT_MONITOR_H \ No newline at end of file diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index fbd6f80..da47538 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -20,6 +20,7 @@ #include "common_event_manager.h" #include "selection_input_monitor.h" #include "screenlock_manager.h" +#include "window_manager.h" using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -27,12 +28,7 @@ using namespace OHOS::AppExecFwk; using namespace OHOS::MMI; using namespace OHOS::EventFwk; -uint32_t SelectionInputMonitor::curSelectState = SELECT_INPUT_INITIAL; -uint32_t SelectionInputMonitor::subSelectState = SUB_INITIAL; -int64_t SelectionInputMonitor::lastClickTime = 0; -bool SelectionInputMonitor::ctrlSelectFlag = false; -bool SelectionInputMonitor::lastTextSelectedFlag = false; - +bool BaseSelectionInputMonitor::ctrlSelectFlag = false; static int64_t GetCurrentTimeMillis() { auto now = std::chrono::system_clock::now(); @@ -40,32 +36,15 @@ static int64_t GetCurrentTimeMillis() { return std::chrono::duration_cast(duration).count(); } -void DefaultSelectionEventListener::OnTextSelected(std::shared_ptr selectionData) -{ - SELECTION_HILOGI("End word selection action."); - InjectCtrlC(); - SELECTION_HILOGI("End Inject Ctrl + C."); - sptr listener = SelectionService::GetInstance()->GetListener(); - if (listener == nullptr) { - SELECTION_HILOGE("get listener is null"); - return; - } - selectionData->text = "Hello World."; // TODO modify - SelectionDataInner dataInner; - dataInner.data = *selectionData; - listener->OnSelectionChange(dataInner); - return; +bool BaseSelectionInputMonitor::IsTextSelected() const { + return isTextSelected_; } -bool SelectionInputMonitor::IsTextSelected() const { - if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_DOUBLE_CLICKED && - curSelectState != SELECT_INPUT_TRIPLE_CLICKED) { - return false; - } - return true; +const SelectionInfo& BaseSelectionInputMonitor::GetSelectionInfo() const { + return selectionInfo_; } -void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const +void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { if (!ctrlSelectFlag) { return; @@ -110,7 +89,7 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) con return; } -void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { bool screenLockedFlag = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); if (screenLockedFlag) { @@ -170,32 +149,47 @@ void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEv return; } -void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const +void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const { SELECTION_HILOGI("[SelectionService] into axisEvent"); }; -void SelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const { curSelectState = SELECT_INPUT_INITIAL; subSelectState = SUB_INITIAL; OnInputEvent(pointerEvent); } -void SelectionInputMonitor::SaveSelectionStartInfo(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::SaveSelectionStartInfo(std::shared_ptr pointerEvent) const { int32_t pointerId = pointerEvent->GetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); - selectionData_->startPosX = pointerItem.GetDisplayX(); - selectionData_->startPosY = pointerItem.GetDisplayY(); - selectionData_->endPosX = pointerItem.GetDisplayX(); - selectionData_->endPosY = pointerItem.GetDisplayY(); - selectionData_->windowId = pointerEvent->GetTargetWindowId(); - selectionData_->bundleID = 1; // TODO modify + selectionInfo_.startPosX = pointerItem.GetDisplayX(); + selectionInfo_.startPosY = pointerItem.GetDisplayY(); + selectionInfo_.endPosX = pointerItem.GetDisplayX(); + selectionInfo_.endPosY = pointerItem.GetDisplayY(); + selectionInfo_.displayId = pointerEvent->GetTargetDisplayId(); + selectionInfo_.windowId = pointerEvent->GetTargetWindowId(); + + OHOS::Rosen::WindowInfoOption windowInfoOption; + windowInfoOption.displayId = selectionInfo_.displayId; + windowInfoOption.windowId = selectionInfo_.windowId; + std::vector> infos; + Rosen::WMError ret = Rosen::WindowManager::GetInstance().ListWindowInfo(windowInfoOption, infos); + SELECTION_HILOGI("ListWindowInfo ret: %{public}d, infos size: %{public}d", ret, infos.size()); + for (unsigned int i = 0; i < infos.size(); i++) { + auto info = infos[i]; + SELECTION_HILOGI("ListWindowInfo bundleName: %{public}s", info->windowMetaInfo.bundleName.c_str()); + } + if (ret == Rosen::WMError::WM_OK && infos.size() > 0) { + selectionInfo_.bundleName = infos[0]->windowMetaInfo.bundleName; + } + } -void SelectionInputMonitor::SaveSelectionEndInfo(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::SaveSelectionEndInfo(std::shared_ptr pointerEvent) const { if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_WAIT_LEFT_MOVE) { return; @@ -203,23 +197,23 @@ void SelectionInputMonitor::SaveSelectionEndInfo(std::shared_ptr p int32_t pointerId = pointerEvent->GetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); - selectionData_->endPosX = pointerItem.GetDisplayX(); - selectionData_->endPosY = pointerItem.GetDisplayY(); + selectionInfo_.endPosX = pointerItem.GetDisplayX(); + selectionInfo_.endPosY = pointerItem.GetDisplayY(); } -void SelectionInputMonitor::SaveSelectionType() const +void BaseSelectionInputMonitor::SaveSelectionType() const { switch (curSelectState) { case SELECT_INPUT_LEFT_MOVE: - selectionData_->selectionType = MOVE_SELECTION; + selectionInfo_.selectionType = MOVE_SELECTION; break; case SELECT_INPUT_DOUBLE_CLICKED: - selectionData_->selectionType = DOUBLE_CLICKED_SELECTION; + selectionInfo_.selectionType = DOUBLE_CLICKED_SELECTION; break; case SELECT_INPUT_TRIPLE_CLICKED: - selectionData_->selectionType = TRIPLE_CLICKED_SELECTION; + selectionInfo_.selectionType = TRIPLE_CLICKED_SELECTION; break; default: @@ -227,7 +221,15 @@ void SelectionInputMonitor::SaveSelectionType() const } } -void SelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const +bool BaseSelectionInputMonitor::IsSelectionDone() const { + if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_DOUBLE_CLICKED && + curSelectState != SELECT_INPUT_TRIPLE_CLICKED) { + return false; + } + return true; +} + +void BaseSelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); int32_t buttonId = pointerEvent->GetButtonId(); @@ -241,7 +243,7 @@ void SelectionInputMonitor::InputInitialProcess(std::shared_ptr po return; } -void SelectionInputMonitor::InputWordBeginProcess(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::InputWordBeginProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); if (action == PointerEvent::POINTER_ACTION_MOVE) { @@ -256,7 +258,7 @@ void SelectionInputMonitor::InputWordBeginProcess(std::shared_ptr return; } -void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { @@ -275,7 +277,7 @@ void SelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { @@ -329,7 +331,7 @@ void SelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); if (subSelectState == SUB_INITIAL && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { @@ -341,7 +343,7 @@ void SelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const +void BaseSelectionInputMonitor::InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); if (subSelectState != SUB_WAIT_POINTER_ACTION_BUTTON_UP) { @@ -367,38 +369,72 @@ void SelectionInputMonitor::InputWordWaitTripleClickProcess(std::shared_ptrOnTextSelected(selectionData_); + isTextSelected_ = false; } -void DefaultSelectionEventListener::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) +void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { - auto KeyEvent = KeyEvent::Create(); - KeyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - KeyEvent->SetKeyAction(keyAction); - KeyEvent::KeyItem item1, item2; - item1.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); - item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - item2.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); - item2.SetKeyCode(keyCode); - KeyEvent->AddKeyItem(item1); - KeyEvent->AddKeyItem(item2); - InputManager::GetInstance()->SimulateInputEvent(KeyEvent); + delegate_->OnInputEvent(keyEvent); + FinishedWordSelection(); +} + +void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const +{ + delegate_->OnInputEvent(pointerEvent); + FinishedWordSelection(); +} + +void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const +{ + delegate_->OnInputEvent(axisEvent); +}; + +void SelectionInputMonitor::FinishedWordSelection() const +{ + if (!delegate_->IsTextSelected()) { + return; + } + OnSelectionTriggered(); +} + +void SelectionInputMonitor::OnSelectionTriggered() const +{ + delegate_->ResetState(); + auto selectionInfo = delegate_->GetSelectionInfo(); + + SELECTION_HILOGI("End word selection action."); + InjectCtrlC(); + SELECTION_HILOGI("End Inject Ctrl + C."); + selectionInfo.text = "Hello World."; // TODO modify + SelectionInfoData dataInner; + dataInner.data = selectionInfo; + SELECTION_HILOGI("selectionInfo: %{public}s.", dataInner.ToString().c_str()); + sptr listener = SelectionService::GetInstance()->GetListener(); + if (listener == nullptr) { + SELECTION_HILOGE("get listener is null"); + return; + } + listener->OnSelectionChange(dataInner); + return; } -void DefaultSelectionEventListener::InjectCtrlC() +void SelectionInputMonitor::InjectCtrlC() const { std::this_thread::sleep_for(std::chrono::milliseconds(20)); SimulateKeyWithCtrl(KeyEvent::KEYCODE_C, KeyEvent::KEY_ACTION_DOWN); @@ -468,3 +504,18 @@ void DefaultSelectionEventListener::InjectCtrlC() // keyEvent4->AddKeyItem(item4); // InputManager::GetInstance()->SimulateInputEvent(keyEvent4); } + +void SelectionInputMonitor::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) const +{ + auto KeyEvent = KeyEvent::Create(); + KeyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + KeyEvent->SetKeyAction(keyAction); + KeyEvent::KeyItem item1, item2; + item1.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); + item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + item2.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); + item2.SetKeyCode(keyCode); + KeyEvent->AddKeyItem(item1); + KeyEvent->AddKeyItem(item2); + InputManager::GetInstance()->SimulateInputEvent(KeyEvent); +} diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 2abba2e..365df05 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -142,11 +142,11 @@ static void WatchTriggerMode(const char *key, const char *value, void *context) SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); if (strcmp(key, SYS_SELECTION_TRIGGER_USERNAM) == 0) { if (strcmp(value, SYS_SELECTION_TRIGGER_VAL) == 0) { - SelectionInputMonitor::ctrlSelectFlag = true; + BaseSelectionInputMonitor::ctrlSelectFlag = true; } else { - SelectionInputMonitor::ctrlSelectFlag = false; + BaseSelectionInputMonitor::ctrlSelectFlag = false; } - SELECTION_HILOGI("ctrlSelectFlag is %{public}d", SelectionInputMonitor::ctrlSelectFlag); + SELECTION_HILOGI("ctrlSelectFlag is %{public}d", BaseSelectionInputMonitor::ctrlSelectFlag); } } @@ -235,20 +235,19 @@ void SelectionService::OnStop() void SelectionService::InputMonitorInit() { SELECTION_HILOGI("[SelectionService] input monitor init"); - std::shared_ptr inputMonitor = std::make_shared( - std::make_shared()); + std::shared_ptr inputMonitor = std::make_shared(); if (inputMonitorId_ > 0) { return; } auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - auto remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); + auto remoteObj = sam->CheckSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); while (remoteObj == nullptr) { - SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID failed. wait..."); + SELECTION_HILOGI("CheckSystemAbility MULTIMODAL_INPUT_SERVICE_ID failed. wait..."); sleep(1); - remoteObj = sam->GetSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); + remoteObj = sam->CheckSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); } - SELECTION_HILOGI("GetSystemAbility MULTIMODAL_INPUT_SERVICE_ID succeed."); + SELECTION_HILOGI("CheckSystemAbility MULTIMODAL_INPUT_SERVICE_ID succeed."); inputMonitorId_ = InputManager::GetInstance()->AddMonitor(inputMonitor); SELECTION_HILOGI("[SelectionService] input monitor init end"); } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 94024d4..f05270c 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -28,6 +28,7 @@ ohos_unittest("selection_service_unit_test") { ] deps = [ "${selection_fwk_root_path}/service:selection_service", + "${selection_fwk_root_path}/common:selection_common", ] external_deps = [ "ability_base:want", diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index 762ac11..bf7900d 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -1,95 +1,89 @@ -/* - * Copyright (c) 2022 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 "gtest/gtest.h" - -#define private public -#include "selection_input_monitor.h" -#include "screenlock_manager.h" - -namespace OHOS { -namespace SelectionFwk { - -using namespace testing::ext; - -class SelectionInputMonitorTest : public testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - void SetUp(); - void TearDown(); - std::shared_ptr inputMonitor = nullptr; -}; - -void SelectionInputMonitorTest::SetUpTestCase() -{ - std::cout << "SelectionInputMonitorTest SetUpTestCase" << std::endl; -} - -void SelectionInputMonitorTest::TearDownTestCase() -{ - std::cout << "SelectionInputMonitorTest TearDownTestCase" << std::endl; -} - -void SelectionInputMonitorTest::SetUp() -{ - std::cout << "SelectionInputMonitorTest SetUp" << std::endl; - inputMonitor = std::make_shared(std::make_shared()); -} - -void SelectionInputMonitorTest::TearDown() -{ - std::cout << "SelectionInputMonitorTest TearDown" << std::endl; -} - -/** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event - * @tc.type: FUNC - */ -HWTEST_F(SelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) -{ - std::cout << " SelectInputMonitor001 start " << std::endl; - SelectionInputMonitor::ctrlSelectFlag = false; - SelectionInputMonitor::lastTextSelectedFlag = false; - - // bool screenLockedFlag = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); - // if (screenLockedFlag) { - // ASSERT_EQ(true, true); - // return; - // } - - std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); - pointEvent->SetPointerId(PointerEvent::MOUSE_BUTTON_LEFT); - pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN); - inputMonitor->OnInputEvent(pointEvent); - - pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); - pointEvent->SetPointerId(PointerEvent::MOUSE_BUTTON_LEFT); - pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_MOVE); - inputMonitor->OnInputEvent(pointEvent); - - pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); - pointEvent->SetPointerId(PointerEvent::MOUSE_BUTTON_LEFT); - pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP); - inputMonitor->OnInputEvent(pointEvent); - - auto ret = inputMonitor->lastTextSelectedFlag; - ASSERT_EQ(ret, true); -} - -} -} \ No newline at end of file +/* + * Copyright (c) 2022 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 "gtest/gtest.h" + +#define private public +#include "selection_input_monitor.h" +#include "screenlock_manager.h" + +namespace OHOS { +namespace SelectionFwk { + +using namespace testing::ext; + +struct EventStruct { + int buttonId; + int pointId; + int action; +}; +class BaseSelectionInputMonitorTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); + std::shared_ptr inputMonitor = nullptr; +}; + +void BaseSelectionInputMonitorTest::SetUpTestCase() +{ + std::cout << "BaseSelectionInputMonitorTest SetUpTestCase" << std::endl; +} + +void BaseSelectionInputMonitorTest::TearDownTestCase() +{ + std::cout << "BaseSelectionInputMonitorTest TearDownTestCase" << std::endl; +} + +void BaseSelectionInputMonitorTest::SetUp() +{ + std::cout << "BaseSelectionInputMonitorTest SetUp" << std::endl; + inputMonitor = std::make_shared(); +} + +void BaseSelectionInputMonitorTest::TearDown() +{ + std::cout << "BaseSelectionInputMonitorTest TearDown" << std::endl; +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) +{ + std::cout << " SelectInputMonitor001 start " << std::endl; + vector events = { + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_MOVE}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} + }; + + for (uint16_t i = 0; i < events.size(); i++) { + auto event = events[i]; + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetButtonId(event.buttonId); + pointEvent->SetPointerId(event.pointId); + pointEvent->SetPointerAction(event.action); + inputMonitor->OnInputEvent(pointEvent); + } + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +} +} -- Gitee From d885f31b67fcfd25e212237db7c0a23d9f8accd4 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Sat, 7 Jun 2025 18:12:40 +0800 Subject: [PATCH 58/93] =?UTF-8?q?1.=E5=AE=9E=E7=8E=B0on(destroyed/hidden),?= =?UTF-8?q?off(destroyed/hidden)=202.=E6=B3=A8=E9=87=8A=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E4=B8=8D=E7=94=A8=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/callback_object.cpp | 25 ++ common/callback_object.h | 2 + common/event_checker.cpp | 2 +- .../js/napi/selection_ability/js_panel.cpp | 12 +- .../selection_ability/panel_listener_impl.cpp | 219 ++++++++++-------- .../selection_ability/panel_listener_impl.h | 16 +- .../include/panel_status_listener.h | 8 +- .../include/selection_panel.h | 8 +- .../include/selection_window_info.h | 4 +- .../selection_ability/src/selection_panel.cpp | 42 ++-- 10 files changed, 196 insertions(+), 142 deletions(-) diff --git a/common/callback_object.cpp b/common/callback_object.cpp index d661443..3f05463 100644 --- a/common/callback_object.cpp +++ b/common/callback_object.cpp @@ -54,6 +54,31 @@ JSCallbackObject::~JSCallbackObject() env_ = nullptr; } +bool JSCallbackObject::operator==(const JSCallbackObject& other) const +{ + if (other.env_ != env_ || other.threadId_ != threadId_) { + return false; + } + + napi_value thisValue, otherValue; + napi_status status; + status = napi_get_reference_value(env_, this->callback_, &thisValue); + if (status != napi_ok) { + return false; + } + status = napi_get_reference_value(env_, other.callback_, &otherValue); + if (status != napi_ok) { + return false; + } + + bool result; + status = napi_strict_equals(env_, thisValue, otherValue, &result); + if (status != napi_ok) { + return false; + } + + return result; +} JSMsgHandlerCallbackObject::JSMsgHandlerCallbackObject(napi_env env, napi_value onTerminated, napi_value onMessage) : env_(env), handler_(AppExecFwk::EventHandler::Current()), threadId_(std::this_thread::get_id()) diff --git a/common/callback_object.h b/common/callback_object.h index cf18785..0fc441d 100644 --- a/common/callback_object.h +++ b/common/callback_object.h @@ -30,6 +30,8 @@ public: JSCallbackObject(napi_env env, napi_value callback, std::thread::id threadId, std::shared_ptr jsHandler); ~JSCallbackObject(); + bool operator==(const JSCallbackObject& other) const; + napi_ref callback_ = nullptr; napi_env env_{}; std::thread::id threadId_; diff --git a/common/event_checker.cpp b/common/event_checker.cpp index 4543b72..97ec29f 100644 --- a/common/event_checker.cpp +++ b/common/event_checker.cpp @@ -20,7 +20,7 @@ namespace OHOS { namespace SelectionFwk { const std::unordered_set EVENT_TYPES[static_cast(EventSubscribeModule::MODULE_END)] = { [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionEvent", "selectionPanelEvent" }, - [static_cast(EventSubscribeModule::PANEL)] = { "show", "hide" } + [static_cast(EventSubscribeModule::PANEL)] = { "destroyed", "hidden" } }; bool EventChecker::IsValidEventType(EventSubscribeModule module, const std::string &type) diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 0df449b..20d5e0b 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -349,8 +349,16 @@ napi_value JsPanel::UnSubscribe(napi_env env, napi_callback_info info) SELECTION_HILOGE("selectionPanel is nullptr!"); return nullptr; } - observer->RemoveInfo(type, selectionPanel->windowId_); - selectionPanel->ClearPanelListener(type); + + if (paramType == napi_function) { + std::shared_ptr cbObject = std::make_shared( + env, argv[1], std::this_thread::get_id(), AppExecFwk::EventHandler::Current()); + observer->RemoveInfo(type, selectionPanel->windowId_, cbObject); + } else { + observer->RemoveInfo(type, selectionPanel->windowId_); + selectionPanel->ClearPanelListener(type); + } + napi_value result = nullptr; napi_get_null(env, &result); return result; diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp index 75d9a3f..359eeb8 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -48,109 +48,105 @@ std::shared_ptr PanelListenerImpl::GetEventHandler() return handler_; } -void PanelListenerImpl::OnPanelStatus(uint32_t windowId, bool isShow) +void PanelListenerImpl::OnPanelStatus(uint32_t windowId, const std::string& status) { - std::string type = isShow ? "show" : "hide"; auto eventHandler = GetEventHandler(); if (eventHandler == nullptr) { SELECTION_HILOGE("eventHandler is nullptr!"); return; } - std::shared_ptr callBack = GetCallback(windowId, type); - if (callBack == nullptr) { + CallbackVector callBacks = GetCallback(windowId, status); + if (callBacks.empty()) { SELECTION_HILOGE("callBack is nullptr!"); return; } - auto entry = std::make_shared(callBack); - SELECTION_HILOGI("windowId = %{public}u, type = %{public}s", windowId, type.c_str()); - auto task = [entry]() { - SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }); + SELECTION_HILOGI("OnPanelStatus status: %{public}s", status.c_str()); + auto task = [callBacks]() { + SelectionFwk::JsCallbackHandler::Traverse(callBacks); }; - eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); + eventHandler->PostTask(task, status, 0, AppExecFwk::EventQueue::Priority::VIP); } -void PanelListenerImpl::OnSizeChange(uint32_t windowId, const WindowSize &size) +// void PanelListenerImpl::OnSizeChange(uint32_t windowId, const WindowSize &size) +// { +// std::string type = "sizeChange"; +// auto eventHandler = GetEventHandler(); +// if (eventHandler == nullptr) { +// SELECTION_HILOGE("eventHandler is nullptr!"); +// return; +// } +// std::shared_ptr callBack = GetCallback(windowId, type); +// if (callBack == nullptr) { +// return; +// } +// auto entry = std::make_shared(callBack); +// entry->size = size; +// SELECTION_HILOGI("OnSizeChange start. windowId:%{public}u, w:%{public}u, h:%{public}u", windowId, size.width, +// size.height); +// auto task = [entry]() { +// auto gitWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { +// if (argc == 0) { +// return false; +// } +// napi_value windowSize = JsWindowSize::Write(env, entry->size); +// // 0 means the first param of callback. +// args[0] = { windowSize }; +// return true; +// }; +// SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 1, gitWindowSizeParams }); +// }; +// eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); +// } + +// void PanelListenerImpl::OnSizeChange( +// uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) +// { + // std::string type = "sizeUpdate"; + // auto eventHandler = GetEventHandler(); + // if (eventHandler == nullptr) { + // SELECTION_HILOGE("eventHandler is nullptr!"); + // return; + // } + // std::shared_ptr callBack = GetCallback(windowId, event); + // if (callBack == nullptr) { + // SELECTION_HILOGE("callback is nullptr"); + // return; + // } + // auto entry = std::make_shared(callBack); + // entry->size = size; + // entry->keyboardArea = keyboardArea; + // SELECTION_HILOGI("%{public}s start. windowId:%{public}u, windowSize[%{public}u/%{public}u], " + // "keyboardArea:[%{public}d/%{public}d/%{public}d/%{public}d]", + // event.c_str(), windowId, size.width, size.height, keyboardArea.top, keyboardArea.bottom, keyboardArea.left, + // keyboardArea.right); + // auto task = [entry]() { + // auto getWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { + // if (argc == 0) { + // return false; + // } + // napi_value windowSize = JsWindowSize::Write(env, entry->size); + // napi_value jsKeyboardArea = JsKeyboardArea::Write(env, entry->keyboardArea); + // args[0] = { windowSize }; + // args[1] = { jsKeyboardArea }; + // return true; + // }; + // // 2 means 'sizeChange' has 2 params + // SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 2, getWindowSizeParams }); + // }; + // eventHandler->PostTask(task, event, 0, AppExecFwk::EventQueue::Priority::VIP); +// } + + +CallbackVector PanelListenerImpl::GetCallback(uint32_t windowId, const std::string &type) { - std::string type = "sizeChange"; - auto eventHandler = GetEventHandler(); - if (eventHandler == nullptr) { - SELECTION_HILOGE("eventHandler is nullptr!"); - return; - } - std::shared_ptr callBack = GetCallback(windowId, type); - if (callBack == nullptr) { - return; - } - auto entry = std::make_shared(callBack); - entry->size = size; - SELECTION_HILOGI("OnSizeChange start. windowId:%{public}u, w:%{public}u, h:%{public}u", windowId, size.width, - size.height); - auto task = [entry]() { - auto gitWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { - if (argc == 0) { - return false; - } - napi_value windowSize = JsWindowSize::Write(env, entry->size); - // 0 means the first param of callback. - args[0] = { windowSize }; - return true; - }; - SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 1, gitWindowSizeParams }); - }; - eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); -} - -void PanelListenerImpl::OnSizeChange( - uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) -{ - std::string type = "sizeUpdate"; - auto eventHandler = GetEventHandler(); - if (eventHandler == nullptr) { - SELECTION_HILOGE("eventHandler is nullptr!"); - return; - } - std::shared_ptr callBack = GetCallback(windowId, event); - if (callBack == nullptr) { - SELECTION_HILOGE("callback is nullptr"); - return; - } - auto entry = std::make_shared(callBack); - entry->size = size; - entry->keyboardArea = keyboardArea; - SELECTION_HILOGI("%{public}s start. windowId:%{public}u, windowSize[%{public}u/%{public}u], " - "keyboardArea:[%{public}d/%{public}d/%{public}d/%{public}d]", - event.c_str(), windowId, size.width, size.height, keyboardArea.top, keyboardArea.bottom, keyboardArea.left, - keyboardArea.right); - auto task = [entry]() { - auto getWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { - if (argc == 0) { - return false; - } - napi_value windowSize = JsWindowSize::Write(env, entry->size); - napi_value jsKeyboardArea = JsKeyboardArea::Write(env, entry->keyboardArea); - args[0] = { windowSize }; - args[1] = { jsKeyboardArea }; - return true; - }; - // 2 means 'sizeChange' has 2 params - SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 2, getWindowSizeParams }); - }; - eventHandler->PostTask(task, event, 0, AppExecFwk::EventQueue::Priority::VIP); -} - - -std::shared_ptr PanelListenerImpl::GetCallback(uint32_t windowId, const std::string &type) -{ - std::shared_ptr callBack = nullptr; - callbacks_.ComputeIfPresent(windowId, [&type, &callBack](uint32_t id, auto callbacks) { - auto it = callbacks.find(type); - if (it == callbacks.end()) { - return !callbacks.empty(); + CallbackVector callBackVector; + callbacks_.ComputeIfPresent(windowId, [&type, &callBackVector](uint32_t id, TypeMap& callbacks) { + if (callbacks.find(type) != callbacks.end()) { + callBackVector = callbacks[type]; } - callBack = it->second; return !callbacks.empty(); }); - return callBack; + return callBackVector; } napi_value JsWindowSize::Write(napi_env env, const WindowSize &nativeObject) @@ -192,25 +188,48 @@ bool JsKeyboardArea::Read(napi_env env, napi_value jsObject, PanelAdjustInfo &na void PanelListenerImpl::Subscribe(uint32_t windowId, const std::string &type, std::shared_ptr cbObject) { - callbacks_.Compute(windowId, - [cbObject, &type](auto windowId, std::map> &cbs) { - auto [it, insert] = cbs.try_emplace(type, cbObject); - if (insert) { - SELECTION_HILOGI("start to subscribe type: %{public}s of windowId: %{public}u.", type.c_str(), windowId); - } else { - SELECTION_HILOGD("type: %{public}s of windowId: %{public}u already subscribed.", type.c_str(), windowId); - } + callbacks_.Compute(windowId, [cbObject, &type](auto windowId, TypeMap& cbs) { + if (cbs.find(type) == cbs.end()) { + cbs.try_emplace(type, CallbackVector {cbObject}); return !cbs.empty(); - }); + } + auto it = std::find_if( + cbs[type].begin(), cbs[type].end(), + [cbObject](const std::shared_ptr& vecCbObject) { return *vecCbObject == *cbObject; }); + if (it == cbs[type].end()) { + cbs[type].emplace_back(cbObject); + SELECTION_HILOGI("start to subscribe type: %{public}s of windowId: %{public}u.", type.c_str(), windowId); + } else { + SELECTION_HILOGI("type: %{public}s of windowId: %{public}u already subscribed.", type.c_str(), windowId); + } + return !cbs.empty(); + }); } void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId) { - callbacks_.ComputeIfPresent(windowId, - [&type](auto windowId, std::map> &cbs) { - cbs.erase(type); + callbacks_.ComputeIfPresent(windowId, [&type](auto windowId, TypeMap& cbs) { + cbs.erase(type); + return !cbs.empty(); + }); +} + +void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId, std::shared_ptr cbObject) +{ + callbacks_.ComputeIfPresent(windowId, [&type, cbObject](auto windowId, TypeMap& cbs) { + auto it = cbs.find(type); + if (it == cbs.end()) { return !cbs.empty(); - }); + } + auto targetCallback = std::find_if( + cbs[type].begin(), cbs[type].end(), + [cbObject](std::shared_ptr vecCbObject) { return *vecCbObject == *cbObject; }); + if (targetCallback != cbs[type].end()) { + cbs[type].erase(targetCallback); + } + + return !cbs.empty(); + }); } } // namespace SelectionFwk diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.h b/frameworks/js/napi/selection_ability/panel_listener_impl.h index 6332d3e..c1f35d8 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.h +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.h @@ -33,6 +33,8 @@ namespace OHOS { namespace SelectionFwk { +using CallbackVector = std::vector>; +using TypeMap = std::map; struct JsWindowSize { static napi_value Write(napi_env env, const WindowSize &nativeObject); @@ -62,21 +64,21 @@ struct UvEntry { void SetEventHandler(std::shared_ptr handler); std::shared_ptr GetEventHandler(); - void OnPanelStatus(uint32_t windowId, bool isShow) override; - void OnSizeChange(uint32_t windowId, const WindowSize &size) override; - void OnSizeChange(uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, - const std::string &event) override; + void OnPanelStatus(uint32_t windowId, const std::string& status) override; + // void OnSizeChange(uint32_t windowId, const WindowSize &size) override; + // void OnSizeChange(uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, + // const std::string &event) override; void Subscribe(uint32_t windowId, const std::string &type, std::shared_ptr cbObject); + void RemoveInfo(const std::string &type, uint32_t windowId, std::shared_ptr cbObject); void RemoveInfo(const std::string &type, uint32_t windowId); - std::shared_ptr GetCallback(uint32_t windowId, const std::string &type); + CallbackVector GetCallback(uint32_t windowId, const std::string &type); static std::mutex listenerMutex_; static std::shared_ptr instance_; mutable std::shared_mutex eventHandlerMutex_; std::shared_ptr handler_; - - ConcurrentMap>> callbacks_; + ConcurrentMap callbacks_; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/native/selection_ability/include/panel_status_listener.h b/frameworks/native/selection_ability/include/panel_status_listener.h index 86a0f39..88d83e4 100644 --- a/frameworks/native/selection_ability/include/panel_status_listener.h +++ b/frameworks/native/selection_ability/include/panel_status_listener.h @@ -24,10 +24,10 @@ namespace SelectionFwk { class PanelStatusListener { public: virtual ~PanelStatusListener() {}; - virtual void OnPanelStatus(uint32_t windowId, bool isShow) = 0; - virtual void OnSizeChange(uint32_t windowId, const WindowSize &size) = 0; - virtual void OnSizeChange( - uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) = 0; + virtual void OnPanelStatus(uint32_t windowId, const std::string& status) = 0; + // virtual void OnSizeChange(uint32_t windowId, const WindowSize &size) = 0; + // virtual void OnSizeChange( + // uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) = 0; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 3c8bf62..cff5999 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -57,6 +57,10 @@ public: uint32_t windowId_ = INVALID_WINDOW_ID; private: + inline static const std::unordered_map panelStatusMap_ { + { SelectionWindowStatus::HIDDEN, "hidden" }, + { SelectionWindowStatus::DESTROYED, "destroyed" } + }; std::string GeneratePanelName(); int32_t SetPanelProperties(); static uint32_t GenerateSequenceId(); @@ -75,8 +79,8 @@ private: uint32_t invalidGravityPercent = 0; std::atomic isWaitSetUiContent_ { true }; std::shared_ptr panelStatusListener_ = nullptr; - bool showRegistered_ = false; - bool hideRegistered_ = false; + bool destroyedRegistered_ = false; + bool hiddedRegistered_ = false; }; } // namespace SelectionFwk diff --git a/frameworks/native/selection_ability/include/selection_window_info.h b/frameworks/native/selection_ability/include/selection_window_info.h index 72345bf..08605b5 100644 --- a/frameworks/native/selection_ability/include/selection_window_info.h +++ b/frameworks/native/selection_ability/include/selection_window_info.h @@ -24,8 +24,8 @@ namespace OHOS { namespace SelectionFwk { enum class SelectionWindowStatus : uint32_t { - SHOW, - HIDE, + HIDDEN, + DESTROYED, NONE }; diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index b4f286b..e4b22b6 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -166,6 +166,7 @@ int32_t SelectionPanel::DestroyPanel() } auto result = window_->Destroy(); SELECTION_HILOGI("destroy ret: %{public}d", result); + PanelStatusChange(SelectionWindowStatus::DESTROYED); return ErrorCode::NO_ERROR; } @@ -228,7 +229,6 @@ int32_t SelectionPanel::ShowPanel() return ErrorCode::ERROR_OPERATE_PANEL; } SELECTION_HILOGI("Selection panel shown successfully."); - PanelStatusChange(SelectionWindowStatus::SHOW); return ErrorCode::NO_ERROR; } @@ -248,13 +248,14 @@ bool SelectionPanel::IsShowing() void SelectionPanel::PanelStatusChange(const SelectionWindowStatus &status) { - if (status == SelectionWindowStatus::SHOW && showRegistered_ && panelStatusListener_ != nullptr) { - SELECTION_HILOGD("ShowPanel panelStatusListener_ is not nullptr."); - panelStatusListener_->OnPanelStatus(windowId_, true); - } - if (status == SelectionWindowStatus::HIDE && hideRegistered_ && panelStatusListener_ != nullptr) { - SELECTION_HILOGD("HidePanel panelStatusListener_ is not nullptr."); - panelStatusListener_->OnPanelStatus(windowId_, false); + if (panelStatusListener_ != nullptr) { + SELECTION_HILOGD("panelStatusListener_ is not nullptr."); + if (status == SelectionWindowStatus::HIDDEN && hiddedRegistered_ ) { + panelStatusListener_->OnPanelStatus(windowId_, panelStatusMap_.at(status)); + } + if (status == SelectionWindowStatus::DESTROYED && destroyedRegistered_ ) { + panelStatusListener_->OnPanelStatus(windowId_, panelStatusMap_.at(status)); + } } } @@ -280,7 +281,7 @@ int32_t SelectionPanel::HidePanel() } SELECTION_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast(panelType_), static_cast(panelFlag_)); - PanelStatusChange(SelectionWindowStatus::HIDE); + PanelStatusChange(SelectionWindowStatus::HIDDEN); return ErrorCode::NO_ERROR; } @@ -335,29 +336,22 @@ bool SelectionPanel::SetPanelStatusListener(std::shared_ptr return false; } SELECTION_HILOGD("type: %{public}s.", type.c_str()); - if (type == "show" || type == "hide") { - if (panelStatusListener_ == nullptr) { + if (panelStatusListener_ == nullptr) { + auto isExist = [&type](const auto& pair) { return pair.second == type; }; + if (std::find_if(panelStatusMap_.begin(), panelStatusMap_.end(), isExist) != panelStatusMap_.end()) { SELECTION_HILOGD("panelStatusListener_ is nullptr, need to be set"); panelStatusListener_ = std::move(statusListener); } - if (window_ != nullptr) { - if (type == "show" && IsShowing()) { - panelStatusListener_->OnPanelStatus(windowId_, true); - } - if (type == "hide" && IsHidden()) { - panelStatusListener_->OnPanelStatus(windowId_, false); - } - } } return true; } bool SelectionPanel::MarkListener(const std::string &type, bool isRegister) { - if (type == "show") { - showRegistered_ = isRegister; - } else if (type == "hide") { - hideRegistered_ = isRegister; + if (type == panelStatusMap_.at(SelectionWindowStatus::DESTROYED)) { + destroyedRegistered_ = isRegister; + } else if (type == panelStatusMap_.at(SelectionWindowStatus::HIDDEN)) { + hiddedRegistered_ = isRegister; } else { SELECTION_HILOGE("type error!"); return false; @@ -375,7 +369,7 @@ void SelectionPanel::ClearPanelListener(const std::string &type) SELECTION_HILOGD("panelStatusListener_ not set, don't need to remove."); return; } - if (showRegistered_ || hideRegistered_) { + if (destroyedRegistered_ || hiddedRegistered_) { return; } panelStatusListener_ = nullptr; -- Gitee From 3ca836c6759f192b25f5f3bbde8f83042c308579 Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Sat, 7 Jun 2025 18:22:18 +0800 Subject: [PATCH 59/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9panelInfo=E5=8F=8A?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/js_utils.cpp | 23 ---------- .../js/napi/selection_ability/js_panel.h | 1 - .../js_selection_engine_setting.cpp | 4 +- .../selection_client/js_selection_utils.cpp | 22 ++++------ .../selection_ability/include/panel_info.h | 34 +++++++++------ .../include/selection_panel.h | 7 ++- .../selection_ability/src/selection_panel.cpp | 43 ++++++------------- 7 files changed, 50 insertions(+), 84 deletions(-) diff --git a/common/js_utils.cpp b/common/js_utils.cpp index 936c704..4d25192 100644 --- a/common/js_utils.cpp +++ b/common/js_utils.cpp @@ -304,29 +304,6 @@ napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &ty return napi_generic_failure; } -// napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out) -// { -// SELECTION_HILOGD("napi_value -> PanelInfo "); -// napi_value propType = nullptr; -// napi_status status = napi_get_named_property(env, in, "type", &propType); -// CHECK_RETURN((status == napi_ok), "no property type ", status); -// int32_t panelType = 0; -// status = GetValue(env, propType, panelType); -// CHECK_RETURN((status == napi_ok), "no value of type ", status); - -// // PanelFlag is optional, defaults to FLG_FIXED when empty. -// int32_t panelFlag = static_cast(PanelFlag::FLG_FIXED); -// napi_value panelFlagObj = nullptr; -// status = napi_get_named_property(env, in, "flag", &panelFlagObj); -// if (status == napi_ok) { -// JsUtils::GetValue(env, panelFlagObj, panelFlag); -// } - -// out.panelType = PanelType(panelType); -// out.panelFlag = PanelFlag(panelFlag); -// return napi_ok; -// } - napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out) { return napi_create_string_utf8(env, in.c_str(), in.size(), &out); diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index 93d2608..80584cd 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -72,7 +72,6 @@ private: HotAreas hotAreas; std::vector hotArea; bool isEnhancedCall{ false }; - PanelFlag panelFlag = PanelFlag::FLG_FIXED; std::string path = ""; uint32_t width = 0; uint32_t height = 0; diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index a239f78..acbf0ba 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -138,7 +138,9 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf napi_invalid_arg); status = OHOS::SelectionFwk::JsSelectionUtils::GetValue(env, argv[1], ctxt->panelInfo); SELECTION_HILOGD( - "output js param panelInfo covert , type/flag: %{public}d/%{public}d.", static_cast(ctxt->panelInfo.panelType), static_cast(ctxt->panelInfo.panelFlag)); + "output js param panelInfo covert , panelType/x/y/width/height: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", + static_cast(ctxt->panelInfo.panelType), ctxt->panelInfo.x, ctxt->panelInfo.y, ctxt->panelInfo.width, + ctxt->panelInfo.height); PARAM_CHECK_RETURN(env, status == napi_ok, "js param info covert failed!", TYPE_NONE, napi_invalid_arg); return status; }; diff --git a/frameworks/js/napi/selection_client/js_selection_utils.cpp b/frameworks/js/napi/selection_client/js_selection_utils.cpp index f240f11..0d6b32d 100644 --- a/frameworks/js/napi/selection_client/js_selection_utils.cpp +++ b/frameworks/js/napi/selection_client/js_selection_utils.cpp @@ -28,23 +28,19 @@ napi_status JsSelectionUtils::GetValue(napi_env env, napi_value in, PanelInfo &o { SELECTION_HILOGD("napi_value -> PanelInfo "); napi_value propType = nullptr; - napi_status status = napi_get_named_property(env, in, "type", &propType); - CHECK_RETURN((status == napi_ok), "no property type ", status); + napi_status status = napi_get_named_property(env, in, "panelType", &propType); + CHECK_RETURN((status == napi_ok), "no property panelType ", status); int32_t panelType = 0; status = JsUtils::GetValue(env, propType, panelType); - CHECK_RETURN((status == napi_ok), "no value of type ", status); + CHECK_RETURN((status == napi_ok), "no value of panelType ", status); + out.panelType = PanelType(panelType); - // PanelFlag is optional, defaults to FLG_FIXED when empty. - int32_t panelFlag = static_cast(PanelFlag::FLG_FIXED); - napi_value panelFlagObj = nullptr; - status = napi_get_named_property(env, in, "flag", &panelFlagObj); - if (status == napi_ok) { - JsUtils::GetValue(env, panelFlagObj, panelFlag); - } + bool ret = JsUtil::Object::ReadProperty(env, in, "x", out.x); + ret = ret && JsUtil::Object::ReadProperty(env, in, "y", out.y); + ret = ret && JsUtil::Object::ReadProperty(env, in, "width", out.width); + ret = ret && JsUtil::Object::ReadProperty(env, in, "height", out.height); - out.panelType = PanelType(panelType); - out.panelFlag = PanelFlag(panelFlag); - return napi_ok; + return ret ? napi_ok : napi_generic_failure; } } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/panel_info.h b/frameworks/native/selection_ability/include/panel_info.h index 7e93eec..56cd5bc 100644 --- a/frameworks/native/selection_ability/include/panel_info.h +++ b/frameworks/native/selection_ability/include/panel_info.h @@ -21,26 +21,25 @@ namespace OHOS { namespace SelectionFwk { enum PanelType { - SOFT_KEYBOARD = 0, - STATUS_BAR, -}; - -enum PanelFlag { - FLG_FIXED = 0, - FLG_FLOATING, - FLG_CANDIDATE_COLUMN, + MENU_PANEL = 1, + MAIN_PANEL = 2, }; struct PanelInfo : public Parcelable { - PanelType panelType = SOFT_KEYBOARD; - PanelFlag panelFlag = FLG_FIXED; + PanelType panelType = MAIN_PANEL; + int32_t x = 0; + int32_t y = 0; + int32_t width = 0; + int32_t height = 0; bool ReadFromParcel(Parcel &in) { int32_t panelTypeData = in.ReadInt32(); - int32_t panelFlagData = in.ReadInt32(); panelType = static_cast(panelTypeData); - panelFlag = static_cast(panelFlagData); + x = in.ReadInt32(); + y = in.ReadInt32(); + width = in.ReadInt32(); + height = in.ReadInt32(); return true; } bool Marshalling(Parcel &out) const @@ -48,7 +47,16 @@ struct PanelInfo : public Parcelable { if (!out.WriteInt32(static_cast(panelType))) { return false; } - if (!out.WriteInt32(static_cast(panelFlag))) { + if (!out.WriteInt32(x)) { + return false; + } + if (!out.WriteInt32(y)) { + return false; + } + if (!out.WriteInt32(width)) { + return false; + } + if (!out.WriteInt32(height)) { return false; } return true; diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index cff5999..93f66c2 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -67,9 +67,12 @@ private: void PanelStatusChange(const SelectionWindowStatus &status); bool MarkListener(const std::string &type, bool isRegister); + PanelType panelType_ = PanelType::MENU_PANEL; + int32_t x_ = 0; + int32_t y_ = 0; + int32_t width_ = 0; + int32_t height_ = 0; - PanelType panelType_ = PanelType::STATUS_BAR;//待修改 - PanelFlag panelFlag_ = PanelFlag::FLG_FIXED;//待修改 static std::mutex windowMutex_; static sptr window_; sptr winOption_ = nullptr; diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index e4b22b6..b79ea2b 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -43,9 +43,14 @@ int32_t SelectionPanel::CreatePanel( { SELECTION_HILOGI("SelectionPanel CreatePanel start."); panelType_ = panelInfo.panelType; - panelFlag_ = panelInfo.panelFlag; - SELECTION_HILOGD( - "start, type/flag: %{public}d/%{public}d.", static_cast(panelType_), static_cast(panelFlag_)); + x_ = panelInfo.x; + y_ = panelInfo.y; + width_ = panelInfo.width; + height_ = panelInfo.height; + SELECTION_HILOGI( + "start , panelType/x/y/width/height: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", + static_cast(panelType_), x_, y_, width_, height_); + // winOption_ = new (std::nothrow) OHOS::Rosen::WindowOption(); // if (winOption_ == nullptr) { // return ErrorCode::ERROR_NULL_POINTER; @@ -104,8 +109,8 @@ int32_t SelectionPanel::CreatePanel( std::string SelectionPanel::GeneratePanelName() { uint32_t sequenceId = GenerateSequenceId(); - std::string windowName = panelType_ == SOFT_KEYBOARD ? "softKeyboard" + std::to_string(sequenceId) : - "statusBar" + std::to_string(sequenceId); + std::string windowName = panelType_ == MENU_PANEL ? "menuPanel" + std::to_string(sequenceId) : + "mainPanel" + std::to_string(sequenceId); SELECTION_HILOGD("SelectionPanel, windowName: %{public}s.", windowName.c_str()); return windowName; } @@ -117,26 +122,6 @@ int32_t SelectionPanel::SetPanelProperties() return ErrorCode::ERROR_OPERATE_PANEL; } WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT; - if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) { - gravity = WindowGravity::WINDOW_GRAVITY_BOTTOM; - } else if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FLOATING) { - auto surfaceNode = window_->GetSurfaceNode(); - if (surfaceNode == nullptr) { - SELECTION_HILOGE("surfaceNode is nullptr!"); - return ErrorCode::ERROR_OPERATE_PANEL; - } - surfaceNode->SetFrameGravity(Rosen::Gravity::TOP_LEFT); - Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction(); - } else if (panelType_ == STATUS_BAR) { - auto surfaceNo = window_->GetSurfaceNode(); - if (surfaceNo == nullptr) { - SELECTION_HILOGE("surfaceNo is nullptr!"); - return ErrorCode::ERROR_OPERATE_PANEL; - } - surfaceNo->SetFrameGravity(Rosen::Gravity::TOP_LEFT); - Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction(); - return ErrorCode::NO_ERROR; - } if (!isScbEnable_) { WMError wmError = window_->SetWindowGravity(gravity, invalidGravityPercent); if (wmError != WMError::WM_OK) { @@ -279,8 +264,8 @@ int32_t SelectionPanel::HidePanel() SELECTION_HILOGE("HidePanel error, err: %{public}d!", ret); return ErrorCode::ERROR_OPERATE_PANEL; } - SELECTION_HILOGI("success, type/flag: %{public}d/%{public}d.", static_cast(panelType_), - static_cast(panelFlag_)); + SELECTION_HILOGI("success, panelType/x/y/width/height: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", + static_cast(panelType_), x_, y_, width_, height_); PanelStatusChange(SelectionWindowStatus::HIDDEN); return ErrorCode::NO_ERROR; } @@ -321,10 +306,6 @@ int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) SELECTION_HILOGE("window_ is nullptr!"); return ErrorCode::ERROR_NULL_POINTER; } - if (panelFlag_ == FLG_FIXED) { - SELECTION_HILOGE("FLG_FIXED panel can not moveTo!"); - return ErrorCode::NO_ERROR; - } auto ret = window_->MoveTo(x, y); SELECTION_HILOGI("x/y: %{public}d/%{public}d, ret = %{public}d", x, y, ret); return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR; -- Gitee From 76db6e0e3e817ed9341953cbed4a1cc804b84d1a Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Sat, 7 Jun 2025 19:03:56 +0800 Subject: [PATCH 60/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=89=AA=E8=B4=B4?= =?UTF-8?q?=E6=9D=BF=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- .../include/PasteboardDisposableObserver.h | 14 +++++++ service/include/selection_input_monitor.h | 23 ++++++++-- service/src/selection_input_monitor.cpp | 42 ++++++++++++++----- .../unittest/selection_input_monitor_test.cpp | 8 ++-- 4 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 service/include/PasteboardDisposableObserver.h diff --git a/service/include/PasteboardDisposableObserver.h b/service/include/PasteboardDisposableObserver.h new file mode 100644 index 0000000..21087a0 --- /dev/null +++ b/service/include/PasteboardDisposableObserver.h @@ -0,0 +1,14 @@ +#ifndef PASTEBOARD_DISPOSABLE_OBSERVER_H +#define PASTEBOARD_DISPOSABLE_OBSERVER_H + +#include + +namespace OHOS { +namespace MiscServices { +class PasteboardDisposableObserver { +public: + virtual void OnTextReceived(const std::string &text, int32_t errCode) = 0; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // PASTEBOARD_DISPOSABLE_OBSERVER_H \ No newline at end of file diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h index ad95e27..25d5c31 100644 --- a/service/include/selection_input_monitor.h +++ b/service/include/selection_input_monitor.h @@ -19,8 +19,10 @@ #include #include #include "selection_interface.h" +#include "PasteboardDisposableObserver.h" namespace OHOS::SelectionFwk { using namespace MMI; +using namespace OHOS::MiscServices; constexpr const uint32_t DOUBLE_CLICK_TIME = 500; @@ -78,12 +80,26 @@ private: mutable uint32_t curSelectState = SELECT_INPUT_INITIAL; mutable uint32_t subSelectState = SUB_INITIAL; mutable int64_t lastClickTime = 0; - mutable bool isTextSelected_ = false; mutable SelectionInfo selectionInfo_; }; -class SelectionInputMonitor : public IInputEventConsumer { +class SelectionInputMonitor; + +class SelectionPasteboardDisposableObserver : public PasteboardDisposableObserver { +public: + SelectionPasteboardDisposableObserver(std::shared_ptr pInputMonitor) + : pInputMonitor_(pInputMonitor) { + } + virtual ~SelectionPasteboardDisposableObserver() = default; + + void OnTextReceived(const std::string &text, int32_t errCode) override; + +private: + std::shared_ptr pInputMonitor_; +}; + +class SelectionInputMonitor : public IInputEventConsumer, public std::enable_shared_from_this { public: SelectionInputMonitor() { delegate_ = std::make_shared(); @@ -92,15 +108,16 @@ public: virtual void OnInputEvent(std::shared_ptr keyEvent) const; virtual void OnInputEvent(std::shared_ptr pointerEvent) const; virtual void OnInputEvent(std::shared_ptr axisEvent) const; + void OnSelectionTriggered(const std::string &text) const; private: void FinishedWordSelection() const; - void OnSelectionTriggered() const; void InjectCtrlC() const; void SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) const; private: std::shared_ptr delegate_; + mutable std::shared_ptr pasteboardObserver_; }; } diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index da47538..e90dcd6 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -232,8 +232,8 @@ bool BaseSelectionInputMonitor::IsSelectionDone() const { void BaseSelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - int32_t buttonId = pointerEvent->GetButtonId(); - if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && buttonId == PointerEvent::MOUSE_BUTTON_LEFT) { + int32_t pointerId = pointerEvent->GetPointerId(); + if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && pointerId == PointerEvent::MOUSE_BUTTON_LEFT) { curSelectState = SELECT_INPUT_WORD_BEGIN; subSelectState = SUB_INITIAL; lastClickTime = GetCurrentTimeMillis(); @@ -410,18 +410,28 @@ void SelectionInputMonitor::FinishedWordSelection() const if (!delegate_->IsTextSelected()) { return; } - OnSelectionTriggered(); + delegate_->ResetState(); + if (pasteboardObserver_ == nullptr) { + pasteboardObserver_ = std::make_shared(shared_from_this()); + } + // TODO 调用剪贴板 + // uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); + // int32_t ret = PasteboardClient::GetInstance()->SubscribeDisposableObserver(pasteboardObserver_, + // static_cast(tokenId), DisposableType::PLAIN_TEXT, 100); + // if (ret != ERR_OK) { + // SELECTION_HILOGE("SubscribeDisposableObserver failed ret is %{public}d.", ret); + // } + InjectCtrlC(); + SELECTION_HILOGI("End Inject Ctrl + C."); + // TODO DELETE + std::string test = "Hello World eeee"; + pasteboardObserver_->OnTextReceived(test, 0); } -void SelectionInputMonitor::OnSelectionTriggered() const +void SelectionInputMonitor::OnSelectionTriggered(const std::string &text) const { - delegate_->ResetState(); auto selectionInfo = delegate_->GetSelectionInfo(); - - SELECTION_HILOGI("End word selection action."); - InjectCtrlC(); - SELECTION_HILOGI("End Inject Ctrl + C."); - selectionInfo.text = "Hello World."; // TODO modify + selectionInfo.text = text; SelectionInfoData dataInner; dataInner.data = selectionInfo; SELECTION_HILOGI("selectionInfo: %{public}s.", dataInner.ToString().c_str()); @@ -519,3 +529,15 @@ void SelectionInputMonitor::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyActi KeyEvent->AddKeyItem(item2); InputManager::GetInstance()->SimulateInputEvent(KeyEvent); } + +void SelectionPasteboardDisposableObserver::OnTextReceived(const std::string &text, int32_t errCode) +{ + if (errCode == 0) { + SELECTION_HILOGI("Text received: %{public}s.", text.c_str()); + if (pInputMonitor_) { + pInputMonitor_->OnSelectionTriggered(text); + } + } else { + SELECTION_HILOGI("Error receiving text: errCode: %{public}d", errCode); + } +} \ No newline at end of file diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index bf7900d..03c78f0 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -25,7 +25,6 @@ namespace SelectionFwk { using namespace testing::ext; struct EventStruct { - int buttonId; int pointId; int action; }; @@ -68,15 +67,14 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) { std::cout << " SelectInputMonitor001 start " << std::endl; vector events = { - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_MOVE}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_MOVE}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} }; for (uint16_t i = 0; i < events.size(); i++) { auto event = events[i]; std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetButtonId(event.buttonId); pointEvent->SetPointerId(event.pointId); pointEvent->SetPointerAction(event.action); inputMonitor->OnInputEvent(pointEvent); -- Gitee From a84a649cee2bd972ddbe178a133ef0645a940551 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Mon, 9 Jun 2025 13:58:16 +0800 Subject: [PATCH 61/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=9D=9E=E9=BC=A0?= =?UTF-8?q?=E6=A0=87=E5=B7=A6=E9=94=AE=E5=A4=84=E7=90=86=E7=9A=84BUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/include/selection_input_monitor.h | 3 +- service/src/selection_input_monitor.cpp | 21 +++--- .../unittest/selection_input_monitor_test.cpp | 65 +++++++++++++++++++ 3 files changed, 80 insertions(+), 9 deletions(-) diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h index 25d5c31..bc1fc73 100644 --- a/service/include/selection_input_monitor.h +++ b/service/include/selection_input_monitor.h @@ -54,7 +54,7 @@ public: virtual void OnInputEvent(std::shared_ptr pointerEvent) const; virtual void OnInputEvent(std::shared_ptr axisEvent) const; - void ResetState() const; + void ResetFinishedState() const; bool IsTextSelected() const; const SelectionInfo& GetSelectionInfo() const; @@ -70,6 +70,7 @@ private: void InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const; void FinishedWordSelection() const; void ResetProcess(std::shared_ptr pointerEvent) const; + void ResetState() const; void JudgeTripleClick() const; void SaveSelectionStartInfo(std::shared_ptr pointerEvent) const; void SaveSelectionEndInfo(std::shared_ptr pointerEvent) const; diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index e90dcd6..30bc04c 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -101,6 +101,9 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr point int32_t pointerId = pointerEvent->GetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); + if (pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { + ResetState(); + } // SELECTION_HILOGI("pointerItem, display: %{public}d, %{public}d, \ // RawDxy: %{public}d, %{public}d. \ // windows: %{public}d, %{public}d, windowId: %{public}d, deviceId: %{public}d", @@ -108,11 +111,6 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr point // pointerItem.GetRawDx(),pointerItem.GetRawDy(), // pointerItem.GetWindowX(), pointerItem.GetWindowY(), // pointerItem.GetTargetWindowId(), pointerItem.GetDeviceId()); - if (curSelectState == SELECT_INPUT_INITIAL && pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { - // SELECTION_HILOGI("[SelectionService] into PointerEvent, pointerId = %{public}d. curSelectState: %{public}d", - // pointerId, curSelectState); - return; - } SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); switch (curSelectState) @@ -378,9 +376,8 @@ void BaseSelectionInputMonitor::FinishedWordSelection() const SaveSelectionType(); } -void BaseSelectionInputMonitor::ResetState() const +void BaseSelectionInputMonitor::ResetFinishedState() const { - // world selection action if (curSelectState != SELECT_INPUT_DOUBLE_CLICKED) { curSelectState = SELECT_INPUT_INITIAL; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); @@ -388,6 +385,14 @@ void BaseSelectionInputMonitor::ResetState() const isTextSelected_ = false; } +void BaseSelectionInputMonitor::ResetState() const +{ + isTextSelected_ = false; + curSelectState = SELECT_INPUT_INITIAL; + subSelectState = SUB_INITIAL; + SELECTION_HILOGI("ResetFinishedState."); +} + void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { delegate_->OnInputEvent(keyEvent); @@ -410,7 +415,7 @@ void SelectionInputMonitor::FinishedWordSelection() const if (!delegate_->IsTextSelected()) { return; } - delegate_->ResetState(); + delegate_->ResetFinishedState(); if (pasteboardObserver_ == nullptr) { pasteboardObserver_ = std::make_shared(shared_from_this()); } diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index 03c78f0..4d6a174 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -83,5 +83,70 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) ASSERT_EQ(ret, true); } +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) +{ + std::cout << " SelectInputMonitor002 start " << std::endl; + vector events = { + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} + }; + + for (uint16_t i = 0; i < events.size(); i++) { + auto event = events[i]; + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetPointerId(event.pointId); + pointEvent->SetPointerAction(event.action); + inputMonitor->OnInputEvent(pointEvent); + } + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) +{ + std::cout << " SelectInputMonitor003 start " << std::endl; + vector events = { + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} + }; + + for (uint16_t i = 0; i < events.size(); i++) { + auto event = events[i]; + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetPointerId(event.pointId); + pointEvent->SetPointerAction(event.action); + inputMonitor->OnInputEvent(pointEvent); + } + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor004, TestSize.Level1) +{ + std::cout << " SelectInputMonitor004 start " << std::endl; + vector events = { + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, + {PointerEvent::MOUSE_BUTTON_RIGHT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, + {PointerEvent::MOUSE_BUTTON_RIGHT, PointerEvent::POINTER_ACTION_BUTTON_UP} + }; + + for (uint16_t i = 0; i < events.size(); i++) { + auto event = events[i]; + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetPointerId(event.pointId); + pointEvent->SetPointerAction(event.action); + inputMonitor->OnInputEvent(pointEvent); + } + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, false); +} + } } -- Gitee From 81adcb94dd1b1d3631484cd3d4a366680257fe4c Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Mon, 9 Jun 2025 16:37:04 +0800 Subject: [PATCH 62/93] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../selection_ability/panel_listener_impl.cpp | 70 ------------------- .../selection_ability/panel_listener_impl.h | 3 - .../selection_extension_ability.js | 8 --- .../include/js_selection_extension.h | 17 ----- .../src/js_selection_extension.cpp | 17 ----- 5 files changed, 115 deletions(-) diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp index 359eeb8..8c9b766 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -67,76 +67,6 @@ void PanelListenerImpl::OnPanelStatus(uint32_t windowId, const std::string& stat eventHandler->PostTask(task, status, 0, AppExecFwk::EventQueue::Priority::VIP); } -// void PanelListenerImpl::OnSizeChange(uint32_t windowId, const WindowSize &size) -// { -// std::string type = "sizeChange"; -// auto eventHandler = GetEventHandler(); -// if (eventHandler == nullptr) { -// SELECTION_HILOGE("eventHandler is nullptr!"); -// return; -// } -// std::shared_ptr callBack = GetCallback(windowId, type); -// if (callBack == nullptr) { -// return; -// } -// auto entry = std::make_shared(callBack); -// entry->size = size; -// SELECTION_HILOGI("OnSizeChange start. windowId:%{public}u, w:%{public}u, h:%{public}u", windowId, size.width, -// size.height); -// auto task = [entry]() { -// auto gitWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { -// if (argc == 0) { -// return false; -// } -// napi_value windowSize = JsWindowSize::Write(env, entry->size); -// // 0 means the first param of callback. -// args[0] = { windowSize }; -// return true; -// }; -// SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 1, gitWindowSizeParams }); -// }; -// eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); -// } - -// void PanelListenerImpl::OnSizeChange( -// uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) -// { - // std::string type = "sizeUpdate"; - // auto eventHandler = GetEventHandler(); - // if (eventHandler == nullptr) { - // SELECTION_HILOGE("eventHandler is nullptr!"); - // return; - // } - // std::shared_ptr callBack = GetCallback(windowId, event); - // if (callBack == nullptr) { - // SELECTION_HILOGE("callback is nullptr"); - // return; - // } - // auto entry = std::make_shared(callBack); - // entry->size = size; - // entry->keyboardArea = keyboardArea; - // SELECTION_HILOGI("%{public}s start. windowId:%{public}u, windowSize[%{public}u/%{public}u], " - // "keyboardArea:[%{public}d/%{public}d/%{public}d/%{public}d]", - // event.c_str(), windowId, size.width, size.height, keyboardArea.top, keyboardArea.bottom, keyboardArea.left, - // keyboardArea.right); - // auto task = [entry]() { - // auto getWindowSizeParams = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { - // if (argc == 0) { - // return false; - // } - // napi_value windowSize = JsWindowSize::Write(env, entry->size); - // napi_value jsKeyboardArea = JsKeyboardArea::Write(env, entry->keyboardArea); - // args[0] = { windowSize }; - // args[1] = { jsKeyboardArea }; - // return true; - // }; - // // 2 means 'sizeChange' has 2 params - // SelectionFwk::JsCallbackHandler::Traverse({ entry->cbCopy }, { 2, getWindowSizeParams }); - // }; - // eventHandler->PostTask(task, event, 0, AppExecFwk::EventQueue::Priority::VIP); -// } - - CallbackVector PanelListenerImpl::GetCallback(uint32_t windowId, const std::string &type) { CallbackVector callBackVector; diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.h b/frameworks/js/napi/selection_ability/panel_listener_impl.h index c1f35d8..fe3d4c0 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.h +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.h @@ -65,9 +65,6 @@ struct UvEntry { std::shared_ptr GetEventHandler(); void OnPanelStatus(uint32_t windowId, const std::string& status) override; - // void OnSizeChange(uint32_t windowId, const WindowSize &size) override; - // void OnSizeChange(uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, - // const std::string &event) override; void Subscribe(uint32_t windowId, const std::string &type, std::shared_ptr cbObject); void RemoveInfo(const std::string &type, uint32_t windowId, std::shared_ptr cbObject); void RemoveInfo(const std::string &type, uint32_t windowId); diff --git a/frameworks/js/napi/selection_extension_ability/selection_extension_ability.js b/frameworks/js/napi/selection_extension_ability/selection_extension_ability.js index 30c73ff..4851d70 100644 --- a/frameworks/js/napi/selection_extension_ability/selection_extension_ability.js +++ b/frameworks/js/napi/selection_extension_ability/selection_extension_ability.js @@ -16,10 +16,6 @@ let ExtensionAbility = requireNapi('app.ability.ExtensionAbility'); class SelectionExtensionAbility extends ExtensionAbility { - onCreate(want) { - console.log('onCreate, want:' + want.abilityName); - } - onConnect(want) { console.log('onConnect, want:' + want.abilityName); } @@ -27,10 +23,6 @@ class SelectionExtensionAbility extends ExtensionAbility { onDisconnect(want) { console.log('onDisconnect'); } - - onDestroy() { - console.log('onDestroy'); - } } export default SelectionExtensionAbility; diff --git a/frameworks/native/selection_extension/include/js_selection_extension.h b/frameworks/native/selection_extension/include/js_selection_extension.h index 932e11c..8101aad 100644 --- a/frameworks/native/selection_extension/include/js_selection_extension.h +++ b/frameworks/native/selection_extension/include/js_selection_extension.h @@ -44,15 +44,6 @@ public: std::shared_ptr& handler, const sptr& token) override; - /** - * @brief Called when this extension is started. You must override this function if you want to perform some - * initialization operations during extension startup. - * - * This function can be called only once in the entire lifecycle of an extension. - * @param Want Indicates the {@link Want} structure containing startup information about the extension. - */ - virtual void OnStart(const AAFwk::Want& want) override; - /** * @brief Called when this Service extension is connected for the first time. * @@ -71,14 +62,6 @@ public: */ virtual void OnDisconnect(const AAFwk::Want& want) override; - /** - * @brief Called when this extension enters the STATE_STOP state. - * - * The extension in the STATE_STOP is being destroyed. - * You can override this function to implement your own processing logic. - */ - virtual void OnStop() override; - private: napi_value CallObjectMethod(const char* methodName, const napi_value* argv = nullptr, size_t argc = 0); void GetSrcPath(std::string& srcPath); diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index cd2b021..b3c38a3 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -115,17 +115,6 @@ void JsSelectionExtension::Init(const std::shared_ptr& recor SELECTION_HILOGI("%{public}s end.", __func__); } -void JsSelectionExtension::OnStart(const AAFwk::Want& want) -{ - SELECTION_HILOGI("%{public}s start.", __func__); - Extension::OnStart(want); - napi_env env = jsRuntime_.GetNapiEnv(); - napi_value napiWant = OHOS::AppExecFwk::WrapWant(env, want); - napi_value argv[] = {napiWant}; - CallObjectMethod("onCreate", argv, ARGC_ONE); - SELECTION_HILOGI("%{public}s end.", __func__); -} - sptr JsSelectionExtension::OnConnect(const AAFwk::Want& want) { SELECTION_HILOGI("%{public}s start.", __func__); @@ -155,12 +144,6 @@ void JsSelectionExtension::OnDisconnect(const AAFwk::Want& want) SELECTION_HILOGI("%{public}s end.", __func__); } -void JsSelectionExtension::OnStop() -{ - SELECTION_HILOGI("%{public}s start.", __func__); - SelectionExtension::OnStop(); -} - napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const napi_value* argv, size_t argc) { SELECTION_HILOGI("JsSelectionExtension::CallObjectMethod(%{public}s), start.", methodName); -- Gitee From 6941f3fae454c74fd479606a3847ede43772e9bd Mon Sep 17 00:00:00 2001 From: fanzhe Date: Fri, 6 Jun 2025 15:20:43 +0800 Subject: [PATCH 63/93] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E5=A4=B1=E7=84=A6=E7=9B=91=E5=90=AC=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E9=87=8D=E5=90=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- common/BUILD.gn | 1 + frameworks/js/napi/selection_ability/BUILD.gn | 1 + .../js_selection_engine_setting.cpp | 46 +++++++++---- .../js_selection_engine_setting.h | 7 +- frameworks/native/selection_ability/BUILD.gn | 1 + .../selection_ability/ISelectionListener.idl | 2 +- .../include/selection_listener_impl.h | 2 +- .../include/selection_panel.h | 2 +- .../include/selection_panel_manger.h | 68 +++++++++++++++++++ .../src/selection_ability.cpp | 2 + .../src/selection_listener_impl.cpp | 26 ++++--- .../selection_ability/src/selection_panel.cpp | 2 +- service/BUILD.gn | 16 +++++ .../include/focus_monitor_manager.h | 2 +- .../src/focus_change_listener.cpp | 10 +-- service/include/selection_service.h | 4 +- service/src/selection_service.cpp | 13 ++-- 17 files changed, 161 insertions(+), 44 deletions(-) create mode 100644 frameworks/native/selection_ability/include/selection_panel_manger.h diff --git a/common/BUILD.gn b/common/BUILD.gn index a202b79..2478078 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -31,6 +31,7 @@ ohos_static_library("selection_common") { sanitize = { cfi = true cfi_cross_dso = true + cfi_vcall_icall_only = true debug = false } sources = [ diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 54cbc3e..c27a903 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -20,6 +20,7 @@ ohos_shared_library("selectionengine_napi") { boundary_sanitize = true cfi = true cfi_cross_dso = true + cfi_vcall_icall_only = true debug = false integer_overflow = true ubsan = true diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index acbf0ba..aa6dc1f 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -26,6 +26,8 @@ std::mutex JsSelectionEngineSetting::selectionMutex_; std::shared_ptr JsSelectionEngineSetting::selectionDelegate_{ nullptr }; std::mutex JsSelectionEngineSetting::eventHandlerMutex_; std::shared_ptr JsSelectionEngineSetting::handler_{ nullptr }; +sptr JsSelectionEngineSetting::listenerStub_ { nullptr }; +sptr JsSelectionEngineSetting::abilityManager_ { nullptr }; napi_value JsSelectionEngineSetting::GetSelectionAbility(napi_env env, napi_callback_info info) @@ -254,19 +256,19 @@ void JsSelectionEngineSetting::RegisterListener(napi_value callback, std::string SELECTION_HILOGI("add %{public}s callbackObj into jsCbMap_.", type.c_str()); jsCbMap_[type].push_back(std::move(callbackObj)); - auto proxy = GetSelectionSystemAbility(); - if (proxy == nullptr) { - SELECTION_HILOGE("selection system ability is nullptr!"); - return; - } - auto selectionInterface = GetJsSelectionEngineSetting(); - listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionInterface); - if (listenerStub_ == nullptr) { - SELECTION_HILOGE("Failed to create SelectionListenerImpl instance."); - return; - } - SELECTION_HILOGI("Begin calling SA RegisterListener!"); - proxy->RegisterListener(listenerStub_->AsObject()); + // auto proxy = GetSelectionSystemAbility(); + // if (proxy == nullptr) { + // SELECTION_HILOGE("selection system ability is nullptr!"); + // return; + // } + // auto selectionInterface = GetJsSelectionEngineSetting(); + // listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionInterface); + // if (listenerStub_ == nullptr) { + // SELECTION_HILOGE("Failed to create SelectionListenerImpl instance."); + // return; + // } + // SELECTION_HILOGI("Begin calling SA RegisterListener!"); + // proxy->RegisterListener(listenerStub_->AsObject()); } void JsSelectionEngineSetting::UnRegisterListener(napi_value callback, std::string type) @@ -339,6 +341,23 @@ std::shared_ptr JsSelectionEngineSetting::GetJsSelecti return selectionDelegate_; } +void JsSelectionEngineSetting::RegisterListerToService(std::shared_ptr &selectionEnging) +{ + auto proxy = GetSelectionSystemAbility(); + if (proxy == nullptr) { + SELECTION_HILOGE("selection system ability is nullptr!"); + return; + } + // auto selectionInterface = GetJsSelectionEngineSetting(); + listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionEnging); + if (listenerStub_ == nullptr) { + SELECTION_HILOGE("Failed to create SelectionListenerImpl instance."); + return; + } + SELECTION_HILOGI("Begin calling SA RegisterListener!"); + proxy->RegisterListener(listenerStub_->AsObject()); +} + napi_value JsSelectionEngineSetting::JsConstructor(napi_env env, napi_callback_info cbinfo) { napi_value thisVar = nullptr; @@ -356,6 +375,7 @@ napi_value JsSelectionEngineSetting::JsConstructor(napi_env env, napi_callback_i SELECTION_HILOGE("failed to wrap: %{public}d!", status); return nullptr; } + RegisterListerToService(delegate); return thisVar; }; diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index 6a27a54..86c1713 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -89,7 +89,8 @@ private: static std::shared_ptr GetJsSelectionEngineSetting(); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); - sptr GetSelectionSystemAbility(); + static sptr GetSelectionSystemAbility(); + static void RegisterListerToService(std::shared_ptr &selectionEnging); static std::shared_ptr GetEventHandler(); using EntrySetter = std::function; std::shared_ptr GetEntry(const std::string &type, EntrySetter entrySetter = nullptr); @@ -101,8 +102,8 @@ private: static std::mutex selectionMutex_; static std::shared_ptr selectionDelegate_; std::recursive_mutex mutex_; - sptr listenerStub_ { nullptr }; - sptr abilityManager_ { nullptr }; + static sptr listenerStub_; + static sptr abilityManager_; static std::mutex eventHandlerMutex_; static std::shared_ptr handler_; }; diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn index 326dc15..8cc9d53 100644 --- a/frameworks/native/selection_ability/BUILD.gn +++ b/frameworks/native/selection_ability/BUILD.gn @@ -64,6 +64,7 @@ ohos_shared_library("selection_ability") { boundary_sanitize = true cfi = true cfi_cross_dso = true + cfi_vcall_icall_only = true debug = false integer_overflow = true ubsan = true diff --git a/frameworks/native/selection_ability/ISelectionListener.idl b/frameworks/native/selection_ability/ISelectionListener.idl index afbeafb..e8d68c0 100644 --- a/frameworks/native/selection_ability/ISelectionListener.idl +++ b/frameworks/native/selection_ability/ISelectionListener.idl @@ -17,5 +17,5 @@ sequenceable selection_data_inner..OHOS.SelectionFwk.SelectionInfoData; interface OHOS.SelectionFwk.ISelectionListener { void OnSelectionChange([in] SelectionInfoData selectionInfoData); - void FocusChange([in] int windowID); + void FocusChange([in] unsigned int windowID, [in] unsigned int windowType); } diff --git a/frameworks/native/selection_ability/include/selection_listener_impl.h b/frameworks/native/selection_ability/include/selection_listener_impl.h index 833bf2d..dc2775f 100644 --- a/frameworks/native/selection_ability/include/selection_listener_impl.h +++ b/frameworks/native/selection_ability/include/selection_listener_impl.h @@ -26,7 +26,7 @@ public: SelectionListenerImpl(std::shared_ptr selectionI) : selectionI_(selectionI) {} ~SelectionListenerImpl() override = default; ErrCode OnSelectionChange(const SelectionInfoData& SelectionInfoData) override; - ErrCode FocusChange(int32_t windowID)override; + ErrCode FocusChange(uint32_t windowID, uint32_t windowType)override; private: std::shared_ptr selectionI_; }; diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 93f66c2..afa575c 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -74,7 +74,7 @@ private: int32_t height_ = 0; static std::mutex windowMutex_; - static sptr window_; + sptr window_; sptr winOption_ = nullptr; bool isScbEnable_ { false }; Rosen::KeyboardLayoutParams keyboardLayoutParams_; diff --git a/frameworks/native/selection_ability/include/selection_panel_manger.h b/frameworks/native/selection_ability/include/selection_panel_manger.h new file mode 100644 index 0000000..77b9c07 --- /dev/null +++ b/frameworks/native/selection_ability/include/selection_panel_manger.h @@ -0,0 +1,68 @@ +/* + * 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 SELECTION_PANEL_MANGER_H +#define SELECTION_PANEL_MANGER_H +#include +#include +#include +#include +#include + +#include "selection_panel.h" + +namespace OHOS { +namespace SelectionFwk { +class SelectionPanelManger { +public: + static SelectionPanelManger& GetInstance() { + static SelectionPanelManger instance; + return instance; + } + + void AddSelectionPanel(int32_t id, std::shared_ptr &obj) { + std::lock_guard lock(mutex_); + storage_[id] = obj; + } + + std::shared_ptr GetSelectionPanel(int32_t id) const { + std::lock_guard lock(mutex_); + auto it = storage_.find(id); + return (it != storage_.end()) ? it->second : nullptr; + } + + void RemoveSelectionPanel(int32_t id) { + std::lock_guard lock(mutex_); + storage_.erase(id); + } + + bool FindWindowID(uint32_t id) const { + std::lock_guard lock(mutex_); + return storage_.find(id) != storage_.end(); + } + +private: + SelectionPanelManger() = default; + ~SelectionPanelManger() = default; + std::unordered_map> storage_; + mutable std::mutex mutex_; + +}; +} // namespace SelectionFwk +} // namespace OHOS + + +#endif // SELECTION_PANEL_MANGER_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index 4ed5d6d..2a51459 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -19,6 +19,7 @@ #include #include "selection_panel.h" #include "selection_log.h" +#include "selection_panel_manger.h" namespace OHOS { namespace SelectionFwk { @@ -78,6 +79,7 @@ int32_t SelectionAbility::CreatePanel(const std::shared_ptrCreatePanel(context, panelInfo); if (ret == ErrorCode::NO_ERROR) { panel = selectionPanel; + SelectionPanelManger::GetInstance().AddSelectionPanel(selectionPanel->GetWindowId(), selectionPanel); return true; } selectionPanel = nullptr; diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index 094b84c..2318a61 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -16,7 +16,7 @@ #include "selection_listener_impl.h" #include "selection_log.h" #include "selection_data_inner.h" -#include "selection_panel.h" +#include "selection_panel_manger.h" namespace OHOS { @@ -40,23 +40,27 @@ ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionInfoData& select return 0; } -ErrCode SelectionListenerImpl::FocusChange(int32_t windowID) +ErrCode SelectionListenerImpl::FocusChange(uint32_t windowID, uint32_t windowType) { SELECTION_HILOGI("Recveive windowID: %{public}d", windowID); if (selectionI_ == nullptr) { - SELECTION_HILOGI("selectionI_ is nullptr"); + SELECTION_HILOGE("selectionI_ is nullptr"); return 1; } - auto selectionPanel = std::make_shared(); - if (selectionPanel == nullptr) { - SELECTION_HILOGE("selectionPanel is nullptr"); - return 1; + auto& panelManager = SelectionPanelManger::GetInstance(); + if (!panelManager.FindWindowID(windowID)) { + return 0; } - int32_t panelWindowID = selectionPanel->GetWindowId(); - if (windowID != panelWindowID) { - SELECTION_HILOGI("selectionPanel is UnFocus"); - selectionPanel->HidePanel(); + if (windowType == PanelType::MENU_PANEL) { + SELECTION_HILOGI("hide windowID: %{public}d", windowID); + panelManager.GetSelectionPanel(windowID)->HidePanel(); + } + + if (windowType == PanelType::MAIN_PANEL) { + SELECTION_HILOGI("destroy windowID: %{public}d", windowID); + panelManager.GetSelectionPanel(windowID)->DestroyPanel(); + panelManager.RemoveSelectionPanel(windowID); } return 0; } diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index b79ea2b..153dc13 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -23,6 +23,7 @@ #include "scene_board_judgement.h" #include "selection_log.h" #include "selectionmethod_trace.h" +#include "selection_panel_manger.h" namespace OHOS { namespace SelectionFwk { @@ -34,7 +35,6 @@ using WindowState = OHOS::Rosen::WindowState; std::atomic SelectionPanel::sequenceId_ { 0 }; constexpr int32_t MAXWAITTIME = 30; constexpr int32_t WAITTIME = 10; -sptr SelectionPanel::window_ {nullptr}; std::mutex SelectionPanel::windowMutex_; SelectionPanel::~SelectionPanel() = default; diff --git a/service/BUILD.gn b/service/BUILD.gn index bf3705d..775d84b 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -38,6 +38,7 @@ ohos_source_set("selection_service_proxy") { sanitize = { cfi = true cfi_cross_dso = true + cfi_vcall_icall_only = true debug = false } include_dirs = [ @@ -58,6 +59,21 @@ ohos_source_set("selection_service_proxy") { } ohos_shared_library("selection_service") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + integer_overflow = true + ubsan = true + } + cflags_cc = [ + "-fdata-sections", + "-ffunction-sections", + "-Oz", + ] configs = [ ":selection_sa_config", ] output_values = get_target_outputs(":selection_service_interface") diff --git a/service/focus_monitor/include/focus_monitor_manager.h b/service/focus_monitor/include/focus_monitor_manager.h index 9068ad8..2b78646 100644 --- a/service/focus_monitor/include/focus_monitor_manager.h +++ b/service/focus_monitor/include/focus_monitor_manager.h @@ -20,7 +20,7 @@ namespace OHOS { namespace SelectionFwk { -using FocusHandle = std::function; +using FocusHandle = std::function; class FocusMonitorManager { public: static FocusMonitorManager &GetInstance(); diff --git a/service/focus_monitor/src/focus_change_listener.cpp b/service/focus_monitor/src/focus_change_listener.cpp index e662e43..bd31471 100644 --- a/service/focus_monitor/src/focus_change_listener.cpp +++ b/service/focus_monitor/src/focus_change_listener.cpp @@ -29,7 +29,8 @@ void FocusChangedListener::OnFocused(const sptr &focusCh } SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64 " pid: %{public}d, uid: %{public}d", focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_); - focusHandle_(true, focusChangeInfo->windowId_); + uint32_t windowType = static_cast(focusChangeInfo->windowType_); + focusHandle_(true, focusChangeInfo->windowId_, windowType); } void FocusChangedListener::OnUnfocused(const sptr &focusChangeInfo) @@ -38,9 +39,10 @@ void FocusChangedListener::OnUnfocused(const sptr &focus SELECTION_HILOGE("error nullptr"); return; } - SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64 " pid: %{public}d, uid: %{public}d", - focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_); - focusHandle_(false, focusChangeInfo->windowId_); + SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64 " Windowtype: %{public}d", + focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->windowType_); + uint32_t windowType = static_cast(focusChangeInfo->windowType_); + focusHandle_(false, focusChangeInfo->windowId_, windowType); } } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/service/include/selection_service.h b/service/include/selection_service.h index e16ab71..b6980cf 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -72,14 +72,14 @@ private: void InputMonitorCancel(); void WatchParams(); void InitFocusChangedMonitor(); - void HandleFocusChanged(bool isOnFocused, uint32_t windowId); + void HandleFocusChanged(bool isOnFocused, uint32_t windowId, uint32_t windowType); int32_t inputMonitorId_ {-1}; static sptr instance_; static std::shared_mutex adminLock_; mutable std::mutex mutex_; - sptr listenerStub_ { nullptr }; + static sptr listenerStub_; sptr connectInner_ {nullptr}; }; } diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 365df05..a87d460 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -41,6 +41,7 @@ using namespace OHOS::EventFwk; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(SelectionService::GetInstance().GetRefPtr()); std::shared_mutex SelectionService::adminLock_; sptr SelectionService::instance_; +sptr SelectionService::listenerStub_ { nullptr }; void SelectionExtensionAbilityConnection::OnAbilityConnectDone( const ElementName &element, const sptr &remoteObject, int resultCode) @@ -101,7 +102,7 @@ sptr SelectionService::GetListener() { ErrCode SelectionService::RegisterListener(const sptr &listener) { - SELECTION_HILOGD("Enter RegisterListener"); + SELECTION_HILOGI("Enter RegisterListener"); if (listener == nullptr) { SELECTION_HILOGE("RegisterListener: selection listener is nullptr."); return 1; @@ -266,16 +267,16 @@ void SelectionService::InitFocusChangedMonitor() { SELECTION_HILOGI("[SelectionService] init focus changed monitor"); FocusMonitorManager::GetInstance().RegisterFocusChangedListener( - [this](bool isOnFocused, uint32_t windowId) { - HandleFocusChanged(isOnFocused, windowId); + [this](bool isOnFocused, int32_t windowId, uint32_t windowType) { + HandleFocusChanged(isOnFocused, windowId, windowType); }); } -void SelectionService::HandleFocusChanged(bool isOnFocused, uint32_t windowId) +void SelectionService::HandleFocusChanged(bool isOnFocused, uint32_t windowId, uint32_t windowType) { SELECTION_HILOGI("[SelectionService] handle focus changed"); - if (!isOnFocused) { - listenerStub_->FocusChange(windowId); + if (!isOnFocused && listenerStub_ != nullptr) { + listenerStub_->FocusChange(windowId, windowType); } } -- Gitee From a40de96279895afcadd1e2866ef991200e452024 Mon Sep 17 00:00:00 2001 From: lixiaojuan Date: Wed, 11 Jun 2025 10:10:00 +0800 Subject: [PATCH 64/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- etc/para/selection.para | 7 ++++--- etc/para/selection.para.dac | 2 +- sa_profile/8500.json | 4 ++-- service/include/selection_service.h | 10 ++++++---- service/src/selection_service.cpp | 20 +++++++------------- 5 files changed, 20 insertions(+), 23 deletions(-) diff --git a/etc/para/selection.para b/etc/para/selection.para index 34d5bc9..ee2ba16 100644 --- a/etc/para/selection.para +++ b/etc/para/selection.para @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -persist.sys.selection.switch.username = off -persist.sys.selection.trigger.username = ctrl -persist.sys.selection.app.username = com.hm.youdao/ExtensionAbility +sys.selection.switch = on +sys.selection.trigger = ctrl +sys.selection.app = com.hm.youdao/ExtensionAbility +sys.selection.uid = -1 diff --git a/etc/para/selection.para.dac b/etc/para/selection.para.dac index 5e0c38f..91f5f12 100644 --- a/etc/para/selection.para.dac +++ b/etc/para/selection.para.dac @@ -11,4 +11,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -persist.sys.selection. = sysselection:sysselection:0775 \ No newline at end of file +sys.selection. = sysselection:sysselection:0775 \ No newline at end of file diff --git a/sa_profile/8500.json b/sa_profile/8500.json index e4cca62..cbb7f40 100644 --- a/sa_profile/8500.json +++ b/sa_profile/8500.json @@ -13,7 +13,7 @@ "allow-update": true, "param": [ { - "name":"persist.sys.selection.switch.username", + "name":"sys.selection.switch", "value":"on" } ] @@ -22,7 +22,7 @@ "allow-update": true, "param": [ { - "name":"persist.sys.selection.switch.username", + "name":"sys.selection.switch", "value":"off" } ] diff --git a/service/include/selection_service.h b/service/include/selection_service.h index b6980cf..d8b0ce5 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -30,10 +30,12 @@ namespace OHOS::SelectionFwk { using namespace MMI; -constexpr const char *SYS_SELECTION_SWITCH_USERNAM = "persist.sys.selection.switch.username"; -constexpr const char *SYS_SELECTION_TRIGGER_USERNAM = "persist.sys.selection.trigger.username"; -constexpr const char *SYS_SELECTION_APP_USERNAM = "persist.sys.selection.app.username"; -constexpr const char *SYS_SELECTION_TRIGGER_VAL = "ctrl"; +constexpr const char *SYS_SELECTION_SWITCH = "sys.selection.switch"; +constexpr const char *SYS_SELECTION_TRIGGER = "sys.selection.trigger"; +constexpr const char *SYS_SELECTION_APP = "sys.selection.app"; +constexpr const char *DEFAULT_SWITCH = "on"; +constexpr const char *DEFAULT_TRIGGER = "ctrl"; +constexpr const char *DEFAULT_SELECTION_APP = "com.hm.youdao/ExtensionAbility"; class SelectionExtensionAbilityConnection : public OHOS::AAFwk::AbilityConnectionStub { public: diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index a87d460..bf315c6 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -31,7 +31,6 @@ #include "screenlock_manager.h" #include "focus_monitor_manager.h" - using namespace OHOS; using namespace OHOS::SelectionFwk; using namespace OHOS::AppExecFwk; @@ -129,7 +128,7 @@ int32_t SelectionService::Dump(int32_t fd, const std::vector &ar return OHOS::NO_ERROR; } -static void WatchParameterFunc(const char *key, const char *value, void *context) +static void WatchEnableSwitch(const char *key, const char *value, void *context) { (void)context; SELECTION_HILOGI("WatchParameterFunc begin"); @@ -141,14 +140,9 @@ static void WatchTriggerMode(const char *key, const char *value, void *context) (void)context; SELECTION_HILOGI("WatchParameterFunc begin"); SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); - if (strcmp(key, SYS_SELECTION_TRIGGER_USERNAM) == 0) { - if (strcmp(value, SYS_SELECTION_TRIGGER_VAL) == 0) { - BaseSelectionInputMonitor::ctrlSelectFlag = true; - } else { - BaseSelectionInputMonitor::ctrlSelectFlag = false; - } - SELECTION_HILOGI("ctrlSelectFlag is %{public}d", BaseSelectionInputMonitor::ctrlSelectFlag); - } + int triggerCmpResult = strcmp(value, DEFAULT_TRIGGER); + BaseSelectionInputMonitor::ctrlSelectFlag = (triggerCmpResult == 0); + SELECTION_HILOGI("ctrlSelectFlag is %{public}d", BaseSelectionInputMonitor::ctrlSelectFlag); } void SelectionService::DisconnectCurrentExtAbility() @@ -210,9 +204,9 @@ static void WatchAppSwitch(const char *key, const char *value, void *context) void SelectionService::WatchParams() { SELECTION_HILOGI("WatchParams begin"); - WatchParameter(SYS_SELECTION_SWITCH_USERNAM, WatchParameterFunc, nullptr); - WatchParameter(SYS_SELECTION_TRIGGER_USERNAM, WatchTriggerMode, nullptr); - WatchParameter(SYS_SELECTION_APP_USERNAM, WatchAppSwitch, this); + WatchParameter(SYS_SELECTION_SWITCH, WatchEnableSwitch, nullptr); + WatchParameter(SYS_SELECTION_TRIGGER, WatchTriggerMode, nullptr); + WatchParameter(SYS_SELECTION_APP, WatchAppSwitch, this); SELECTION_HILOGI("WatchParams end"); } -- Gitee From df8bffbfb66410ad1f0f093fa873ead57bbf7cb8 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Tue, 10 Jun 2025 20:22:56 +0800 Subject: [PATCH 65/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=A0=81=20&=20=E4=BF=AE=E6=94=B9=E7=89=88=E6=9D=83=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/BUILD.gn | 2 +- common/block_data.h | 2 +- common/callback_object.cpp | 2 +- common/callback_object.h | 2 +- common/concurrent_map.h | 2 +- common/event_checker.cpp | 2 +- common/ffrt_block_queue.h | 2 +- common/js_utils.cpp | 12 ++++++++- common/js_utils.h | 12 ++++++--- common/selectionmethod_trace.cpp | 2 +- common/selectionmethod_trace.h | 2 +- common/util.cpp | 2 +- common/util.h | 2 +- frameworks/common/concurrent_map.h | 2 +- .../js/napi/selection_ability/js_panel.cpp | 21 ++++++++------- .../js/napi/selection_ability/js_panel.h | 2 +- .../js_selection_ability.cpp | 15 +++++++++++ .../js_selection_engine_setting.cpp | 24 ++++++++++++++--- .../selection_ability/panel_listener_impl.cpp | 2 +- .../selection_ability/panel_listener_impl.h | 2 +- .../js/napi/selection_client/async_call.cpp | 2 +- .../js/napi/selection_client/async_call.h | 2 +- .../selection_client/js_selection_utils.cpp | 2 +- .../selection_client/js_selection_utils.h | 2 +- .../include/actions/action.h | 2 +- .../include/actions/action_wait.h | 2 +- .../selection_ability/include/panel_common.h | 2 +- .../selection_ability/include/panel_info.h | 2 +- .../include/panel_status_listener.h | 2 +- .../include/selection_attribute.h | 2 +- .../include/selection_panel.h | 1 + .../include/selection_window_info.h | 2 +- .../selection_ability/include/task_manager.h | 2 +- .../selection_ability/src/selection_panel.cpp | 27 ++++++++++++++++++- .../selection_ability/src/task_manager.cpp | 2 +- .../selection_ability/src/tasks/task.cpp | 2 +- .../include/focus_change_listener.h | 2 +- .../src/focus_change_listener.cpp | 2 +- .../src/focus_monitor_manager.cpp | 2 +- .../include/PasteboardDisposableObserver.h | 15 +++++++++++ test/unittest/BUILD.gn | 2 +- .../unittest/selection_input_monitor_test.cpp | 2 +- utils/include/selection_log.h | 3 +++ 43 files changed, 146 insertions(+), 52 deletions(-) diff --git a/common/BUILD.gn b/common/BUILD.gn index 2478078..a643f4a 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (C) 2023 Huawei Device Co., Ltd. +# 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 diff --git a/common/block_data.h b/common/block_data.h index 78db7d5..d857a2f 100644 --- a/common/block_data.h +++ b/common/block_data.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/common/callback_object.cpp b/common/callback_object.cpp index 3f05463..3d8c4b5 100644 --- a/common/callback_object.cpp +++ b/common/callback_object.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 diff --git a/common/callback_object.h b/common/callback_object.h index 0fc441d..a6dfdd7 100644 --- a/common/callback_object.h +++ b/common/callback_object.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 diff --git a/common/concurrent_map.h b/common/concurrent_map.h index eff3b24..85266bb 100644 --- a/common/concurrent_map.h +++ b/common/concurrent_map.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/common/event_checker.cpp b/common/event_checker.cpp index 97ec29f..bcfb661 100644 --- a/common/event_checker.cpp +++ b/common/event_checker.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/common/ffrt_block_queue.h b/common/ffrt_block_queue.h index 8823968..ae90f51 100644 --- a/common/ffrt_block_queue.h +++ b/common/ffrt_block_queue.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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 diff --git a/common/js_utils.cpp b/common/js_utils.cpp index 4d25192..7067c5f 100644 --- a/common/js_utils.cpp +++ b/common/js_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * 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 @@ -86,6 +86,8 @@ const std::map JsUtils::ERROR_CODE_MAP = { { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS }, { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS }, { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED }, + { ErrorCode::ERROR_SELECTION_SERVICE, EXCEPTION_SELECTION_SERVICE }, + { ErrorCode::ERROR_PANEL_DESTORYED, EXCEPTION_PANEL_DESTORYED } }; const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { @@ -114,6 +116,8 @@ const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." }, { EXCEPTION_EDITABLE, "the edit mode need enable." }, { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." }, + { EXCEPTION_SELECTION_SERVICE, "selection service exception." }, + { EXCEPTION_PANEL_DESTORYED, "this panel has been destroyed." } }; const std::map JsUtils::PARAMETER_TYPE = { @@ -154,6 +158,12 @@ void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, NAPI_CALL_RETURN_VOID(env, napi_throw(env, error)); } +void JsUtils::ThrowException(napi_env env, int32_t errCode, const std::string& msg) +{ + std::string errMsg = ToMessage(JsUtils::Convert(errCode)) + " " + msg; + NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, std::to_string(errCode).c_str(), errMsg.c_str())); +} + napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg) { SELECTION_HILOGD("ToError start"); diff --git a/common/js_utils.h b/common/js_utils.h index 8fc629b..793bef4 100644 --- a/common/js_utils.h +++ b/common/js_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * 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 @@ -30,7 +30,7 @@ using Ability = OHOS::AppExecFwk::Ability; namespace OHOS { namespace SelectionFwk { -enum IMFErrorCode : int32_t { +enum SEErrorCode : int32_t { EXCEPTION_PERMISSION = 201, EXCEPTION_SYSTEM_PERMISSION = 202, EXCEPTION_PARAMCHECK = 401, @@ -52,6 +52,8 @@ enum IMFErrorCode : int32_t { EXCEPTION_REQUEST_NOT_ACCEPT = 12800015, EXCEPTION_EDITABLE = 12800016, EXCEPTION_INVALID_PANEL_TYPE_FLAG = 12800017, + EXCEPTION_SELECTION_SERVICE = 25600001, // TODO:待定 + EXCEPTION_PANEL_DESTORYED // TODO:待定 }; enum TypeCode : int32_t { @@ -74,7 +76,7 @@ enum TypeCode : int32_t { #define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \ do { \ if (!(condition)) { \ - JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + JsUtils::ThrowException(env, SEErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ return retVal; \ } \ } while (0) @@ -82,7 +84,7 @@ enum TypeCode : int32_t { #define PARAM_CHECK_RETURN_VOID(env, condition, message, typeCode) \ do { \ if (!(condition)) { \ - JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + JsUtils::ThrowException(env, SEErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ return; \ } \ } while (0) @@ -131,6 +133,8 @@ class JsUtils { public: static void ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type); + static void ThrowException(napi_env env, int32_t err, const std::string &msg = ""); + static napi_value ToError(napi_env env, int32_t code, const std::string &msg); static int32_t Convert(int32_t code); diff --git a/common/selectionmethod_trace.cpp b/common/selectionmethod_trace.cpp index 8de772a..0aa7f90 100644 --- a/common/selectionmethod_trace.cpp +++ b/common/selectionmethod_trace.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * 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 diff --git a/common/selectionmethod_trace.h b/common/selectionmethod_trace.h index 11738f3..8ed9bd3 100644 --- a/common/selectionmethod_trace.h +++ b/common/selectionmethod_trace.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * 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 diff --git a/common/util.cpp b/common/util.cpp index 26438fe..742be22 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/common/util.h b/common/util.h index 8e6efaf..6e50208 100644 --- a/common/util.h +++ b/common/util.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/common/concurrent_map.h b/frameworks/common/concurrent_map.h index 44a6ccc..0d60556 100644 --- a/frameworks/common/concurrent_map.h +++ b/frameworks/common/concurrent_map.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 20d5e0b..69277b6 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 @@ -137,7 +137,10 @@ napi_value JsPanel::SetUiContent(napi_env env, napi_callback_info info) ctxt->SetErrorCode(code); ctxt->SetErrorMessage("path should be a path to specific page."); return napi_generic_failure; + } else if (code == ErrorCode::ERROR_SELECTION_SERVICE || code == ErrorCode::ERROR_PANEL_DESTORYED) { + JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to SetUiContent", TYPE_NONE); } + return napi_ok; }; ctxt->SetAction(std::move(input), std::move(output)); @@ -155,7 +158,7 @@ napi_value JsPanel::Show(napi_env env, napi_callback_info info) jsQueue_.Push(ctxt->info); return napi_ok; }; - auto exec = [ctxt](AsyncCall::Context *ctx) { + auto exec = [env, ctxt](AsyncCall::Context *ctx) { jsQueue_.Wait(ctxt->info); if (ctxt->selectionPanel == nullptr) { SELECTION_HILOGE("selectionPanel is nullptr!"); @@ -163,13 +166,13 @@ napi_value JsPanel::Show(napi_env env, napi_callback_info info) return; } auto code = SelectionAbility::GetInstance()->ShowPanel(ctxt->selectionPanel); + jsQueue_.Pop(); if (code == ErrorCode::NO_ERROR) { ctxt->SetState(napi_ok); - jsQueue_.Pop(); return; } - jsQueue_.Pop(); ctxt->SetErrorCode(code); + JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to show", TYPE_NONE); }; ctxt->SetAction(std::move(input)); // 1 means JsAPI:show has 1 param at most. @@ -187,7 +190,7 @@ napi_value JsPanel::Hide(napi_env env, napi_callback_info info) jsQueue_.Push(ctxt->info); return napi_ok; }; - auto exec = [ctxt](AsyncCall::Context *ctx) { + auto exec = [env, ctxt](AsyncCall::Context *ctx) { jsQueue_.Wait(ctxt->info); if (ctxt->selectionPanel == nullptr) { SELECTION_HILOGE("selectionPanel is nullptr!"); @@ -201,6 +204,7 @@ napi_value JsPanel::Hide(napi_env env, napi_callback_info info) return; } ctxt->SetErrorCode(code); + JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to hide", TYPE_NONE); }; ctxt->SetAction(std::move(input)); // 1 means JsAPI:hide has 1 param at most. @@ -251,7 +255,7 @@ napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info) return napi_ok; }; - auto exec = [ctxt](AsyncCall::Context *ctx) { + auto exec = [env, ctxt](AsyncCall::Context *ctx) { int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); jsQueue_.Wait(ctxt->info); PrintEditorQueueInfoIfTimeout(start, ctxt->info); @@ -262,9 +266,8 @@ napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info) } auto code = ctxt->selectionPanel->MoveTo(ctxt->x, ctxt->y); jsQueue_.Pop(); - if (code == ErrorCode::ERROR_PARAMETER_CHECK_FAILED) { - ctxt->SetErrorCode(code); - return; + if(code != ErrorCode::NO_ERROR) { + JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to moveTo", TYPE_NONE); } ctxt->SetState(napi_ok); }; diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index 80584cd..562e963 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/js/napi/selection_ability/js_selection_ability.cpp b/frameworks/js/napi/selection_ability/js_selection_ability.cpp index 1ea4a5d..bf6764f 100644 --- a/frameworks/js/napi/selection_ability/js_selection_ability.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_ability.cpp @@ -1,3 +1,18 @@ +/* + * 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_selection_ability.h" #include "event_checker.h" diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index aa6dc1f..42bb18c 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -1,3 +1,18 @@ +/* + * 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_selection_engine_setting.h" #include "event_checker.h" @@ -122,7 +137,6 @@ napi_status JsSelectionEngineSetting::GetContext(napi_env env, napi_value in, napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_info info) { SELECTION_HILOGI("SelectionEngineSetting CreatePanel start."); - auto ctxt = std::make_shared(); auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { PARAM_CHECK_RETURN(env, argc >= 2, "at least two parameters is required.", TYPE_NONE, napi_invalid_arg); @@ -147,10 +161,13 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf return status; }; - auto exec = [ctxt](AsyncCall::Context *ctx) { + auto exec = [env, ctxt](AsyncCall::Context *ctx) { auto ret = SelectionAbility::GetInstance()->CreatePanel(ctxt->context, ctxt->panelInfo, ctxt->panel); - ctxt->SetErrorCode(ret); CHECK_RETURN_VOID(ret == ErrorCode::NO_ERROR, "JsSelectionEngineSetting CreatePanel failed!"); + if(ret != ErrorCode::NO_ERROR) { + ctxt->SetErrorCode(ret); + JsUtils::ThrowException(env, JsUtils::Convert(ret), "CreatePanel failed!", TYPE_NONE); + } ctxt->SetState(napi_ok); }; @@ -205,6 +222,7 @@ napi_value JsSelectionEngineSetting::DestroyPanel(napi_env env, napi_callback_in auto errCode = SelectionAbility::GetInstance()->DestroyPanel(ctxt->panel); if (errCode != ErrorCode::NO_ERROR) { SELECTION_HILOGE("DestroyPanel failed, errCode: %{public}d!", errCode); + JsUtils::ThrowException(env, JsUtils::Convert(errCode), "DestroyPanel failed!", TYPE_NONE); return napi_generic_failure; } ctxt->panel = nullptr; diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp index 8c9b766..f51099a 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.h b/frameworks/js/napi/selection_ability/panel_listener_impl.h index fe3d4c0..623bd90 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.h +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/js/napi/selection_client/async_call.cpp b/frameworks/js/napi/selection_client/async_call.cpp index 6f287b9..38b2c1a 100644 --- a/frameworks/js/napi/selection_client/async_call.cpp +++ b/frameworks/js/napi/selection_client/async_call.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/js/napi/selection_client/async_call.h b/frameworks/js/napi/selection_client/async_call.h index 23f69f1..9f66be4 100644 --- a/frameworks/js/napi/selection_client/async_call.h +++ b/frameworks/js/napi/selection_client/async_call.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/js/napi/selection_client/js_selection_utils.cpp b/frameworks/js/napi/selection_client/js_selection_utils.cpp index 0d6b32d..cf0a79c 100644 --- a/frameworks/js/napi/selection_client/js_selection_utils.cpp +++ b/frameworks/js/napi/selection_client/js_selection_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/js/napi/selection_client/js_selection_utils.h b/frameworks/js/napi/selection_client/js_selection_utils.h index ba314fa..78ae20f 100644 --- a/frameworks/js/napi/selection_client/js_selection_utils.h +++ b/frameworks/js/napi/selection_client/js_selection_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/actions/action.h b/frameworks/native/selection_ability/include/actions/action.h index 62d913c..65d2813 100644 --- a/frameworks/native/selection_ability/include/actions/action.h +++ b/frameworks/native/selection_ability/include/actions/action.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024-2024 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/actions/action_wait.h b/frameworks/native/selection_ability/include/actions/action_wait.h index b88cd86..5ea8271 100644 --- a/frameworks/native/selection_ability/include/actions/action_wait.h +++ b/frameworks/native/selection_ability/include/actions/action_wait.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024-2024 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/panel_common.h b/frameworks/native/selection_ability/include/panel_common.h index 03a1de3..7e17e79 100644 --- a/frameworks/native/selection_ability/include/panel_common.h +++ b/frameworks/native/selection_ability/include/panel_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/panel_info.h b/frameworks/native/selection_ability/include/panel_info.h index 56cd5bc..232f834 100644 --- a/frameworks/native/selection_ability/include/panel_info.h +++ b/frameworks/native/selection_ability/include/panel_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/panel_status_listener.h b/frameworks/native/selection_ability/include/panel_status_listener.h index 88d83e4..bc4c1da 100644 --- a/frameworks/native/selection_ability/include/panel_status_listener.h +++ b/frameworks/native/selection_ability/include/panel_status_listener.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/selection_attribute.h b/frameworks/native/selection_ability/include/selection_attribute.h index fd89988..3680218 100644 --- a/frameworks/native/selection_ability/include/selection_attribute.h +++ b/frameworks/native/selection_ability/include/selection_attribute.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index afa575c..2bccb6e 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -50,6 +50,7 @@ public: PanelType GetPanelType(); bool IsShowing(); bool IsHidden(); + bool IsDestroyed() const; bool SetPanelStatusListener(std::shared_ptr statusListener, const std::string &type); void ClearPanelListener(const std::string &type); int32_t GetWindowId(); diff --git a/frameworks/native/selection_ability/include/selection_window_info.h b/frameworks/native/selection_ability/include/selection_window_info.h index 08605b5..5949aba 100644 --- a/frameworks/native/selection_ability/include/selection_window_info.h +++ b/frameworks/native/selection_ability/include/selection_window_info.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/include/task_manager.h b/frameworks/native/selection_ability/include/task_manager.h index 93a4c93..16445e0 100644 --- a/frameworks/native/selection_ability/include/task_manager.h +++ b/frameworks/native/selection_ability/include/task_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024-2024 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index 153dc13..5444f55 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2024 Huawei Device Co., Ltd. + * 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 @@ -170,6 +170,10 @@ int32_t SelectionPanel::SetUiContent(const std::string &contentInfo, napi_env en SELECTION_HILOGE("window_ is nullptr, can not SetUiContent!"); return ErrorCode::ERROR_NULL_POINTER; } + if(IsDestroyed()) { + SELECTION_HILOGE("window is destroyed!"); + return ErrorCode::ERROR_PANEL_DESTORYED; + } WMError ret = WMError::WM_OK; window_->NapiSetUIContent(contentInfo, env, nullptr); @@ -200,6 +204,10 @@ int32_t SelectionPanel::ShowPanel() SELECTION_HILOGE("window_ is nullptr!"); return ErrorCode::ERROR_IMA_NULLPTR; } + if(IsDestroyed()) { + SELECTION_HILOGE("window is destroyed!"); + return ErrorCode::ERROR_PANEL_DESTORYED; + } if (IsShowing()) { SELECTION_HILOGI("panel already shown."); return ErrorCode::NO_ERROR; @@ -251,6 +259,10 @@ int32_t SelectionPanel::HidePanel() SELECTION_HILOGE("window_ is nullptr!"); return ErrorCode::ERROR_NULL_POINTER; } + if(IsDestroyed()) { + SELECTION_HILOGE("window is destroyed!"); + return ErrorCode::ERROR_PANEL_DESTORYED; + } if (IsHidden()) { SELECTION_HILOGI("panel already hidden."); return ErrorCode::NO_ERROR; @@ -280,12 +292,21 @@ bool SelectionPanel::IsHidden() return false; } +bool SelectionPanel::IsDestroyed() const +{ + return window_ && window_->GetWindowState() == WindowState::STATE_DESTROYED; +} + int32_t SelectionPanel::StartMoving() { if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); return ErrorCode::ERROR_IME; } + if(IsDestroyed()) { + SELECTION_HILOGE("window is destroyed!"); + return ErrorCode::ERROR_PANEL_DESTORYED; + } auto ret = window_->StartMoveWindow(); if (ret == WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT) { SELECTION_HILOGE("window manager service not support error ret = %{public}d.", ret); @@ -306,6 +327,10 @@ int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) SELECTION_HILOGE("window_ is nullptr!"); return ErrorCode::ERROR_NULL_POINTER; } + if(IsDestroyed()) { + SELECTION_HILOGE("window is destroyed!"); + return ErrorCode::ERROR_PANEL_DESTORYED; + } auto ret = window_->MoveTo(x, y); SELECTION_HILOGI("x/y: %{public}d/%{public}d, ret = %{public}d", x, y, ret); return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR; diff --git a/frameworks/native/selection_ability/src/task_manager.cpp b/frameworks/native/selection_ability/src/task_manager.cpp index fae65be..f4b231b 100644 --- a/frameworks/native/selection_ability/src/task_manager.cpp +++ b/frameworks/native/selection_ability/src/task_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024-2024 Huawei Device Co., Ltd. + * 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 diff --git a/frameworks/native/selection_ability/src/tasks/task.cpp b/frameworks/native/selection_ability/src/tasks/task.cpp index b75bc06..a13d78a 100644 --- a/frameworks/native/selection_ability/src/tasks/task.cpp +++ b/frameworks/native/selection_ability/src/tasks/task.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024-2024 Huawei Device Co., Ltd. + * 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 diff --git a/service/focus_monitor/include/focus_change_listener.h b/service/focus_monitor/include/focus_change_listener.h index 5807667..ec86714 100644 --- a/service/focus_monitor/include/focus_change_listener.h +++ b/service/focus_monitor/include/focus_change_listener.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/service/focus_monitor/src/focus_change_listener.cpp b/service/focus_monitor/src/focus_change_listener.cpp index bd31471..3c59f84 100644 --- a/service/focus_monitor/src/focus_change_listener.cpp +++ b/service/focus_monitor/src/focus_change_listener.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/service/focus_monitor/src/focus_monitor_manager.cpp b/service/focus_monitor/src/focus_monitor_manager.cpp index 76ad5eb..1bda8e3 100644 --- a/service/focus_monitor/src/focus_monitor_manager.cpp +++ b/service/focus_monitor/src/focus_monitor_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * 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 diff --git a/service/include/PasteboardDisposableObserver.h b/service/include/PasteboardDisposableObserver.h index 21087a0..f2788ec 100644 --- a/service/include/PasteboardDisposableObserver.h +++ b/service/include/PasteboardDisposableObserver.h @@ -1,3 +1,18 @@ +/* + * 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 PASTEBOARD_DISPOSABLE_OBSERVER_H #define PASTEBOARD_DISPOSABLE_OBSERVER_H diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index f05270c..db35c4f 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. +# Copyright (c) 2025 Shenzhen Kaihong Digital Industry Development 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 diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index 4d6a174..a968447 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * 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 diff --git a/utils/include/selection_log.h b/utils/include/selection_log.h index 6f8a1f0..ae4a709 100644 --- a/utils/include/selection_log.h +++ b/utils/include/selection_log.h @@ -149,6 +149,9 @@ enum { ERROR_SCENE_UNSUPPORTED, ERROR_PRIVATE_COMMAND_IS_EMPTY, ERROR_IMSA_END, + + ERROR_SELECTION_SERVICE, + ERROR_PANEL_DESTORYED }; }; // namespace ErrorCode -- Gitee From 25070d0ceece8d82038fd621075ecc4a04a45823 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Wed, 11 Jun 2025 11:26:57 +0800 Subject: [PATCH 66/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8Dselecti=5Ffwk=E4=B8=BAselectionfwk?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- README.md | 8 +++---- bundle.json | 24 +++++++++---------- common/BUILD.gn | 4 ++-- common/{js_utils.h => selection_js_utils.h} | 8 +++---- ...js_utils.cpp => selectionfwk_js_utils.cpp} | 2 +- frameworks/common/concurrent_map.h | 6 ++--- frameworks/js/napi/selection_ability/BUILD.gn | 3 ++- .../js/napi/selection_ability/js_panel.cpp | 2 +- .../js_selection_ability.cpp | 2 +- .../js_selection_engine_setting.cpp | 2 +- .../selection_ability/panel_listener_impl.cpp | 2 +- .../js/napi/selection_client/async_call.cpp | 2 +- .../js/napi/selection_client/async_call.h | 2 +- .../selection_client/js_selection_utils.h | 2 +- .../js/napi/selection_client/js_utils.cpp.bak | 2 +- frameworks/native/selection_ability/BUILD.gn | 2 +- .../selection_ability/include/panel_common.h | 6 ++--- .../selection_ability/include/panel_info.h | 6 ++--- .../native/selection_extension/BUILD.gn | 2 +- .../src/js_selection_extension_context.cpp | 2 +- selection_service.gni | 2 +- service/BUILD.gn | 2 +- test/unittest/BUILD.gn | 4 ++-- 23 files changed, 49 insertions(+), 48 deletions(-) rename common/{js_utils.h => selection_js_utils.h} (98%) rename common/{js_utils.cpp => selectionfwk_js_utils.cpp} (99%) diff --git a/README.md b/README.md index 01a5191..d6e1a9e 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ │ ├── foundation │ │ ├──systemabilitymgr │ │ │ ├── samgr => 代码提交仓: https://gitee.com/sinall/systemabilitymgr_samgr.git, selection_fwk分支 -│ │ │ └── selection_fwk => 代码提交仓: https://gitee.com/sinall/selection_fwk.git, master分支 +│ │ │ └── selectionfwk => 代码提交仓: https://gitee.com/sinall/selectionfwk.git, master分支 │ │ ├──bundlemanager │ │ │ └── bundle_framework =>代码提交仓: https://gitee.com/sinall/bundlemanager_bundle_framework.git selection_fwk分支 │ │ └──ability @@ -27,12 +27,12 @@ ``` 1. selection_fwk仓库: cd foundation/systemabilitymgr -git clone https://gitee.com/sinall/selection_fwk.git +git clone https://gitee.com/sinall/selectionfwk.git 2. 其余仓库 $ cd foundation/systemabilitymgr/samgr(修改为对应仓库路径) $ git remote add sinall https://gitee.com/sinall/systemabilitymgr_samgr.git(修改为对应仓库的网址) -$ git fetch sinall selection_fwk -$ git checkout -b selection_fwk sinall/selection_fwk +$ git fetch sinall selectionfwk +$ git checkout -b selectionfwk sinall/selectionfwk ``` - 后续更新代码 diff --git a/bundle.json b/bundle.json index 9a12f60..ea27097 100644 --- a/bundle.json +++ b/bundle.json @@ -44,21 +44,21 @@ }, "build": { "sub_component": [ - "//foundation/systemabilitymgr/selection_fwk/common:selection_common", - "//foundation/systemabilitymgr/selection_fwk/etc/init:selection_service_cfg", - "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para", - "//foundation/systemabilitymgr/selection_fwk/etc/para:selection_para_dac", - "//foundation/systemabilitymgr/selection_fwk/service:selection_service", - "//foundation/systemabilitymgr/selection_fwk/sa_profile:selection_service_sa_profile", - "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", - "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_extension_context:selectionextensioncontext_napi", - "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_extension:selection_extension_ability_native", - "//foundation/systemabilitymgr/selection_fwk/frameworks/js/napi/selection_ability:selectionengine_napi", - "//foundation/systemabilitymgr/selection_fwk/frameworks/native/selection_ability:selection_ability" + "//foundation/systemabilitymgr/selectionfwk/common:selection_common", + "//foundation/systemabilitymgr/selectionfwk/etc/init:selection_service_cfg", + "//foundation/systemabilitymgr/selectionfwk/etc/para:selection_para", + "//foundation/systemabilitymgr/selectionfwk/etc/para:selection_para_dac", + "//foundation/systemabilitymgr/selectionfwk/service:selection_service", + "//foundation/systemabilitymgr/selectionfwk/sa_profile:selection_service_sa_profile", + "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", + "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_extension_context:selectionextensioncontext_napi", + "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_extension:selection_extension_ability_native", + "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_ability:selectionengine_napi", + "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_ability:selection_ability" ], "inner_kits": [], "test": [ - "//foundation/systemabilitymgr/selection_fwk/test/unittest:selection_service_unit_test" + "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_service_unit_test" ] } } diff --git a/common/BUILD.gn b/common/BUILD.gn index a643f4a..a84c3bd 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") import("//build/ohos.gni") config("selection_js_common_public_config") { @@ -40,7 +40,7 @@ ohos_static_library("selection_common") { "callback_object.cpp", "util.cpp", "selectionmethod_trace.cpp", - "js_utils.cpp", + "selectionfwk_js_utils.cpp", ] ldflags = [ "-Wl,--exclude-libs=ALL" ] diff --git a/common/js_utils.h b/common/selection_js_utils.h similarity index 98% rename from common/js_utils.h rename to common/selection_js_utils.h index 793bef4..4cd42a9 100644 --- a/common/js_utils.h +++ b/common/selection_js_utils.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef INTERFACE_KITS_JS_UTILS_H -#define INTERFACE_KITS_JS_UTILS_H +#ifndef SELECTAIONFWK_JS_UTILS_H +#define SELECTAIONFWK_JS_UTILS_H #include @@ -186,6 +186,6 @@ private: static constexpr uint8_t MAX_ARGMENT_COUNT = 10; }; -} // namespace MiscServices +} // namespace SelectionFwk } // namespace OHOS -#endif // INTERFACE_KITS_JS_UTILS_H \ No newline at end of file +#endif // SELECTAIONFWK_JS_UTILS_H \ No newline at end of file diff --git a/common/js_utils.cpp b/common/selectionfwk_js_utils.cpp similarity index 99% rename from common/js_utils.cpp rename to common/selectionfwk_js_utils.cpp index 7067c5f..689ca32 100644 --- a/common/js_utils.cpp +++ b/common/selectionfwk_js_utils.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "js_utils.h" +#include "selection_js_utils.h" namespace OHOS { namespace SelectionFwk { diff --git a/frameworks/common/concurrent_map.h b/frameworks/common/concurrent_map.h index 0d60556..415db14 100644 --- a/frameworks/common/concurrent_map.h +++ b/frameworks/common/concurrent_map.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef OHOS_SELECTION_FWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H -#define OHOS_SELECTION_FWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#ifndef OHOS_SELECTIONFWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#define OHOS_SELECTIONFWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H #include #include #include @@ -299,4 +299,4 @@ private: std::map<_Key, _Tp> entries_; }; } // namespace OHOS -#endif // OHOS_SELECTION_FWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#endif // OHOS_SELECTIONFWK_FRAMEWORKS_COMMON_CONCURRENT_MAP_H diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index c27a903..2aaad95 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -12,7 +12,7 @@ # limitations under the License. import("//build/ohos.gni") -import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") ohos_shared_library("selectionengine_napi") { branch_protector_ret = "pac_ret" @@ -71,6 +71,7 @@ ohos_shared_library("selectionengine_napi") { "graphic_2d:librender_service_base", "graphic_2d:librender_service_client", "graphic_2d:window_animation", + "samgr:samgr_proxy", ] relative_install_dir = "module" diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index 69277b6..eeac547 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -19,7 +19,7 @@ #include "napi/native_node_api.h" #include "selection_log.h" #include "panel_listener_impl.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "selectionmethod_trace.h" #include "selection_ability.h" #include "event_checker.h" diff --git a/frameworks/js/napi/selection_ability/js_selection_ability.cpp b/frameworks/js/napi/selection_ability/js_selection_ability.cpp index bf6764f..28db841 100644 --- a/frameworks/js/napi/selection_ability/js_selection_ability.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_ability.cpp @@ -16,7 +16,7 @@ #include "js_selection_ability.h" #include "event_checker.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "napi/native_node_api.h" #include "selection_log.h" #include "util.h" diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 42bb18c..b62ee49 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -18,7 +18,7 @@ #include "event_checker.h" #include "iservice_registry.h" #include "selection_ability.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "callback_handler.h" #include "napi/native_node_api.h" #include "selection_listener_impl.h" diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp index f51099a..147241b 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -15,7 +15,7 @@ #include "panel_listener_impl.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "callback_handler.h" #include "util.h" diff --git a/frameworks/js/napi/selection_client/async_call.cpp b/frameworks/js/napi/selection_client/async_call.cpp index 38b2c1a..4160e6f 100644 --- a/frameworks/js/napi/selection_client/async_call.cpp +++ b/frameworks/js/napi/selection_client/async_call.cpp @@ -18,7 +18,7 @@ #include #include #include "selection_log.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "napi/native_node_api.h" namespace OHOS { diff --git a/frameworks/js/napi/selection_client/async_call.h b/frameworks/js/napi/selection_client/async_call.h index 9f66be4..79195dd 100644 --- a/frameworks/js/napi/selection_client/async_call.h +++ b/frameworks/js/napi/selection_client/async_call.h @@ -19,7 +19,7 @@ #include #include "cpp/mutex.h" #include "selection_log.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "ffrt.h" #include "napi/native_api.h" #include "napi/native_common.h" diff --git a/frameworks/js/napi/selection_client/js_selection_utils.h b/frameworks/js/napi/selection_client/js_selection_utils.h index 78ae20f..acd0c63 100644 --- a/frameworks/js/napi/selection_client/js_selection_utils.h +++ b/frameworks/js/napi/selection_client/js_selection_utils.h @@ -22,7 +22,7 @@ #include "selection_log.h" #include "selection_panel.h" #include "util.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" diff --git a/frameworks/js/napi/selection_client/js_utils.cpp.bak b/frameworks/js/napi/selection_client/js_utils.cpp.bak index 1546d8f..bd982df 100644 --- a/frameworks/js/napi/selection_client/js_utils.cpp.bak +++ b/frameworks/js/napi/selection_client/js_utils.cpp.bak @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "js_utils.h" +#include "selection_js_utils.h" #include "js_util.h" diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn index 8cc9d53..db5a25e 100644 --- a/frameworks/native/selection_ability/BUILD.gn +++ b/frameworks/native/selection_ability/BUILD.gn @@ -13,7 +13,7 @@ import("//build/ohos.gni") import("//build/config/components/idl_tool/idl.gni") -import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") config("selection_listener_config") { include_dirs = [ diff --git a/frameworks/native/selection_ability/include/panel_common.h b/frameworks/native/selection_ability/include/panel_common.h index 7e17e79..f00ba99 100644 --- a/frameworks/native/selection_ability/include/panel_common.h +++ b/frameworks/native/selection_ability/include/panel_common.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef SELECTION_FWK_PANEL_COMMON_H -#define SELECTION_FWK_PANEL_COMMON_H +#ifndef SELECTIONFWK_PANEL_COMMON_H +#define SELECTIONFWK_PANEL_COMMON_H #include @@ -93,4 +93,4 @@ struct FullPanelAdjustInfo { }; } // namespace SelectionFwk } // namespace OHOS -#endif //SELECTION_FWK_PANEL_COMMON_H +#endif //SELECTIONFWK_PANEL_COMMON_H diff --git a/frameworks/native/selection_ability/include/panel_info.h b/frameworks/native/selection_ability/include/panel_info.h index 232f834..47ff030 100644 --- a/frameworks/native/selection_ability/include/panel_info.h +++ b/frameworks/native/selection_ability/include/panel_info.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef SELECTION_FWK_PANEL_INFO_H -#define SELECTION_FWK_PANEL_INFO_H +#ifndef SELECTIONFWK_PANEL_INFO_H +#define SELECTIONFWK_PANEL_INFO_H #include "parcel.h" @@ -82,4 +82,4 @@ enum class ImmersiveMode : int32_t { } // namespace SelectionFwk } // namespace OHOS -#endif // SELECTION_FWK_PANEL_INFO_H +#endif // SELECTIONFWK_PANEL_INFO_H diff --git a/frameworks/native/selection_extension/BUILD.gn b/frameworks/native/selection_extension/BUILD.gn index 039b5e6..7b50d9c 100644 --- a/frameworks/native/selection_extension/BUILD.gn +++ b/frameworks/native/selection_extension/BUILD.gn @@ -11,7 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") ohos_shared_library("selection_extension_ability_native") { diff --git a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp index d0f46ab..875cabe 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp @@ -17,7 +17,7 @@ #include "js_error_utils.h" #include "js_extension_context.h" #include "js_runtime_utils.h" -#include "js_utils.h" +#include "selection_js_utils.h" #include "napi_common_want.h" #include "selection_log.h" diff --git a/selection_service.gni b/selection_service.gni index d189fd4..54394dd 100644 --- a/selection_service.gni +++ b/selection_service.gni @@ -25,7 +25,7 @@ ability_runtime_inner_api_path = "${ability_runtime_path}/interfaces/inner_api" ability_runtime_services_path = "${ability_runtime_path}/services" word_selection_part_name = "word_selection" -selection_fwk_root_path = "//foundation/systemabilitymgr/selection_fwk" +selection_fwk_root_path = "//foundation/systemabilitymgr/selectionfwk" selection_path = "//commonlibrary/c_utils" diff --git a/service/BUILD.gn b/service/BUILD.gn index 775d84b..c101601 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -13,7 +13,7 @@ import("//build/ohos.gni") import("//build/config/components/idl_tool/idl.gni") -import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") config("selection_sa_config") { # visibility = [ ":*" ] diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index db35c4f..fa8ef63 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -12,9 +12,9 @@ # limitations under the License. import("//build/test.gni") -import("//foundation/systemabilitymgr/selection_fwk/selection_service.gni") +import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") -module_out_path = "selection_fwk/selection_fwk" +module_out_path = "selectionfwk/selectionfwk" ohos_unittest("selection_service_unit_test") { module_out_path = module_out_path include_dirs = [ -- Gitee From 60e71728bcb0219095552943b46da9747bc75c64 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Wed, 11 Jun 2025 17:05:28 +0800 Subject: [PATCH 67/93] =?UTF-8?q?=E6=95=B4=E6=94=B9=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/selection_js_utils.h | 31 +----- common/selectionfwk_js_utils.cpp | 103 +----------------- .../js/napi/selection_ability/js_panel.cpp | 13 +-- .../js_selection_engine_setting.cpp | 3 +- .../include/panel_status_listener.h | 3 - .../src/selection_ability.cpp | 8 +- .../selection_ability/src/selection_panel.cpp | 34 +++--- .../selection_ability/src/task_manager.cpp | 4 +- utils/include/selection_log.h | 97 +---------------- 9 files changed, 43 insertions(+), 253 deletions(-) diff --git a/common/selection_js_utils.h b/common/selection_js_utils.h index 4cd42a9..6d232a1 100644 --- a/common/selection_js_utils.h +++ b/common/selection_js_utils.h @@ -30,30 +30,11 @@ using Ability = OHOS::AppExecFwk::Ability; namespace OHOS { namespace SelectionFwk { -enum SEErrorCode : int32_t { - EXCEPTION_PERMISSION = 201, - EXCEPTION_SYSTEM_PERMISSION = 202, +enum SFErrorCode : int32_t { EXCEPTION_PARAMCHECK = 401, - EXCEPTION_UNSUPPORTED = 801, - EXCEPTION_PACKAGEMANAGER = 12800001, - EXCEPTION_IMENGINE = 12800002, - EXCEPTION_IMCLIENT = 12800003, - EXCEPTION_IME = 12800004, - EXCEPTION_CONFPERSIST = 12800005, - EXCEPTION_CONTROLLER = 12800006, - EXCEPTION_SETTINGS = 12800007, - EXCEPTION_IMMS = 12800008, - EXCEPTION_DETACHED = 12800009, - EXCEPTION_DEFAULTIME = 12800010, - EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED = 12800011, - EXCEPTION_PANEL_NOT_FOUND = 12800012, - EXCEPTION_WINDOW_MANAGER = 12800013, - EXCEPTION_BASIC_MODE = 12800014, - EXCEPTION_REQUEST_NOT_ACCEPT = 12800015, - EXCEPTION_EDITABLE = 12800016, - EXCEPTION_INVALID_PANEL_TYPE_FLAG = 12800017, - EXCEPTION_SELECTION_SERVICE = 25600001, // TODO:待定 - EXCEPTION_PANEL_DESTORYED // TODO:待定 + EXCEPTION_SELECTION_SERVICE = 33600001, + EXCEPTION_PANEL_DESTORYED = 33600002, + EXCEPTION_INVALID_OPERATION = 33600003, }; enum TypeCode : int32_t { @@ -76,7 +57,7 @@ enum TypeCode : int32_t { #define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \ do { \ if (!(condition)) { \ - JsUtils::ThrowException(env, SEErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + JsUtils::ThrowException(env, SFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ return retVal; \ } \ } while (0) @@ -84,7 +65,7 @@ enum TypeCode : int32_t { #define PARAM_CHECK_RETURN_VOID(env, condition, message, typeCode) \ do { \ if (!(condition)) { \ - JsUtils::ThrowException(env, SEErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ + JsUtils::ThrowException(env, SFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ return; \ } \ } while (0) diff --git a/common/selectionfwk_js_utils.cpp b/common/selectionfwk_js_utils.cpp index 689ca32..f9387c0 100644 --- a/common/selectionfwk_js_utils.cpp +++ b/common/selectionfwk_js_utils.cpp @@ -22,102 +22,17 @@ constexpr size_t STR_TAIL_LENGTH = 1; constexpr size_t ARGC_MAX = 6; const std::map JsUtils::ERROR_CODE_MAP = { - { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER }, - { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION }, - { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION }, - { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_EDITABLE }, - { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED }, - { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS }, - { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS }, - { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS }, - { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST }, - { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER }, - { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IME_START_INPUT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME }, - { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE }, { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME }, - { ErrorCode::ERROR_ENABLE_IME, EXCEPTION_IMMS }, - { ErrorCode::ERROR_NOT_CURRENT_IME, EXCEPTION_IMMS }, - { ErrorCode::ERROR_PANEL_NOT_FOUND, EXCEPTION_PANEL_NOT_FOUND }, - { ErrorCode::ERROR_WINDOW_MANAGER, EXCEPTION_WINDOW_MANAGER }, - { ErrorCode::ERROR_GET_TEXT_CONFIG, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_TEXT_LISTENER_ERROR, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED, EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED }, - { ErrorCode::ERROR_INVALID_RANGE, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_SECURITY_MODE_OFF, EXCEPTION_BASIC_MODE }, - { ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST, EXCEPTION_REQUEST_NOT_ACCEPT }, - { ErrorCode::ERROR_MESSAGE_HANDLER, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_INVALID_PANEL_TYPE, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, - { ErrorCode::ERROR_INVALID_PANEL_FLAG, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, - { ErrorCode::ERROR_IMA_CHANNEL_NULLPTR, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_IPC_REMOTE_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMA_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_INPUT_TYPE_NOT_FOUND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_MALLOC_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_START_TIMEOUT, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED }, { ErrorCode::ERROR_SELECTION_SERVICE, EXCEPTION_SELECTION_SERVICE }, - { ErrorCode::ERROR_PANEL_DESTORYED, EXCEPTION_PANEL_DESTORYED } + { ErrorCode::ERROR_PANEL_DESTORYED, EXCEPTION_PANEL_DESTORYED }, + { ErrorCode::ERROR_INVALID_OPERATION, EXCEPTION_INVALID_OPERATION } }; const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { - { EXCEPTION_PERMISSION, "the permissions check fails." }, - { EXCEPTION_SYSTEM_PERMISSION, "not system application." }, - { EXCEPTION_PARAMCHECK, "the parameters check fails." }, - { EXCEPTION_UNSUPPORTED, "capability not supported." }, - { EXCEPTION_PACKAGEMANAGER, "bundle manager error." }, - { EXCEPTION_IMENGINE, "input method engine error. Possible causes: 1.input method panel not created.\ - 2.the input method application does not subscribe to related events." }, - { EXCEPTION_IMCLIENT, "input method client error. Possible causes: 1.the edit box is not focused.\ - 2.no edit box is bound to current input method application." }, - { EXCEPTION_IME, "not an input method application." }, - { EXCEPTION_CONFPERSIST, "configuration persistence error." }, - { EXCEPTION_CONTROLLER, "input method controller error.\ - Possible cause: create InputmethodController object failed." }, - { EXCEPTION_SETTINGS, "input method setter error. Possible cause: create InputmethodSetting object failed." }, - { EXCEPTION_IMMS, "input method manager service error. Possible cause: a system error, such as null pointer,\ - IPC exception." }, - { EXCEPTION_DETACHED, "input method client detached." }, - { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." }, - { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." }, - { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." }, - { EXCEPTION_WINDOW_MANAGER, "window manager service error." }, - { EXCEPTION_BASIC_MODE, "the input method is basic mode." }, - { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." }, - { EXCEPTION_EDITABLE, "the edit mode need enable." }, - { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." }, - { EXCEPTION_SELECTION_SERVICE, "selection service exception." }, - { EXCEPTION_PANEL_DESTORYED, "this panel has been destroyed." } + { EXCEPTION_PARAMCHECK, "The parameters check fails." }, + { EXCEPTION_SELECTION_SERVICE, "Selection service exception." }, + { EXCEPTION_PANEL_DESTORYED, "This selection window has been destroyed." }, + { EXCEPTION_INVALID_OPERATION, "Invalid operation. The selection app is not valid." } }; const std::map JsUtils::PARAMETER_TYPE = { @@ -158,12 +73,6 @@ void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, NAPI_CALL_RETURN_VOID(env, napi_throw(env, error)); } -void JsUtils::ThrowException(napi_env env, int32_t errCode, const std::string& msg) -{ - std::string errMsg = ToMessage(JsUtils::Convert(errCode)) + " " + msg; - NAPI_CALL_RETURN_VOID(env, napi_throw_error(env, std::to_string(errCode).c_str(), errMsg.c_str())); -} - napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg) { SELECTION_HILOGD("ToError start"); diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index eeac547..c73ef97 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -133,14 +133,11 @@ napi_value JsPanel::SetUiContent(napi_env env, napi_callback_info info) } auto code = ctxt->selectionPanel->SetUiContent(ctxt->path, env); jsQueue_.Pop(); - if (code == ErrorCode::ERROR_PARAMETER_CHECK_FAILED) { + if (code != ErrorCode::NO_ERROR) { ctxt->SetErrorCode(code); - ctxt->SetErrorMessage("path should be a path to specific page."); - return napi_generic_failure; - } else if (code == ErrorCode::ERROR_SELECTION_SERVICE || code == ErrorCode::ERROR_PANEL_DESTORYED) { JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to SetUiContent", TYPE_NONE); + return napi_generic_failure; } - return napi_ok; }; ctxt->SetAction(std::move(input), std::move(output)); @@ -216,16 +213,16 @@ napi_value JsPanel::StartMoving(napi_env env, napi_callback_info info) { napi_value self = nullptr; NAPI_CALL(env, napi_get_cb_info(env, info, 0, nullptr, &self, nullptr)); - RESULT_CHECK_RETURN(env, (self != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), + RESULT_CHECK_RETURN(env, (self != nullptr), JsUtils::Convert(ErrorCode::ERROR_SELECTION_SERVICE), "", TYPE_NONE, JsUtil::Const::Null(env)); void *native = nullptr; NAPI_CALL(env, napi_unwrap(env, self, &native)); - RESULT_CHECK_RETURN(env, (native != nullptr), JsUtils::Convert(ErrorCode::ERROR_IME), + RESULT_CHECK_RETURN(env, (native != nullptr), JsUtils::Convert(ErrorCode::ERROR_SELECTION_SERVICE), "", TYPE_NONE, JsUtil::Const::Null(env)); auto selectionPanel = reinterpret_cast(native)->GetNative(); if (selectionPanel == nullptr) { SELECTION_HILOGE("selectionPanel is nullptr!"); - JsUtils::ThrowException(env, JsUtils::Convert(ErrorCode::ERROR_IME), + JsUtils::ThrowException(env, JsUtils::Convert(ErrorCode::ERROR_SELECTION_SERVICE), "failed to start moving, selectionPanel is nullptr", TYPE_NONE); return JsUtil::Const::Null(env); } diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index b62ee49..5547a34 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -163,7 +163,6 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf auto exec = [env, ctxt](AsyncCall::Context *ctx) { auto ret = SelectionAbility::GetInstance()->CreatePanel(ctxt->context, ctxt->panelInfo, ctxt->panel); - CHECK_RETURN_VOID(ret == ErrorCode::NO_ERROR, "JsSelectionEngineSetting CreatePanel failed!"); if(ret != ErrorCode::NO_ERROR) { ctxt->SetErrorCode(ret); JsUtils::ThrowException(env, JsUtils::Convert(ret), "CreatePanel failed!", TYPE_NONE); @@ -221,7 +220,7 @@ napi_value JsSelectionEngineSetting::DestroyPanel(napi_env env, napi_callback_in CHECK_RETURN((ctxt->panel != nullptr), "panel is nullptr!", napi_generic_failure); auto errCode = SelectionAbility::GetInstance()->DestroyPanel(ctxt->panel); if (errCode != ErrorCode::NO_ERROR) { - SELECTION_HILOGE("DestroyPanel failed, errCode: %{public}d!", errCode); + SELECTION_HILOGE("DestroyPanel failed, errCode: %{public}d!", JsUtils::Convert(errCode)); JsUtils::ThrowException(env, JsUtils::Convert(errCode), "DestroyPanel failed!", TYPE_NONE); return napi_generic_failure; } diff --git a/frameworks/native/selection_ability/include/panel_status_listener.h b/frameworks/native/selection_ability/include/panel_status_listener.h index bc4c1da..3a20cc3 100644 --- a/frameworks/native/selection_ability/include/panel_status_listener.h +++ b/frameworks/native/selection_ability/include/panel_status_listener.h @@ -25,9 +25,6 @@ class PanelStatusListener { public: virtual ~PanelStatusListener() {}; virtual void OnPanelStatus(uint32_t windowId, const std::string& status) = 0; - // virtual void OnSizeChange(uint32_t windowId, const WindowSize &size) = 0; - // virtual void OnSizeChange( - // uint32_t windowId, const WindowSize &size, const PanelAdjustInfo &keyboardArea, const std::string &event) = 0; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index 2a51459..be259d1 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -85,7 +85,7 @@ int32_t SelectionAbility::CreatePanel(const std::shared_ptr &selectionPanel) @@ -93,7 +93,7 @@ int32_t SelectionAbility::DestroyPanel(const std::shared_ptr &se SELECTION_HILOGI("SelectionAbility DestroyPanel start."); if (selectionPanel == nullptr) { SELECTION_HILOGE("panel is nullptr!"); - return ErrorCode::ERROR_BAD_PARAMETERS; + return ErrorCode::ERROR_SELECTION_SERVICE; } auto ret = selectionPanel->DestroyPanel(); if (ret == ErrorCode::NO_ERROR) { @@ -106,7 +106,7 @@ int32_t SelectionAbility::DestroyPanel(const std::shared_ptr &se int32_t SelectionAbility::ShowPanel(const std::shared_ptr &selectionpanel) { if (selectionpanel == nullptr) { - return ErrorCode::ERROR_BAD_PARAMETERS; + return ErrorCode::ERROR_SELECTION_SERVICE; } auto ret = selectionpanel->ShowPanel(); if (ret != ErrorCode::NO_ERROR) { @@ -119,7 +119,7 @@ int32_t SelectionAbility::ShowPanel(const std::shared_ptr &selec int32_t SelectionAbility::HidePanel(const std::shared_ptr &selectionpanel) { if (selectionpanel == nullptr) { - return ErrorCode::ERROR_BAD_PARAMETERS; + return ErrorCode::ERROR_SELECTION_SERVICE; } auto ret = selectionpanel->HidePanel(); if (ret != ErrorCode::NO_ERROR) { diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index 5444f55..7217b97 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -53,7 +53,7 @@ int32_t SelectionPanel::CreatePanel( // winOption_ = new (std::nothrow) OHOS::Rosen::WindowOption(); // if (winOption_ == nullptr) { - // return ErrorCode::ERROR_NULL_POINTER; + // return ErrorCode::ERROR_SELECTION_SERVICE; // } // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DYNAMIC); // winOption_->SetWindowRect(OHOS::Rosen::Rect{10, 10, 80, 50}); @@ -65,13 +65,13 @@ int32_t SelectionPanel::CreatePanel( // } // if (window_ == nullptr || wmError != WMError::WM_OK) { // SELECTION_HILOGE("create window failed: %{public}d!", wmError); - // return ErrorCode::ERROR_OPERATE_PANEL; + // return ErrorCode::ERROR_SELECTION_SERVICE; // } // isScbEnable_ = Rosen::SceneBoardJudgement::IsSceneBoardEnabled(); // if (SetPanelProperties() != ErrorCode::NO_ERROR) { // wmError = window_->Destroy(); // SELECTION_HILOGI("destroy window end, wmError is %{public}d.", wmError); - // return ErrorCode::ERROR_OPERATE_PANEL; + // return ErrorCode::ERROR_SELECTION_SERVICE; // } // windowId_ = window_->GetWindowId(); // SELECTION_HILOGI("success, type/flag/windowId/isScbEnable_: %{public}d/%{public}d/%{public}u/%{public}d.", @@ -119,14 +119,14 @@ int32_t SelectionPanel::SetPanelProperties() { if (window_ == nullptr) { SELECTION_HILOGE("window is nullptr!"); - return ErrorCode::ERROR_OPERATE_PANEL; + return ErrorCode::ERROR_SELECTION_SERVICE; } WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT; if (!isScbEnable_) { WMError wmError = window_->SetWindowGravity(gravity, invalidGravityPercent); if (wmError != WMError::WM_OK) { SELECTION_HILOGE("failed to set window gravity, wmError is %{public}d, start destroy window!", wmError); - return ErrorCode::ERROR_OPERATE_PANEL; + return ErrorCode::ERROR_SELECTION_SERVICE; } return ErrorCode::NO_ERROR; } @@ -134,7 +134,7 @@ int32_t SelectionPanel::SetPanelProperties() auto ret = window_->AdjustKeyboardLayout(keyboardLayoutParams_); if (ret != WMError::WM_OK) { SELECTION_HILOGE("SetWindowGravity failed, wmError is %{public}d, start destroy window!", ret); - return ErrorCode::ERROR_OPERATE_PANEL; + return ErrorCode::ERROR_SELECTION_SERVICE; } return ErrorCode::NO_ERROR; } @@ -147,7 +147,7 @@ int32_t SelectionPanel::DestroyPanel() } if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_NULL_POINTER; + return ErrorCode::ERROR_SELECTION_SERVICE; } auto result = window_->Destroy(); SELECTION_HILOGI("destroy ret: %{public}d", result); @@ -168,7 +168,7 @@ int32_t SelectionPanel::SetUiContent(const std::string &contentInfo, napi_env en { if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr, can not SetUiContent!"); - return ErrorCode::ERROR_NULL_POINTER; + return ErrorCode::ERROR_SELECTION_SERVICE; } if(IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); @@ -202,7 +202,7 @@ int32_t SelectionPanel::ShowPanel() } if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_IMA_NULLPTR; + return ErrorCode::ERROR_SELECTION_SERVICE; } if(IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); @@ -219,7 +219,7 @@ int32_t SelectionPanel::ShowPanel() } if (ret != WMError::WM_OK) { SELECTION_HILOGE("ShowPanel error, err = %{public}d", ret); - return ErrorCode::ERROR_OPERATE_PANEL; + return ErrorCode::ERROR_SELECTION_SERVICE; } SELECTION_HILOGI("Selection panel shown successfully."); return ErrorCode::NO_ERROR; @@ -229,7 +229,7 @@ bool SelectionPanel::IsShowing() { if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_NULL_POINTER; + return ErrorCode::ERROR_SELECTION_SERVICE; } auto windowState = window_->GetWindowState(); if (windowState == WindowState::STATE_SHOWN) { @@ -257,7 +257,7 @@ int32_t SelectionPanel::HidePanel() SELECTION_HILOGD("SelectionPanel start"); if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_NULL_POINTER; + return ErrorCode::ERROR_SELECTION_SERVICE; } if(IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); @@ -274,7 +274,7 @@ int32_t SelectionPanel::HidePanel() } if (ret != WMError::WM_OK) { SELECTION_HILOGE("HidePanel error, err: %{public}d!", ret); - return ErrorCode::ERROR_OPERATE_PANEL; + return ErrorCode::ERROR_SELECTION_SERVICE; } SELECTION_HILOGI("success, panelType/x/y/width/height: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", static_cast(panelType_), x_, y_, width_, height_); @@ -301,7 +301,7 @@ int32_t SelectionPanel::StartMoving() { if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_IME; + return ErrorCode::ERROR_SELECTION_SERVICE; } if(IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); @@ -310,11 +310,11 @@ int32_t SelectionPanel::StartMoving() auto ret = window_->StartMoveWindow(); if (ret == WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT) { SELECTION_HILOGE("window manager service not support error ret = %{public}d.", ret); - return ErrorCode::ERROR_DEVICE_UNSUPPORTED; + return ErrorCode::ERROR_SELECTION_SERVICE; } if (ret != WmErrorCode::WM_OK) { SELECTION_HILOGE("window manager service error ret = %{public}d.", ret); - return ErrorCode::ERROR_WINDOW_MANAGER; + return ErrorCode::ERROR_SELECTION_SERVICE; } SELECTION_HILOGI("StartMoving success!"); return ErrorCode::NO_ERROR; @@ -325,7 +325,7 @@ int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) SELECTION_HILOGD("moveto start!"); if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_NULL_POINTER; + return ErrorCode::ERROR_SELECTION_SERVICE; } if(IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); diff --git a/frameworks/native/selection_ability/src/task_manager.cpp b/frameworks/native/selection_ability/src/task_manager.cpp index f4b231b..42f04c2 100644 --- a/frameworks/native/selection_ability/src/task_manager.cpp +++ b/frameworks/native/selection_ability/src/task_manager.cpp @@ -72,11 +72,11 @@ int32_t TaskManager::Pend(action_ptr_t action) { if (action == nullptr) { SELECTION_HILOGE("curTask_ is NULL or not runing, pend failed!"); - return ErrorCode::ERROR_NULL_POINTER; + return ErrorCode::ERROR_SELECTION_SERVICE; } if (curTask_ == nullptr || !curTask_->IsRunning()) { SELECTION_HILOGE("curTask_ is NULL or not runing, pend failed!"); - return ErrorCode::ERROR_TASK_MANAGER_PEND_FAILED; + return ErrorCode::ERROR_SELECTION_SERVICE; } return curTask_->Pend(std::move(action)); } diff --git a/utils/include/selection_log.h b/utils/include/selection_log.h index ae4a709..eb56468 100644 --- a/utils/include/selection_log.h +++ b/utils/include/selection_log.h @@ -52,106 +52,13 @@ extern "C" { namespace ErrorCode { // Error Code definition in the input method management system enum { - ERROR_STATUS_UNKNOWN_TRANSACTION = -EBADMSG, // unknown transaction - - // binder exception error code from Status.h - ERROR_EX_ILLEGAL_ARGUMENT = -3, // illegal argument exception - ERROR_EX_NULL_POINTER = -4, // null pointer exception - ERROR_EX_ILLEGAL_STATE = -5, // illegal state exception - ERROR_EX_PARCELABLE = -6, // parcelable exception - ERROR_EX_UNSUPPORTED_OPERATION = -7, // unsupported operation exception - ERROR_EX_SERVICE_SPECIFIC = -8, // service specific exception // no error NO_ERROR = 0, // no error - - ERROR_NULL_POINTER, // null pointer - ERROR_BAD_PARAMETERS, // bad parameters - ERROR_SUBSCRIBE_KEYBOARD_EVENT, - - ERROR_CONTROLLER_INVOKING_FAILED, - ERROR_PERSIST_CONFIG, - ERROR_KBD_HIDE_FAILED, - ERROR_PACKAGE_MANAGER, - ERROR_REMOTE_CLIENT_DIED, - - ERROR_NOT_CURRENT_IME, - ERROR_NOT_IME, - ERROR_NOT_AI_APP_IME, - ERROR_ADD_DEATH_RECIPIENT_FAILED, - ERROR_STATUS_SYSTEM_PERMISSION, // not system application ERROR_PARAMETER_CHECK_FAILED, - ERROR_KEYWORD_NOT_FOUND, - ERROR_ENABLE_IME, - ERROR_NOT_DEFAULT_IME, - ERROR_ENABLE_SECURITY_MODE, - ERROR_DISPATCH_KEY_EVENT, - ERROR_INVALID_PRIVATE_COMMAND_SIZE, - ERROR_PANEL_NOT_FOUND, - ERROR_WINDOW_MANAGER, - ERROR_GET_TEXT_CONFIG, - ERROR_SYSTEM_CMD_CHANNEL_ERROR, - ERROR_INVALID_PRIVATE_COMMAND, - ERROR_OS_ACCOUNT, - ERROR_TASK_MANAGER_PEND_FAILED, - ERROR_INVALID_PANEL_TYPE, - ERROR_INVALID_PANEL_FLAG, - ERROR_MSG_HANDLER_NOT_REGIST, - ERROR_SECURITY_MODE_OFF, - ERROR_MESSAGE_HANDLER, - ERROR_INVALID_ARRAY_BUFFER_SIZE, - ERROR_SERVICE_START_FAILED, - ERROR_JS_CB_NOT_REGISTER, // only for hiSysEvent - ERROR_DEAL_TIMEOUT, // only for hiSysEvent - ERROR_IPC_REMOTE_NULLPTR, - - ERROR_IMA_BEGIN, - ERROR_IME, - ERROR_OPERATE_PANEL, - ERROR_IMA_CHANNEL_NULLPTR, - ERROR_IMA_NULLPTR, - ERROR_IMA_END, - - ERROR_IMC_BEGIN, - ERROR_CLIENT_NOT_EDITABLE, - ERROR_TEXT_PREVIEW_NOT_SUPPORTED, - ERROR_TEXT_LISTENER_ERROR, - ERROR_INVALID_RANGE, - ERROR_CLIENT_NOT_BOUND, - ERROR_IMC_NULLPTR, - ERROR_IMC_END, - - ERROR_IMSA_BEGIN, - ERROR_PARSE_CONFIG_FILE, - ERROR_IME_START_INPUT_FAILED, - ERROR_STATUS_PERMISSION_DENIED, - ERROR_CLIENT_NOT_FOCUSED, - ERROR_CLIENT_NULL_POINTER, - ERROR_CLIENT_ADD_FAILED, - ERROR_CLIENT_NOT_FOUND, - ERROR_IME_NOT_STARTED, - ERROR_KBD_SHOW_FAILED, // failed to show keyboard - ERROR_IMSA_INPUT_TYPE_NOT_FOUND, - ERROR_IMSA_DEFAULT_IME_NOT_FOUND, - ERROR_IMSA_CLIENT_INPUT_READY_FAILED, - ERROR_IMSA_MALLOC_FAILED, - ERROR_IMSA_NULLPTR, - ERROR_IMSA_USER_SESSION_NOT_FOUND, - ERROR_IMSA_GET_IME_INFO_FAILED, - ERROR_IMSA_IME_TO_START_NULLPTR, - ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, - ERROR_IMSA_IME_EVENT_CONVERT_FAILED, - ERROR_IMSA_IME_CONNECT_FAILED, - ERROR_IMSA_IME_DISCONNECT_FAILED, - ERROR_IMSA_IME_START_TIMEOUT, - ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, - ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, - ERROR_DEVICE_UNSUPPORTED, - ERROR_SCENE_UNSUPPORTED, - ERROR_PRIVATE_COMMAND_IS_EMPTY, - ERROR_IMSA_END, ERROR_SELECTION_SERVICE, - ERROR_PANEL_DESTORYED + ERROR_PANEL_DESTORYED, + ERROR_INVALID_OPERATION }; }; // namespace ErrorCode -- Gitee From 65d214273bb708ceabcbd6f5ab5fbe129d66d55c Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Tue, 10 Jun 2025 19:13:15 +0800 Subject: [PATCH 68/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 4 +- common/event_checker.cpp | 2 +- common/selection_js_utils.h | 3 +- frameworks/js/napi/selection_ability/BUILD.gn | 4 +- .../js_selection_engine_setting.cpp | 74 +++++-------------- .../js_selection_engine_setting.h | 7 +- .../selection_engine_module.cpp | 2 +- .../napi/selection_extension_ability/BUILD.gn | 2 +- .../selection_extension_ability_module.cpp | 8 +- .../napi/selection_extension_context/BUILD.gn | 2 +- .../selection_extension_context.js | 4 - .../selection_extension_context_module.cpp | 8 +- .../include/selection_extension_context.h | 12 --- .../src/js_selection_extension.cpp | 4 +- .../src/js_selection_extension_context.cpp | 52 ------------- .../src/selection_extension_context.cpp | 13 ---- 16 files changed, 42 insertions(+), 159 deletions(-) diff --git a/bundle.json b/bundle.json index ea27097..34bacaa 100644 --- a/bundle.json +++ b/bundle.json @@ -53,7 +53,7 @@ "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_extension_context:selectionextensioncontext_napi", "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_extension:selection_extension_ability_native", - "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_ability:selectionengine_napi", + "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_ability:selectionmanager_napi", "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_ability:selection_ability" ], "inner_kits": [], @@ -62,4 +62,4 @@ ] } } -} \ No newline at end of file +} diff --git a/common/event_checker.cpp b/common/event_checker.cpp index bcfb661..1693040 100644 --- a/common/event_checker.cpp +++ b/common/event_checker.cpp @@ -19,7 +19,7 @@ namespace OHOS { namespace SelectionFwk { const std::unordered_set EVENT_TYPES[static_cast(EventSubscribeModule::MODULE_END)] = { - [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionEvent", "selectionPanelEvent" }, + [static_cast(EventSubscribeModule::SELECTION_METHOD_ABILITY)] = { "selectionCompleted" }, [static_cast(EventSubscribeModule::PANEL)] = { "destroyed", "hidden" } }; diff --git a/common/selection_js_utils.h b/common/selection_js_utils.h index 6d232a1..469007c 100644 --- a/common/selection_js_utils.h +++ b/common/selection_js_utils.h @@ -31,6 +31,7 @@ using Ability = OHOS::AppExecFwk::Ability; namespace OHOS { namespace SelectionFwk { enum SFErrorCode : int32_t { + EXCEPTION_SUCCESS = 0, EXCEPTION_PARAMCHECK = 401, EXCEPTION_SELECTION_SERVICE = 33600001, EXCEPTION_PANEL_DESTORYED = 33600002, @@ -169,4 +170,4 @@ private: }; } // namespace SelectionFwk } // namespace OHOS -#endif // SELECTAIONFWK_JS_UTILS_H \ No newline at end of file +#endif // SELECTAIONFWK_JS_UTILS_H diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 2aaad95..44d1cd9 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -14,7 +14,7 @@ import("//build/ohos.gni") import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") -ohos_shared_library("selectionengine_napi") { +ohos_shared_library("selectionmanager_napi") { branch_protector_ret = "pac_ret" sanitize = { boundary_sanitize = true @@ -74,7 +74,7 @@ ohos_shared_library("selectionengine_napi") { "samgr:samgr_proxy", ] - relative_install_dir = "module" + relative_install_dir = "module/selectioninput" subsystem_name = "systemabilitymgr" part_name = "selectionfwk" } diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 5547a34..c558efe 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -30,7 +30,8 @@ #include "js_selection_utils.h" using namespace OHOS; -using namespace OHOS::SelectionFwk; +namespace OHOS { +namespace SelectionFwk { constexpr size_t ARGC_ONE = 1; constexpr size_t ARGC_TWO = 2; @@ -44,7 +45,6 @@ std::shared_ptr JsSelectionEngineSetting::handler_{ nu sptr JsSelectionEngineSetting::listenerStub_ { nullptr }; sptr JsSelectionEngineSetting::abilityManager_ { nullptr }; - napi_value JsSelectionEngineSetting::GetSelectionAbility(napi_env env, napi_callback_info info) { SELECTION_HILOGI("SelectionEngineSetting---GetSelectionAbility"); @@ -68,15 +68,12 @@ napi_value JsSelectionEngineSetting::Subscribe(napi_env env, napi_callback_info return nullptr; } SELECTION_HILOGI("subscribe type: %{public}s.", type.c_str()); - auto engine = reinterpret_cast(JsUtils::GetNativeSelf(env, info)); - if (engine == nullptr) { - return nullptr; - } + std::shared_ptr callback = std::make_shared(env, argv[1], std::this_thread::get_id(), AppExecFwk::EventHandler::Current()); + auto engine = JsSelectionEngineSetting::GetJsSelectionEngineSetting(); engine->RegisterListener(argv[ARGC_ONE], type, callback); - napi_value result = nullptr; napi_get_null(env, &result); return result; @@ -256,36 +253,22 @@ sptr JsSelectionEngineSetting::GetSelectionSystemAbility() void JsSelectionEngineSetting::RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj) { - SELECTION_HILOGD("RegisterListener %{public}s", type.c_str()); + SELECTION_HILOGI("RegisterListener %{public}s", type.c_str()); std::lock_guard lock(mutex_); if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { - SELECTION_HILOGD("methodName %{public}s is not registered!", type.c_str()); + SELECTION_HILOGI("methodName %{public}s is not registered!", type.c_str()); } auto callbacks = jsCbMap_[type]; bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr cb) { return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_); }); if (ret) { - SELECTION_HILOGD("JsSelectionEngineSetting callback already registered!"); + SELECTION_HILOGI("JsSelectionEngineSetting callback already registered!"); return; } SELECTION_HILOGI("add %{public}s callbackObj into jsCbMap_.", type.c_str()); jsCbMap_[type].push_back(std::move(callbackObj)); - - // auto proxy = GetSelectionSystemAbility(); - // if (proxy == nullptr) { - // SELECTION_HILOGE("selection system ability is nullptr!"); - // return; - // } - // auto selectionInterface = GetJsSelectionEngineSetting(); - // listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionInterface); - // if (listenerStub_ == nullptr) { - // SELECTION_HILOGE("Failed to create SelectionListenerImpl instance."); - // return; - // } - // SELECTION_HILOGI("Begin calling SA RegisterListener!"); - // proxy->RegisterListener(listenerStub_->AsObject()); } void JsSelectionEngineSetting::UnRegisterListener(napi_value callback, std::string type) @@ -343,7 +326,7 @@ std::shared_ptr JsSelectionEngineSetting::GetJsSelecti if (selectionDelegate_ == nullptr) { std::lock_guard lock(selectionMutex_); if (selectionDelegate_ == nullptr) { - auto delegate = std::make_shared(); + std::shared_ptr delegate(new JsSelectionEngineSetting); if (delegate == nullptr) { SELECTION_HILOGE("JsSelectionEngineSetting is nullptr!"); return nullptr; @@ -375,25 +358,15 @@ void JsSelectionEngineSetting::RegisterListerToService(std::shared_ptrRegisterListener(listenerStub_->AsObject()); } -napi_value JsSelectionEngineSetting::JsConstructor(napi_env env, napi_callback_info cbinfo) +SFErrorCode JsSelectionEngineSetting::Register() { - napi_value thisVar = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, cbinfo, nullptr, nullptr, &thisVar, nullptr)); auto delegate = GetJsSelectionEngineSetting(); if (delegate == nullptr) { SELECTION_HILOGE("failed to get delegate!"); - napi_value result = nullptr; - napi_get_null(env, &result); - return result; - } - napi_status status = napi_wrap( - env, thisVar, delegate.get(), [](napi_env env, void *nativeObject, void *hint) {}, nullptr, nullptr); - if (status != napi_ok) { - SELECTION_HILOGE("failed to wrap: %{public}d!", status); - return nullptr; + return EXCEPTION_SELECTION_SERVICE; } RegisterListerToService(delegate); - return thisVar; + return EXCEPTION_SUCCESS; }; napi_value JsSelectionEngineSetting::Init(napi_env env, napi_value exports) @@ -401,26 +374,16 @@ napi_value JsSelectionEngineSetting::Init(napi_env env, napi_value exports) SELECTION_HILOGI("napi init"); napi_property_descriptor descriptor[] = { DECLARE_NAPI_FUNCTION("getSelectionAbility", GetSelectionAbility), - }; - NAPI_CALL(env, napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor)); - return InitProperty(env, exports); -} - -napi_value JsSelectionEngineSetting::InitProperty(napi_env env, napi_value exports) -{ - SELECTION_HILOGI("napi init"); - napi_property_descriptor properties[] = { DECLARE_NAPI_FUNCTION("on", Subscribe), DECLARE_NAPI_FUNCTION("off", UnSubscribe), DECLARE_NAPI_FUNCTION("createPanel", CreatePanel), DECLARE_NAPI_FUNCTION("destroyPanel", DestroyPanel), }; - - napi_value cons = nullptr; - NAPI_CALL(env, napi_define_class(env, KDS_CLASS_NAME.c_str(), KDS_CLASS_NAME.size(), JsConstructor, nullptr, - sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons)); - NAPI_CALL(env, napi_create_reference(env, cons, 1, &KDSRef_)); - NAPI_CALL(env, napi_set_named_property(env, exports, KDS_CLASS_NAME.c_str(), cons)); + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor)); + if (Register() != EXCEPTION_SUCCESS) { + SELECTION_HILOGE("regist lister to service failed!"); + return nullptr; + } return exports; } @@ -467,7 +430,7 @@ napi_value JsSelectionEngineSetting::Write(napi_env env, const SelectionInfo &se int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionInfo &selectionInfo) { SELECTION_HILOGD("OnSelectionEvent begin"); - std::string type = "selectionEvent"; + std::string type = "selectionCompleted"; auto entry = GetEntry(type, [&selectionInfo](SelectionEntry &entry) {entry.selectionInfo = selectionInfo; }); if (entry == nullptr) { @@ -502,4 +465,5 @@ int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionInfo &selectio eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::VIP); return 0; } - +} +} diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index 86c1713..38010bb 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -36,10 +36,8 @@ namespace OHOS { namespace SelectionFwk { -class JsSelectionEngineSetting : public SelectionInterface{ +class JsSelectionEngineSetting : public SelectionInterface { public: - JsSelectionEngineSetting() = default; - ~JsSelectionEngineSetting() = default; static napi_value Init(napi_env env, napi_value exports); static napi_value InitProperty(napi_env env, napi_value exports); static napi_value GetSelectionAbility(napi_env env, napi_callback_info info); @@ -82,8 +80,9 @@ private: } }; + JsSelectionEngineSetting() = default; static napi_value GetSEInstance(napi_env env, napi_callback_info info); - static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo); + static SFErrorCode Register(); static napi_value Write(napi_env env, const SelectionInfo &selectionInfo); static napi_status GetContext(napi_env env, napi_value in, std::shared_ptr &context); static std::shared_ptr GetJsSelectionEngineSetting(); diff --git a/frameworks/js/napi/selection_ability/selection_engine_module.cpp b/frameworks/js/napi/selection_ability/selection_engine_module.cpp index 2ac7b3e..55d70ec 100644 --- a/frameworks/js/napi/selection_ability/selection_engine_module.cpp +++ b/frameworks/js/napi/selection_ability/selection_engine_module.cpp @@ -36,7 +36,7 @@ static napi_module _module = { .nm_flags = 0, .nm_filename = nullptr, .nm_register_func = Init, - .nm_modname = "selectionEngine", + .nm_modname = "selectionInput.selectionManager", .nm_priv = ((void *)0), .reserved = { 0 } }; /* diff --git a/frameworks/js/napi/selection_extension_ability/BUILD.gn b/frameworks/js/napi/selection_extension_ability/BUILD.gn index f102505..5bb3207 100644 --- a/frameworks/js/napi/selection_extension_ability/BUILD.gn +++ b/frameworks/js/napi/selection_extension_ability/BUILD.gn @@ -44,7 +44,7 @@ ohos_shared_library("selectionextensionability_napi") { external_deps = [ "napi:ace_napi" ] - relative_install_dir = "module" + relative_install_dir = "module/selectioninput" subsystem_name = "systemabilitymgr" part_name = "selectionfwk" } diff --git a/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp index 1c7edbe..c1ad916 100644 --- a/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp +++ b/frameworks/js/napi/selection_extension_ability/selection_extension_ability_module.cpp @@ -22,16 +22,16 @@ extern const char _binary_selection_extension_ability_abc_end[]; static napi_module _module = { .nm_filename = "libselectionextensionability_napi.so/selection_extension_ability.js", - .nm_modname = "SelectionExtensionAbility", + .nm_modname = "selectionInput.SelectionExtensionAbility", }; -extern "C" __attribute__((constructor)) void NAPI_SelectionExtensionAbility_AutoRegister() +extern "C" __attribute__((constructor)) void NAPI_selectionInput_SelectionExtensionAbility_AutoRegister() { napi_module_register(&_module); } extern "C" __attribute__((visibility("default"))) void - NAPI_SelectionExtensionAbility_GetJSCode(const char** buf, int* bufLen) + NAPI_selectionInput_SelectionExtensionAbility_GetJSCode(const char** buf, int* bufLen) { if (buf != nullptr) { *buf = _binary_selection_extension_ability_js_start; @@ -43,7 +43,7 @@ extern "C" __attribute__((visibility("default"))) void } extern "C" __attribute__((visibility("default"))) void - NAPI_SelectionExtensionAbility_GetABCCode(const char** buf, int* buflen) + NAPI_selectionInput_SelectionExtensionAbility_GetABCCode(const char** buf, int* buflen) { if (buf != nullptr) { *buf = _binary_selection_extension_ability_abc_start; diff --git a/frameworks/js/napi/selection_extension_context/BUILD.gn b/frameworks/js/napi/selection_extension_context/BUILD.gn index bbb99c2..3045f29 100644 --- a/frameworks/js/napi/selection_extension_context/BUILD.gn +++ b/frameworks/js/napi/selection_extension_context/BUILD.gn @@ -55,7 +55,7 @@ ohos_shared_library("selectionextensioncontext_napi") { external_deps = [ "napi:ace_napi" ] - relative_install_dir = "module" + relative_install_dir = "module/selectioninput" subsystem_name = "systemabilitymgr" part_name = "selectionfwk" } diff --git a/frameworks/js/napi/selection_extension_context/selection_extension_context.js b/frameworks/js/napi/selection_extension_context/selection_extension_context.js index 2d65b3a..b3e5cf3 100644 --- a/frameworks/js/napi/selection_extension_context/selection_extension_context.js +++ b/frameworks/js/napi/selection_extension_context/selection_extension_context.js @@ -20,10 +20,6 @@ class SelectionExtensionContext extends ExtensionContext { super(obj); this.extensionAbilityInfo = obj.extensionAbilityInfo; } - - startAbility(want) { - return this.__context_impl__.startAbility(want); - } } export default SelectionExtensionContext; \ No newline at end of file diff --git a/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp b/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp index 9db1fa9..e287dcf 100644 --- a/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp +++ b/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp @@ -23,15 +23,15 @@ extern const char _binary_selection_extension_context_abc_end[]; static napi_module g_ExtensionContextModule = { .nm_version = 0, .nm_filename = "libselectionextensioncontext_napi.so/selection_extension_context.js", - .nm_modname = "SelectionExtensionContext", + .nm_modname = "selectionInput.SelectionExtensionContext", }; -extern "C" __attribute__((constructor)) void NAPI_SelectionExtensionContext_AutoRegister() +extern "C" __attribute__((constructor)) void NAPI_selectionInput_SelectionExtensionContext_AutoRegister() { napi_module_register(&g_ExtensionContextModule); } -extern "C" __attribute__((visibility("default"))) void NAPI_SelectionExtensionContext_GetJSCode( +extern "C" __attribute__((visibility("default"))) void NAPI_selectionInput_SelectionExtensionContext_GetJSCode( const char **buf, int *bufLen) { if (buf != nullptr) { @@ -43,7 +43,7 @@ extern "C" __attribute__((visibility("default"))) void NAPI_SelectionExtensionCo } // ability_context JS register -extern "C" __attribute__((visibility("default"))) void NAPI_SelectionExtensionContext_GetABCCode( +extern "C" __attribute__((visibility("default"))) void NAPI_selectionInput_SelectionExtensionContext_GetABCCode( const char **buf, int *buflen) { if (buf != nullptr) { diff --git a/frameworks/native/selection_extension/include/selection_extension_context.h b/frameworks/native/selection_extension/include/selection_extension_context.h index 6ea410f..b0a22b4 100644 --- a/frameworks/native/selection_extension/include/selection_extension_context.h +++ b/frameworks/native/selection_extension/include/selection_extension_context.h @@ -26,18 +26,6 @@ public: SelectionExtensionContext() = default; virtual ~SelectionExtensionContext() = default; - /** - * @brief Starts a new ability. - * An ability using the AbilityInfo.AbilityType.SERVICE or AbilityInfo.AbilityType.PAGE template uses this method - * to start a specific ability. The system locates the target ability from installed abilities based on the value - * of the want parameter and then starts it. You can specify the ability to start using the want parameter. - * - * @param want Indicates the Want containing information about the target ability to start. - * - * @return errCode ERR_OK on success, others on failure. - */ - ErrCode StartAbility(const AAFwk::Want& want) const; - static const size_t CONTEXT_TYPE_ID; protected: diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index b3c38a3..b64c814 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -40,7 +40,7 @@ napi_value AttachSelectionExtensionContext(napi_env env, void* value, void*) return nullptr; } napi_value object = CreateJsSelectionExtensionContext(env, ptr); - auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "SelectionExtensionContext", &object, 1); + auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "selectionInput.SelectionExtensionContext", &object, 1); if (systemModule == nullptr) { SELECTION_HILOGE("failed to load system module by engine!"); return nullptr; @@ -206,7 +206,7 @@ void JsSelectionExtension::BindContext(napi_env env, napi_value obj) } SELECTION_HILOGD("JsSelectionExtension::Init CreateJsSelectionExtensionContext."); napi_value contextObj = CreateJsSelectionExtensionContext(env, context); - auto shellContextRef = jsRuntime_.LoadSystemModule("SelectionExtensionContext", &contextObj, ARGC_ONE); + auto shellContextRef = jsRuntime_.LoadSystemModule("selectionInput.SelectionExtensionContext", &contextObj, ARGC_ONE); if (shellContextRef == nullptr) { SELECTION_HILOGE("shellContextRef is nullptr!"); return; diff --git a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp index 875cabe..713f2b7 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp @@ -25,9 +25,6 @@ namespace OHOS::AbilityRuntime { using namespace OHOS::SelectionFwk; namespace { -constexpr int32_t INDEX_ZERO = 0; -constexpr int32_t ERROR_CODE_ONE = 1; -constexpr size_t ARGC_ONE = 1; class JsSelectionExtensionContext final { public: @@ -44,54 +41,8 @@ public: std::unique_ptr(static_cast(data)); } - static napi_value StartAbility(napi_env env, napi_callback_info info) - { - GET_CB_INFO_AND_CALL(env, info, JsSelectionExtensionContext, OnStartAbility); - } - private: std::weak_ptr context_; - - napi_value OnStartAbility(napi_env env, size_t argc, napi_value* argv) - { - SELECTION_HILOGI("SelectionExtensionContext OnStartAbility."); - // only support one params - PARAM_CHECK_RETURN(env, argc == ARGC_ONE, "number of param should in 1", TYPE_NONE, CreateJsUndefined(env)); - PARAM_CHECK_RETURN(env, JsUtil::GetType(env, argv[0]) == napi_object, "param want type must be Want", TYPE_NONE, - JsUtil::Const::Null(env)); - decltype(argc) unwrapArgc = 0; - AAFwk::Want want; - OHOS::AppExecFwk::UnwrapWant(env, argv[INDEX_ZERO], want); - SELECTION_HILOGI("%{public}s bundleName: %{public}s abilityName: %{public}s.", __func__, - want.GetBundle().c_str(), want.GetElement().GetAbilityName().c_str()); - unwrapArgc++; - napi_value lastParam = argc > unwrapArgc ? argv[unwrapArgc] : nullptr; - napi_value result = nullptr; - std::unique_ptr napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result); - auto asyncTask = [weak = context_, want, unwrapArgc, env, task = napiAsyncTask.get()]() { - SELECTION_HILOGI("startAbility start."); - auto context = weak.lock(); - if (context == nullptr) { - SELECTION_HILOGW("context is released."); - task->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "Context is released")); - delete task; - return; - } - ErrCode errcode = (unwrapArgc == 1) ? context->StartAbility(want) : ERR_INVALID_VALUE; - if (errcode == 0) { - task->Resolve(env, CreateJsUndefined(env)); - } else { - task->Reject(env, CreateJsErrorByNativeErr(env, errcode)); - } - delete task; - }; - if (napi_send_event(env, asyncTask, napi_eprio_high) != napi_status::napi_ok) { - napiAsyncTask->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "send event failed")); - } else { - napiAsyncTask.release(); - } - return result; - } }; } // namespace @@ -106,9 +57,6 @@ napi_value CreateJsSelectionExtensionContext(napi_env env, std::shared_ptr jsContext = std::make_unique(context); napi_wrap(env, objValue, jsContext.release(), JsSelectionExtensionContext::Finalizer, nullptr, nullptr); - - const char* moduleName = "JsSelectionExtensionContext"; - BindNativeFunction(env, objValue, "startAbility", moduleName, JsSelectionExtensionContext::StartAbility); return objValue; } } // namespace OHOS::AbilityRuntime diff --git a/frameworks/native/selection_extension/src/selection_extension_context.cpp b/frameworks/native/selection_extension/src/selection_extension_context.cpp index d0163c7..9d8ec12 100644 --- a/frameworks/native/selection_extension/src/selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_context.cpp @@ -19,17 +19,4 @@ namespace OHOS::AbilityRuntime { const size_t SelectionExtensionContext::CONTEXT_TYPE_ID(std::hash {}("SelectionExtensionContext")); -int32_t SelectionExtensionContext::ILLEGAL_REQUEST_CODE(-1); - -ErrCode SelectionExtensionContext::StartAbility(const AAFwk::Want& want) const -{ - SELECTION_HILOGD("%{public}s begin.", __func__); - ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, ILLEGAL_REQUEST_CODE); - SELECTION_HILOGD("%{public}s ret=%{public}d", __func__, err); - if (err != ERR_OK) { - SELECTION_HILOGE("SelectionExtensionContext::StartAbility failed: %{public}d", err); - } - return err; -} - } // namespace OHOS::AbilityRuntime \ No newline at end of file -- Gitee From c135633c5fa30bab83d8728434b03a07231ba6f3 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Wed, 11 Jun 2025 19:54:47 +0800 Subject: [PATCH 69/93] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 1 + .../js/napi/selection_client/js_utils.cpp.bak | 567 ------------------ .../js/napi/selection_client/js_utils.h.bak | 195 ------ service/BUILD.gn | 2 + 4 files changed, 3 insertions(+), 762 deletions(-) delete mode 100644 frameworks/js/napi/selection_client/js_utils.cpp.bak delete mode 100644 frameworks/js/napi/selection_client/js_utils.h.bak diff --git a/bundle.json b/bundle.json index 34bacaa..dc3e71c 100644 --- a/bundle.json +++ b/bundle.json @@ -32,6 +32,7 @@ "ability_base", "ability_runtime", "window_manager", + "pasteboard", "resource_management", "graphic_2d", "bundle_framework", diff --git a/frameworks/js/napi/selection_client/js_utils.cpp.bak b/frameworks/js/napi/selection_client/js_utils.cpp.bak deleted file mode 100644 index bd982df..0000000 --- a/frameworks/js/napi/selection_client/js_utils.cpp.bak +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Copyright (c) 2022-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 "selection_js_utils.h" - -#include "js_util.h" - -namespace OHOS { -namespace MiscServices { -constexpr int32_t STR_MAX_LENGTH = 4096; -constexpr size_t STR_TAIL_LENGTH = 1; -constexpr size_t ARGC_MAX = 6; -constexpr size_t ARGC_ONE = 1; -const std::map JsUtils::ERROR_CODE_MAP = { - { ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER }, - { ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION }, - { ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION, EXCEPTION_SYSTEM_PERMISSION }, - { ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NULL_POINTER, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NOT_FOCUSED, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_CLIENT_NOT_EDITABLE, EXCEPTION_EDITABLE }, - { ErrorCode::ERROR_CLIENT_NOT_BOUND, EXCEPTION_DETACHED }, - { ErrorCode::ERROR_CLIENT_ADD_FAILED, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_NULL_POINTER, EXCEPTION_IMMS }, - { ErrorCode::ERROR_BAD_PARAMETERS, EXCEPTION_IMMS }, - { ErrorCode::ERROR_SERVICE_START_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_KBD_SHOW_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_KBD_HIDE_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IME_NOT_STARTED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_NULL_POINTER, EXCEPTION_IMMS }, - { ErrorCode::ERROR_PERSIST_CONFIG, EXCEPTION_CONFPERSIST }, - { ErrorCode::ERROR_PACKAGE_MANAGER, EXCEPTION_PACKAGEMANAGER }, - { ErrorCode::ERROR_EX_UNSUPPORTED_OPERATION, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_SERVICE_SPECIFIC, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_PARCELABLE, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT, EXCEPTION_IMMS }, - { ErrorCode::ERROR_EX_ILLEGAL_STATE, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IME_START_INPUT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_NOT_IME, EXCEPTION_IME }, - { ErrorCode::ERROR_IME, EXCEPTION_IMENGINE }, - { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_NOT_DEFAULT_IME, EXCEPTION_DEFAULTIME }, - { ErrorCode::ERROR_ENABLE_IME, EXCEPTION_IMMS }, - { ErrorCode::ERROR_NOT_CURRENT_IME, EXCEPTION_IMMS }, - { ErrorCode::ERROR_PANEL_NOT_FOUND, EXCEPTION_PANEL_NOT_FOUND }, - { ErrorCode::ERROR_WINDOW_MANAGER, EXCEPTION_WINDOW_MANAGER }, - { ErrorCode::ERROR_GET_TEXT_CONFIG, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_TEXT_LISTENER_ERROR, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED, EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED }, - { ErrorCode::ERROR_INVALID_RANGE, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_SECURITY_MODE_OFF, EXCEPTION_BASIC_MODE }, - { ErrorCode::ERROR_MSG_HANDLER_NOT_REGIST, EXCEPTION_REQUEST_NOT_ACCEPT }, - { ErrorCode::ERROR_MESSAGE_HANDLER, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_INVALID_ARRAY_BUFFER_SIZE, EXCEPTION_PARAMCHECK }, - { ErrorCode::ERROR_INVALID_PANEL_TYPE, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, - { ErrorCode::ERROR_INVALID_PANEL_FLAG, EXCEPTION_INVALID_PANEL_TYPE_FLAG }, - { ErrorCode::ERROR_IMA_CHANNEL_NULLPTR, EXCEPTION_IMCLIENT }, - { ErrorCode::ERROR_IPC_REMOTE_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMA_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_INPUT_TYPE_NOT_FOUND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_DEFAULT_IME_NOT_FOUND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_CLIENT_INPUT_READY_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_MALLOC_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_EVENT_CONVERT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_START_TIMEOUT, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_IME_START_MORE_THAN_EIGHT_SECOND, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, EXCEPTION_IMMS }, - { ErrorCode::ERROR_IMC_NULLPTR, EXCEPTION_IMMS }, - { ErrorCode::ERROR_DEVICE_UNSUPPORTED, EXCEPTION_UNSUPPORTED }, -}; - -const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { - { EXCEPTION_PERMISSION, "the permissions check fails." }, - { EXCEPTION_SYSTEM_PERMISSION, "not system application." }, - { EXCEPTION_PARAMCHECK, "the parameters check fails." }, - { EXCEPTION_UNSUPPORTED, "capability not supported." }, - { EXCEPTION_PACKAGEMANAGER, "bundle manager error." }, - { EXCEPTION_IMENGINE, "input method engine error. Possible causes: 1.input method panel not created.\ - 2.the input method application does not subscribe to related events." }, - { EXCEPTION_IMCLIENT, "input method client error. Possible causes: 1.the edit box is not focused.\ - 2.no edit box is bound to current input method application." }, - { EXCEPTION_IME, "not an input method application." }, - { EXCEPTION_CONFPERSIST, "configuration persistence error." }, - { EXCEPTION_CONTROLLER, "input method controller error.\ - Possible cause: create InputmethodController object failed." }, - { EXCEPTION_SETTINGS, "input method setter error. Possible cause: create InputmethodSetting object failed." }, - { EXCEPTION_IMMS, "input method manager service error. Possible cause: a system error, such as null pointer,\ - IPC exception." }, - { EXCEPTION_DETACHED, "input method client detached." }, - { EXCEPTION_DEFAULTIME, "not the preconfigured default input method." }, - { EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED, "text preview not supported." }, - { EXCEPTION_PANEL_NOT_FOUND, "the input method panel does not exist." }, - { EXCEPTION_WINDOW_MANAGER, "window manager service error." }, - { EXCEPTION_BASIC_MODE, "the input method is basic mode." }, - { EXCEPTION_REQUEST_NOT_ACCEPT, "the another side does not accept the request." }, - { EXCEPTION_EDITABLE, "the edit mode need enable." }, - { EXCEPTION_INVALID_PANEL_TYPE_FLAG, "invalid panel type or panel flag." }, -}; - -const std::map JsUtils::PARAMETER_TYPE = { - { TYPE_UNDEFINED, "napi_undefine." }, - { TYPE_NULL, "napi_null." }, - { TYPE_BOOLEAN, "napi_boolean." }, - { TYPE_NUMBER, "napi_number." }, - { TYPE_STRING, "napi_string." }, - { TYPE_SYMBOL, "napi_symbol." }, - { TYPE_OBJECT, "napi_object." }, - { TYPE_FUNCTION, "napi_function." }, - { TYPE_EXTERNAL, "napi_external." }, - { TYPE_BIGINT, "napi_bigint." }, - { TYPE_ARRAY_BUFFER, "ArrayBuffer." }, - { TYPE_ARRAY, "napi_array." }, -}; - -void JsUtils::ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type) -{ - std::string errMsg = ToMessage(err); - napi_value error; - napi_value code; - napi_value message; - if (type == TypeCode::TYPE_NONE) { - errMsg = errMsg + " " + msg; - IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); - } else { - auto iter = PARAMETER_TYPE.find(type); - if (iter != PARAMETER_TYPE.end()) { - errMsg = errMsg + "The type of " + msg + " must be " + iter->second; - IMSA_HILOGE("THROW_ERROR message: %{public}s!", errMsg.c_str()); - } - } - NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message)); - NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error)); - NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, err, &code)); - NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", code)); - NAPI_CALL_RETURN_VOID(env, napi_throw(env, error)); -} - -napi_value JsUtils::ToError(napi_env env, int32_t code, const std::string &msg) -{ - IMSA_HILOGD("ToError start"); - napi_value errorObj; - NAPI_CALL(env, napi_create_object(env, &errorObj)); - napi_value errorCode = nullptr; - NAPI_CALL(env, napi_create_int32(env, Convert(code), &errorCode)); - napi_value errorMessage = nullptr; - std::string errMsg = ToMessage(Convert(code)) + " " + msg; - NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errorMessage)); - NAPI_CALL(env, napi_set_named_property(env, errorObj, "code", errorCode)); - NAPI_CALL(env, napi_set_named_property(env, errorObj, "message", errorMessage)); - IMSA_HILOGD("ToError end"); - return errorObj; -} - -int32_t JsUtils::Convert(int32_t code) -{ - IMSA_HILOGD("Convert start."); - auto iter = ERROR_CODE_MAP.find(code); - if (iter != ERROR_CODE_MAP.end()) { - IMSA_HILOGD("ErrorCode: %{public}d", iter->second); - return iter->second; - } - IMSA_HILOGD("Convert end."); - return ERROR_CODE_QUERY_FAILED; -} - -const std::string JsUtils::ToMessage(int32_t code) -{ - IMSA_HILOGD("ToMessage start"); - auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code); - if (iter != ERROR_CODE_CONVERT_MESSAGE_MAP.end()) { - IMSA_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str()); - return iter->second; - } - return "error is out of definition."; -} - -bool JsUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId) -{ - if (copy == nullptr) { - return value == nullptr; - } - - if (threadId != std::this_thread::get_id()) { - IMSA_HILOGD("napi_value can not be compared"); - return false; - } - - napi_value copyValue = nullptr; - napi_get_reference_value(env, copy, ©Value); - - bool isEquals = false; - napi_strict_equals(env, value, copyValue, &isEquals); - IMSA_HILOGD("value compare result: %{public}d", isEquals); - return isEquals; -} - -void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info) -{ - size_t argc = ARGC_MAX; - void *native = nullptr; - napi_value self = nullptr; - napi_value argv[ARGC_MAX] = { nullptr }; - napi_status status = napi_invalid_arg; - napi_get_cb_info(env, info, &argc, argv, &self, nullptr); - CHECK_RETURN((self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!", nullptr); - - status = napi_unwrap(env, self, &native); - CHECK_RETURN((status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr); - return native; -} - -napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &out) -{ - napi_valuetype type = napi_undefined; - napi_status status = napi_typeof(env, in, &type); - CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); - return napi_get_value_int32(env, in, &out); -} - -/* napi_value <-> uint32_t */ -napi_status JsUtils::GetValue(napi_env env, napi_value in, uint32_t &out) -{ - napi_valuetype type = napi_undefined; - napi_status status = napi_typeof(env, in, &type); - CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid type", napi_generic_failure); - return napi_get_value_uint32(env, in, &out); -} - -napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out) -{ - napi_valuetype type = napi_undefined; - napi_status status = napi_typeof(env, in, &type); - CHECK_RETURN((status == napi_ok) && (type == napi_boolean), "invalid type", napi_generic_failure); - return napi_get_value_bool(env, in, &out); -} - -napi_status JsUtils::GetValue(napi_env env, napi_value in, double &out) -{ - napi_valuetype type = napi_undefined; - napi_status status = napi_typeof(env, in, &type); - CHECK_RETURN((status == napi_ok) && (type == napi_number), "invalid double type", napi_generic_failure); - return napi_get_value_double(env, in, &out); -} - -/* napi_value <-> std::string */ -napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out) -{ - IMSA_HILOGD("JsUtils get string value in."); - napi_valuetype type = napi_undefined; - napi_status status = napi_typeof(env, in, &type); - CHECK_RETURN((status == napi_ok) && (type == napi_string), "invalid type", napi_generic_failure); - - size_t maxLen = STR_MAX_LENGTH; - status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen); - if (maxLen <= 0) { - return status; - } - IMSA_HILOGD("napi_value -> std::string get length %{public}zu", maxLen); - char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH]; - if (buf != nullptr) { - size_t len = 0; - status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len); - if (status == napi_ok) { - buf[len] = 0; - out = std::string(buf); - } - delete[] buf; - } else { - status = napi_generic_failure; - } - return status; -} - -/* napi_value <-> std::unordered_map */ -napi_status JsUtils::GetValue(napi_env env, napi_value in, std::unordered_map &out) -{ - napi_valuetype type = napi_undefined; - napi_status status = napi_typeof(env, in, &type); - PARAM_CHECK_RETURN(env, type != napi_undefined, "param is undefined.", TYPE_NONE, napi_generic_failure); - - napi_value keys = nullptr; - napi_get_property_names(env, in, &keys); - uint32_t arrLen = 0; - status = napi_get_array_length(env, keys, &arrLen); - if (status != napi_ok) { - IMSA_HILOGE("napi_get_array_length error"); - return status; - } - // 5 means max private command count. - PARAM_CHECK_RETURN(env, arrLen <= 5 && arrLen > 0, "privateCommand must more than 0 and less than 5.", TYPE_NONE, - napi_generic_failure); - IMSA_HILOGD("length : %{public}u", arrLen); - for (size_t iter = 0; iter < arrLen; ++iter) { - napi_value key = nullptr; - status = napi_get_element(env, keys, iter, &key); - CHECK_RETURN(status == napi_ok, "napi_get_element error", status); - - napi_value value = nullptr; - status = napi_get_property(env, in, key, &value); - CHECK_RETURN(status == napi_ok, "napi_get_property error", status); - - std::string keyStr; - status = GetValue(env, key, keyStr); - CHECK_RETURN(status == napi_ok, "GetValue keyStr error", status); - - PrivateDataValue privateCommand; - status = GetValue(env, value, privateCommand); - CHECK_RETURN(status == napi_ok, "GetValue privateCommand error", status); - out.emplace(keyStr, privateCommand); - } - return status; -} - -napi_status JsUtils::GetValue(napi_env env, napi_value in, PrivateDataValue &out) -{ - napi_valuetype valueType = napi_undefined; - napi_status status = napi_typeof(env, in, &valueType); - CHECK_RETURN(status == napi_ok, "napi_typeof error", napi_generic_failure); - if (valueType == napi_string) { - std::string privateDataStr; - status = GetValue(env, in, privateDataStr); - CHECK_RETURN(status == napi_ok, "GetValue napi_string error", napi_generic_failure); - out.emplace(privateDataStr); - } else if (valueType == napi_boolean) { - bool privateDataBool = false; - status = GetValue(env, in, privateDataBool); - CHECK_RETURN(status == napi_ok, "GetValue napi_boolean error", napi_generic_failure); - out.emplace(privateDataBool); - } else if (valueType == napi_number) { - int32_t privateDataInt = 0; - status = GetValue(env, in, privateDataInt); - CHECK_RETURN(status == napi_ok, "GetValue napi_number error", napi_generic_failure); - out.emplace(privateDataInt); - } else { - PARAM_CHECK_RETURN(env, false, "value type must be string | boolean | number", TYPE_NONE, napi_generic_failure); - } - return status; -} - -napi_status JsUtils::GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out) -{ - napi_valuetype valueType = napi_undefined; - napi_status status = napi_typeof(env, in, &valueType); - if ((status == napi_ok) && (valueType == napi_object)) { - status = napi_get_named_property(env, in, type.c_str(), &out); - return status; - } - return napi_generic_failure; -} - -/* napi_value <-> PanelInfo */ -napi_status JsUtils::GetValue(napi_env env, napi_value in, PanelInfo &out) -{ - IMSA_HILOGD("napi_value -> PanelInfo "); - napi_value propType = nullptr; - napi_status status = napi_get_named_property(env, in, "type", &propType); - CHECK_RETURN((status == napi_ok), "no property type ", status); - int32_t panelType = 0; - status = GetValue(env, propType, panelType); - CHECK_RETURN((status == napi_ok), "no value of type ", status); - - // PanelFlag is optional, defaults to FLG_FIXED when empty. - int32_t panelFlag = static_cast(PanelFlag::FLG_FIXED); - napi_value panelFlagObj = nullptr; - status = napi_get_named_property(env, in, "flag", &panelFlagObj); - if (status == napi_ok) { - JsUtils::GetValue(env, panelFlagObj, panelFlag); - } - - out.panelType = PanelType(panelType); - out.panelFlag = PanelFlag(panelFlag); - return napi_ok; -} - -napi_value JsUtils::GetValue(napi_env env, const std::vector &in) -{ - napi_value array = nullptr; - uint32_t index = 0; - napi_create_array(env, &array); - if (array == nullptr) { - IMSA_HILOGE("create array failed"); - return array; - } - for (const auto &info : in) { - napi_value jsInfo = GetValue(env, info); - napi_set_element(env, array, index, jsInfo); - ++index; - } - return array; -} - -napi_value JsUtils::GetValue(napi_env env, const InputWindowInfo &in) -{ - napi_value info = nullptr; - napi_create_object(env, &info); - - napi_value name = nullptr; - napi_create_string_utf8(env, in.name.c_str(), in.name.size(), &name); - napi_set_named_property(env, info, "name", name); - - napi_value left = nullptr; - napi_create_int32(env, in.left, &left); - napi_set_named_property(env, info, "left", left); - - napi_value top = nullptr; - napi_create_int32(env, in.top, &top); - napi_set_named_property(env, info, "top", top); - - napi_value width = nullptr; - napi_create_uint32(env, in.width, &width); - napi_set_named_property(env, info, "width", width); - - napi_value height = nullptr; - napi_create_uint32(env, in.height, &height); - napi_set_named_property(env, info, "height", height); - - return info; -} - -napi_status JsUtils::GetValue(napi_env env, const std::string &in, napi_value &out) -{ - return napi_create_string_utf8(env, in.c_str(), in.size(), &out); -} - -napi_value JsUtils::GetJsPrivateCommand(napi_env env, const std::unordered_map &in) -{ - napi_value jsPrivateCommand = nullptr; - NAPI_CALL(env, napi_create_object(env, &jsPrivateCommand)); - for (const auto &iter : in) { - size_t idx = iter.second.index(); - napi_value value = nullptr; - if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_STRING)) { - auto stringValue = std::get_if(&iter.second); - if (stringValue != nullptr) { - NAPI_CALL(env, napi_create_string_utf8(env, (*stringValue).c_str(), (*stringValue).size(), &value)); - } - } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_BOOL)) { - auto boolValue = std::get_if(&iter.second); - if (boolValue != nullptr) { - NAPI_CALL(env, napi_get_boolean(env, *boolValue, &value)); - } - } else if (idx == static_cast(PrivateDataValueType::VALUE_TYPE_NUMBER)) { - auto numberValue = std::get_if(&iter.second); - if (numberValue != nullptr) { - NAPI_CALL(env, napi_create_int32(env, *numberValue, &value)); - } - } - NAPI_CALL(env, napi_set_named_property(env, jsPrivateCommand, iter.first.c_str(), value)); - } - return jsPrivateCommand; -} - -napi_value JsUtils::GetValue(napi_env env, const std::vector &in) -{ - void *data = nullptr; - napi_value arrayBuffer = nullptr; - size_t length = in.size(); - NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer)); - // 0 means the size of data. - CHECK_RETURN(length != 0, "Data size is 0.", arrayBuffer); - if (memcpy_s(data, length, reinterpret_cast(in.data()), length) != 0) { - return nullptr; - } - return arrayBuffer; -} - -napi_status JsUtils::GetValue(napi_env env, napi_value in, std::vector &out) -{ - size_t length = 0; - void *data = nullptr; - auto status = napi_get_arraybuffer_info(env, in, &data, &length); - if (status != napi_ok) { - IMSA_HILOGE("Get ArrayBuffer info failed!"); - return status; - } - if (data == nullptr && length == 0) { - IMSA_HILOGE("Empty ArrayBuffer."); - out.clear(); - return napi_ok; - } - if (data == nullptr) { - IMSA_HILOGE("ArrayBuffer data is nullptr!"); - return napi_generic_failure; - } - IMSA_HILOGD("ArrayBuffer data size: %{public}zu.", length); - out.assign(reinterpret_cast(data), reinterpret_cast(data) + length); - return napi_ok; -} - -napi_status JsUtils::GetMessageHandlerCallbackParam(napi_value *argv, - const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, size_t size) -{ - if (argv == nullptr) { - IMSA_HILOGE("argv is nullptr!."); - return napi_generic_failure; - } - if (size < ARGC_ONE) { - IMSA_HILOGE("argv size is less than 1!."); - return napi_generic_failure; - } - if (jsMessageHandler == nullptr) { - IMSA_HILOGE("jsMessageHandler is nullptr!."); - return napi_generic_failure; - } - napi_value jsMsgId = nullptr; - auto status = napi_create_string_utf8( - jsMessageHandler->env_, arrayBuffer.msgId.c_str(), NAPI_AUTO_LENGTH, &jsMsgId); - if (status != napi_ok) { - IMSA_HILOGE("napi_create_string_utf8 failed!."); - return napi_generic_failure; - } - // 0 means the first param index of callback. - argv[0] = { jsMsgId }; - if (arrayBuffer.jsArgc > ARGC_ONE) { - napi_value jsMsgParam = JsUtils::GetValue(jsMessageHandler->env_, arrayBuffer.msgParam); - if (jsMsgParam == nullptr) { - IMSA_HILOGE("Get js messageParam object failed!."); - return napi_generic_failure; - } - // 0 means the second param index of callback. - argv[1] = { jsMsgParam }; - } - return napi_ok; -} - -napi_status JsUtils::GetValue(napi_env env, napi_value in, Rosen::Rect &out) -{ - bool ret = JsUtil::Object::ReadProperty(env, in, "left", out.posX_); - ret = ret && JsUtil::Object::ReadProperty(env, in, "top", out.posY_); - ret = ret && JsUtil::Object::ReadProperty(env, in, "width", out.width_); - ret = ret && JsUtil::Object::ReadProperty(env, in, "height", out.height_); - return ret ? napi_ok : napi_generic_failure; -} - -napi_value JsUtils::GetValue(napi_env env, const Rosen::Rect &in) -{ - napi_value jsObject = nullptr; - napi_create_object(env, &jsObject); - bool ret = JsUtil::Object::WriteProperty(env, jsObject, "left", in.posX_); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "top", in.posY_); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "width", in.width_); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "height", in.height_); - return ret ? jsObject : JsUtil::Const::Null(env); -} -} // namespace MiscServices -} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/selection_client/js_utils.h.bak b/frameworks/js/napi/selection_client/js_utils.h.bak deleted file mode 100644 index 0ae0a1a..0000000 --- a/frameworks/js/napi/selection_client/js_utils.h.bak +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2022-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 INTERFACE_KITS_JS_UTILS_H -#define INTERFACE_KITS_JS_UTILS_H - -#include - -#include "ability.h" -#include "selection_log.h" -#include "selection_panel.h" -// #include "selection_utils.h" -#include "js_callback_object.h" -#include "js_util.h" -#include "napi/native_api.h" -#include "napi/native_common.h" -#include "napi/native_node_api.h" -#include "string_ex.h" - -using Ability = OHOS::AppExecFwk::Ability; -namespace OHOS { -namespace MiscServices { -enum IMFErrorCode : int32_t { - EXCEPTION_PERMISSION = 201, - EXCEPTION_SYSTEM_PERMISSION = 202, - EXCEPTION_PARAMCHECK = 401, - EXCEPTION_UNSUPPORTED = 801, - EXCEPTION_PACKAGEMANAGER = 12800001, - EXCEPTION_IMENGINE = 12800002, - EXCEPTION_IMCLIENT = 12800003, - EXCEPTION_IME = 12800004, - EXCEPTION_CONFPERSIST = 12800005, - EXCEPTION_CONTROLLER = 12800006, - EXCEPTION_SETTINGS = 12800007, - EXCEPTION_IMMS = 12800008, - EXCEPTION_DETACHED = 12800009, - EXCEPTION_DEFAULTIME = 12800010, - EXCEPTION_TEXT_PREVIEW_NOT_SUPPORTED = 12800011, - EXCEPTION_PANEL_NOT_FOUND = 12800012, - EXCEPTION_WINDOW_MANAGER = 12800013, - EXCEPTION_BASIC_MODE = 12800014, - EXCEPTION_REQUEST_NOT_ACCEPT = 12800015, - EXCEPTION_EDITABLE = 12800016, - EXCEPTION_INVALID_PANEL_TYPE_FLAG = 12800017, -}; - -enum TypeCode : int32_t { - TYPE_NONE = 0, - TYPE_UNDEFINED, - TYPE_NULL, - TYPE_BOOLEAN, - TYPE_NUMBER, - TYPE_STRING, - TYPE_SYMBOL, - TYPE_OBJECT, - TYPE_FUNCTION, - TYPE_EXTERNAL, - TYPE_BIGINT, - TYPE_ARRAY_BUFFER, - TYPE_ARRAY, -}; - -/* check condition, return and logging if condition not true. */ -#define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \ - do { \ - if (!(condition)) { \ - JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ - return retVal; \ - } \ - } while (0) - -#define PARAM_CHECK_RETURN_VOID(env, condition, message, typeCode) \ - do { \ - if (!(condition)) { \ - JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \ - return; \ - } \ - } while (0) - -#define RESULT_CHECK_RETURN(env, condition, errCode, message, typeCode, retVal) \ - do { \ - if (!(condition)) { \ - JsUtils::ThrowException(env, errCode, message, typeCode); \ - return retVal; \ - } \ - } while (0) - -#define RESULT_CHECK_RETURN_VOID(env, condition, errCode, message, typeCode) \ - do { \ - if (!(condition)) { \ - JsUtils::ThrowException(env, errCode, message, typeCode); \ - return; \ - } \ - } while (0) - -/* check condition, return and logging. */ -#define CHECK_RETURN_VOID(condition, message) \ - do { \ - if (!(condition)) { \ - IMSA_HILOGE("test (" #condition ") failed: " message); \ - return; \ - } \ - } while (0) - -/* check condition, return and logging. */ -#define CHECK_RETURN(condition, message, retVal) \ - do { \ - if (!(condition)) { \ - IMSA_HILOGE("test (" #condition ") failed: " message); \ - return retVal; \ - } \ - } while (0) - -struct JsPropertyInfo { - napi_valuetype type; - TypeCode typeCode; - std::string propertyName; -}; - -class JsUtils { -public: - static void ThrowException(napi_env env, int32_t err, const std::string &msg, TypeCode type); - - static napi_value ToError(napi_env env, int32_t code, const std::string &msg); - - static int32_t Convert(int32_t code); - - static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId); - - static void *GetNativeSelf(napi_env env, napi_callback_info info); - - static const std::string ToMessage(int32_t code); - - template - static bool ReadOptionalProperty(napi_env env, napi_value object, const JsPropertyInfo &jsPropInfo, T &value) - { - if (!JsUtil::HasProperty(env, object, jsPropInfo.propertyName.c_str())) { - return false; - } - napi_value jsObject = nullptr; - napi_get_named_property(env, object, jsPropInfo.propertyName.c_str(), &jsObject); - PARAM_CHECK_RETURN(env, JsUtil::GetType(env, jsObject) == jsPropInfo.type, jsPropInfo.propertyName, - jsPropInfo.typeCode, false); - PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, jsObject, value) == napi_ok, - "failed to convert " + jsPropInfo.propertyName, TYPE_NONE, false); - return true; - } - - static napi_status GetValue(napi_env env, napi_value in, int32_t &out); - static napi_status GetValue(napi_env env, napi_value in, uint32_t &out); - static napi_status GetValue(napi_env env, napi_value in, bool &out); - static napi_status GetValue(napi_env env, napi_value in, double &out); - static napi_status GetValue(napi_env env, napi_value in, std::string &out); - static napi_status GetValue(napi_env env, napi_value in, std::unordered_map &out); - static napi_status GetValue(napi_env env, napi_value in, PrivateDataValue &out); - static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); - static napi_status GetValue(napi_env env, napi_value in, PanelInfo &out); - static napi_status GetValue(napi_env env, napi_value in, std::vector &out); - static napi_status GetValue(napi_env env, napi_value in, Rosen::Rect &out); - static napi_value GetValue(napi_env env, const std::vector &in); - static napi_value GetValue(napi_env env, const InputWindowInfo &in); - static napi_value GetValue(napi_env env, const Rosen::Rect &in); - static napi_value GetJsPrivateCommand(napi_env env, const std::unordered_map &in); - static napi_value GetValue(napi_env env, const std::vector &in); - static napi_status GetValue(napi_env env, const std::string &in, napi_value &out); - static napi_status GetMessageHandlerCallbackParam(napi_value *argv, - const std::shared_ptr &jsMessageHandler, const ArrayBuffer &arrayBuffer, - size_t size); - -private: - static const std::map ERROR_CODE_MAP; - - static const std::map ERROR_CODE_CONVERT_MESSAGE_MAP; - - static const std::map PARAMETER_TYPE; - - static constexpr int32_t ERROR_CODE_QUERY_FAILED = 1; - - static constexpr uint8_t MAX_ARGMENT_COUNT = 10; -}; -} // namespace MiscServices -} // namespace OHOS -#endif // INTERFACE_KITS_JS_UTILS_H \ No newline at end of file diff --git a/service/BUILD.gn b/service/BUILD.gn index c101601..2d7aeb0 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -103,6 +103,7 @@ ohos_shared_library("selection_service") { "ipc:ipc_single", "init:libbeget_proxy", "input:libmmi-client", + "pasteboard:pasteboard_client", "safwk:system_ability_fwk", "samgr:samgr_proxy", "screenlock_mgr:screenlock_client", @@ -111,6 +112,7 @@ ohos_shared_library("selection_service") { "window_manager:libwsutils", ] + defines = [] if (window_manager_use_sceneboard) { external_deps += [ "window_manager:libwm_lite" ] defines += [ "SCENE_BOARD_ENABLE" ] -- Gitee From 97ef53c6c0114501f7be113611246d139d2d1eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Wed, 11 Jun 2025 20:59:20 +0800 Subject: [PATCH 70/93] =?UTF-8?q?codecheck=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/callback_object.cpp | 6 +- common/selection_js_utils.h | 1 - .../js/napi/selection_ability/js_panel.cpp | 5 +- .../js_selection_engine_setting.cpp | 11 ++- .../js/napi/selection_client/async_call.cpp | 6 +- .../include/selection_ability.h | 1 - .../src/selection_ability.cpp | 18 ----- .../selection_ability/src/selection_panel.cpp | 3 +- .../selection_ability/src/task_manager.cpp | 4 - service/src/selection_input_monitor.cpp | 75 +------------------ utils/include/selection_log.h | 12 +-- 11 files changed, 24 insertions(+), 118 deletions(-) diff --git a/common/callback_object.cpp b/common/callback_object.cpp index 3d8c4b5..2d1f340 100644 --- a/common/callback_object.cpp +++ b/common/callback_object.cpp @@ -60,9 +60,9 @@ bool JSCallbackObject::operator==(const JSCallbackObject& other) const return false; } - napi_value thisValue, otherValue; - napi_status status; - status = napi_get_reference_value(env_, this->callback_, &thisValue); + napi_value thisValue; + napi_value otherValue; + napi_status status = napi_get_reference_value(env_, this->callback_, &thisValue); if (status != napi_ok) { return false; } diff --git a/common/selection_js_utils.h b/common/selection_js_utils.h index 469007c..675f9f5 100644 --- a/common/selection_js_utils.h +++ b/common/selection_js_utils.h @@ -150,7 +150,6 @@ public: static napi_status GetValue(napi_env env, napi_value in, const std::string &type, napi_value &out); - // static napi_status GetValue(napi_env env, napi_value in, PanelInfo &out); static napi_status GetValue(napi_env env, napi_value in, std::vector &out); diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index c73ef97..e2af368 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -282,8 +282,9 @@ void JsPanel::PrintEditorQueueInfoIfTimeout(int64_t start, const JsEventInfo &cu auto ret = jsQueue_.GetFront(frontInfo); int64_t frontTime = duration_cast(frontInfo.timestamp.time_since_epoch()).count(); int64_t currentTime = duration_cast(currentInfo.timestamp.time_since_epoch()).count(); - SELECTION_HILOGI("ret:%{public}d,front[%{public}" PRId64 ",%{public}d],current[%{public}" PRId64 ",%{public}d]", ret, - frontTime, static_cast(frontInfo.event), currentTime, static_cast(currentInfo.event)); + SELECTION_HILOGI("ret:%{public}d,front[%{public}" PRId64 ",%{public}d],current[%{public}" PRId64 + ",%{public}d]", ret, frontTime, static_cast(frontInfo.event), currentTime, + static_cast(currentInfo.event)); } } diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index c558efe..6e1b547 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -150,10 +150,9 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf PARAM_CHECK_RETURN(env, valueType == napi_object, "param info type must be PanelInfo.", TYPE_NONE, napi_invalid_arg); status = OHOS::SelectionFwk::JsSelectionUtils::GetValue(env, argv[1], ctxt->panelInfo); - SELECTION_HILOGD( - "output js param panelInfo covert , panelType/x/y/width/height: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", - static_cast(ctxt->panelInfo.panelType), ctxt->panelInfo.x, ctxt->panelInfo.y, ctxt->panelInfo.width, - ctxt->panelInfo.height); + SELECTION_HILOGD("output js param panelInfo covert , panelType/x/y/width/height: \ + %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", static_cast(ctxt->panelInfo.panelType), + ctxt->panelInfo.x, ctxt->panelInfo.y, ctxt->panelInfo.width, ctxt->panelInfo.height); PARAM_CHECK_RETURN(env, status == napi_ok, "js param info covert failed!", TYPE_NONE, napi_invalid_arg); return status; }; @@ -348,7 +347,6 @@ void JsSelectionEngineSetting::RegisterListerToService(std::shared_ptr #include -#include +#include #include "selection_log.h" #include "selection_js_utils.h" #include "napi/native_node_api.h" @@ -188,8 +188,8 @@ void AsyncCall::OnComplete(napi_env env, napi_status status, void *data) napi_get_undefined(env, &result[ARG_DATA]); } } else { - SELECTION_HILOGE("failed, [status:%{public}d, runStatus:%{public}d, errorCode:%{public}d, errMessage:%{public}s].", - status, runStatus, context->ctx->errorCode_, context->ctx->errMessage_.c_str()); + SELECTION_HILOGE("failed, [status:%{public}d, runStatus:%{public}d, errorCode:%{public}d, \ + errMessage:%{public}s].", status, runStatus, context->ctx->errorCode_, context->ctx->errMessage_.c_str()); result[ARG_ERROR] = JsUtils::ToError(env, context->ctx->errorCode_, context->ctx->errMessage_); napi_get_undefined(env, &result[ARG_DATA]); } diff --git a/frameworks/native/selection_ability/include/selection_ability.h b/frameworks/native/selection_ability/include/selection_ability.h index 77b0035..7b85c9c 100644 --- a/frameworks/native/selection_ability/include/selection_ability.h +++ b/frameworks/native/selection_ability/include/selection_ability.h @@ -43,7 +43,6 @@ private: static sptr instance_; std::mutex dataChannelLock_; - void Initialize(); ConcurrentMap> panels_ {}; std::atomic_bool isShowAfterCreate_ { false }; diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index be259d1..449196d 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -44,29 +44,11 @@ sptr SelectionAbility::GetInstance() SELECTION_HILOGE("instance is nullptr!"); return instance_; } - instance_->Initialize(); } } return instance_; } -void SelectionAbility::Initialize() -{ - SELECTION_HILOGD("SelectionAbility init."); - // sptr coreStub = new (std::nothrow) SelectionCoreServiceImpl();//核心功能,处理文本操作 - // if (coreStub == nullptr) { - // SELECTION_HILOGE("failed to create core!"); - // return; - // } - // sptr agentStub = new (std::nothrow) SelectionAgentServiceImpl();//服务代理,将核心功能暴露给外部,处理通信和事件分发, - // if (agentStub == nullptr) { - // SELECTION_HILOGE("failed to create agent!"); - // return; - // } - // agentStub_ = agentStub; - // coreStub_ = coreStub; -} - int32_t SelectionAbility::CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo, std::shared_ptr &selectionPanel) { diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index 7217b97..c757e49 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -336,7 +336,8 @@ int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) return ret == WMError::WM_ERROR_INVALID_PARAM ? ErrorCode::ERROR_PARAMETER_CHECK_FAILED : ErrorCode::NO_ERROR; } -bool SelectionPanel::SetPanelStatusListener(std::shared_ptr statusListener, const std::string &type) +bool SelectionPanel::SetPanelStatusListener(std::shared_ptr statusListener, + const std::string &type) { if (!MarkListener(type, true)) { return false; diff --git a/frameworks/native/selection_ability/src/task_manager.cpp b/frameworks/native/selection_ability/src/task_manager.cpp index 42f04c2..871ba99 100644 --- a/frameworks/native/selection_ability/src/task_manager.cpp +++ b/frameworks/native/selection_ability/src/task_manager.cpp @@ -16,13 +16,9 @@ #include "task_manager.h" #include - #include "actions/action.h" #include "actions/action_wait.h" - -// #include "global.h" #include "selection_log.h" - #include "tasks/task.h" #include "tasks/task_inner.h" diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index 30bc04c..39726a2 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -96,21 +96,12 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr point SELECTION_HILOGD("It is not screen on."); return; } - // SELECTION_HILOGD("pointerEvent->windowId: %{public}d, displayId: %{public}d", - // pointerEvent->GetTargetWindowId(), pointerEvent->GetTargetDisplayId()); int32_t pointerId = pointerEvent->GetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); if (pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { ResetState(); } - // SELECTION_HILOGI("pointerItem, display: %{public}d, %{public}d, \ - // RawDxy: %{public}d, %{public}d. \ - // windows: %{public}d, %{public}d, windowId: %{public}d, deviceId: %{public}d", - // pointerItem.GetDisplayX(),pointerItem.GetDisplayY(), - // pointerItem.GetRawDx(),pointerItem.GetRawDy(), - // pointerItem.GetWindowX(), pointerItem.GetWindowY(), - // pointerItem.GetTargetWindowId(), pointerItem.GetDeviceId()); SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); switch (curSelectState) @@ -455,69 +446,6 @@ void SelectionInputMonitor::InjectCtrlC() const SimulateKeyWithCtrl(KeyEvent::KEYCODE_C, KeyEvent::KEY_ACTION_DOWN); SimulateKeyWithCtrl(KeyEvent::KEYCODE_C, KeyEvent::KEY_ACTION_UP); std::this_thread::sleep_for(std::chrono::milliseconds(10)); - // // 创建KeyEvent对象 - // auto keyEvent1 = KeyEvent::Create(); - - // // 设置Ctrl键按下 - // int deviceId = 100; - // int downTime = 104329296; - // keyEvent1->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // keyEvent1->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // keyEvent1->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - // keyEvent1->SetDeviceId(deviceId); - // KeyEvent::KeyItem item1; - // item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // item1.SetPressed(true); - // item1.SetDeviceId(deviceId); - // item1.SetDownTime(downTime); - // keyEvent1->AddKeyItem(item1); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent1); - - // // 设置C键按下 - // auto keyEvent2 = KeyEvent::Create(); - // keyEvent2->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // keyEvent2->SetKeyCode(KeyEvent::KEYCODE_C); - // keyEvent2->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); - // keyEvent2->SetDeviceId(deviceId); - // KeyEvent::KeyItem item2; - // item2.SetKeyCode(KeyEvent::KEYCODE_C); - // item2.SetPressed(true); - // item2.SetDeviceId(deviceId); - // item2.SetUnicode(99); - // item2.SetDownTime(downTime); - // keyEvent2->AddKeyItem(item1); - // keyEvent2->AddKeyItem(item2); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent2); - - // // 设置C键释放 - // auto keyEvent3 = KeyEvent::Create(); - // keyEvent3->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // keyEvent3->SetKeyCode(KeyEvent::KEYCODE_C); - // keyEvent3->SetKeyAction(KeyEvent::KEY_ACTION_UP); - // keyEvent3->SetDeviceId(deviceId); - // KeyEvent::KeyItem item3; - // item3.SetKeyCode(KeyEvent::KEYCODE_C); - // item3.SetPressed(false); - // item3.SetDeviceId(deviceId); - // item3.SetUnicode(99); - // item3.SetDownTime(downTime); - // keyEvent3->AddKeyItem(item1); - // keyEvent3->AddKeyItem(item3); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent3); - - // // 设置Ctrl键释放 - // auto keyEvent4 = KeyEvent::Create(); - // keyEvent4->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); - // keyEvent4->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // keyEvent4->SetKeyAction(KeyEvent::KEY_ACTION_UP); - // keyEvent4->SetDeviceId(deviceId); - // KeyEvent::KeyItem item4; - // item4.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - // item4.SetPressed(false); - // item4.SetDeviceId(deviceId); - // item4.SetDownTime(downTime); - // keyEvent4->AddKeyItem(item4); - // InputManager::GetInstance()->SimulateInputEvent(keyEvent4); } void SelectionInputMonitor::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) const @@ -525,7 +453,8 @@ void SelectionInputMonitor::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyActi auto KeyEvent = KeyEvent::Create(); KeyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); KeyEvent->SetKeyAction(keyAction); - KeyEvent::KeyItem item1, item2; + KeyEvent::KeyItem item1; + KeyEvent::KeyItem item2; item1.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); item2.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); diff --git a/utils/include/selection_log.h b/utils/include/selection_log.h index eb56468..8b52cc7 100644 --- a/utils/include/selection_log.h +++ b/utils/include/selection_log.h @@ -31,23 +31,23 @@ extern "C" { #define SELETION_DEBUG_ENABLE 0 #endif -#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) +#define __BASE_FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) #define SELECTION_HILOGF(fmt, ...) \ ((void)HILOG_IMPL(LOG_CORE, LOG_FATAL, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) + __BASE_FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) #define SELECTION_HILOGE(fmt, ...) \ ((void)HILOG_IMPL(LOG_CORE, LOG_ERROR, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) + __BASE_FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) #define SELECTION_HILOGW(fmt, ...) \ ((void)HILOG_IMPL(LOG_CORE, LOG_WARN, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) + __BASE_FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) #define SELECTION_HILOGI(fmt, ...) \ ((void)HILOG_IMPL(LOG_CORE, LOG_INFO, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) + __BASE_FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) #define SELECTION_HILOGD(fmt, ...) \ ((void)HILOG_IMPL(LOG_CORE, LOG_DEBUG, LOG_DOMAIN, LOG_TAG, "[%{public}s(%{public}s:%{public}d)]" fmt, \ - __FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) + __BASE_FILENAME__, __FUNCTION__, __LINE__, ##__VA_ARGS__)) namespace ErrorCode { // Error Code definition in the input method management system -- Gitee From de835351cc606f3c262b72c5e33f624912614570 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Thu, 12 Jun 2025 09:49:50 +0800 Subject: [PATCH 71/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=9B=91=E5=90=AC?= =?UTF-8?q?=E5=88=B0=E5=A4=B1=E7=84=A6=E7=AA=97=E5=8F=A3=E7=9A=84destory?= =?UTF-8?q?=E5=92=8Chide=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- .../selection_ability/src/selection_listener_impl.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index 2318a61..c604d31 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -52,12 +52,17 @@ ErrCode SelectionListenerImpl::FocusChange(uint32_t windowID, uint32_t windowTyp if (!panelManager.FindWindowID(windowID)) { return 0; } - if (windowType == PanelType::MENU_PANEL) { + auto selectionPanel = panelManager.GetSelectionPanel(windowID); + if (selectionPanel == nullptr) { + SELECTION_HILOGE("get selectionPanel is nullptr, windowID: %{public}d", windowID); + return 1; + } + if (selectionPanel->GetPanelType() == PanelType::MENU_PANEL) { SELECTION_HILOGI("hide windowID: %{public}d", windowID); panelManager.GetSelectionPanel(windowID)->HidePanel(); } - if (windowType == PanelType::MAIN_PANEL) { + if (selectionPanel->GetPanelType() == PanelType::MAIN_PANEL) { SELECTION_HILOGI("destroy windowID: %{public}d", windowID); panelManager.GetSelectionPanel(windowID)->DestroyPanel(); panelManager.RemoveSelectionPanel(windowID); -- Gitee From 8c15fa8a76d505db5514c35180530e19c0e4314f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Thu, 12 Jun 2025 10:26:24 +0800 Subject: [PATCH 72/93] =?UTF-8?q?readme=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- README.md | 110 ++++++++++++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index d6e1a9e..c28be8d 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,38 @@ -## 划词服务代码环境搭建 +# selectionfwk -### 代码结构 +#### 介绍 +划词服务,通过剪贴板获取划词内存,提供划词配置同步接口,划词服务SA监听多模键鼠事件获取鼠标和触控板操作窗口和应用信息,DFX增强。 -``` -│ ├── base -│ │ ├── startup -│ │ │ └── init => 代码提交仓: https://gitee.com/sinall/startup_init.git, selection_fwk分支 -│ │ └── security -│ │ └── selinux_adapter => 代码提交仓: https://gitee.com/sinall/security_selinux_adapter.git, selection_fwk分支 -│ ├── foundation -│ │ ├──systemabilitymgr -│ │ │ ├── samgr => 代码提交仓: https://gitee.com/sinall/systemabilitymgr_samgr.git, selection_fwk分支 -│ │ │ └── selectionfwk => 代码提交仓: https://gitee.com/sinall/selectionfwk.git, master分支 -│ │ ├──bundlemanager -│ │ │ └── bundle_framework =>代码提交仓: https://gitee.com/sinall/bundlemanager_bundle_framework.git selection_fwk分支 -│ │ └──ability -│ │ └── ability_runtime => 代码提交仓: https://gitee.com/sinall/ability_ability_runtime.git, selection_fwk分支 -│ ├── productdefine -│ │ └── common => 代码提交仓: https://gitee.com/sinall/productdefine_common.git, selection_fwk分支 -``` - -### 更新代码命令 - -- 初次环境搭建,在代码仓库对应目录下执行以下命令 - -``` -1. selection_fwk仓库: -cd foundation/systemabilitymgr -git clone https://gitee.com/sinall/selectionfwk.git -2. 其余仓库 -$ cd foundation/systemabilitymgr/samgr(修改为对应仓库路径) -$ git remote add sinall https://gitee.com/sinall/systemabilitymgr_samgr.git(修改为对应仓库的网址) -$ git fetch sinall selectionfwk -$ git checkout -b selectionfwk sinall/selectionfwk -``` +#### 仓路径 +/foundation/systemabilitymgr/selectionfwk -- 后续更新代码 +## 目录 ``` -cd foundation/systemabilitymgr(修改为对应的仓库路径) -git pull --reb sinall master(修改为对应的分支名) +/foundation/systemabilitymgr +├── selectionfwk +│ ├── common # 公共代码 +│ ├── etc # 组件包含的进程的配置文件 +│ ├── frameworks # 接口实现 +│ │ └── js/napi # 划词框架napi接口 +│ │ └── native # native接口 +│ ├── sa_profile # sa定义 +│ ├── services # 划词框架服务 +│ ├── test # 接口测试目录 +│ │ └── unitest # 接口的单元测试 +│ ├── utils # 核心服务工具代码目录 ``` -### 编译命令 +### 编译步骤 - 全量编译 -``` 修改build.gn文件后编译命令 +``` $ ./build.sh --product-name rk3568 --ccache +``` 未修改build.gn文件编译命令 +``` $ ./build.sh --product-name rk3568 --ccache --fast-rebuild ``` @@ -59,32 +42,45 @@ $ ./build.sh --product-name rk3568 --ccache --fast-rebuild $ ./build.sh --product-name rk3568 --ccache --build-target selectionfwk ``` -### 测试命令 +### 测试步骤 -1. 测试启动服务 +1. 测试方法 +查看服务进程 ``` -# ps -ef | grep selection_service -未启动服务 -# param set sys.selection.switch.username on -# ps -e未启动服务f | grep selection_service -服务已启动 +# ps -ef | grep selection ``` - -2. 测试关闭服务 (系统参数关闭会延时,等待约20-30s) - +启动划词服务 +``` +# param set sys.selection.switch on +``` +关闭划词服务 +``` +# param set sys.selection.switch off +``` +切换划词应用 +``` +# param set sys.selection.app com.selection.selectionapplication/SelectionExtensionAbility ``` -# ps -ef | grep selection_service -服务已启动 -# param set sys.selection.switch.username off -# ps -ef | grep selection_service -服务已退出 +设置划词触发方式 +``` +# param set sys.selection.trigger "" ``` -3. 获取日志命令 +2. 获取日志命令 +打开debug日志 ``` -# dmesg | grep selection_service # hilog -b D -# hilog | grep 8500 ``` +过滤日志 +``` +# hilog -T SELECTION_SERVICE +``` + +## 参与贡献 + +1. Fork 本仓库 +2. 提交代码 +3. 新建 Pull Request +4. commit完成即可 \ No newline at end of file -- Gitee From bbe1f6341ded7c41273c194658444848969c4ffe Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Thu, 12 Jun 2025 14:14:53 +0800 Subject: [PATCH 73/93] =?UTF-8?q?=E5=AE=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- common/concurrent_map.h | 6 +++--- frameworks/js/napi/selection_ability/js_panel.h | 6 +++--- frameworks/js/napi/selection_ability/panel_listener_impl.h | 6 +++--- frameworks/js/napi/selection_client/async_call.cpp | 2 +- .../selection_ability/include/panel_status_listener.h | 6 +++--- frameworks/native/selection_ability/src/task_manager.cpp | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/common/concurrent_map.h b/common/concurrent_map.h index 85266bb..986b01a 100644 --- a/common/concurrent_map.h +++ b/common/concurrent_map.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef OHOS_SELECTION_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H -#define OHOS_SELECTION_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#ifndef OHOS_SELECTION_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#define OHOS_SELECTION_FRAMEWORKS_COMMON_CONCURRENT_MAP_H #include #include #include @@ -299,4 +299,4 @@ private: std::map<_Key, _Tp> entries_; }; } // namespace OHOS -#endif // OHOS_SELECTION_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H +#endif // OHOS_SELECTION_FRAMEWORKS_COMMON_CONCURRENT_MAP_H diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index 562e963..24bf326 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef SELECTION_IMF_JSPANEL_H -#define SELECTION_IMF_JSPANEL_H +#ifndef SELECTION_JSPANEL_H +#define SELECTION_JSPANEL_H #include "napi/native_api.h" #include "selection_panel.h" @@ -119,4 +119,4 @@ private: } // namespace SelectionFwk } // namespace OHOS -#endif //SELECTION_IMF_JSPANEL_H +#endif //SELECTION_JSPANEL_H diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.h b/frameworks/js/napi/selection_ability/panel_listener_impl.h index 623bd90..1656404 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.h +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef SELECTION_IMF_PANEL_LISTENER_IMPL_H -#define SELECTION_IMF_PANEL_LISTENER_IMPL_H +#ifndef SELECTION_PANEL_LISTENER_IMPL_H +#define SELECTION_PANEL_LISTENER_IMPL_H #include #include @@ -80,4 +80,4 @@ struct UvEntry { } // namespace SelectionFwk } // namespace OHOS -#endif //SELECTION_IMF_PANEL_LISTENER_IMPL_H +#endif //SELECTION_PANEL_LISTENER_IMPL_H diff --git a/frameworks/js/napi/selection_client/async_call.cpp b/frameworks/js/napi/selection_client/async_call.cpp index 3bdd104..6b11951 100644 --- a/frameworks/js/napi/selection_client/async_call.cpp +++ b/frameworks/js/napi/selection_client/async_call.cpp @@ -81,7 +81,7 @@ napi_value AsyncCall::Call(napi_env env, Context::ExecAction exec, const std::st } napi_async_work work = context_->work; napi_value resource = nullptr; - std::string name = "IMF_" + resourceName; + std::string name = "SF_" + resourceName; napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &resource); napi_create_async_work(env, nullptr, resource, AsyncCall::OnExecute, AsyncCall::OnComplete, context_, &work); context_->work = work; diff --git a/frameworks/native/selection_ability/include/panel_status_listener.h b/frameworks/native/selection_ability/include/panel_status_listener.h index 3a20cc3..8080d4f 100644 --- a/frameworks/native/selection_ability/include/panel_status_listener.h +++ b/frameworks/native/selection_ability/include/panel_status_listener.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef SELECTION_IMF_PANEL_STATUS_LISTENER_H -#define SELECTION_IMF_PANEL_STATUS_LISTENER_H +#ifndef SELECTION_PANEL_STATUS_LISTENER_H +#define SELECTION_PANEL_STATUS_LISTENER_H #include #include "panel_common.h" @@ -29,4 +29,4 @@ public: } // namespace SelectionFwk } // namespace OHOS -#endif // SELECTION_IMF_PANEL_STATUS_LISTENER_H +#endif // SELECTION_PANEL_STATUS_LISTENER_H diff --git a/frameworks/native/selection_ability/src/task_manager.cpp b/frameworks/native/selection_ability/src/task_manager.cpp index 871ba99..1707710 100644 --- a/frameworks/native/selection_ability/src/task_manager.cpp +++ b/frameworks/native/selection_ability/src/task_manager.cpp @@ -25,7 +25,7 @@ namespace OHOS { namespace SelectionFwk { -static const std::string THREAD_NAME = "OS_imf_task_manager"; +static const std::string THREAD_NAME = "OS_sf_task_manager"; TaskManager::TaskManager() { -- Gitee From 5aedeb2ac06f2d0c0f121619b78f81aa2df38fe4 Mon Sep 17 00:00:00 2001 From: xying6 Date: Thu, 5 Jun 2025 10:05:06 +0800 Subject: [PATCH 74/93] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=AE=A1=E7=90=86=E5=A4=9A=E7=94=A8=E6=88=B7=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 2 + etc/init/selection_service.cfg | 17 +- service/BUILD.gn | 12 +- .../include/db_selection_config_repository.h | 72 ++++++ service/include/selection_config.h | 64 +++++ service/include/selection_config_comparator.h | 49 ++++ service/include/selection_config_database.h | 86 ++++++ service/include/selection_service.h | 8 +- .../include/sys_selection_config_repository.h | 44 ++++ .../src/db_selection_config_repository.cpp | 229 ++++++++++++++++ service/src/selection_config.cpp | 114 ++++++++ service/src/selection_config_comparator.cpp | 83 ++++++ service/src/selection_config_database.cpp | 244 ++++++++++++++++++ service/src/selection_service.cpp | 141 +++++++--- .../src/sys_selection_config_repository.cpp | 131 ++++++++++ test/unittest/BUILD.gn | 4 +- .../selection_config_comparator_test.cpp | 190 ++++++++++++++ utils/include/selection_errors.h | 40 +++ 18 files changed, 1491 insertions(+), 39 deletions(-) create mode 100644 service/include/db_selection_config_repository.h create mode 100644 service/include/selection_config.h create mode 100644 service/include/selection_config_comparator.h create mode 100644 service/include/selection_config_database.h create mode 100644 service/include/sys_selection_config_repository.h create mode 100644 service/src/db_selection_config_repository.cpp create mode 100644 service/src/selection_config.cpp create mode 100644 service/src/selection_config_comparator.cpp create mode 100644 service/src/selection_config_database.cpp create mode 100644 service/src/sys_selection_config_repository.cpp create mode 100644 test/unittest/selection_config_comparator_test.cpp create mode 100644 utils/include/selection_errors.h diff --git a/bundle.json b/bundle.json index dc3e71c..43bef53 100644 --- a/bundle.json +++ b/bundle.json @@ -33,11 +33,13 @@ "ability_runtime", "window_manager", "pasteboard", + "relational_store", "resource_management", "graphic_2d", "bundle_framework", "ffrt", "config_policy", + "os_account", "screenlock_mgr" ], "third_party": [ diff --git a/etc/init/selection_service.cfg b/etc/init/selection_service.cfg index 9c1b471..4ed738d 100644 --- a/etc/init/selection_service.cfg +++ b/etc/init/selection_service.cfg @@ -16,11 +16,20 @@ "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT", "ohos.permission.SYSTEM_FLOAT_WINDOW" ], - "permission_acls" : [ - "ohos.permission.INPUT_MONITORING" - ], + "jobs" : { + "on-start" : "services:selection_service" + }, + "permission_acls" : ["ohos.permission.INPUT_MONITORING"], "caps" : [], "secon" : "u:r:selection_service:s0" } - ] + ], + "jobs" : [{ + "name" : "services:selection_service", + "cmds" : [ + "mkdir /data/service/el1/public/selection_service 0770 sysselection sysselection", + "chown sysselection sysselection /data/service/el1/public/selection_service", + "chmod 0770 /data/service/el1/public/selection_service" + ] + }] } diff --git a/service/BUILD.gn b/service/BUILD.gn index 2d7aeb0..9136972 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -73,6 +73,7 @@ ohos_shared_library("selection_service") { "-fdata-sections", "-ffunction-sections", "-Oz", + "-std=c++17", ] configs = [ ":selection_sa_config", ] output_values = get_target_outputs(":selection_service_interface") @@ -82,10 +83,15 @@ ohos_shared_library("selection_service") { ] sources = [ + "src/db_selection_config_repository.cpp", "src/selection_service.cpp", "src/selection_input_monitor.cpp", - "./focus_monitor/src/focus_change_listener.cpp", - "./focus_monitor/src/focus_monitor_manager.cpp", + "focus_monitor/src/focus_change_listener.cpp", + "focus_monitor/src/focus_monitor_manager.cpp", + "src/selection_config.cpp", + "src/selection_config_database.cpp", + "src/sys_selection_config_repository.cpp", + "src/selection_config_comparator.cpp", ] sources += filter_include(output_values, [ "*.cpp" ]) deps = [ @@ -110,6 +116,8 @@ ohos_shared_library("selection_service") { "input:libmmi-client", "window_manager:libdm_lite", "window_manager:libwsutils", + "os_account:os_account_innerkits", + "relational_store:native_rdb", ] defines = [] diff --git a/service/include/db_selection_config_repository.h b/service/include/db_selection_config_repository.h new file mode 100644 index 0000000..d4c9e02 --- /dev/null +++ b/service/include/db_selection_config_repository.h @@ -0,0 +1,72 @@ +/* + * 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 DB_SELECTION_CONFIG_REPOSITORY_H +#define DB_SELECTION_CONFIG_REPOSITORY_H + +#include +#include +#include + +#include "data_ability_predicates.h" +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_open_callback.h" +#include "rdb_predicates.h" +#include "rdb_store.h" +#include "result_set.h" +#include "selection_config.h" +#include "selection_config_database.h" +#include "value_object.h" + +namespace OHOS { +namespace SelectionFwk { + +class DbSelectionConfigRepository { +public: + static std::shared_ptr GetInstance(); + int Save(int uid, const SelectionConfig &info); + std::optional GetOneByUserId(int uid); + +private: + struct SelectionConfigTableInfo { + int32_t rowCount; + int32_t columnCount; + int32_t primaryKeyIndex; + int32_t uidIndex; + int32_t enableIndex; + int32_t bundleNameIndex; + int32_t triggerIndex; + int32_t shortcutKeysIndex; + }; + +private: + DbSelectionConfigRepository(); + DISALLOW_COPY_AND_MOVE(DbSelectionConfigRepository); + int GetConfigFromDatabase(const OHOS::NativeRdb::RdbPredicates &rdbPredicates, + const std::vector &columns, SelectionConfig &info); + int ProcessQueryResult(const std::shared_ptr &resultSet, + SelectionConfig &info); + int RetrieveResultSetMetadata(const std::shared_ptr &resultSet, + struct SelectionConfigTableInfo &table); + + static std::shared_ptr instance_; + std::mutex databaseMutex_; + std::shared_ptr selectionDatabase_; +}; +} // namespace SelectionFwk +} // namespace OHOS + +#endif // DB_SELECTION_CONFIG_REPOSITORY_H \ No newline at end of file diff --git a/service/include/selection_config.h b/service/include/selection_config.h new file mode 100644 index 0000000..cccd3b9 --- /dev/null +++ b/service/include/selection_config.h @@ -0,0 +1,64 @@ +/* + * 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 SELECTION_CONFIG_H +#define SELECTION_CONFIG_H + +#include +#include "selection_config.h" + +namespace OHOS { +namespace SelectionFwk { +class SelectionConfig { +public: + int IsEnabled() const; + int IsTriggered() const; + int GetUid() const; + std::string GetBundleName() const; + void SetEnabled(int enabled); + void SetTriggered(int isTriggered); + void SetBundleName(const std::string &bundleName); + void SetUid(int uid); + + std::string ToString() const; + +private: + int isEnabled_ = 1; + int isTriggered_ = 1; + int uid_ = 0; + std::string bundleName_ = "com.hm.youdao/ExtensionAbility"; +}; + + +class MemSelectionConfig { +public: + static MemSelectionConfig &GetInstance(); + SelectionConfig &GetSelectionConfig(); + void SetSelectionConfig(const SelectionConfig &config); + int IsEnabled() const; + int IsTriggered() const; + std::string GetBundleName() const; + void SetEnabled(int enabled); + void SetTriggered(int isTriggered); + void SetBundleName(const std::string &bundleName); + +private: + MemSelectionConfig() = default; + ~MemSelectionConfig() = default; + SelectionConfig delegate_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // SELECTION_CONFIG_H \ No newline at end of file diff --git a/service/include/selection_config_comparator.h b/service/include/selection_config_comparator.h new file mode 100644 index 0000000..02f9079 --- /dev/null +++ b/service/include/selection_config_comparator.h @@ -0,0 +1,49 @@ +/* + * 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 SELECTION_CONFIG_COMPARATOR_CPP +#define SELECTION_CONFIG_COMPARATOR_CPP + +#include +#include "selection_config.h" + +namespace OHOS { +namespace SelectionFwk { +enum SyncDirection { + FromDbToSys, + FromSysToDb +}; + +struct ComparisionResult { + SyncDirection direction = FromDbToSys; + bool shouldStop = false; + bool shouldCreate = false; + SelectionConfig selectionConfig; + + std::string ToString() const; +}; + +class SelectionConfigComparator { +public: + static ComparisionResult Compare(int uid, const SelectionConfig &sysSelectionConfig, + std::optional &dbSelectionConfig); + +private: + static ComparisionResult DoCompare(int uid, const SelectionConfig &sysSelectionConfig, + std::optional &dbSelectionConfig); +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // SELECTION_CONFIG_COMPARATOR_CPP \ No newline at end of file diff --git a/service/include/selection_config_database.h b/service/include/selection_config_database.h new file mode 100644 index 0000000..96f8654 --- /dev/null +++ b/service/include/selection_config_database.h @@ -0,0 +1,86 @@ +/* + * 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 SELECTION_CONFIG_DATABASE_H +#define SELECTION_CONFIG_DATABASE_H + +#include + +#include "data_ability_predicates.h" +#include "rdb_errno.h" +#include "rdb_helper.h" +#include "rdb_open_callback.h" +#include "rdb_predicates.h" +#include "rdb_store.h" +#include "result_set.h" +#include "value_object.h" + +namespace OHOS { +namespace SelectionFwk { + +static std::string SELECTION_CONFIG_DB_PATH = "/data/service/el1/public/selection_service/"; + +constexpr const char *SELECTION_CONFIG_DB_NAME = "selection_config.db"; +constexpr const char *SELECTION_CONFIG_TABLE_NAME = "selection_config"; +constexpr int32_t DATABASE_OPEN_VERSION = 2; + +constexpr const char *CREATE_SELECTION_CONFIG_TABLE = "CREATE TABLE IF NOT EXISTS [selection_config](" + "[id] INTEGER PRIMARY KEY AUTOINCREMENT, " + "[enable] INTEGER, " + "[bundleName] TEXT, " + "[trigger] INTEGER, " + "[shortcutKeys] TEXT, " + "[uid] TEXT NOT NULL UNIQUE);"; +constexpr const char *SQL_ADD_TOKEN_ID = "ALTER TABLE selection_config ADD COLUMN tokenId TEXT DEFAULT ''"; + +class SelectionConfigDataBase { +public: + static std::shared_ptr GetInstance(); + int64_t Insert(const OHOS::NativeRdb::ValuesBucket &insertValues); + int32_t Update(int32_t &changedRows, const OHOS::NativeRdb::ValuesBucket &values, + const OHOS::NativeRdb::RdbPredicates &predicates); + int32_t Update(int32_t &changedRows, const OHOS::NativeRdb::ValuesBucket &values, const std::string &whereClause, + const std::vector &whereArgs); + int32_t Delete(const OHOS::NativeRdb::RdbPredicates &rdbPredicates); + int32_t Delete(int32_t &changedRows, const std::string &whereClause, const std::vector &whereArgs); + int32_t ExecuteSql(const std::string &sql, + const std::vector &bindArgs = std::vector()); + std::shared_ptr QuerySql( + const std::string &sql, const std::vector &selectionArgs); + std::shared_ptr Query( + const OHOS::NativeRdb::AbsRdbPredicates &predicates, const std::vector &columns); + int32_t BeginTransaction(); + int32_t Commit(); + int32_t RollBack(); + +private: + SelectionConfigDataBase(); + DISALLOW_COPY_AND_MOVE(SelectionConfigDataBase); + + static std::shared_ptr instance_; + std::shared_ptr store_; +}; + +class SelectionConfigDataBaseCallBack : public OHOS::NativeRdb::RdbOpenCallback { +public: + int32_t OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) override; + int32_t OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int32_t oldVersion, int32_t newVersion) override; + int32_t OnDowngrade(OHOS::NativeRdb::RdbStore &rdbStore, int32_t currentVersion, int32_t targetVersion) override; +}; + +} // namespace SelectionFwk +} // namespace OHOS + +#endif // SELECTION_CONFIG_DATABASE_H diff --git a/service/include/selection_service.h b/service/include/selection_service.h index d8b0ce5..bf9f71d 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -64,6 +64,9 @@ public: int32_t ConnectNewExtAbility(const std::string& bundleName, const std::string& abilityName); void DisconnectCurrentExtAbility(); sptr GetListener(); + int GetUserId(); + bool IsExistUid(); + protected: void OnStart() override; void OnStop() override; @@ -75,7 +78,8 @@ private: void WatchParams(); void InitFocusChangedMonitor(); void HandleFocusChanged(bool isOnFocused, uint32_t windowId, uint32_t windowType); - + void SynchronizeSelectionConfig(); + void GetAccountLocalId(); int32_t inputMonitorId_ {-1}; static sptr instance_; @@ -83,6 +87,8 @@ private: mutable std::mutex mutex_; static sptr listenerStub_; sptr connectInner_ {nullptr}; + int userId_ = -1; + bool isExistUid_ = false; }; } diff --git a/service/include/sys_selection_config_repository.h b/service/include/sys_selection_config_repository.h new file mode 100644 index 0000000..e09a49a --- /dev/null +++ b/service/include/sys_selection_config_repository.h @@ -0,0 +1,44 @@ +/* + * 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 SYS_SELECTION_CONFIG_REPOSITORY_H +#define SYS_SELECTION_CONFIG_REPOSITORY_H +#include +#include +#include "selection_config.h" + +namespace OHOS { +namespace SelectionFwk { +class SysSelectionConfigRepository { +public: + static std::shared_ptr GetInstance(); + int SetSysParameters(const SelectionConfig &config); + SelectionConfig GetSysParameters(); + void DisableSAService(); + +private: + void SetEnabled(int enabled); + void SetTriggered(int isTriggered); + void SetUid(int uid); + void SetBundleName(const std::string &bundleName); + int IsEnabled(); + int IsTriggered(); + int GetUid(); + std::string GetBundleName(); + static std::shared_ptr instance_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // SYS_SELECTION_CONFIG_REPOSITORY_H \ No newline at end of file diff --git a/service/src/db_selection_config_repository.cpp b/service/src/db_selection_config_repository.cpp new file mode 100644 index 0000000..e60665e --- /dev/null +++ b/service/src/db_selection_config_repository.cpp @@ -0,0 +1,229 @@ +/* + * 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 "db_selection_config_repository.h" + +#include + +#include "selection_errors.h" +#include "selection_config_database.h" +#include "selection_log.h" + +using namespace OHOS::NativeRdb; + +namespace OHOS { +namespace SelectionFwk { +std::shared_ptr DbSelectionConfigRepository::instance_ = nullptr; + +DbSelectionConfigRepository::DbSelectionConfigRepository() +{ + selectionDatabase_ = SelectionConfigDataBase::GetInstance(); +} + +std::shared_ptr DbSelectionConfigRepository::GetInstance() +{ + static std::mutex instanceMutex; + std::lock_guard guard(instanceMutex); + if (instance_ == nullptr) { + SELECTION_HILOGI("reset to new DbSelectionConfigRepository instance"); + instance_.reset(new DbSelectionConfigRepository()); + } + return instance_; +} + +int DbSelectionConfigRepository::Save(int uid, const SelectionConfig &info) +{ + if (selectionDatabase_ == nullptr) { + SELECTION_HILOGE("selectionDatabase_ is null"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + std::lock_guard guard(databaseMutex_); + ValuesBucket values; + values.Clear(); + values.PutInt("uid", uid); + values.PutInt("enable", info.IsEnabled()); + values.PutInt("trigger", info.IsTriggered()); + values.PutString("bundleName", info.GetBundleName()); + int ret = selectionDatabase_->BeginTransaction(); + if (ret < SELECTION_CONFIG_OK) { + SELECTION_HILOGE("BeginTransaction error: %{public}d", ret); + return ret; + } + + int changedRows = 0; + RdbPredicates predicates(SELECTION_CONFIG_TABLE_NAME); + predicates.EqualTo("uid", std::to_string(uid)); + + ret = selectionDatabase_->Update(changedRows, values, predicates); + if (ret != SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Update error: %{public}d", ret); + return ret; + } + + if (changedRows == 0) { + ret = selectionDatabase_->Insert(values); + if (ret < SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Insert error: %{public}d", ret); + (void)selectionDatabase_->RollBack(); + return ret; + } + } + ret = selectionDatabase_->Commit(); + if (ret < SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Commit error: %{public}d", ret); + (void)selectionDatabase_->RollBack(); + return ret; + } + SELECTION_HILOGI("add success: uid=%{public}d enable=%{public}d trigger=%{public}d bundleName=%{public}s", + uid, info.IsEnabled(), info.IsTriggered(), info.GetBundleName().c_str()); + return ret; +} + +std::optional DbSelectionConfigRepository::GetOneByUserId(int uid) +{ + SelectionConfig info; + std::lock_guard guard(databaseMutex_); + std::vector columns; + RdbPredicates rdbPredicates(SELECTION_CONFIG_TABLE_NAME); + rdbPredicates.EqualTo("uid", std::to_string(uid)); + if (GetConfigFromDatabase(rdbPredicates, columns, info) != SELECTION_CONFIG_OK) { + return std::nullopt; + } + SELECTION_HILOGI("uid=%{public}d enable=%{public}d trigger=%{public}d bundleName=%{public}s", + uid, info.IsEnabled(), info.IsTriggered(), info.GetBundleName().c_str()); + return info; +} + +int DbSelectionConfigRepository::GetConfigFromDatabase(const RdbPredicates &rdbPredicates, + const std::vector &columns, SelectionConfig &info) +{ + if (selectionDatabase_ == nullptr) { + SELECTION_HILOGE("rightDatabase_ is null"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int ret = selectionDatabase_->BeginTransaction(); + if (ret < SELECTION_CONFIG_OK) { + SELECTION_HILOGE("BeginTransaction error: %{public}d", ret); + return ret; + } + auto resultSet = selectionDatabase_->Query(rdbPredicates, columns); + if (resultSet == nullptr) { + SELECTION_HILOGE("Query error"); + (void)selectionDatabase_->RollBack(); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + ret = selectionDatabase_->Commit(); + if (ret < SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Commit error: %{public}d", ret); + (void)selectionDatabase_->RollBack(); + return ret; + } + int32_t rowCount = 0; + resultSet->GetRowCount(rowCount); + if (rowCount == 0) { + SELECTION_HILOGI("Can not found uid in selection_config table"); + return SELECTION_CONFIG_NOT_FOUND; + } + return ProcessQueryResult(resultSet, info); +} + +int DbSelectionConfigRepository::ProcessQueryResult(const std::shared_ptr &resultSet, + SelectionConfig &info) +{ + struct SelectionConfigTableInfo table; + int ret = RetrieveResultSetMetadata(resultSet, table); + if (ret < SELECTION_CONFIG_OK) { + SELECTION_HILOGE("GetResultSetTableInfo failed"); + return ret; + } + + bool endFlag = false; + int enable = 0; + std::string bundleName = ""; + int trigger = 0; + int uid = -1; + + for (int32_t i = 0; i < table.rowCount && !endFlag; i++, resultSet->IsEnded(endFlag)) { + if (resultSet->GoToRow(i) != E_OK) { + SELECTION_HILOGE("GoToRow %{public}d", i); + return -1; + } + if (resultSet->GetInt(table.enableIndex, enable) == E_OK && + resultSet->GetString(table.bundleNameIndex, bundleName) == E_OK && + resultSet->GetInt(table.triggerIndex, trigger) == E_OK && + resultSet->GetInt(table.uidIndex, uid) == E_OK) { + info.SetEnabled(enable); + info.SetTriggered(trigger); + info.SetBundleName(bundleName); + info.SetUid(uid); + } + SELECTION_HILOGI("enable=%{public}d trigger=%{public}d bundleName=%{public}s uid=%{public}d", + enable, trigger, bundleName.c_str(), uid); + } + + int position = 0; + resultSet->GetRowIndex(position); + resultSet->IsEnded(endFlag); + SELECTION_HILOGI("row=%{public}d col=%{public}d pos=%{public}d end=%{public}s", + table.rowCount, table.columnCount, position, (endFlag ? "yes" : "no")); + return 0; +} + +int DbSelectionConfigRepository::RetrieveResultSetMetadata( + const std::shared_ptr &resultSet, struct SelectionConfigTableInfo &table) +{ + if (resultSet == nullptr) { + SELECTION_HILOGE("resultSet is null"); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + int32_t rowCount = 0; + int32_t columnCount = 0; + std::vector columnNames; + if (resultSet->GetRowCount(rowCount) != E_OK || resultSet->GetColumnCount(columnCount) != E_OK || + resultSet->GetAllColumnNames(columnNames) != E_OK) { + SELECTION_HILOGE("get table info failed"); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + int32_t columnNamesCount = static_cast(columnNames.size()); + for (int32_t i = 0; i < columnNamesCount; i++) { + std::string &columnName = columnNames.at(i); + if (columnName == "id") { + table.primaryKeyIndex = i; + } + if (columnName == "uid") { + table.uidIndex = i; + } + if (columnName == "enable") { + table.enableIndex = i; + } + if (columnName == "bundleName") { + table.bundleNameIndex = i; + } + if (columnName == "trigger") { + table.triggerIndex = i; + } + if (columnName == "shortcutKeys") { + table.shortcutKeysIndex = i; + } + } + table.rowCount = rowCount; + table.columnCount = columnCount; + SELECTION_HILOGI("info[%{public}d/%{public}d]: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d/%{public}d", + rowCount, columnCount, table.primaryKeyIndex, table.uidIndex, table.enableIndex, table.bundleNameIndex, + table.triggerIndex, table.shortcutKeysIndex); + return SELECTION_CONFIG_OK; +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/service/src/selection_config.cpp b/service/src/selection_config.cpp new file mode 100644 index 0000000..6322202 --- /dev/null +++ b/service/src/selection_config.cpp @@ -0,0 +1,114 @@ +/* + * 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 "selection_config.h" + +#include + +namespace OHOS { +namespace SelectionFwk { +int SelectionConfig::IsEnabled() const +{ + return isEnabled_; +} + +int SelectionConfig::IsTriggered() const +{ + return isTriggered_; +} + +int SelectionConfig::GetUid() const +{ + return uid_; +} + +std::string SelectionConfig::GetBundleName() const +{ + return bundleName_; +} + +void SelectionConfig::SetEnabled(int enabled) +{ + isEnabled_ = enabled; +} + +void SelectionConfig::SetTriggered(int isTriggered) +{ + isTriggered_ = isTriggered; +} + +void SelectionConfig::SetUid(int uid) +{ + uid_ = uid; +} + +void SelectionConfig::SetBundleName(const std::string &bundleName) +{ + bundleName_ = bundleName; +} + +std::string SelectionConfig::ToString() const { + std::string str = "uid: " + std::to_string(uid_) + ", enable: " + std::to_string(isEnabled_) + ", trigger: " + + std::to_string(isTriggered_) + ", bundleName: " + bundleName_; + return str; +} + +MemSelectionConfig& MemSelectionConfig::GetInstance() +{ + static MemSelectionConfig instance; + return instance; +} + +void MemSelectionConfig::SetSelectionConfig(const SelectionConfig &config) +{ + delegate_ = config; +} + +SelectionConfig& MemSelectionConfig::GetSelectionConfig() +{ + return delegate_; +} + +int MemSelectionConfig::IsEnabled() const +{ + return delegate_.IsEnabled(); +} + +int MemSelectionConfig::IsTriggered() const +{ + return delegate_.IsTriggered(); +} + +std::string MemSelectionConfig::GetBundleName() const +{ + return delegate_.GetBundleName(); +} + +void MemSelectionConfig::SetEnabled(int enabled) +{ + delegate_.SetEnabled(enabled); +} + +void MemSelectionConfig::SetTriggered(int isTriggered) +{ + delegate_.SetTriggered(isTriggered); +} + +void MemSelectionConfig::SetBundleName(const std::string &bundleName) +{ + delegate_.SetBundleName(bundleName); +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/service/src/selection_config_comparator.cpp b/service/src/selection_config_comparator.cpp new file mode 100644 index 0000000..cc4eeff --- /dev/null +++ b/service/src/selection_config_comparator.cpp @@ -0,0 +1,83 @@ +/* + * 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 "selection_config_comparator.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { + +std::string ComparisionResult::ToString() const { + std::string result = ""; + result = "ComparisionResult: shouldCreate: " + std::to_string(shouldCreate) + " shouldStop: " + + std::to_string(shouldStop) + " direction: " + std::to_string(static_cast(direction)) + + " selectionConfig: [ " + selectionConfig.ToString() + "]"; + return result; +} + +ComparisionResult SelectionConfigComparator::Compare(int uid, const SelectionConfig &sysSelectionConfig, + std::optional &dbSelectionConfig) +{ + SELECTION_HILOGI("sysSelectionConfig: %{public}s", sysSelectionConfig.ToString().c_str()); + if (dbSelectionConfig.has_value()) { + SELECTION_HILOGI("dbSelectionConfig: %{public}s", dbSelectionConfig->ToString().c_str()); + } else { + SELECTION_HILOGE("dbSelectionConfig is nullopt!"); + } + auto result = DoCompare(uid, sysSelectionConfig, dbSelectionConfig); + SELECTION_HILOGI("result: %{public}s", result.ToString().c_str()); + return result; +} +ComparisionResult SelectionConfigComparator::DoCompare(int uid, const SelectionConfig &sysSelectionConfig, + std::optional &dbSelectionConfig) +{ + ComparisionResult result; + if (!dbSelectionConfig.has_value()) { + result.shouldCreate = true; + result.selectionConfig = sysSelectionConfig; + result.selectionConfig.SetUid(uid); + return result; + } + + if (dbSelectionConfig.value().IsEnabled()) { + if (sysSelectionConfig.GetUid() != uid) { + result.direction = FromDbToSys; + result.selectionConfig = dbSelectionConfig.value(); + return result; + } + result.direction = FromSysToDb; + result.selectionConfig = sysSelectionConfig; + if (!sysSelectionConfig.IsEnabled()) { + result.shouldStop = true; + } + return result; + } + + if (sysSelectionConfig.GetUid() != uid) { + result.selectionConfig = dbSelectionConfig.value(); + result.shouldStop = true; + return result; + } + + result.direction = FromSysToDb; + result.selectionConfig = sysSelectionConfig; + if (!sysSelectionConfig.IsEnabled()) { + result.shouldStop = true; + } + + return result; +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/service/src/selection_config_database.cpp b/service/src/selection_config_database.cpp new file mode 100644 index 0000000..2d01695 --- /dev/null +++ b/service/src/selection_config_database.cpp @@ -0,0 +1,244 @@ +/* + * 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 "selection_config_database.h" + +#include "selection_errors.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { + +std::shared_ptr SelectionConfigDataBase::instance_ = nullptr; + +SelectionConfigDataBase::SelectionConfigDataBase() +{ + std::string selectiontDatabaseName = SELECTION_CONFIG_DB_PATH + SELECTION_CONFIG_DB_NAME; + int32_t errCode = OHOS::NativeRdb::E_OK; + OHOS::NativeRdb::RdbStoreConfig config(selectiontDatabaseName); + config.SetSecurityLevel(NativeRdb::SecurityLevel::S1); + SelectionConfigDataBaseCallBack sqliteOpenHelperCallback; + store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION, sqliteOpenHelperCallback, errCode); + if (errCode != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("GetRdbStore errCode :%{public}d", errCode); + + } else { + SELECTION_HILOGE("GetRdbStore success :%{public}d", errCode); + } +} + +std::shared_ptr SelectionConfigDataBase::GetInstance() +{ + static std::mutex instanceMutex; + std::lock_guard guard(instanceMutex); + if (instance_ == nullptr) { + SELECTION_HILOGI("reset to new SelectionConfigDataBase instance"); + instance_.reset(new SelectionConfigDataBase()); + return instance_; + } + return instance_; +} + +int32_t SelectionConfigDataBase::BeginTransaction() +{ + if (store_ == nullptr) { + SELECTION_HILOGE("BeginTransaction store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t ret = store_->BeginTransaction(); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("BeginTransaction fail :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBase::Commit() +{ + if (store_ == nullptr) { + SELECTION_HILOGE("Commit store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t ret = store_->Commit(); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("Commit fail :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBase::RollBack() +{ + if (store_ == nullptr) { + SELECTION_HILOGE("RollBack store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t ret = store_->RollBack(); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("RollBack fail :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +int64_t SelectionConfigDataBase::Insert(const OHOS::NativeRdb::ValuesBucket &insertValues) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("Insert store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int64_t outRowId = 0; + int32_t ret = store_->Insert(outRowId, SELECTION_CONFIG_TABLE_NAME, insertValues); + SELECTION_HILOGI("Insert id=%{public}" PRIu64 "", outRowId); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("Insert ret :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return outRowId; +} + +int32_t SelectionConfigDataBase::Update( + int32_t &changedRows, const OHOS::NativeRdb::ValuesBucket &values, const OHOS::NativeRdb::RdbPredicates &predicates) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("Update(RdbPredicates) store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t ret = store_->Update(changedRows, values, predicates); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("Update(RdbPredicates) ret :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBase::Update(int32_t &changedRows, const OHOS::NativeRdb::ValuesBucket &values, + const std::string &whereClause, const std::vector &whereArgs) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("Update(whereClause) store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t ret = store_->Update(changedRows, SELECTION_CONFIG_TABLE_NAME, values, whereClause, whereArgs); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("Update(whereClause) ret :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBase::Delete(const OHOS::NativeRdb::RdbPredicates &predicates) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("Delete(RdbPredicates) store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t deleteRow = 0; + int32_t ret = store_->Delete(deleteRow, predicates); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("Delete(RdbPredicates) ret :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBase::Delete( + int32_t &changedRows, const std::string &whereClause, const std::vector &whereArgs) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("Delete store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t ret = store_->Delete(changedRows, SELECTION_CONFIG_TABLE_NAME, whereClause, whereArgs); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("Delete(whereClause) ret :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBase::ExecuteSql(const std::string &sql, const std::vector &bindArgs) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("ExecuteSql store_ is nullptr"); + return SELECTION_CONFIG_RDB_NO_INIT; + } + int32_t ret = store_->ExecuteSql(sql, bindArgs); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("ExecuteSql ret :%{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + return SELECTION_CONFIG_OK; +} + +std::shared_ptr SelectionConfigDataBase::QuerySql( + const std::string &sql, const std::vector &selectionArgs) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("QuerySql(sql) store_ is nullptr"); + return nullptr; + } + return store_->QuerySql(sql); +} + +std::shared_ptr SelectionConfigDataBase::Query( + const OHOS::NativeRdb::AbsRdbPredicates &predicates, const std::vector &columns) +{ + if (store_ == nullptr) { + SELECTION_HILOGE("Query(AbsRdbPredicates) store_ is nullptr"); + return nullptr; + } + return store_->Query(predicates, columns); +} + +int32_t SelectionConfigDataBaseCallBack::OnCreate(OHOS::NativeRdb::RdbStore &store) +{ + std::string sql = CREATE_SELECTION_CONFIG_TABLE; + int32_t ret = store.ExecuteSql(sql); + if (ret != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("OnCreate failed: %{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; + } + SELECTION_HILOGI("DB OnCreate Done: %{public}d", ret); + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBaseCallBack::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion) +{ + SELECTION_HILOGI("DB OnUpgrade Enter %{public}d => %{public}d", oldVersion, newVersion); + if (oldVersion >= newVersion) { + return SELECTION_CONFIG_OK; + } + + std::string sql = SQL_ADD_TOKEN_ID; + int32_t ret = store.ExecuteSql(sql); + if (ret != OHOS::NativeRdb::E_OK) { + // ignore sql error when tokenId is already exists + SELECTION_HILOGW("DB OnUpgrade failed: %{public}d", ret); + } + return SELECTION_CONFIG_OK; +} + +int32_t SelectionConfigDataBaseCallBack::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion) +{ + SELECTION_HILOGI("DB OnDowngrade Enter"); + (void)store; + (void)oldVersion; + (void)newVersion; + return SELECTION_CONFIG_OK; +} + +} // namespace SelectionFwk +} // namespace OHOS diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index bf315c6..dbcf6d2 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -16,20 +16,25 @@ #include "selection_service.h" #include "ability_manager_client.h" +#include "db_selection_config_repository.h" #include "iremote_object.h" #include "callback_handler.h" #include "system_ability_definition.h" +#include "selection_errors.h" #include "selection_log.h" #include #include "parameter.h" #include #include "common_event_manager.h" +#include "selection_config_comparator.h" #include "selection_input_monitor.h" #include "selection_interface.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" #include "screenlock_manager.h" #include "focus_monitor_manager.h" +#include "os_account_manager.h" +#include "sys_selection_config_repository.h" using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -130,19 +135,66 @@ int32_t SelectionService::Dump(int32_t fd, const std::vector &ar static void WatchEnableSwitch(const char *key, const char *value, void *context) { - (void)context; - SELECTION_HILOGI("WatchParameterFunc begin"); - SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); + SelectionService *selectionService = static_cast(context); + SELECTION_HILOGI("WatchEnableSwitch begin"); + SELECTION_HILOGI("%{public}s: value=[%{public}s], DEFAULT_SWITCH =[%{public}s]", key, value, DEFAULT_SWITCH); + int isEnabledValue = strcmp(value, DEFAULT_SWITCH) == 0 ? 1 : 0; + SELECTION_HILOGI("isEnabledValue is %{public}d", isEnabledValue); + MemSelectionConfig::GetInstance().SetEnabled(isEnabledValue); + auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); + SELECTION_HILOGI("selectionConfig.selectionConfig is %{public}d", selectionConfig.IsEnabled()); + int ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); + SELECTION_HILOGI("ADD Database ret = %{public}d", ret); } static void WatchTriggerMode(const char *key, const char *value, void *context) { - (void)context; - SELECTION_HILOGI("WatchParameterFunc begin"); + SelectionService *selectionService = static_cast(context); + SELECTION_HILOGI("WatchTriggerMode begin"); SELECTION_HILOGI("%{public}s: value=%{public}s", key, value); int triggerCmpResult = strcmp(value, DEFAULT_TRIGGER); BaseSelectionInputMonitor::ctrlSelectFlag = (triggerCmpResult == 0); SELECTION_HILOGI("ctrlSelectFlag is %{public}d", BaseSelectionInputMonitor::ctrlSelectFlag); + + int triggerValue = triggerCmpResult == 0 ? 1 : 0; + MemSelectionConfig::GetInstance().SetTriggered(triggerValue); + auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); + int ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); + SELECTION_HILOGI("ADD Database ret = %{public}d", ret); +} + +static void WatchAppSwitch(const char *key, const char *value, void *context) +{ + SELECTION_HILOGD("WatchAppSwitch begin"); + SELECTION_HILOGD("%{public}s: value=%{public}s", key, value); + SelectionService *selectionService = static_cast(context); + if (selectionService == nullptr) { + SELECTION_HILOGE("selectionService is nullptr"); + return; + } + + const std::string appInfo = value; + auto pos = appInfo.find('/'); + if (appInfo.empty() || pos == std::string::npos || pos + 1 >= appInfo.size()) { + SELECTION_HILOGE("app info: %{public}s is invalid!", appInfo.c_str()); + return; + } + const std::string bundleName = appInfo.substr(0, pos); + const std::string extName = appInfo.substr(pos + 1); + SELECTION_HILOGD("bundleName: %{public}s, extName: %{public}s", bundleName.c_str(), extName.c_str()); + selectionService->DisconnectCurrentExtAbility(); + auto ret = selectionService->ConnectNewExtAbility(bundleName, extName); + SELECTION_HILOGD("StartExtensionAbility ret = %{public}d", ret); + + MemSelectionConfig::GetInstance().SetBundleName(appInfo); + auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); + ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); + SELECTION_HILOGI("ADD Database ret = %{public}d", ret); +} + +bool SelectionService::IsExistUid() +{ + return isExistUid_; } void SelectionService::DisconnectCurrentExtAbility() @@ -177,37 +229,63 @@ int32_t SelectionService::ConnectNewExtAbility( const std::string& bundleName, c return 0; } -static void WatchAppSwitch(const char *key, const char *value, void *context) +void SelectionService::WatchParams() { - SELECTION_HILOGD("WatchAppSwitch begin"); - SELECTION_HILOGD("%{public}s: value=%{public}s", key, value); - SelectionService *selectionService = static_cast(context); - if (selectionService == nullptr) { - SELECTION_HILOGE("selectionService is nullptr"); - return; - } + SELECTION_HILOGI("WatchParams begin"); + WatchParameter(SYS_SELECTION_SWITCH, WatchEnableSwitch, this); + WatchParameter(SYS_SELECTION_TRIGGER, WatchTriggerMode, this); + WatchParameter(SYS_SELECTION_APP, WatchAppSwitch, this); + SELECTION_HILOGI("WatchParams end"); +} - const std::string appInfo = value; - auto pos = appInfo.find('/'); - if (pos == std::string::npos || pos + 1 >= appInfo.size()) { - SELECTION_HILOGE("app info: %{public}s is abnormal!", appInfo.c_str()); - return; +int SelectionService::GetUserId() +{ + return userId_; +} + +void SelectionService::GetAccountLocalId() +{ + int32_t userId = -1; + int32_t ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); + while (ret != 0) { + sleep(1); + ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); } - const std::string bundleName = appInfo.substr(0, pos); - const std::string extName = appInfo.substr(pos + 1); - SELECTION_HILOGD("bundleName: %{public}s, extName: %{public}s", bundleName.c_str(), extName.c_str()); - selectionService->DisconnectCurrentExtAbility(); - auto ret = selectionService->ConnectNewExtAbility(bundleName, extName); - SELECTION_HILOGD("StartExtensionAbility ret = %{public}d", ret); + SELECTION_HILOGI("GetForegroundOsAccountLocalId userId = %{public}d", userId); + userId_ = userId; } -void SelectionService::WatchParams() +void SelectionService::SynchronizeSelectionConfig() { - SELECTION_HILOGI("WatchParams begin"); - WatchParameter(SYS_SELECTION_SWITCH, WatchEnableSwitch, nullptr); - WatchParameter(SYS_SELECTION_TRIGGER, WatchTriggerMode, nullptr); - WatchParameter(SYS_SELECTION_APP, WatchAppSwitch, this); - SELECTION_HILOGI("WatchParams end"); + GetAccountLocalId(); + SelectionConfig sysSelectionConfig = SysSelectionConfigRepository::GetInstance()->GetSysParameters(); + SELECTION_HILOGI("sysSelectionConfig: uid=%{public}d enable=%{public}d trigger=%{public}d bundleName=%{public}s", + sysSelectionConfig.GetUid(), sysSelectionConfig.IsEnabled(), sysSelectionConfig.IsTriggered(), sysSelectionConfig.GetBundleName().c_str()); + auto dbSelectionConfig = DbSelectionConfigRepository::GetInstance()->GetOneByUserId(userId_); + auto result = SelectionConfigComparator::Compare(userId_, sysSelectionConfig, dbSelectionConfig); + MemSelectionConfig::GetInstance().SetSelectionConfig(result.selectionConfig); + + if (result.shouldCreate) { + SELECTION_HILOGI("result.shouldCreate"); + DbSelectionConfigRepository::GetInstance()->Save(userId_, result.selectionConfig); + SELECTION_HILOGI("result.selectionConfig.isEnable = %{public}d", result.selectionConfig.IsEnabled()); + SysSelectionConfigRepository::GetInstance()->SetSysParameters(result.selectionConfig); + return; + } + + if (result.direction == SyncDirection::FromDbToSys) { + SELECTION_HILOGI("result.direction == SyncDirection::FromDbToSys"); + SELECTION_HILOGI("FromDbToSys result: %{public}s", result.ToString().c_str()); + SysSelectionConfigRepository::GetInstance()->SetSysParameters(result.selectionConfig); + } else if (result.direction == SyncDirection::FromSysToDb) { + SELECTION_HILOGI("result.direction == SyncDirection::FromSysToDb"); + DbSelectionConfigRepository::GetInstance()->Save(userId_, result.selectionConfig); + } + + if (result.shouldStop) { + SELECTION_HILOGI("result.shouldStop"); + SysSelectionConfigRepository::GetInstance()->DisableSAService(); + } } void SelectionService::OnStart() @@ -215,6 +293,7 @@ void SelectionService::OnStart() SELECTION_HILOGI("[SelectionService][OnStart]begin"); Publish(SelectionService::GetInstance()); InputMonitorInit(); + SynchronizeSelectionConfig(); WatchParams(); InitFocusChangedMonitor(); SELECTION_HILOGI("[SelectionService][OnStart]end"); @@ -280,4 +359,4 @@ void SelectionService::HandleKeyEvent(int32_t keyCode) void SelectionService::HandlePointEvent(int32_t type) { -} \ No newline at end of file +} diff --git a/service/src/sys_selection_config_repository.cpp b/service/src/sys_selection_config_repository.cpp new file mode 100644 index 0000000..34c22db --- /dev/null +++ b/service/src/sys_selection_config_repository.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 "sys_selection_config_repository.h" +#include +#include "parameter.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { +static const char *SELECTION_SWITCH = "sys.selection.switch"; +static const char *SELECTION_TRIGGER = "sys.selection.trigger"; +static const char *SELECTION_APPLICATION = "sys.selection.app"; +static const char *SELECTION_UID = "sys.selection.uid"; +static const int BUFFER_LEN = 200; + +std::shared_ptr SysSelectionConfigRepository::instance_ = nullptr; + +std::shared_ptr SysSelectionConfigRepository::GetInstance() +{ + static std::mutex instanceMutex; + std::lock_guard guard(instanceMutex); + if (instance_ == nullptr) { + SELECTION_HILOGI("reset to new SysSelectionConfigRepository instance"); + instance_ = std::make_shared(); + } + return instance_; +} + +int SysSelectionConfigRepository::SetSysParameters(const SelectionConfig &info) +{ + SELECTION_HILOGI("info.uid = %{public}d", info.GetUid()); + SetEnabled(info.IsEnabled()); + SetTriggered(info.IsTriggered()); + SetBundleName(info.GetBundleName()); + SetUid(info.GetUid()); + return 0; +} + +SelectionConfig SysSelectionConfigRepository::GetSysParameters() +{ + SelectionConfig info; + info.SetEnabled(IsEnabled()); + info.SetTriggered(IsTriggered()); + info.SetBundleName(GetBundleName()); + info.SetUid(GetUid()); + return info; +} + +void SysSelectionConfigRepository::DisableSAService() +{ + SetParameter(SELECTION_SWITCH, "off"); +} + +int SysSelectionConfigRepository::IsEnabled() +{ + char value[BUFFER_LEN]; + GetParameter(SELECTION_SWITCH, "", value, BUFFER_LEN); + if (strcmp(value, "on") == 0) { + return 1; + } + return 0; +} + +int SysSelectionConfigRepository::IsTriggered() +{ + char value[BUFFER_LEN]; + GetParameter(SELECTION_TRIGGER, "", value, BUFFER_LEN); + if (strcmp(value, "ctrl") == 0) { + return 1; + } + return 0; +} + +int SysSelectionConfigRepository::GetUid() +{ + char value[BUFFER_LEN]; + GetParameter(SELECTION_UID, "", value, BUFFER_LEN); + return std::atoi(value); +} + +std::string SysSelectionConfigRepository::GetBundleName() +{ + char value[BUFFER_LEN]; + GetParameter(SELECTION_APPLICATION, "", value, BUFFER_LEN); + return value; +} + +void SysSelectionConfigRepository::SetEnabled(int enabled) +{ + SELECTION_HILOGI("[XYING6]enabled: %{public}d", enabled); + if (enabled == 1) { + SetParameter(SELECTION_SWITCH, "on"); + } else if (enabled == 0) { + SetParameter(SELECTION_SWITCH, "off"); + } +} + +void SysSelectionConfigRepository::SetTriggered(int isTriggered) +{ + if (isTriggered == 1) { + SetParameter(SELECTION_TRIGGER, "ctrl"); + } else if (isTriggered == 0) { + SetParameter(SELECTION_TRIGGER, ""); + } +} + +void SysSelectionConfigRepository::SetUid(int uid) +{ + SELECTION_HILOGI("uid = %{public}d", uid); + SetParameter(SELECTION_UID, std::to_string(uid).c_str()); +} + +void SysSelectionConfigRepository::SetBundleName(const std::string &bundleName) +{ + SetParameter(SELECTION_APPLICATION, bundleName.c_str()); +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index fa8ef63..80d70df 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -17,6 +17,7 @@ import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") module_out_path = "selectionfwk/selectionfwk" ohos_unittest("selection_service_unit_test") { module_out_path = module_out_path + cflags_cc = [ "-std=c++17" ] include_dirs = [ "./", "${selection_fwk_root_path}/service/include", @@ -24,7 +25,8 @@ ohos_unittest("selection_service_unit_test") { ] sources = [ - "selection_input_monitor_test.cpp", + "selection_config_comparator_test.cpp", + "selection_input_monitor_test.cpp", ] deps = [ "${selection_fwk_root_path}/service:selection_service", diff --git a/test/unittest/selection_config_comparator_test.cpp b/test/unittest/selection_config_comparator_test.cpp new file mode 100644 index 0000000..738af92 --- /dev/null +++ b/test/unittest/selection_config_comparator_test.cpp @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2022 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 + +#include "gtest/gtest.h" + +#define private public +#include "selection_config_comparator.h" +#include "screenlock_manager.h" +#include "selection_config.h" + +namespace OHOS { +namespace SelectionFwk { + +using namespace testing::ext; + +class SelectionConfigComparatorTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void SelectionConfigComparatorTest::SetUpTestCase() +{ + std::cout << "SelectionConfigComparatorTest SetUpTestCase" << std::endl; +} + +void SelectionConfigComparatorTest::TearDownTestCase() +{ + std::cout << "SelectionConfigComparatorTest TearDownTestCase" << std::endl; +} + +void SelectionConfigComparatorTest::SetUp() +{ + std::cout << "SelectionConfigComparatorTest SetUp" << std::endl; +} + +void SelectionConfigComparatorTest::TearDown() +{ + std::cout << "SelectionConfigComparatorTest TearDown" << std::endl; +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator001, TestSize.Level1) +{ + int uid = 100; + SelectionConfig sysSelectionConfig; + std::optional dbSelectionConfig = std::nullopt; + auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfig); + ASSERT_TRUE(result.shouldCreate); +} + + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator002, TestSize.Level1) +{ + int uid = 100; + SelectionConfig dbSelectionConfig; + dbSelectionConfig.SetUid(100); + dbSelectionConfig.SetEnabled(true); + std::optional dbSelectionConfigOpt = dbSelectionConfig; + SelectionConfig sysSelectionConfig; + auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); + ASSERT_EQ(result.direction, SyncDirection::FromDbToSys); + ASSERT_EQ(result.selectionConfig.GetUid(), 100); + ASSERT_TRUE(result.selectionConfig.IsEnabled()); +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator003, TestSize.Level1) +{ + int uid = 100; + SelectionConfig dbSelectionConfig; + dbSelectionConfig.SetUid(100); + dbSelectionConfig.SetEnabled(true); + std::optional dbSelectionConfigOpt = dbSelectionConfig; + SelectionConfig sysSelectionConfig; + sysSelectionConfig.SetUid(100); + sysSelectionConfig.SetEnabled(false); + auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); + ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); + ASSERT_TRUE(result.shouldStop); + ASSERT_FALSE(result.selectionConfig.IsEnabled()); +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator004, TestSize.Level1) +{ + int uid = 100; + SelectionConfig dbSelectionConfig; + dbSelectionConfig.SetUid(100); + dbSelectionConfig.SetEnabled(true); + std::optional dbSelectionConfigOpt = dbSelectionConfig; + SelectionConfig sysSelectionConfig; + sysSelectionConfig.SetUid(100); + sysSelectionConfig.SetEnabled(true); + auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); + ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator005, TestSize.Level1) +{ + int uid = 100; + SelectionConfig dbSelectionConfig; + dbSelectionConfig.SetUid(100); + dbSelectionConfig.SetEnabled(false); + std::optional dbSelectionConfigOpt = dbSelectionConfig; + SelectionConfig sysSelectionConfig; + auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); + ASSERT_TRUE(result.shouldStop); + ASSERT_EQ(result.selectionConfig.GetUid(), 100); +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator006, TestSize.Level1) +{ + int uid = 100; + SelectionConfig dbSelectionConfig; + dbSelectionConfig.SetUid(100); + dbSelectionConfig.SetEnabled(false); + std::optional dbSelectionConfigOpt = dbSelectionConfig; + SelectionConfig sysSelectionConfig; + sysSelectionConfig.SetUid(100); + sysSelectionConfig.SetEnabled(false); + auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); + ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); + ASSERT_TRUE(result.shouldStop); +} + +/** + * @tc.name: param check samgr ready event + * @tc.desc: param check samgr ready event + * @tc.type: FUNC + */ +HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator007, TestSize.Level1) +{ + int uid = 100; + SelectionConfig dbSelectionConfig; + dbSelectionConfig.SetUid(100); + dbSelectionConfig.SetEnabled(false); + std::optional dbSelectionConfigOpt = dbSelectionConfig; + SelectionConfig sysSelectionConfig; + sysSelectionConfig.SetUid(100); + sysSelectionConfig.SetEnabled(true); + auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); + ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); + ASSERT_TRUE(result.selectionConfig.IsEnabled()); +} +} +} \ No newline at end of file diff --git a/utils/include/selection_errors.h b/utils/include/selection_errors.h new file mode 100644 index 0000000..6b542d2 --- /dev/null +++ b/utils/include/selection_errors.h @@ -0,0 +1,40 @@ +/* + * 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 SELECTION_ERRORS_H +#define SELECTION_ERRORS_H + +#include +#include +#include + +namespace OHOS { +namespace SelectionFwk { + +enum SelectionConfigErrCode { + SELECTION_CONFIG_OK = 0, + SELECTION_CONFIG_FAILURE = -1, + SELECTION_CONFIG_RDB_EXECUTE_FAILTURE = -2, + SELECTION_CONFIG_RDB_NO_INIT = -3, + SELECTION_CONFIG_RDB_EMPTY = -4, + SELECTION_CONFIG_PERMISSION_DENIED = -5, + SELECTION_CONFIG_NOP = -6, + SELECTION_CONFIG_OVERFLOW = -7, + SELECTION_CONFIG_NOT_FOUND = -8, +}; + +} // namespace USB +} // namespace OHOS +#endif // SELECTION_ERRORS_H -- Gitee From 4630f8ee75ffad14bede39a6d1f54c07070c79c1 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Thu, 12 Jun 2025 19:28:36 +0800 Subject: [PATCH 75/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9SelectionInfo=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- common/selection_data_inner.h | 41 ++++++++++++++----- common/selection_interface.h | 12 ++++-- .../js_selection_engine_setting.cpp | 15 ++++--- service/src/selection_input_monitor.cpp | 18 +++++--- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/common/selection_data_inner.h b/common/selection_data_inner.h index 290467a..eff59e4 100644 --- a/common/selection_data_inner.h +++ b/common/selection_data_inner.h @@ -32,10 +32,14 @@ struct SelectionInfoData : public Parcelable { bool ReadFromParcel(Parcel &in) { data.selectionType = static_cast(in.ReadInt8()); data.text = in.ReadString(); - data.startPosX = in.ReadInt32(); - data.startPosY = in.ReadInt32(); - data.endPosX = in.ReadInt32(); - data.endPosY = in.ReadInt32(); + data.startDisplayX = in.ReadInt32(); + data.startDisplayY = in.ReadInt32(); + data.endDisplayX = in.ReadInt32(); + data.endDisplayY = in.ReadInt32(); + data.startWindowX = in.ReadInt32(); + data.startWindowY = in.ReadInt32(); + data.endWindowX = in.ReadInt32(); + data.endWindowY = in.ReadInt32(); data.displayId = in.ReadUint32(); data.windowId = in.ReadUint32(); data.bundleName = in.ReadString(); @@ -49,16 +53,28 @@ struct SelectionInfoData : public Parcelable { if (!out.WriteString(data.text)) { return false; } - if (!out.WriteInt32(data.startPosX)) { + if (!out.WriteInt32(data.startDisplayX)) { return false; } - if (!out.WriteInt32(data.startPosY)) { + if (!out.WriteInt32(data.startDisplayY)) { return false; } - if (!out.WriteInt32(data.endPosX)) { + if (!out.WriteInt32(data.endDisplayX)) { return false; } - if (!out.WriteInt32(data.endPosY)) { + if (!out.WriteInt32(data.endDisplayY)) { + return false; + } + if (!out.WriteInt32(data.startWindowX)) { + return false; + } + if (!out.WriteInt32(data.startWindowY)) { + return false; + } + if (!out.WriteInt32(data.endWindowX)) { + return false; + } + if (!out.WriteInt32(data.endWindowY)) { return false; } if (!out.WriteUint32(data.displayId)) { @@ -85,9 +101,12 @@ struct SelectionInfoData : public Parcelable { std::string ToString() const { std::ostringstream oss; oss << "SelectionInfo { selectionType: " << data.selectionType << ", text: \"" << data.text << "\" \ - startPosX: " << data.startPosX << ", startPosY: " << data.startPosY << ", endPosX: " << data.endPosX << ",\ - endPosY: " << data.endPosY << ", displayId: " << data.displayId << ", windowId: " << data.windowId << - ", bundleName: " << data.bundleName << "}"; + startDisplayX: " << data.startDisplayX << ", startDisplayY: " << data.startDisplayY << ", \ + endDisplayX: " << data.endDisplayX << ", endDisplayY: " << data.endDisplayY << ", \ + startWindowX: " << data.startWindowX << ", startWindowY: " << data.startWindowY << ", \ + endWindowX: " << data.endWindowX << ", endWindowY: " << data.endWindowY << ", \ + displayId: " << data.displayId << ", windowId: " << data.windowId << ", bundleName: \ + " << data.bundleName << "}"; return oss.str(); } }; diff --git a/common/selection_interface.h b/common/selection_interface.h index ebda748..70444e7 100644 --- a/common/selection_interface.h +++ b/common/selection_interface.h @@ -33,10 +33,14 @@ typedef enum { struct SelectionInfo { SelectionType selectionType; std::string text = ""; - int32_t startPosX = 0; - int32_t startPosY = 0; - int32_t endPosX = 0; - int32_t endPosY = 0; + int32_t startDisplayX = 0; + int32_t startDisplayY = 0; + int32_t endDisplayX = 0; + int32_t endDisplayY = 0; + int32_t startWindowX = 0; + int32_t startWindowY = 0; + int32_t endWindowX = 0; + int32_t endWindowY = 0; uint32_t displayId = 0; uint32_t windowId = 0; std::string bundleName = ""; diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 6e1b547..627beda 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -416,11 +416,16 @@ napi_value JsSelectionEngineSetting::Write(napi_env env, const SelectionInfo &se napi_value jsObject = nullptr; napi_create_object(env, &jsObject); auto ret = JsUtil::Object::WriteProperty(env, jsObject, "bundleName", selectionInfo.bundleName); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "winID", selectionInfo.windowId); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosX", selectionInfo.startPosX); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startPosY", selectionInfo.startPosY); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosX", selectionInfo.endPosX); - ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endPosY", selectionInfo.endPosY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "windowID", selectionInfo.windowId); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "displayID", selectionInfo.displayId); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endWindowY", selectionInfo.endWindowY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endWindowX", selectionInfo.endWindowX); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startWindowY", selectionInfo.startWindowY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startWindowX", selectionInfo.startWindowX); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endDisplayY", selectionInfo.endDisplayY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "endDisplayX", selectionInfo.endDisplayX); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startDisplayY", selectionInfo.startDisplayY); + ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "startDisplayX", selectionInfo.startDisplayX); ret = ret && JsUtil::Object::WriteProperty(env, jsObject, "text", selectionInfo.text); SELECTION_HILOGD("write selectionInfo into object, ret=%{public}s", ret ? "true" : "false"); return ret ? jsObject : JsUtil::Const::Null(env); diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index 39726a2..9f7446e 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -155,10 +155,14 @@ void BaseSelectionInputMonitor::SaveSelectionStartInfo(std::shared_ptrGetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); - selectionInfo_.startPosX = pointerItem.GetDisplayX(); - selectionInfo_.startPosY = pointerItem.GetDisplayY(); - selectionInfo_.endPosX = pointerItem.GetDisplayX(); - selectionInfo_.endPosY = pointerItem.GetDisplayY(); + selectionInfo_.startDisplayX = pointerItem.GetDisplayX(); + selectionInfo_.startDisplayY = pointerItem.GetDisplayY(); + selectionInfo_.endDisplayX = pointerItem.GetDisplayX(); + selectionInfo_.endDisplayY = pointerItem.GetDisplayY(); + selectionInfo_.startWindowX = pointerItem.GetWindowX(); + selectionInfo_.startWindowY = pointerItem.GetWindowY(); + selectionInfo_.endWindowX = pointerItem.GetWindowX(); + selectionInfo_.endWindowY = pointerItem.GetWindowY(); selectionInfo_.displayId = pointerEvent->GetTargetDisplayId(); selectionInfo_.windowId = pointerEvent->GetTargetWindowId(); @@ -186,8 +190,10 @@ void BaseSelectionInputMonitor::SaveSelectionEndInfo(std::shared_ptrGetPointerId(); PointerEvent::PointerItem pointerItem; pointerEvent->GetPointerItem(pointerId, pointerItem); - selectionInfo_.endPosX = pointerItem.GetDisplayX(); - selectionInfo_.endPosY = pointerItem.GetDisplayY(); + selectionInfo_.endDisplayX = pointerItem.GetDisplayX(); + selectionInfo_.endDisplayY = pointerItem.GetDisplayY(); + selectionInfo_.endWindowX = pointerItem.GetWindowX(); + selectionInfo_.endWindowY = pointerItem.GetWindowY(); } void BaseSelectionInputMonitor::SaveSelectionType() const -- Gitee From a5d4da797b08180444d6f0b2f269f377aa765c84 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Fri, 13 Jun 2025 09:18:11 +0800 Subject: [PATCH 76/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/src/selection_input_monitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index 9f7446e..eafb6d5 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -171,7 +171,7 @@ void BaseSelectionInputMonitor::SaveSelectionStartInfo(std::shared_ptr> infos; Rosen::WMError ret = Rosen::WindowManager::GetInstance().ListWindowInfo(windowInfoOption, infos); - SELECTION_HILOGI("ListWindowInfo ret: %{public}d, infos size: %{public}d", ret, infos.size()); + SELECTION_HILOGI("ListWindowInfo ret: %{public}d, infos size: %{public}zu", ret, infos.size()); for (unsigned int i = 0; i < infos.size(); i++) { auto info = infos[i]; SELECTION_HILOGI("ListWindowInfo bundleName: %{public}s", info->windowMetaInfo.bundleName.c_str()); -- Gitee From 536c2d7b193d2e2d018af130cb88a9c07f2a1058 Mon Sep 17 00:00:00 2001 From: yangmaoquan Date: Fri, 13 Jun 2025 09:18:11 +0800 Subject: [PATCH 77/93] =?UTF-8?q?=E4=BF=AE=E6=94=B9pointId=E4=B8=BAbuttonI?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yangmaoquan Signed-off-by: Sunjiamei --- service/src/selection_input_monitor.cpp | 10 ++++------ test/unittest/selection_input_monitor_test.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index eafb6d5..88e8b9a 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -96,10 +96,8 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr point SELECTION_HILOGD("It is not screen on."); return; } - int32_t pointerId = pointerEvent->GetPointerId(); - PointerEvent::PointerItem pointerItem; - pointerEvent->GetPointerItem(pointerId, pointerItem); - if (pointerId != PointerEvent::MOUSE_BUTTON_LEFT) { + int32_t buttonId = pointerEvent->GetButtonId(); + if (buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { ResetState(); } SELECTION_HILOGD("[SelectionService] into PointerEvent, curSelectState = %{public}d.", curSelectState); @@ -227,8 +225,8 @@ bool BaseSelectionInputMonitor::IsSelectionDone() const { void BaseSelectionInputMonitor::InputInitialProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - int32_t pointerId = pointerEvent->GetPointerId(); - if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && pointerId == PointerEvent::MOUSE_BUTTON_LEFT) { + int32_t buttonId = pointerEvent->GetButtonId(); + if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && buttonId == PointerEvent::MOUSE_BUTTON_LEFT) { curSelectState = SELECT_INPUT_WORD_BEGIN; subSelectState = SUB_INITIAL; lastClickTime = GetCurrentTimeMillis(); diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index a968447..712279c 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -25,7 +25,7 @@ namespace SelectionFwk { using namespace testing::ext; struct EventStruct { - int pointId; + int buttonId; int action; }; class BaseSelectionInputMonitorTest : public testing::Test { @@ -75,7 +75,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) for (uint16_t i = 0; i < events.size(); i++) { auto event = events[i]; std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetPointerId(event.pointId); + pointEvent->SetButtonId(event.buttonId); pointEvent->SetPointerAction(event.action); inputMonitor->OnInputEvent(pointEvent); } @@ -96,7 +96,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) for (uint16_t i = 0; i < events.size(); i++) { auto event = events[i]; std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetPointerId(event.pointId); + pointEvent->SetButtonId(event.buttonId); pointEvent->SetPointerAction(event.action); inputMonitor->OnInputEvent(pointEvent); } @@ -119,7 +119,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) for (uint16_t i = 0; i < events.size(); i++) { auto event = events[i]; std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetPointerId(event.pointId); + pointEvent->SetButtonId(event.buttonId); pointEvent->SetPointerAction(event.action); inputMonitor->OnInputEvent(pointEvent); } @@ -140,7 +140,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor004, TestSize.Level1) for (uint16_t i = 0; i < events.size(); i++) { auto event = events[i]; std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetPointerId(event.pointId); + pointEvent->SetButtonId(event.buttonId); pointEvent->SetPointerAction(event.action); inputMonitor->OnInputEvent(pointEvent); } -- Gitee From d0c25c6d23695c1c003169a8b0f9f2072dde3b4e Mon Sep 17 00:00:00 2001 From: fanzhe Date: Fri, 13 Jun 2025 10:16:21 +0800 Subject: [PATCH 78/93] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3AddVo?= =?UTF-8?q?lum?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- service/ISelectionService.idl | 1 - service/include/selection_service.h | 1 - service/src/selection_service.cpp | 6 ------ 3 files changed, 8 deletions(-) diff --git a/service/ISelectionService.idl b/service/ISelectionService.idl index c560d00..fef8523 100644 --- a/service/ISelectionService.idl +++ b/service/ISelectionService.idl @@ -15,7 +15,6 @@ sequenceable OHOS.IRemoteObject; interface OHOS.SelectionFwk.ISelectionService { - int AddVolume([in] int volume); void RegisterListener([in] IRemoteObject listener); void UnregisterListener([in] IRemoteObject listener); } \ No newline at end of file diff --git a/service/include/selection_service.h b/service/include/selection_service.h index bf9f71d..65e429f 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -57,7 +57,6 @@ public: SelectionService(int32_t saId, bool runOnCreate); ~SelectionService(); - ErrCode AddVolume(int32_t volume, int32_t& funcResult) override; ErrCode RegisterListener(const sptr &listener) override; ErrCode UnregisterListener(const sptr &listener) override; int32_t Dump(int32_t fd, const std::vector &args) override; diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index dbcf6d2..67d58e7 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -87,12 +87,6 @@ SelectionService::~SelectionService() SELECTION_HILOGI("[~SelectionService]"); } -ErrCode SelectionService::AddVolume(int32_t volume, int32_t& funcResult) -{ - SELECTION_HILOGI("[SelectionService][AddVolume]begin"); - return (volume + 1); -} - ErrCode SelectionService::UnregisterListener(const sptr &listener) { listenerStub_ = nullptr; -- Gitee From 3f537e522a272264377a6e4a969a38dec39fc458 Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Thu, 12 Jun 2025 22:40:00 +0800 Subject: [PATCH 79/93] =?UTF-8?q?=E6=B7=BB=E5=8A=A0fuzztest=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 3 +- test/fuzztest/BUILD.gn | 22 ++++++ .../selectioninputability_fuzzer/BUILD.gn | 70 +++++++++++++++++++ .../selectioninputability_fuzzer/corpus/init | 14 ++++ .../selectioninputability_fuzzer/project.xml | 25 +++++++ .../selectioninputability_fuzzer.cpp | 69 ++++++++++++++++++ .../selectioninputability_fuzzer.h | 19 +++++ 7 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 test/fuzztest/BUILD.gn create mode 100644 test/fuzztest/selectioninputability_fuzzer/BUILD.gn create mode 100644 test/fuzztest/selectioninputability_fuzzer/corpus/init create mode 100644 test/fuzztest/selectioninputability_fuzzer/project.xml create mode 100644 test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp create mode 100644 test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.h diff --git a/bundle.json b/bundle.json index 43bef53..380610d 100644 --- a/bundle.json +++ b/bundle.json @@ -61,7 +61,8 @@ ], "inner_kits": [], "test": [ - "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_service_unit_test" + "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_service_unit_test", + "//foundation/systemabilitymgr/selectionfwk/test/fuzztest:selection_service_fuzztest" ] } } diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn new file mode 100644 index 0000000..edad0ff --- /dev/null +++ b/test/fuzztest/BUILD.gn @@ -0,0 +1,22 @@ +# 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("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") + +group("selection_service_fuzztest") { + testonly = true + + deps = [ + "selectioninputability_fuzzer:fuzztest", + ] +} diff --git a/test/fuzztest/selectioninputability_fuzzer/BUILD.gn b/test/fuzztest/selectioninputability_fuzzer/BUILD.gn new file mode 100644 index 0000000..70d38fb --- /dev/null +++ b/test/fuzztest/selectioninputability_fuzzer/BUILD.gn @@ -0,0 +1,70 @@ +# 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("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") + +#####################hydra-fuzz################### +import("//build/config/features.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +##############################fuzztest########################################## +ohos_fuzztest("SelectionInputAbilityFuzzTest") { + module_out_path = "selectionfwk/selectionfwk" + + fuzz_config_file = + "//foundation/systemabilitymgr/selectionfwk/test/fuzztest/selectioninputability_fuzzer" + + include_dirs = [ + "${selection_fwk_root_path}/frameworks/native/selection_ability/include", + "${selection_fwk_root_path}/utils/include", + "${target_gen_dir}", + "${selection_fwk_root_path}/common", + ] + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ "selectioninputability_fuzzer.cpp" ] + + deps = [ + "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_ability", + "${selection_fwk_root_path}/frameworks/native/selection_extension:selection_extension_ability_native", + "${selection_fwk_root_path}/service:selection_service_proxy", + "${selection_fwk_root_path}/service:selection_service", + ] + + external_deps = [ + "ability_runtime:ability_manager", + "ability_runtime:runtime", + "c_utils:utils", + "hilog:libhilog", + "input:libmmi-client", + "ipc:ipc_single", + "napi:ace_napi", + "window_manager:libdm", + "samgr:samgr_proxy", + ] +} + +############################################################################### +group("fuzztest") { + testonly = true + deps = [] + deps += [ ":SelectionInputAbilityFuzzTest" ] +} +############################################################################### diff --git a/test/fuzztest/selectioninputability_fuzzer/corpus/init b/test/fuzztest/selectioninputability_fuzzer/corpus/init new file mode 100644 index 0000000..65af8ee --- /dev/null +++ b/test/fuzztest/selectioninputability_fuzzer/corpus/init @@ -0,0 +1,14 @@ +# 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. + +FUZZ \ No newline at end of file diff --git a/test/fuzztest/selectioninputability_fuzzer/project.xml b/test/fuzztest/selectioninputability_fuzzer/project.xml new file mode 100644 index 0000000..66e1dca --- /dev/null +++ b/test/fuzztest/selectioninputability_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + diff --git a/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp b/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp new file mode 100644 index 0000000..42640e9 --- /dev/null +++ b/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp @@ -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. + */ + +#include "selectioninputability_fuzzer.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include +#include "selection_log.h" +#include +#include +#include + +namespace OHOS { +namespace SelectionFwk { + +sptr GetSelectionSystemAbility() +{ + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + SELECTION_HILOGE("system ability manager is nullptr!"); + return nullptr; + } + + sptr systemAbility = nullptr; + systemAbility = systemAbilityManager->GetSystemAbility(SELECTION_FWK_SA_ID); + if (systemAbility == nullptr) { + SELECTION_HILOGE("get system ability is nullptr!"); + return nullptr; + } + + return systemAbility; +} + +void TestSendRequest(uint32_t code) +{ + sptr systemAbility = GetSelectionSystemAbility(); + MessageParcel data; + MessageParcel reply; + MessageOption option; + systemAbility->SendRequest(code, data, reply, option); +} + +} // namespace SelectionFwk +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(uint32_t)) { + return 0; + } + + auto fuzzedCode = static_cast(size); + + OHOS::SelectionFwk::TestSendRequest(fuzzedCode); + return 0; +} \ No newline at end of file diff --git a/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.h b/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.h new file mode 100644 index 0000000..008250d --- /dev/null +++ b/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.h @@ -0,0 +1,19 @@ +/* + * 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 SELECTION_INPUT_ABILITY_FUZZER +#define SELECTION_INPUT_ABILITY_FUZZER +#define FUZZ_PROJECT_NAME "selectioninputability_fuzzer" + +#endif // SELECTION_INPUT_ABILITY_FUZZER \ No newline at end of file -- Gitee From 33f509b60db1a8176193c1cc229bf56de93e9193 Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Fri, 13 Jun 2025 19:07:01 +0800 Subject: [PATCH 80/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0unittest=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../unittest/selection_input_monitor_test.cpp | 380 +++++++++++++++--- 1 file changed, 321 insertions(+), 59 deletions(-) diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index 712279c..b18e294 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -13,11 +13,12 @@ * limitations under the License. */ +#include +#include #include "gtest/gtest.h" -#define private public -#include "selection_input_monitor.h" #include "screenlock_manager.h" +#include "selection_input_monitor.h" namespace OHOS { namespace SelectionFwk { @@ -28,6 +29,92 @@ struct EventStruct { int buttonId; int action; }; + +template +void LEFT_BUTTON_DOWN(std::shared_ptr handler) +{ + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN); + handler->OnInputEvent(pointEvent); +} + +template +void LEFT_BUTTON_UP(std::shared_ptr handler) +{ + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP); + handler->OnInputEvent(pointEvent); +} + +template +void RIGHT_BUTTON_DOWN(std::shared_ptr handler) +{ + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_RIGHT); + pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN); + handler->OnInputEvent(pointEvent); +} + +template +void RIGHT_BUTTON_UP(std::shared_ptr handler) +{ + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_RIGHT); + pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP); + handler->OnInputEvent(pointEvent); +} + +template +void LEFT_BUTTON_MOVE(std::shared_ptr handler) +{ + std::shared_ptr pointEvent = PointerEvent::Create(); + pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); + pointEvent->SetPointerAction(PointerEvent::PointerEvent::POINTER_ACTION_MOVE); + handler->OnInputEvent(pointEvent); +} + +template +void CTRL_DOWN(std::shared_ptr handler) +{ + std::shared_ptr keyEvent = KeyEvent::Create(); + keyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + handler->OnInputEvent(keyEvent); +} + +template +void CTRL_UP(std::shared_ptr handler) +{ + std::shared_ptr keyEvent = KeyEvent::Create(); + keyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyEvent->SetKeyAction(KeyEvent::KEY_ACTION_UP); + handler->OnInputEvent(keyEvent); +} + +void WAIT_TIMEOUT(){ + std::this_thread::sleep_for(std::chrono::milliseconds(DOUBLE_CLICK_TIME + 1)); // >500ms +} + +void CHICK_INFO(const SelectionInfo& info) +{ + ASSERT_NE(info.selectionType, 0); + ASSERT_NE(info.text.empty(), true); + ASSERT_NE(info.startDisplayX, 0); + ASSERT_NE(info.startDisplayY, 0); + ASSERT_NE(info.endDisplayX, 0); + ASSERT_NE(info.endDisplayY, 0); + ASSERT_NE(info.startWindowX, 0); + ASSERT_NE(info.startWindowY, 0); + ASSERT_NE(info.endWindowX, 0); + ASSERT_NE(info.endWindowY, 0); + ASSERT_NE(info.displayId, 0); + ASSERT_NE(info.windowId, 0); + ASSERT_NE(info.endWindowY, 0); + ASSERT_NE(info.bundleName.empty(), true); +} + class BaseSelectionInputMonitorTest : public testing::Test { public: static void SetUpTestCase(); @@ -66,19 +153,10 @@ void BaseSelectionInputMonitorTest::TearDown() HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) { std::cout << " SelectInputMonitor001 start " << std::endl; - vector events = { - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_MOVE}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} - }; - - for (uint16_t i = 0; i < events.size(); i++) { - auto event = events[i]; - std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetButtonId(event.buttonId); - pointEvent->SetPointerAction(event.action); - inputMonitor->OnInputEvent(pointEvent); - } + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_MOVE(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); } @@ -86,20 +164,12 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) { std::cout << " SelectInputMonitor002 start " << std::endl; - vector events = { - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} - }; - - for (uint16_t i = 0; i < events.size(); i++) { - auto event = events[i]; - std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetButtonId(event.buttonId); - pointEvent->SetPointerAction(event.action); - inputMonitor->OnInputEvent(pointEvent); - } + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); } @@ -107,22 +177,14 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) { std::cout << " SelectInputMonitor003 start " << std::endl; - vector events = { - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP} - }; - - for (uint16_t i = 0; i < events.size(); i++) { - auto event = events[i]; - std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetButtonId(event.buttonId); - pointEvent->SetPointerAction(event.action); - inputMonitor->OnInputEvent(pointEvent); - } + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); } @@ -130,23 +192,223 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor004, TestSize.Level1) { std::cout << " SelectInputMonitor004 start " << std::endl; - vector events = { - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_LEFT, PointerEvent::POINTER_ACTION_BUTTON_UP}, - {PointerEvent::MOUSE_BUTTON_RIGHT, PointerEvent::POINTER_ACTION_BUTTON_DOWN}, - {PointerEvent::MOUSE_BUTTON_RIGHT, PointerEvent::POINTER_ACTION_BUTTON_UP} - }; - - for (uint16_t i = 0; i < events.size(); i++) { - auto event = events[i]; - std::shared_ptr pointEvent = PointerEvent::Create(); - pointEvent->SetButtonId(event.buttonId); - pointEvent->SetPointerAction(event.action); - inputMonitor->OnInputEvent(pointEvent); - } + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + RIGHT_BUTTON_DOWN(inputMonitor); + RIGHT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, false); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor005, TestSize.Level1) +{ + std::cout << " SelectInputMonitor005 start " << std::endl; + + // double click + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + WAIT_TIMEOUT(); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, false); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor006, TestSize.Level1) +{ + std::cout << " SelectInputMonitor006 start " << std::endl; + + // triple click + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + WAIT_TIMEOUT(); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor007, TestSize.Level1) +{ + std::cout << " SelectInputMonitor007 start " << std::endl; + + // triple click + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + WAIT_TIMEOUT(); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor008, TestSize.Level1) +{ + std::cout << " SelectInputMonitor008 start " << std::endl; + + // triple click + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + WAIT_TIMEOUT(); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + WAIT_TIMEOUT(); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, false); } +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor009, TestSize.Level1) +{ + std::cout << " SelectInputMonitor009 start " << std::endl; + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + // move + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_MOVE(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor010, TestSize.Level1) +{ + std::cout << " SelectInputMonitor010 start " << std::endl; + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_MOVE(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); } + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor011, TestSize.Level1) +{ + std::cout << " SelectInputMonitor011 start " << std::endl; + + // move + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_MOVE(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + // ctrl + CTRL_DOWN(inputMonitor); + CTRL_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); } + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor012, TestSize.Level1) +{ + std::cout << " SelectInputMonitor012 start " << std::endl; + // ctrl + CTRL_DOWN(inputMonitor); + CTRL_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_MOVE(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor013, TestSize.Level1) +{ + std::cout << " SelectInputMonitor013 start " << std::endl; + // ctrl + CTRL_DOWN(inputMonitor); + CTRL_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor014, TestSize.Level1) +{ + std::cout << " SelectInputMonitor014 start " << std::endl; + // ctrl + CTRL_DOWN(inputMonitor); + CTRL_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, true); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor015, TestSize.Level1) +{ + std::cout << " SelectInputMonitor015 start " << std::endl; + // ctrl + CTRL_DOWN(inputMonitor); + CTRL_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, false); +} + +HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor016, TestSize.Level1) +{ + std::cout << " SelectInputMonitor016 start " << std::endl; + // ctrl + CTRL_DOWN(inputMonitor); + CTRL_UP(inputMonitor); + + LEFT_BUTTON_DOWN(inputMonitor); + LEFT_BUTTON_UP(inputMonitor); + + auto ret = inputMonitor->IsTextSelected(); + ASSERT_EQ(ret, false); +} + +} // namespace SelectionFwk +} // namespace OHOS -- Gitee From 200b9e21a1f71826d3b517471b44bf8210f640a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Sat, 14 Jun 2025 12:03:04 +0800 Subject: [PATCH 81/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ts-ut=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 3 +- test/unittest/BUILD.gn | 7 ++ test/unittest/systemapi_js_test/BUILD.gn | 21 ++++++ .../systemapi_js_test/PermissionJsTest.js | 44 ++++++++++++ test/unittest/systemapi_js_test/config.json | 64 ++++++++++++++++++ .../systemapi_js_test/openharmony_sx.p7b | Bin 0 -> 3542 bytes 6 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 test/unittest/systemapi_js_test/BUILD.gn create mode 100644 test/unittest/systemapi_js_test/PermissionJsTest.js create mode 100644 test/unittest/systemapi_js_test/config.json create mode 100644 test/unittest/systemapi_js_test/openharmony_sx.p7b diff --git a/bundle.json b/bundle.json index 380610d..3044ecf 100644 --- a/bundle.json +++ b/bundle.json @@ -62,7 +62,8 @@ "inner_kits": [], "test": [ "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_service_unit_test", - "//foundation/systemabilitymgr/selectionfwk/test/fuzztest:selection_service_fuzztest" + "//foundation/systemabilitymgr/selectionfwk/test/fuzztest:selection_service_fuzztest", + "//foundation/systemabilitymgr/selectionfwk/test/unittest:selcection_manager_ut" ] } } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 80d70df..7b3c9a7 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -50,3 +50,10 @@ ohos_unittest("selection_service_unit_test") { part_name = "selectionfwk" subsystem_name = "systemabilitymgr" } + +group("selcection_manager_ut") { + testonly = true + deps = [ + "systemapi_js_test:SystemApiJsTest", + ] +} \ No newline at end of file diff --git a/test/unittest/systemapi_js_test/BUILD.gn b/test/unittest/systemapi_js_test/BUILD.gn new file mode 100644 index 0000000..cd325de --- /dev/null +++ b/test/unittest/systemapi_js_test/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2024 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/test.gni") + +module_output_path = "selectionfwk/selectionfwk" +ohos_js_unittest("SystemApiJsTest") { + module_out_path = module_output_path + hap_profile = "./config.json" + certificate_profile = "./openharmony_sx.p7b" +} diff --git a/test/unittest/systemapi_js_test/PermissionJsTest.js b/test/unittest/systemapi_js_test/PermissionJsTest.js new file mode 100644 index 0000000..6907322 --- /dev/null +++ b/test/unittest/systemapi_js_test/PermissionJsTest.js @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 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 selectionManager from '@ohos.selectionInput.selectionManager' +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from 'deccjsunit/index' + +describe("SystemApiJsTest", function () { + beforeAll(function () { + console.info('beforeAll called'); + }) + + afterAll(function () { + console.info('AfterAll called'); + }) + + /* + * @tc.name:SystemApi_destroyPanel_001 + * @tc.desc:verify SystemApi of destroyPanel + * @tc.type: FUNC + */ + // it("SystemApi_destroyPanel_001", 0, done => { + // console.info('----------------------SystemApi_destroyPanel_001---------------------------'); + // try { + // selectionManager.destroyPanel(selectionManager.panel); + // expect(false).assertTrue(); + // done(); + // } catch (err) { + // expect(err.code).assertEqual(SYSTEMAPI_DENIED_CODE); + // done(); + // } + // }); +}); \ No newline at end of file diff --git a/test/unittest/systemapi_js_test/config.json b/test/unittest/systemapi_js_test/config.json new file mode 100644 index 0000000..065198e --- /dev/null +++ b/test/unittest/systemapi_js_test/config.json @@ -0,0 +1,64 @@ +{ + "app": { + "bundleName": "com.example.selectionmanagertest", + "vendor": "example", + "version": { + "code": 1, + "name": "1.0" + }, + "apiVersion": { + "compatible": 12, + "target": 12 + } + }, + "deviceConfig": {}, + "module": { + "reqPermissions": [], + "package": "com.example.selectionmanagertest", + "name": ".MyApplication", + "deviceType": [ + "default", + "tablet", + "2in1" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry" + }, + "abilities": [ + { + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "name": "com.example.selectionmanagertest.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "PermissionJsTest", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "pages": [ + "pages/index/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } + } + \ No newline at end of file diff --git a/test/unittest/systemapi_js_test/openharmony_sx.p7b b/test/unittest/systemapi_js_test/openharmony_sx.p7b new file mode 100644 index 0000000000000000000000000000000000000000..3c2b57903f2afe51f8eeb1e1a84fdf8d7bcfe410 GIT binary patch literal 3542 zcmcgvYj6|S6}BF>V?bbH!mEHm5KIBVU0JdvlMr^L)eEm=3CXsMsadU7(%P%twRYu| zMIl5qB)mg21vflm-Vh$?KoW<{1X2>9kOT%oX`28kp-ciLNhu_uVW8cW9k7|?M<+Ar zhjz}n=id9>bH4N4xgeuComVh^p=0598b!XcJ)?OSWHbkr3I(JAz4HoYFLWqKm0GC) zncT$vKt+2dmr!SN8|G+R$OKQZjE=$Mq_#qW!v}Sw9{T$b{rBGnozLrILH@L~R#> z1WA)PPfCl0l1!K;brcg}<@Lg33rVvanb2hsc{q}B;E6cPv`Vo(&O(q0fr?NBF33mH z$v*_OJKZBKsL$`TIW4ds&3fw@%;~gXX^RC8kx^K5B5>4+;vUQ7v=zpXXtX)j)aa@5 zdabY+fH6CkvZP@b5_MN2aL^AoxjoVfKCg&IgVt)VcRDHxRfN4dIm2#i4b_;Fq#v!r z5W)^a0o0Phy#7*z4mHJML>y`fF-_5Gdv&ay3Hi}R%z|d4;1q^G80D=+#E_kC4A%O% zklqmW0#tOw2shSzN1kOxgW#ZRa_8KZ=^gx*DT1SnCo(dZW>4^U=W?keY6Vzn*b` z2cl4$NZ3?WYGd3Ym$p(_8r8BC_ zlM&Pw!JUFH4STZDUK0XGOeg|l7Q_IH4mqPf;6aceYO4}biDZnfX9yqSvS7HiaN z3^*VfAciV?456`Tn9`>sCZ@^Eb9fr{Iwyl#x5z~VlNWZ1ju}Z)MU1vNyD@a zn5<05mGF23594h%iVjZ|Z4Dv@j}SGc0M+_p2@ZZ>bCw!o80fl zE@2_q_#`rg$2ppu#7iAZ$Z`?K89XZW9?1*R1e~L#?&Di|fs8kVaGoNvPEHpgaUm(I zf;J|}O;>;$$Lc7>=RF_RjS+^KtR1gL7pn0&MQ({ z+|U5fKGTpdnz8?Co7t*v&iAPvUWCG#DihsfvbnAClnGvZ6@{M_OPoVvt4; z0X@(|dg*Jd8>BIqA$=*-WdiPJf&gGrCy0`t0#TJF@32fUA8d3#&hedgrv_WkBs?wxNNGzwqO znyIK95K%%oyO!@M$b?$=IL7oxuDw9+kLB%sbX}onn|kNk#>Io8FWeiuzkdSU^wpIN$bU~FgUihrtfK9&_8AQ5DMOx;M7H6J39 z7EpMfJh>B|QRiq?p&T_g{6|!Yl`_26gxBXlD^gT~Jzv8d<{+piFTzGTK#@h{#-5y)KByoP^ zFNb^ipmSb%zWraD5HJn&lZjF!6DJp_q)$&KDe}58X;4MshMhxxeL2Uo>r`9G-nKfi z?}t6Br;6r)uo8%MVhQx&cjES`tJj^aeQm{_lC8a#o$T{w#r_e`&L3|~*KgS{Ot=2b zVOBkw3YG|Klwi!xG0(BHc8$*W4cNTwX8Tg$daBj>pCo#j+uX8l?M<+{*|W0s?6yH? zCTu-nAG|PE;t?+K=yDg2Mv(73*%Qe_tX?-Uf{dm5?mUvshogu;L7`FWzdE|^)j`JH zi;r(^`1}g|c!~Pb(3fv~BrLG(*`D|9?ypORzJK;b&0BAlZ=T21E;>5z7u?>Kt#5qb z12wOGyn0+&)$1Lv9$GVW?Uoyh78Tw&)i!F;t*2+dHlg^|)ngZzf3FK{A^_e)oPLxe z{|Co@RNQ*pFsfJ%AeA6~?pLM-zZbrK`VY4%VhuZvmaV^Zpz!F~qDyllg`Uffz^9Am z4~ca+|9$3a$783jp6xG*)saV7aYsdBgRf((?)K}oyAH2fRd|S=a(-ZD*q!GuxR)g^ zFUK!&L19_+xZ&j~A5VfZ3Pd8=ROtZ%njT6SyKdC(Z=H4u48Hf)DNsSu*bgrx1sHbE zD9DBSNtdD#ltHD^#b|`e>%ipuqiRU29tj;{Hva9<^|!w0#aFJ~HF)OGI}=9~zi>GJ zy`{H2Q$Nq;L9cr^xl-)_Hsz?C1DV|`FFtqfl~10Sv#8HB$EP1`cI7P|u|gGNZT)I* r{$-dH^5vF%%X=qmjmP($8KRoQJ$dv%AJf@u Date: Sat, 14 Jun 2025 12:42:47 +0800 Subject: [PATCH 82/93] =?UTF-8?q?=E5=AE=8C=E5=96=84unittest=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../unittest/selection_input_monitor_test.cpp | 76 +++++++++++++------ 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index b18e294..6579d5b 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -30,10 +30,23 @@ struct EventStruct { int action; }; +std::shared_ptr GetPointerEvent() +{ + static std::shared_ptr pointEvent = PointerEvent::Create(); + PointerEvent::PointerItem pointerItem; + pointerItem.SetDisplayX(100); + pointerItem.SetDisplayY(200); + pointerItem.SetWindowX(50); + pointerItem.SetWindowY(60); + + pointEvent->AddPointerItem(pointerItem); + return pointEvent; +} + template void LEFT_BUTTON_DOWN(std::shared_ptr handler) { - std::shared_ptr pointEvent = PointerEvent::Create(); + std::shared_ptr pointEvent = GetPointerEvent(); pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN); handler->OnInputEvent(pointEvent); @@ -42,7 +55,7 @@ void LEFT_BUTTON_DOWN(std::shared_ptr handler) template void LEFT_BUTTON_UP(std::shared_ptr handler) { - std::shared_ptr pointEvent = PointerEvent::Create(); + std::shared_ptr pointEvent = GetPointerEvent(); pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP); handler->OnInputEvent(pointEvent); @@ -69,7 +82,7 @@ void RIGHT_BUTTON_UP(std::shared_ptr handler) template void LEFT_BUTTON_MOVE(std::shared_ptr handler) { - std::shared_ptr pointEvent = PointerEvent::Create(); + std::shared_ptr pointEvent = GetPointerEvent(); pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_LEFT); pointEvent->SetPointerAction(PointerEvent::PointerEvent::POINTER_ACTION_MOVE); handler->OnInputEvent(pointEvent); @@ -93,26 +106,22 @@ void CTRL_UP(std::shared_ptr handler) handler->OnInputEvent(keyEvent); } -void WAIT_TIMEOUT(){ +void WAIT_TIMEOUT() +{ std::this_thread::sleep_for(std::chrono::milliseconds(DOUBLE_CLICK_TIME + 1)); // >500ms } -void CHICK_INFO(const SelectionInfo& info) +void CHECK_INFO(const SelectionInfo& info) { - ASSERT_NE(info.selectionType, 0); - ASSERT_NE(info.text.empty(), true); - ASSERT_NE(info.startDisplayX, 0); - ASSERT_NE(info.startDisplayY, 0); - ASSERT_NE(info.endDisplayX, 0); - ASSERT_NE(info.endDisplayY, 0); - ASSERT_NE(info.startWindowX, 0); - ASSERT_NE(info.startWindowY, 0); - ASSERT_NE(info.endWindowX, 0); - ASSERT_NE(info.endWindowY, 0); - ASSERT_NE(info.displayId, 0); - ASSERT_NE(info.windowId, 0); - ASSERT_NE(info.endWindowY, 0); - ASSERT_NE(info.bundleName.empty(), true); + EXPECT_NE(info.selectionType, 0); + EXPECT_NE(info.startDisplayX, 0); + EXPECT_NE(info.startDisplayY, 0); + EXPECT_NE(info.endDisplayX, 0); + EXPECT_NE(info.endDisplayY, 0); + EXPECT_NE(info.startWindowX, 0); + EXPECT_NE(info.startWindowY, 0); + EXPECT_NE(info.endWindowX, 0); + EXPECT_NE(info.endWindowY, 0); } class BaseSelectionInputMonitorTest : public testing::Test { @@ -159,6 +168,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) LEFT_BUTTON_UP(inputMonitor); auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) @@ -172,6 +183,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) @@ -187,6 +200,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor004, TestSize.Level1) @@ -232,12 +247,14 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor006, TestSize.Level1) LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); - + LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor007, TestSize.Level1) @@ -250,7 +267,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor007, TestSize.Level1) LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); - + WAIT_TIMEOUT(); LEFT_BUTTON_DOWN(inputMonitor); @@ -258,6 +275,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor007, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor008, TestSize.Level1) @@ -272,7 +291,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor008, TestSize.Level1) LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); - + WAIT_TIMEOUT(); LEFT_BUTTON_DOWN(inputMonitor); @@ -296,6 +315,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor009, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor010, TestSize.Level1) @@ -312,9 +333,10 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor010, TestSize.Level1) LEFT_BUTTON_MOVE(inputMonitor); LEFT_BUTTON_UP(inputMonitor); - auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor011, TestSize.Level1) @@ -331,6 +353,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor011, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor012, TestSize.Level1) @@ -346,6 +370,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor012, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor013, TestSize.Level1) @@ -363,6 +389,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor013, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor014, TestSize.Level1) @@ -383,6 +411,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor014, TestSize.Level1) auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); + auto info = inputMonitor->GetSelectionInfo(); + CHECK_INFO(info); } HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor015, TestSize.Level1) -- Gitee From ee557880205b4d3e76d5910d38981496fcda48be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Sat, 14 Jun 2025 15:01:15 +0800 Subject: [PATCH 83/93] =?UTF-8?q?ut=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../systemapi_js_test/PermissionJsTest.js | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/test/unittest/systemapi_js_test/PermissionJsTest.js b/test/unittest/systemapi_js_test/PermissionJsTest.js index 6907322..75aa313 100644 --- a/test/unittest/systemapi_js_test/PermissionJsTest.js +++ b/test/unittest/systemapi_js_test/PermissionJsTest.js @@ -14,9 +14,11 @@ */ import selectionManager from '@ohos.selectionInput.selectionManager' +import PanelInfo from '@ohos.selectionInput.SelectionPanel' import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from 'deccjsunit/index' describe("SystemApiJsTest", function () { + panel_: selectionManager.Panel = undefined; beforeAll(function () { console.info('beforeAll called'); }) @@ -26,19 +28,37 @@ describe("SystemApiJsTest", function () { }) /* - * @tc.name:SystemApi_destroyPanel_001 - * @tc.desc:verify SystemApi of destroyPanel + * @tc.name:SystemApi_createPanel_001 + * @tc.desc:verify SystemApi of createPanel * @tc.type: FUNC */ - // it("SystemApi_destroyPanel_001", 0, done => { - // console.info('----------------------SystemApi_destroyPanel_001---------------------------'); - // try { - // selectionManager.destroyPanel(selectionManager.panel); - // expect(false).assertTrue(); - // done(); - // } catch (err) { - // expect(err.code).assertEqual(SYSTEMAPI_DENIED_CODE); - // done(); - // } - // }); + it('SystemApi_createPanel_001', 0, async function (done) { + console.info('************* SystemApi_createPanel_001 Test start*************'); + try { + let panelInfo = { + panelType: 1, + x: 0, + y: 0, + width: 100, + height: 100 + } + selectionManager.createPanel(this.context, panelInfo).then((panel) => { + console.info('SystemApi_createPanel_001 promise success'); + this.panel_ = panel; + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* SystemApi_createPanel_001 Test end*************'); + }); + + }); \ No newline at end of file -- Gitee From 26ad5b7da796d1c2c28acad34c0b897216dc2abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Sat, 14 Jun 2025 15:28:08 +0800 Subject: [PATCH 84/93] =?UTF-8?q?ut=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../systemapi_js_test/PermissionJsTest.js | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/test/unittest/systemapi_js_test/PermissionJsTest.js b/test/unittest/systemapi_js_test/PermissionJsTest.js index 75aa313..6b1025c 100644 --- a/test/unittest/systemapi_js_test/PermissionJsTest.js +++ b/test/unittest/systemapi_js_test/PermissionJsTest.js @@ -60,5 +60,82 @@ describe("SystemApiJsTest", function () { console.info('************* SystemApi_createPanel_001 Test end*************'); }); + /* + * @tc.name:SystemApi_hide_001 + * @tc.desc:verify SystemApi of hide + * @tc.type: FUNC + */ + it('SystemApi_hide_001', 0, async function (done) { + console.info('************* SystemApi_hide_001 Test start*************'); + try { + this.panel_.hide().then(() => { + console.info('SystemApi_hide_001 promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* SystemApi_hide_001 Test end*************'); + }); + + /* + * @tc.name:SystemApi_startMoving_001 + * @tc.desc:verify SystemApi of startMoving + * @tc.type: FUNC + */ + it('SystemApi_startMoving_001', 0, async function (done) { + console.info('************* SystemApi_startMoving_001 Test start*************'); + try { + this.panel_.startMoving().then(() => { + console.info('SystemApi_startMoving_001 promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* SystemApi_startMoving_001 Test end*************'); + }); + + /* + * @tc.name:SystemApi_moveTo_001 + * @tc.desc:verify SystemApi of moveTo + * @tc.type: FUNC + */ + it('SystemApi_moveTo_001', 0, async function (done) { + console.info('************* SystemApi_moveTo_001 Test start*************'); + try { + let x = 100; + let y = 100; + this.panel_.moveTo(x, y).then(() => { + console.info('SystemApi_moveTo_001 promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* SystemApi_moveTo_001 Test end*************'); + }); + }); \ No newline at end of file -- Gitee From 7be4c03d9767947fc49e5fa5b2b018e19cdd01f9 Mon Sep 17 00:00:00 2001 From: fanzhe Date: Sat, 14 Jun 2025 16:38:33 +0800 Subject: [PATCH 85/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0js=E7=9A=84on,off?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: fanzhe Signed-off-by: Sunjiamei --- .../systemapi_js_test/PermissionJsTest.js | 123 +++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/test/unittest/systemapi_js_test/PermissionJsTest.js b/test/unittest/systemapi_js_test/PermissionJsTest.js index 6b1025c..e69b245 100644 --- a/test/unittest/systemapi_js_test/PermissionJsTest.js +++ b/test/unittest/systemapi_js_test/PermissionJsTest.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Huawei Device Co., Ltd. + * 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 @@ -138,4 +138,125 @@ describe("SystemApiJsTest", function () { }); + /* + * @tc.number selection_panel_test_off_Hide_001 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_Hide_001', 0, async function (done) { + console.info('************* selection_panel_test_off_Hide_001*************'); + try { + this.panel_.off('hidden', () => { + console.info(`panel on hidde success`); + expect(true).assertTrue(); + done(); + }); + } catch(error) { + console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_off_Hide_002 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_Hide_001', 0, async function (done) { + console.info('************* selection_panel_test_off_Hide_002*************'); + try { + this.panel_.off('hidden'); + } catch(error) { + console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_on_destroyed_001 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_on_destroyed_001', 0, async function (done) { + console.info('************* selection_panel_test_on_destroyed_001*************'); + try { + this.panel_.on('destroyed', () => { + console.info(`panel on hide success`); + expect(true).assertTrue(); + done(); + }); + } catch(error) { + console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_off_destroyed_001 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_destroyed_001', 0, async function (done) { + console.info('************* selection_panel_test_off_destroyed_001*************'); + try { + this.panel_.off('destroyed', () => { + console.info(`panel on destroyed success`); + expect(true).assertTrue(); + done(); + }); + } catch(error) { + console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_off_destroyed_002 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_destroyed_002', 0, async function (done) { + console.info('************* selection_panel_test_off_destroyed_002*************'); + try { + this.panel_.off('destroyed'); + } catch(error) { + console.info(`panel on "hidden fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.name:selection_panel_method_destroyPanel_001 + * @tc.desc:verify method of destroyPanel + * @tc.type: FUNC + */ + it('selection_panel_method_destroyPanel_001', 0, async function (done) { + console.info('************* selection_panel_method_destroyPanel_001 Test start*************'); + try { + selectionManager.destroyPanel(this.panel_).then(() => { + console.info('selection_panel_method_destroyPanel promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* selection_panel_method_destroyPanel Test end*************'); + }); }); \ No newline at end of file -- Gitee From c6f317be994e044299f57c10bf3de5e6d53483a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Sat, 14 Jun 2025 17:46:40 +0800 Subject: [PATCH 86/93] =?UTF-8?q?ut=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 2 +- test/unittest/BUILD.gn | 2 +- .../systemapi_js_test/PermissionJsTest.js | 289 +++++------------- 3 files changed, 86 insertions(+), 207 deletions(-) diff --git a/bundle.json b/bundle.json index 3044ecf..bff4413 100644 --- a/bundle.json +++ b/bundle.json @@ -63,7 +63,7 @@ "test": [ "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_service_unit_test", "//foundation/systemabilitymgr/selectionfwk/test/fuzztest:selection_service_fuzztest", - "//foundation/systemabilitymgr/selectionfwk/test/unittest:selcection_manager_ut" + "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_manager_ut" ] } } diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 7b3c9a7..c6e0a19 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -51,7 +51,7 @@ ohos_unittest("selection_service_unit_test") { subsystem_name = "systemabilitymgr" } -group("selcection_manager_ut") { +group("selection_manager_ut") { testonly = true deps = [ "systemapi_js_test:SystemApiJsTest", diff --git a/test/unittest/systemapi_js_test/PermissionJsTest.js b/test/unittest/systemapi_js_test/PermissionJsTest.js index e69b245..883cf98 100644 --- a/test/unittest/systemapi_js_test/PermissionJsTest.js +++ b/test/unittest/systemapi_js_test/PermissionJsTest.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2025 Huawei Device Co., Ltd. + * Copyright (C) 2024 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 @@ -18,245 +18,124 @@ import PanelInfo from '@ohos.selectionInput.SelectionPanel' import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from 'deccjsunit/index' describe("SystemApiJsTest", function () { - panel_: selectionManager.Panel = undefined; - beforeAll(function () { - console.info('beforeAll called'); - }) - - afterAll(function () { - console.info('AfterAll called'); - }) - - /* - * @tc.name:SystemApi_createPanel_001 - * @tc.desc:verify SystemApi of createPanel - * @tc.type: FUNC - */ - it('SystemApi_createPanel_001', 0, async function (done) { - console.info('************* SystemApi_createPanel_001 Test start*************'); - try { - let panelInfo = { - panelType: 1, - x: 0, - y: 0, - width: 100, - height: 100 - } - selectionManager.createPanel(this.context, panelInfo).then((panel) => { - console.info('SystemApi_createPanel_001 promise success'); - this.panel_ = panel; - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_createPanel_001 Test end*************'); - }); - - /* - * @tc.name:SystemApi_hide_001 - * @tc.desc:verify SystemApi of hide - * @tc.type: FUNC - */ - it('SystemApi_hide_001', 0, async function (done) { - console.info('************* SystemApi_hide_001 Test start*************'); - try { - this.panel_.hide().then(() => { - console.info('SystemApi_hide_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_hide_001 Test end*************'); - }); - - /* - * @tc.name:SystemApi_startMoving_001 - * @tc.desc:verify SystemApi of startMoving - * @tc.type: FUNC - */ - it('SystemApi_startMoving_001', 0, async function (done) { - console.info('************* SystemApi_startMoving_001 Test start*************'); - try { - this.panel_.startMoving().then(() => { - console.info('SystemApi_startMoving_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_startMoving_001 Test end*************'); - }); - - /* - * @tc.name:SystemApi_moveTo_001 - * @tc.desc:verify SystemApi of moveTo - * @tc.type: FUNC - */ - it('SystemApi_moveTo_001', 0, async function (done) { - console.info('************* SystemApi_moveTo_001 Test start*************'); - try { - let x = 100; - let y = 100; - this.panel_.moveTo(x, y).then(() => { - console.info('SystemApi_moveTo_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_moveTo_001 Test end*************'); - }); + panel_: selectionManager.Panel = undefined; + beforeAll(function () { + console.info('beforeAll called'); + }) + afterAll(function () { + console.info('AfterAll called'); + }) /* - * @tc.number selection_panel_test_off_Hide_001 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_Hide_001', 0, async function (done) { - console.info('************* selection_panel_test_off_Hide_001*************'); + * @tc.name:SystemApi_createPanel_001 + * @tc.desc:verify SystemApi of createPanel + * @tc.type: FUNC + */ + it('SystemApi_createPanel_001', 0, async function (done) { + console.info('************* SystemApi_createPanel_001 Test start*************'); try { - this.panel_.off('hidden', () => { - console.info(`panel on hidde success`); + let panelInfo = { + panelType: 1, + x: 0, + y: 0, + width: 100, + height: 100 + } + selectionManager.createPanel(this.context, panelInfo).then((panel) => { + console.info('SystemApi_createPanel_001 promise success'); + this.panel_ = panel; expect(true).assertTrue(); done(); - }); - } catch(error) { - console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); + }).catch((error) => { + console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); expect().assertFail(); done(); } + console.info('************* SystemApi_createPanel_001 Test end*************'); }); /* - * @tc.number selection_panel_test_off_Hide_002 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_Hide_001', 0, async function (done) { - console.info('************* selection_panel_test_off_Hide_002*************'); + * @tc.name:SystemApi_hide_001 + * @tc.desc:verify SystemApi of hide + * @tc.type: FUNC + */ + it('SystemApi_hide_001', 0, async function (done) { + console.info('************* SystemApi_hide_001 Test start*************'); try { - this.panel_.off('hidden'); - } catch(error) { - console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); + this.panel_.hide().then(() => { + console.info('SystemApi_hide_001 promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); expect().assertFail(); done(); } + console.info('************* SystemApi_hide_001 Test end*************'); }); /* - * @tc.number selection_panel_test_on_destroyed_001 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_on_destroyed_001', 0, async function (done) { - console.info('************* selection_panel_test_on_destroyed_001*************'); + * @tc.name:SystemApi_startMoving_001 + * @tc.desc:verify SystemApi of startMoving + * @tc.type: FUNC + */ + it('SystemApi_startMoving_001', 0, async function (done) { + console.info('************* SystemApi_startMoving_001 Test start*************'); try { - this.panel_.on('destroyed', () => { - console.info(`panel on hide success`); + this.panel_.startMoving().then(() => { + console.info('SystemApi_startMoving_001 promise success'); expect(true).assertTrue(); done(); - }); - } catch(error) { - console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); + }).catch((error) => { + console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); expect().assertFail(); done(); } + console.info('************* SystemApi_startMoving_001 Test end*************'); }); /* - * @tc.number selection_panel_test_off_destroyed_001 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_destroyed_001', 0, async function (done) { - console.info('************* selection_panel_test_off_destroyed_001*************'); + * @tc.name:SystemApi_moveTo_001 + * @tc.desc:verify SystemApi of moveTo + * @tc.type: FUNC + */ + it('SystemApi_moveTo_001', 0, async function (done) { + console.info('************* SystemApi_moveTo_001 Test start*************'); try { - this.panel_.off('destroyed', () => { - console.info(`panel on destroyed success`); + let x = 100; + let y = 100; + this.panel_.moveTo(x, y).then(() => { + console.info('SystemApi_moveTo_001 promise success'); expect(true).assertTrue(); done(); - }); - } catch(error) { - console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); + }).catch((error) => { + console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); expect().assertFail(); done(); } + console.info('************* SystemApi_moveTo_001 Test end*************'); }); - /* - * @tc.number selection_panel_test_off_destroyed_002 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_destroyed_002', 0, async function (done) { - console.info('************* selection_panel_test_off_destroyed_002*************'); - try { - this.panel_.off('destroyed'); - } catch(error) { - console.info(`panel on "hidden fail result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - }); - /* - * @tc.name:selection_panel_method_destroyPanel_001 - * @tc.desc:verify method of destroyPanel - * @tc.type: FUNC - */ - it('selection_panel_method_destroyPanel_001', 0, async function (done) { - console.info('************* selection_panel_method_destroyPanel_001 Test start*************'); - try { - selectionManager.destroyPanel(this.panel_).then(() => { - console.info('selection_panel_method_destroyPanel promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* selection_panel_method_destroyPanel Test end*************'); - }); }); \ No newline at end of file -- Gitee From d971db038e5e898b24af536b4dc1f2a25df2602f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=B7=E9=A6=99=E5=A8=9F?= <1799721749@qq.com> Date: Sat, 14 Jun 2025 17:58:38 +0800 Subject: [PATCH 87/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0js=E7=9A=84on,off?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../systemapi_js_test/PermissionJsTest.js | 122 +++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/test/unittest/systemapi_js_test/PermissionJsTest.js b/test/unittest/systemapi_js_test/PermissionJsTest.js index 883cf98..676e16b 100644 --- a/test/unittest/systemapi_js_test/PermissionJsTest.js +++ b/test/unittest/systemapi_js_test/PermissionJsTest.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Huawei Device Co., Ltd. + * 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 @@ -137,5 +137,125 @@ describe("SystemApiJsTest", function () { console.info('************* SystemApi_moveTo_001 Test end*************'); }); + /* + * @tc.number selection_panel_test_off_Hide_001 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_Hide_001', 0, async function (done) { + console.info('************* selection_panel_test_off_Hide_001*************'); + try { + this.panel_.off('hidden', () => { + console.info(`panel on hidde success`); + expect(true).assertTrue(); + done(); + }); + } catch(error) { + console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_off_Hide_002 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_Hide_001', 0, async function (done) { + console.info('************* selection_panel_test_off_Hide_002*************'); + try { + this.panel_.off('hidden'); + } catch(error) { + console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_on_destroyed_001 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_on_destroyed_001', 0, async function (done) { + console.info('************* selection_panel_test_on_destroyed_001*************'); + try { + this.panel_.on('destroyed', () => { + console.info(`panel on hide success`); + expect(true).assertTrue(); + done(); + }); + } catch(error) { + console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_off_destroyed_001 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_destroyed_001', 0, async function (done) { + console.info('************* selection_panel_test_off_destroyed_001*************'); + try { + this.panel_.off('destroyed', () => { + console.info(`panel on destroyed success`); + expect(true).assertTrue(); + done(); + }); + } catch(error) { + console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + + /* + * @tc.number selection_panel_test_off_destroyed_002 + * @tc.name Test whether the register the callback of the panel method is valid. + * @tc.desc Function test + * @tc.level 2 + */ + it('selection_panel_test_off_destroyed_002', 0, async function (done) { + console.info('************* selection_panel_test_off_destroyed_002*************'); + try { + this.panel_.off('destroyed'); + } catch(error) { + console.info(`panel on "hidden fail result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + }); + /* + * @tc.name:selection_panel_method_destroyPanel_001 + * @tc.desc:verify method of destroyPanel + * @tc.type: FUNC + */ + it('selection_panel_method_destroyPanel_001', 0, async function (done) { + console.info('************* selection_panel_method_destroyPanel_001 Test start*************'); + try { + selectionManager.destroyPanel(this.panel_).then(() => { + console.info('selection_panel_method_destroyPanel promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* selection_panel_method_destroyPanel Test end*************'); + }); }); \ No newline at end of file -- Gitee From 2209144c78fb809b0f84706550065e29cd00db3b Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Sat, 14 Jun 2025 18:17:22 +0800 Subject: [PATCH 88/93] =?UTF-8?q?=E5=A2=9E=E5=8A=A0UT=E6=B5=8B=E8=AF=95set?= =?UTF-8?q?UiContent=E3=80=81show=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../systemapi_js_test/PermissionJsTest.js | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/unittest/systemapi_js_test/PermissionJsTest.js b/test/unittest/systemapi_js_test/PermissionJsTest.js index 676e16b..b4e169c 100644 --- a/test/unittest/systemapi_js_test/PermissionJsTest.js +++ b/test/unittest/systemapi_js_test/PermissionJsTest.js @@ -60,6 +60,84 @@ describe("SystemApiJsTest", function () { console.info('************* SystemApi_createPanel_001 Test end*************'); }); + /* + * @tc.name:selection_panel_setUiContent_001 + * @tc.desc:verify method of setUiContent + * @tc.type: FUNC + */ + it('selection_panel_setUiContent_001', 0, async function (done) { + console.info('************* selection_panel_setUiContent_001 Test start*************'); + try { + this.panel_.setUiContent('pages/Index') + .then(() => { + console.info('selection_panel_setUiContent_001 promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`selection_panel_setUiContent_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`selection_panel_setUiContent_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* selection_panel_setUiContent_001 Test end*************'); + }); + + /* + * @tc.name:selection_panel_setUiContent_002 + * @tc.desc:verify method of setUiContent + * @tc.type: FUNC + */ + it('selection_panel_setUiContent_002', 0, async function (done) { + console.info('************* selection_panel_setUiContent_002 Test start*************'); + try { + this.panel_.setUiContent('pages/Panel') + .then(() => { + console.info('selection_panel_setUiContent_002 promise success'); + expect(false).assertTrue(); + done(); + }).catch((error) => { + console.info(`selection_panel_setUiContent_002 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`selection_panel_setUiContent_002 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* selection_panel_setUiContent_002 Test end*************'); + }); + + /* + * @tc.name:selection_panel_show_001 + * @tc.desc:verify method of setUiContent + * @tc.type: FUNC + */ + it('selection_panel_show_001', 0, async function (done) { + console.info('************* selection_panel_show_001 Test start*************'); + try { + this.panel_.show() + .then(() => { + console.info('selection_panel_show_001 promise success'); + expect(true).assertTrue(); + done(); + }).catch((error) => { + console.info(`selection_panel_show_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + }) + } catch (error) { + console.info(`selection_panel_show_001 result: ${JSON.stringify(error)}`); + expect().assertFail(); + done(); + } + console.info('************* selection_panel_show_001 Test end*************'); + }); + /* * @tc.name:SystemApi_hide_001 * @tc.desc:verify SystemApi of hide -- Gitee From 1901cec389f6a289c547a4dfbf7550ac503c371c Mon Sep 17 00:00:00 2001 From: wuyunxun Date: Tue, 17 Jun 2025 09:20:44 +0800 Subject: [PATCH 89/93] =?UTF-8?q?unittest=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../unittest/selection_input_monitor_test.cpp | 64 +++++++++---------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index 6579d5b..00e2ea8 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ +#include "gtest/gtest.h" #include #include -#include "gtest/gtest.h" #include "screenlock_manager.h" #include "selection_input_monitor.h" @@ -32,7 +32,7 @@ struct EventStruct { std::shared_ptr GetPointerEvent() { - static std::shared_ptr pointEvent = PointerEvent::Create(); + std::shared_ptr pointEvent = PointerEvent::Create(); PointerEvent::PointerItem pointerItem; pointerItem.SetDisplayX(100); pointerItem.SetDisplayY(200); @@ -61,10 +61,17 @@ void LEFT_BUTTON_UP(std::shared_ptr handler) handler->OnInputEvent(pointEvent); } +template +void LEFT_BUTTON_CLICK(std::shared_ptr handler) +{ + LEFT_BUTTON_DOWN(handler); + LEFT_BUTTON_UP(handler); +} + template void RIGHT_BUTTON_DOWN(std::shared_ptr handler) { - std::shared_ptr pointEvent = PointerEvent::Create(); + std::shared_ptr pointEvent = GetPointerEvent(); pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_RIGHT); pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_DOWN); handler->OnInputEvent(pointEvent); @@ -73,7 +80,7 @@ void RIGHT_BUTTON_DOWN(std::shared_ptr handler) template void RIGHT_BUTTON_UP(std::shared_ptr handler) { - std::shared_ptr pointEvent = PointerEvent::Create(); + std::shared_ptr pointEvent = GetPointerEvent(); pointEvent->SetButtonId(PointerEvent::MOUSE_BUTTON_RIGHT); pointEvent->SetPointerAction(PointerEvent::POINTER_ACTION_BUTTON_UP); handler->OnInputEvent(pointEvent); @@ -114,14 +121,14 @@ void WAIT_TIMEOUT() void CHECK_INFO(const SelectionInfo& info) { EXPECT_NE(info.selectionType, 0); - EXPECT_NE(info.startDisplayX, 0); - EXPECT_NE(info.startDisplayY, 0); - EXPECT_NE(info.endDisplayX, 0); - EXPECT_NE(info.endDisplayY, 0); - EXPECT_NE(info.startWindowX, 0); - EXPECT_NE(info.startWindowY, 0); - EXPECT_NE(info.endWindowX, 0); - EXPECT_NE(info.endWindowY, 0); + EXPECT_GT(info.startDisplayX, 0); + EXPECT_GT(info.startDisplayY, 0); + EXPECT_GT(info.endDisplayX, 0); + EXPECT_GT(info.endDisplayY, 0); + EXPECT_GT(info.startWindowX, 0); + EXPECT_GT(info.startWindowY, 0); + EXPECT_GT(info.endWindowX, 0); + EXPECT_GT(info.endWindowY, 0); } class BaseSelectionInputMonitorTest : public testing::Test { @@ -176,10 +183,8 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) { std::cout << " SelectInputMonitor002 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); - LEFT_BUTTON_UP(inputMonitor); - LEFT_BUTTON_DOWN(inputMonitor); - LEFT_BUTTON_UP(inputMonitor); + LEFT_BUTTON_CLICK(inputMonitor); + LEFT_BUTTON_CLICK(inputMonitor); auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); @@ -191,12 +196,9 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) { std::cout << " SelectInputMonitor003 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); - LEFT_BUTTON_UP(inputMonitor); - LEFT_BUTTON_DOWN(inputMonitor); - LEFT_BUTTON_UP(inputMonitor); - LEFT_BUTTON_DOWN(inputMonitor); - LEFT_BUTTON_UP(inputMonitor); + LEFT_BUTTON_CLICK(inputMonitor); + LEFT_BUTTON_CLICK(inputMonitor); + LEFT_BUTTON_CLICK(inputMonitor); auto ret = inputMonitor->IsTextSelected(); ASSERT_EQ(ret, true); @@ -222,7 +224,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor005, TestSize.Level1) { std::cout << " SelectInputMonitor005 start " << std::endl; - // double click LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -239,7 +240,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor006, TestSize.Level1) { std::cout << " SelectInputMonitor006 start " << std::endl; - // triple click LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -261,7 +261,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor007, TestSize.Level1) { std::cout << " SelectInputMonitor007 start " << std::endl; - // triple click LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -283,7 +282,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor008, TestSize.Level1) { std::cout << " SelectInputMonitor008 start " << std::endl; - // triple click LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -308,7 +306,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor009, TestSize.Level1) LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); - // move LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_MOVE(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -343,11 +340,10 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor011, TestSize.Level1) { std::cout << " SelectInputMonitor011 start " << std::endl; - // move LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_MOVE(inputMonitor); LEFT_BUTTON_UP(inputMonitor); - // ctrl + CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -360,7 +356,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor011, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor012, TestSize.Level1) { std::cout << " SelectInputMonitor012 start " << std::endl; - // ctrl + CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -377,7 +373,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor012, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor013, TestSize.Level1) { std::cout << " SelectInputMonitor013 start " << std::endl; - // ctrl + CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -396,7 +392,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor013, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor014, TestSize.Level1) { std::cout << " SelectInputMonitor014 start " << std::endl; - // ctrl + CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -418,7 +414,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor014, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor015, TestSize.Level1) { std::cout << " SelectInputMonitor015 start " << std::endl; - // ctrl + CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -429,7 +425,7 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor015, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor016, TestSize.Level1) { std::cout << " SelectInputMonitor016 start " << std::endl; - // ctrl + CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); -- Gitee From cd3207c21fc4a40e28501b026b8a1e7417d5c887 Mon Sep 17 00:00:00 2001 From: Gao Rui Date: Wed, 2 Jul 2025 10:18:46 +0800 Subject: [PATCH 90/93] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 40 +- common/BUILD.gn | 1 + common/callback_handler.cpp | 2 + common/callback_handler.h | 3 + common/selection_data_inner.h | 56 + common/selection_js_utils.h | 2 +- common/selectionfwk_js_utils.cpp | 4 +- common/util.cpp | 239 +-- common/util.h | 264 +-- etc/init/selection_service.cfg | 2 + etc/para/selection.para | 34 +- frameworks/js/napi/selection_ability/BUILD.gn | 4 +- .../js/napi/selection_ability/js_panel.cpp | 72 +- .../js/napi/selection_ability/js_panel.h | 1 + .../js_selection_engine_setting.cpp | 77 +- .../js_selection_engine_setting.h | 5 +- .../selection_ability/panel_listener_impl.cpp | 5 +- .../napi/selection_extension_context/BUILD.gn | 122 +- .../selection_extension_context.js | 52 +- .../selection_extension_context_module.cpp | 110 +- frameworks/js/napi/selection_panel/BUILD.gn | 59 + .../selection_panel/js_selection_panel.cpp | 49 + .../napi/selection_panel/js_selection_panel.h | 34 + .../selection_panel_module.cpp | 47 + frameworks/native/selection_ability/BUILD.gn | 43 +- .../selection_ability/include/panel_common.h | 2 +- .../selection_ability/include/panel_info.h | 45 +- .../include/selection_ability.h | 2 - .../include/selection_app_validator.h | 42 + .../include/selection_attribute.h | 10 +- .../include/selection_listener_impl.h | 3 +- .../include/selection_panel.h | 14 +- .../include/selection_panel_manager.h | 51 + .../selection_ability/include/task_manager.h | 2 +- .../src/selection_ability.cpp | 30 +- .../src/selection_app_validator.cpp | 37 + .../src/selection_listener_impl.cpp | 47 +- .../selection_ability/src/selection_panel.cpp | 186 +- .../src/selection_panel_manager.cpp | 73 + .../selection_client/selection_client.cpp | 50 + .../include/selection_extension_context.h | 12 + .../src/js_selection_extension.cpp | 41 +- .../src/js_selection_extension_context.cpp | 52 + .../src/selection_extension_context.cpp | 13 + .../src/selection_extension_module_loader.cpp | 2 +- interfaces/idl/BUILD.gn | 136 ++ interfaces/idl/ISelectionListener.idl | 22 + interfaces/idl/ISelectionService.idl | 22 + .../inner_kits/selection_client/BUILD.gn | 75 + .../include/selection_client.h | 27 + .../selection_client/include/visibility.h | 23 + .../selection_client.versionscript | 19 + service/BUILD.gn | 47 +- .../include/focus_monitor_manager.h | 11 +- .../src/focus_change_listener.cpp | 10 +- .../src/focus_monitor_manager.cpp | 37 +- .../include/db_selection_config_repository.h | 2 +- service/include/selection_app_validator.h | 41 + service/include/selection_common.h | 21 + service/include/selection_config.h | 32 +- service/include/selection_config_database.h | 5 +- service/include/selection_input_monitor.h | 35 +- service/include/selection_service.h | 21 +- .../include/sys_selection_config_repository.h | 12 +- service/libselection_service.map | 2 +- .../src/db_selection_config_repository.cpp | 32 +- service/src/selection_app_validator.cpp | 79 + service/src/selection_common.cpp | 36 + service/src/selection_config.cpp | 52 +- service/src/selection_config_comparator.cpp | 23 +- service/src/selection_config_database.cpp | 51 +- service/src/selection_input_monitor.cpp | 330 +-- service/src/selection_service.cpp | 198 +- .../src/sys_selection_config_repository.cpp | 85 +- test/fuzztest/BUILD.gn | 1 + .../selectioninputability_fuzzer/BUILD.gn | 1 - .../selectioninputability_fuzzer.cpp | 4 + .../selectioninputlistener_fuzzer/BUILD.gn | 70 + .../selectioninputlistener_fuzzer/corpus/init | 14 + .../selectioninputlistener_fuzzer/project.xml | 25 + .../selectioninputlistener_fuzzer.cpp | 107 + .../selectioninputlistener_fuzzer.h | 19 + test/unittest/BUILD.gn | 7 +- test/unittest/resource/ohos_test/BUILD.gn | 19 + .../unittest/resource/ohos_test/ohos_test.xml | 27 + .../selection_config_comparator_test.cpp | 72 +- .../unittest/selection_input_monitor_test.cpp | 17 +- .../BUILD.gn | 21 + .../InvalidOperationTest.js | 76 + .../config.json | 63 + .../selection_manager_js_test/BUILD.gn | 21 + .../PermissionJsTest.js | 1848 +++++++++++++++++ .../selection_manager_js_test/config.json | 63 + utils/include/selection_log.h | 6 +- 94 files changed, 4807 insertions(+), 1201 deletions(-) create mode 100644 frameworks/js/napi/selection_panel/BUILD.gn create mode 100644 frameworks/js/napi/selection_panel/js_selection_panel.cpp create mode 100644 frameworks/js/napi/selection_panel/js_selection_panel.h create mode 100644 frameworks/js/napi/selection_panel/selection_panel_module.cpp create mode 100644 frameworks/native/selection_ability/include/selection_app_validator.h create mode 100644 frameworks/native/selection_ability/include/selection_panel_manager.h create mode 100644 frameworks/native/selection_ability/src/selection_app_validator.cpp create mode 100644 frameworks/native/selection_ability/src/selection_panel_manager.cpp create mode 100644 frameworks/native/selection_client/selection_client.cpp create mode 100644 interfaces/idl/BUILD.gn create mode 100644 interfaces/idl/ISelectionListener.idl create mode 100644 interfaces/idl/ISelectionService.idl create mode 100644 interfaces/inner_kits/selection_client/BUILD.gn create mode 100644 interfaces/inner_kits/selection_client/include/selection_client.h create mode 100644 interfaces/inner_kits/selection_client/include/visibility.h create mode 100644 interfaces/inner_kits/selection_client/selection_client.versionscript create mode 100644 service/include/selection_app_validator.h create mode 100644 service/include/selection_common.h create mode 100644 service/src/selection_app_validator.cpp create mode 100644 service/src/selection_common.cpp create mode 100644 test/fuzztest/selectioninputlistener_fuzzer/BUILD.gn create mode 100644 test/fuzztest/selectioninputlistener_fuzzer/corpus/init create mode 100644 test/fuzztest/selectioninputlistener_fuzzer/project.xml create mode 100644 test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.cpp create mode 100644 test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.h create mode 100644 test/unittest/resource/ohos_test/BUILD.gn create mode 100644 test/unittest/resource/ohos_test/ohos_test.xml create mode 100644 test/unittest/selection_manager_invalid_operation_js_test/BUILD.gn create mode 100644 test/unittest/selection_manager_invalid_operation_js_test/InvalidOperationTest.js create mode 100644 test/unittest/selection_manager_invalid_operation_js_test/config.json create mode 100644 test/unittest/selection_manager_js_test/BUILD.gn create mode 100644 test/unittest/selection_manager_js_test/PermissionJsTest.js create mode 100644 test/unittest/selection_manager_js_test/config.json diff --git a/bundle.json b/bundle.json index bff4413..ef2950f 100644 --- a/bundle.json +++ b/bundle.json @@ -1,17 +1,21 @@ { - "name": "@ohos/selection_service", + "name": "@ohos/selectionfwk", "description": "Provide word selection capabilities", "version": "1.0", "license": "Apache License 2.0", "segment": { - "destPath": "foundation/systemabilitymgr/selection_service" + "destPath": "foundation/systemabilitymgr/selectionfwk" }, "component": { "name": "selectionfwk", "subsystem": "systemabilitymgr", - "syscap": [], + "syscap": [ + "SystemCapability.SelectionInput.Selection" + ], "features": [], "adapted_system_type": [ + "mini", + "small", "standard" ], "rom": "5831KB", @@ -21,7 +25,6 @@ "c_utils", "eventhandler", "ipc", - "napi", "safwk", "hilog", "hitrace", @@ -31,6 +34,7 @@ "napi", "ability_base", "ability_runtime", + "access_token", "window_manager", "pasteboard", "relational_store", @@ -40,7 +44,12 @@ "ffrt", "config_policy", "os_account", - "screenlock_mgr" + "cJSON", + "common_event_service", + "hicollie", + "hisysevent", + "memmgr", + "resource_schedule_service" ], "third_party": [ ] @@ -53,17 +62,28 @@ "//foundation/systemabilitymgr/selectionfwk/etc/para:selection_para_dac", "//foundation/systemabilitymgr/selectionfwk/service:selection_service", "//foundation/systemabilitymgr/selectionfwk/sa_profile:selection_service_sa_profile", + "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_panel:selectionpanel_napi", "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_extension_ability:selectionextensionability_napi", "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_extension_context:selectionextensioncontext_napi", "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_extension:selection_extension_ability_native", "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_ability:selectionmanager_napi", - "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_ability:selection_ability" + "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_ability:selection_ability", + "//foundation/systemabilitymgr/selectionfwk/interfaces/inner_kits/selection_client:selection_client" + ], + "inner_kits": [ + { + "name": "//foundation/systemabilitymgr/selectionfwk/interfaces/inner_kits/selection_client:selection_client", + "header": { + "header_files": [ + "selection_client.h" + ], + "header_base": "//foundation/systemabilitymgr/selectionfwk/interfaces/inner_kits/selection_client/include" + } + } ], - "inner_kits": [], "test": [ - "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_service_unit_test", - "//foundation/systemabilitymgr/selectionfwk/test/fuzztest:selection_service_fuzztest", - "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_manager_ut" + "//foundation/systemabilitymgr/selectionfwk/test/unittest:selection_manager_ut", + "//foundation/systemabilitymgr/selectionfwk/test/fuzztest:selection_service_fuzztest" ] } } diff --git a/common/BUILD.gn b/common/BUILD.gn index a84c3bd..1ea8add 100644 --- a/common/BUILD.gn +++ b/common/BUILD.gn @@ -55,6 +55,7 @@ ohos_static_library("selection_common") { external_deps = [ "eventhandler:libeventhandler", "napi:ace_napi", + "hilog:libhilog", "hitrace:hitrace_meter", "hitrace:libhitracechain", "ability_base:want", diff --git a/common/callback_handler.cpp b/common/callback_handler.cpp index 4196a5c..a4b3cde 100644 --- a/common/callback_handler.cpp +++ b/common/callback_handler.cpp @@ -43,6 +43,8 @@ void JsCallbackHandler::Execute(const std::shared_ptr &object, auto status = napi_call_function(object->env_, global, callback, argContainer.argc, argv, &output); if (status != napi_ok) { output = nullptr; + SELECTION_HILOGE("napi_call_function is failed!"); + return; } } } // namespace SelectionFwk diff --git a/common/callback_handler.h b/common/callback_handler.h index 3655ecb..d5b55ef 100644 --- a/common/callback_handler.h +++ b/common/callback_handler.h @@ -51,6 +51,9 @@ public: { SelectionMethodSyncTrace tracer("Traverse callback with output"); for (const auto &object : objects) { + if (object == nullptr) { + break; + } JsUtil::ScopeGuard scopeGuard(object->env_); napi_value jsOutput = nullptr; Execute(object, argContainer, jsOutput); diff --git a/common/selection_data_inner.h b/common/selection_data_inner.h index eff59e4..718b230 100644 --- a/common/selection_data_inner.h +++ b/common/selection_data_inner.h @@ -111,6 +111,62 @@ struct SelectionInfoData : public Parcelable { } }; +enum class FocusChangeSource : uint32_t { + WindowManager, + InputManager, +}; + +class SelectionFocusChangeInfo : public Parcelable { +public: + SelectionFocusChangeInfo() = default; + SelectionFocusChangeInfo(uint32_t winId, uint64_t displayId, int32_t pid, int32_t uid, uint32_t type, + bool isFocused, FocusChangeSource source): windowId_(winId), displayId_(displayId), pid_(pid), uid_(uid), + windowType_(type), isFocused_(isFocused), source_(source) {}; + + ~SelectionFocusChangeInfo() = default; + + virtual bool Marshalling(Parcel& parcel) const + { + bool ret = parcel.WriteInt32(windowId_) && parcel.WriteUint64(displayId_) && + parcel.WriteInt32(pid_) && parcel.WriteInt32(uid_) && + parcel.WriteUint32(static_cast(windowType_)) && + parcel.WriteBool(isFocused_) && + parcel.WriteUint32(static_cast(source_)); + return ret; + } + + static SelectionFocusChangeInfo* Unmarshalling(Parcel& parcel) + { + auto focusChangeInfo = new SelectionFocusChangeInfo(); + bool res = parcel.ReadInt32(focusChangeInfo->windowId_) && parcel.ReadUint64(focusChangeInfo->displayId_) && + parcel.ReadInt32(focusChangeInfo->pid_) && parcel.ReadInt32(focusChangeInfo->uid_) && + parcel.ReadUint32(focusChangeInfo->windowType_) && + parcel.ReadBool(focusChangeInfo->isFocused_); + if (!res) { + delete focusChangeInfo; + return nullptr; + } + focusChangeInfo->source_ = static_cast(parcel.ReadUint32()); + return focusChangeInfo; + } + + std::string ToString() const + { + std::ostringstream oss; + oss << "SelectionFocusChangeInfo { windowId: " << windowId_ << ", displayId: \"" << displayId_ << + ", windowType: " << windowType_ << ", isFocused: " << isFocused_ << + ", source_: " << static_cast(source_) << "}"; + return oss.str(); + } + + int32_t windowId_ = -1; + uint64_t displayId_ = 0; + int32_t pid_ = -1; + int32_t uid_ = -1; + uint32_t windowType_ = 1; + bool isFocused_ = false; + FocusChangeSource source_ = FocusChangeSource::WindowManager; +}; } } diff --git a/common/selection_js_utils.h b/common/selection_js_utils.h index 675f9f5..379504a 100644 --- a/common/selection_js_utils.h +++ b/common/selection_js_utils.h @@ -34,7 +34,7 @@ enum SFErrorCode : int32_t { EXCEPTION_SUCCESS = 0, EXCEPTION_PARAMCHECK = 401, EXCEPTION_SELECTION_SERVICE = 33600001, - EXCEPTION_PANEL_DESTORYED = 33600002, + EXCEPTION_PANEL_DESTROYED = 33600002, EXCEPTION_INVALID_OPERATION = 33600003, }; diff --git a/common/selectionfwk_js_utils.cpp b/common/selectionfwk_js_utils.cpp index f9387c0..6154274 100644 --- a/common/selectionfwk_js_utils.cpp +++ b/common/selectionfwk_js_utils.cpp @@ -24,14 +24,14 @@ constexpr size_t ARGC_MAX = 6; const std::map JsUtils::ERROR_CODE_MAP = { { ErrorCode::ERROR_PARAMETER_CHECK_FAILED, EXCEPTION_PARAMCHECK }, { ErrorCode::ERROR_SELECTION_SERVICE, EXCEPTION_SELECTION_SERVICE }, - { ErrorCode::ERROR_PANEL_DESTORYED, EXCEPTION_PANEL_DESTORYED }, + { ErrorCode::ERROR_PANEL_DESTROYED, EXCEPTION_PANEL_DESTROYED }, { ErrorCode::ERROR_INVALID_OPERATION, EXCEPTION_INVALID_OPERATION } }; const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { { EXCEPTION_PARAMCHECK, "The parameters check fails." }, { EXCEPTION_SELECTION_SERVICE, "Selection service exception." }, - { EXCEPTION_PANEL_DESTORYED, "This selection window has been destroyed." }, + { EXCEPTION_PANEL_DESTROYED, "This selection window has been destroyed." }, { EXCEPTION_INVALID_OPERATION, "Invalid operation. The selection app is not valid." } }; diff --git a/common/util.cpp b/common/util.cpp index 742be22..a1c25c2 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -1,119 +1,122 @@ -/* - * 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 "util.h" - -#include "string_ex.h" - -namespace OHOS { -namespace SelectionFwk { -constexpr int64_t JS_NUMBER_MAX_VALUE = (1LL << 53) - 1; -napi_valuetype JsUtil::GetType(napi_env env, napi_value in) -{ - napi_valuetype valueType = napi_undefined; - napi_typeof(env, in, &valueType); - return valueType; -} -bool JsUtil::HasProperty(napi_env env, napi_value object, const std::string &property) -{ - bool hasProperty = false; - napi_status status = napi_has_named_property(env, object, property.c_str(), &hasProperty); - if (status == napi_ok && hasProperty) { - return true; - } - return false; -} -bool JsUtil::GetValue(napi_env env, napi_value in, std::string &out) -{ - size_t size = 0; - auto status = napi_get_value_string_utf8(env, in, nullptr, 0, &size); - if (status != napi_ok) { - return false; - } - out.resize(size + 1, 0); - status = napi_get_value_string_utf8(env, in, const_cast(out.data()), size + 1, &size); - out.resize(size); - return status == napi_ok; -} - -bool JsUtil::GetValue(napi_env env, napi_value in, std::u16string &out) -{ - std::string tempOut; - bool ret = GetValue(env, in, tempOut); - if (ret) { - out = Str8ToStr16(tempOut); - } - return ret; -} -bool JsUtil::GetValue(napi_env env, napi_value in, int32_t &out) -{ - return napi_get_value_int32(env, in, &out) == napi_ok; -} -bool JsUtil::GetValue(napi_env env, napi_value in, uint32_t &out) -{ - return napi_get_value_uint32(env, in, &out) == napi_ok; -} -bool JsUtil::GetValue(napi_env env, napi_value in, int64_t &out) -{ - return napi_get_value_int64(env, in, &out) == napi_ok; -} -bool JsUtil::GetValue(napi_env env, napi_value in, bool &out) -{ - return napi_get_value_bool(env, in, &out) == napi_ok; -} -bool JsUtil::GetValue(napi_env env, napi_value in, double &out) -{ - return napi_get_value_double(env, in, &out) == napi_ok; -} -napi_value JsUtil::GetValue(napi_env env, napi_value in) -{ - return in; -} -napi_value JsUtil::GetValue(napi_env env, const std::string &in) -{ - napi_value out = nullptr; - napi_create_string_utf8(env, in.c_str(), in.length(), &out); - return out; -} -napi_value JsUtil::GetValue(napi_env env, int32_t in) -{ - napi_value out = nullptr; - napi_create_int32(env, in, &out); - return out; -} -napi_value JsUtil::GetValue(napi_env env, uint32_t in) -{ - napi_value out = nullptr; - napi_create_uint32(env, in, &out); - return out; -} -napi_value JsUtil::GetValue(napi_env env, int64_t in) -{ - if (in > JS_NUMBER_MAX_VALUE) { - // cannot exceed the range of js - return nullptr; - } - napi_value out = nullptr; - napi_create_int64(env, in, &out); - return out; -} -napi_value JsUtil::GetValue(napi_env env, bool in) -{ - napi_value out = nullptr; - napi_get_boolean(env, in, &out); - return out; -} -} // namespace SelectionFwk +/* + * 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 "util.h" +#include "selection_log.h" +#include "string_ex.h" + +namespace OHOS { +namespace SelectionFwk { +constexpr int64_t JS_NUMBER_MAX_VALUE = (1LL << 53) - 1; +napi_valuetype JsUtil::GetType(napi_env env, napi_value in) +{ + napi_valuetype valueType = napi_undefined; + napi_status status = napi_typeof(env, in, &valueType); + if (status != napi_ok) { + SELECTION_HILOGE("get value of valueType failed."); + } + return valueType; +} +bool JsUtil::HasProperty(napi_env env, napi_value object, const std::string &property) +{ + bool hasProperty = false; + napi_status status = napi_has_named_property(env, object, property.c_str(), &hasProperty); + if (status == napi_ok && hasProperty) { + return true; + } + return false; +} +bool JsUtil::GetValue(napi_env env, napi_value in, std::string &out) +{ + size_t size = 0; + auto status = napi_get_value_string_utf8(env, in, nullptr, 0, &size); + if (status != napi_ok) { + return false; + } + out.resize(size + 1, 0); + status = napi_get_value_string_utf8(env, in, const_cast(out.data()), size + 1, &size); + out.resize(size); + return status == napi_ok; +} + +bool JsUtil::GetValue(napi_env env, napi_value in, std::u16string &out) +{ + std::string tempOut; + bool ret = GetValue(env, in, tempOut); + if (ret) { + out = Str8ToStr16(tempOut); + } + return ret; +} +bool JsUtil::GetValue(napi_env env, napi_value in, int32_t &out) +{ + return napi_get_value_int32(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, uint32_t &out) +{ + return napi_get_value_uint32(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, int64_t &out) +{ + return napi_get_value_int64(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, bool &out) +{ + return napi_get_value_bool(env, in, &out) == napi_ok; +} +bool JsUtil::GetValue(napi_env env, napi_value in, double &out) +{ + return napi_get_value_double(env, in, &out) == napi_ok; +} +napi_value JsUtil::GetValue(napi_env env, napi_value in) +{ + return in; +} +napi_value JsUtil::GetValue(napi_env env, const std::string &in) +{ + napi_value out = nullptr; + napi_create_string_utf8(env, in.c_str(), in.length(), &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, int32_t in) +{ + napi_value out = nullptr; + napi_create_int32(env, in, &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, uint32_t in) +{ + napi_value out = nullptr; + napi_create_uint32(env, in, &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, int64_t in) +{ + if (in < -JS_NUMBER_MAX_VALUE || in > JS_NUMBER_MAX_VALUE) { + // cannot exceed the range of js + return nullptr; + } + napi_value out = nullptr; + napi_create_int64(env, in, &out); + return out; +} +napi_value JsUtil::GetValue(napi_env env, bool in) +{ + napi_value out = nullptr; + napi_get_boolean(env, in, &out); + return out; +} +} // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/common/util.h b/common/util.h index 6e50208..5c43794 100644 --- a/common/util.h +++ b/common/util.h @@ -1,131 +1,133 @@ -/* - * 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_UTIL_H -#define OHOS_UTIL_H -#include -#include - -#include "napi/native_api.h" -#include "napi/native_node_api.h" -namespace OHOS { -namespace SelectionFwk { -class JsUtil { -public: - static napi_valuetype GetType(napi_env env, napi_value in); - static bool HasProperty(napi_env env, napi_value object, const std::string &property); - // js to native - static bool GetValue(napi_env env, napi_value in, std::string &out); - static bool GetValue(napi_env env, napi_value in, std::u16string &out); - static bool GetValue(napi_env env, napi_value in, int32_t &out); - static bool GetValue(napi_env env, napi_value in, uint32_t &out); - static bool GetValue(napi_env env, napi_value in, int64_t &out); - static bool GetValue(napi_env env, napi_value in, bool &out); - static bool GetValue(napi_env env, napi_value in, double &out); - template - static bool GetValue(napi_env env, napi_value in, std::vector &items) - { - uint32_t len = 0; - napi_get_array_length(env, in, &len); - items.resize(len); - for (uint32_t i = 0; i < len; i++) { - napi_value item = nullptr; - auto status = napi_get_element(env, in, i, &item); - T buff{}; - if (status != napi_ok || !GetValue(env, item, buff)) { - return false; - } - items[i] = std::move(buff); - } - return true; - } - - // native to js - static napi_value GetValue(napi_env env, napi_value in); - static napi_value GetValue(napi_env env, const std::string &in); - static napi_value GetValue(napi_env env, int32_t in); - static napi_value GetValue(napi_env env, uint32_t in); - static napi_value GetValue(napi_env env, int64_t in); - static napi_value GetValue(napi_env env, bool in); - template - static napi_value GetValue(napi_env env, const std::vector &items) - { - napi_value array = nullptr; - auto status = napi_create_array(env, &array); - if (status != napi_ok) { - return nullptr; - } - uint32_t index = 0; - for (const T &item : items) { - auto itemValue = GetValue(env, item); - if (itemValue == nullptr) { - return nullptr; - } - status = napi_set_element(env, array, index++, itemValue); - if (status != napi_ok) { - return nullptr; - } - } - return array; - } - class Object { - public: - template - static bool WriteProperty(napi_env env, napi_value object, const std::string &property, const T &value) - { - return napi_set_named_property(env, object, property.c_str(), GetValue(env, value)) == napi_ok; - } - template - static bool ReadProperty(napi_env env, napi_value object, const std::string &property, T &value) - { - napi_value propValue = nullptr; - napi_get_named_property(env, object, property.c_str(), &propValue); - return GetValue(env, propValue, value); - } - }; - class Const { - public: - static napi_value Null(napi_env env) - { - napi_value value = nullptr; - napi_get_null(env, &value); - return value; - } - static napi_value Undefined(napi_env env) - { - napi_value value = nullptr; - napi_get_undefined(env, &value); - return value; - } - }; - class ScopeGuard { - public: - explicit ScopeGuard(napi_env env) : env_(env), scope_(nullptr) - { - napi_open_handle_scope(env_, &scope_); - } - ~ScopeGuard() - { - napi_close_handle_scope(env_, scope_); - } - - private: - napi_env env_; - napi_handle_scope scope_; - }; -}; -} // namespace SelectionFwk -} // namespace OHOS -#endif // OHOS_UTIL_H +/* + * 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_UTIL_H +#define OHOS_UTIL_H +#include +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +namespace OHOS { +namespace SelectionFwk { +class JsUtil { +public: + static napi_valuetype GetType(napi_env env, napi_value in); + static bool HasProperty(napi_env env, napi_value object, const std::string &property); + // js to native + static bool GetValue(napi_env env, napi_value in, std::string &out); + static bool GetValue(napi_env env, napi_value in, std::u16string &out); + static bool GetValue(napi_env env, napi_value in, int32_t &out); + static bool GetValue(napi_env env, napi_value in, uint32_t &out); + static bool GetValue(napi_env env, napi_value in, int64_t &out); + static bool GetValue(napi_env env, napi_value in, bool &out); + static bool GetValue(napi_env env, napi_value in, double &out); + template + static bool GetValue(napi_env env, napi_value in, std::vector &items) + { + uint32_t len = 0; + napi_get_array_length(env, in, &len); + items.resize(len); + for (uint32_t i = 0; i < len; i++) { + napi_value item = nullptr; + auto status = napi_get_element(env, in, i, &item); + T buff{}; + if (status != napi_ok || !GetValue(env, item, buff)) { + return false; + } + items[i] = std::move(buff); + } + return true; + } + + // native to js + static napi_value GetValue(napi_env env, napi_value in); + static napi_value GetValue(napi_env env, const std::string &in); + static napi_value GetValue(napi_env env, int32_t in); + static napi_value GetValue(napi_env env, uint32_t in); + static napi_value GetValue(napi_env env, int64_t in); + static napi_value GetValue(napi_env env, bool in); + template + static napi_value GetValue(napi_env env, const std::vector &items) + { + napi_value array = nullptr; + auto status = napi_create_array(env, &array); + if (status != napi_ok) { + return nullptr; + } + uint32_t index = 0; + for (const T &item : items) { + auto itemValue = GetValue(env, item); + if (itemValue == nullptr) { + return nullptr; + } + status = napi_set_element(env, array, index++, itemValue); + if (status != napi_ok) { + return nullptr; + } + } + return array; + } + class Object { + public: + template + static bool WriteProperty(napi_env env, napi_value object, const std::string &property, const T &value) + { + return napi_set_named_property(env, object, property.c_str(), GetValue(env, value)) == napi_ok; + } + template + static bool ReadProperty(napi_env env, napi_value object, const std::string &property, T &value) + { + napi_value propValue = nullptr; + napi_get_named_property(env, object, property.c_str(), &propValue); + return GetValue(env, propValue, value); + } + }; + class Const { + public: + static napi_value Null(napi_env env) + { + napi_value value = nullptr; + napi_get_null(env, &value); + return value; + } + static napi_value Undefined(napi_env env) + { + napi_value value = nullptr; + napi_get_undefined(env, &value); + return value; + } + }; + class ScopeGuard { + public: + explicit ScopeGuard(napi_env env) : env_(env), scope_(nullptr) + { + napi_open_handle_scope(env_, &scope_); + } + ~ScopeGuard() + { + if (scope_ != nullptr) { + napi_close_handle_scope(env_, scope_); + } + } + + private: + napi_env env_; + napi_handle_scope scope_; + }; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // OHOS_UTIL_H diff --git a/etc/init/selection_service.cfg b/etc/init/selection_service.cfg index 4ed738d..89d6026 100644 --- a/etc/init/selection_service.cfg +++ b/etc/init/selection_service.cfg @@ -13,7 +13,9 @@ "ohos.permission.INJECT_INPUT_EVENT", "ohos.permission.GET_RUNNING_INFO", "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", + "ohos.permission.READ_PASTEBOARD", "ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT", + "ohos.permission.CONNECT_SELECTION_EXTENSION", "ohos.permission.SYSTEM_FLOAT_WINDOW" ], "jobs" : { diff --git a/etc/para/selection.para b/etc/para/selection.para index ee2ba16..aac6070 100644 --- a/etc/para/selection.para +++ b/etc/para/selection.para @@ -1,17 +1,17 @@ -# 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. - -sys.selection.switch = on -sys.selection.trigger = ctrl -sys.selection.app = com.hm.youdao/ExtensionAbility -sys.selection.uid = -1 +# 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. + +sys.selection.switch = on +sys.selection.trigger = immediate +sys.selection.app = com.huawei.hmos.vassistant/MiniMenuServiceExtAbility +sys.selection.uid = -1 diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 44d1cd9..35cd941 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -45,8 +45,8 @@ ohos_shared_library("selectionmanager_napi") { deps = [ "${selection_fwk_root_path}/common:selection_common", - "${selection_fwk_root_path}/service:selection_service_proxy", - "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_listener_proxy", + "${selection_fwk_root_path}/interfaces/idl:selection_service_proxy", + "${selection_fwk_root_path}/interfaces/idl:selection_listener_proxy", "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_ability", ] diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index e2af368..ca08286 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -74,8 +74,10 @@ napi_value JsPanel::JsNew(napi_env env, napi_callback_info info) SELECTION_HILOGD("jsPanel finalize."); auto *jsPanel = reinterpret_cast(data); CHECK_RETURN_VOID(jsPanel != nullptr, "finalize nullptr!"); - jsPanel->GetNative() = nullptr; - delete jsPanel; + jsPanel->GetNative().reset(); + if (jsPanel != nullptr) { + delete jsPanel; + } }; napi_value thisVar = nullptr; napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); @@ -129,13 +131,13 @@ napi_value JsPanel::SetUiContent(napi_env env, napi_callback_info info) if (ctxt->selectionPanel == nullptr) { SELECTION_HILOGE("selectionPanel is nullptr!"); jsQueue_.Pop(); + ctxt->SetErrorCode(SFErrorCode::EXCEPTION_PANEL_DESTROYED); return napi_generic_failure; } auto code = ctxt->selectionPanel->SetUiContent(ctxt->path, env); jsQueue_.Pop(); if (code != ErrorCode::NO_ERROR) { ctxt->SetErrorCode(code); - JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to SetUiContent", TYPE_NONE); return napi_generic_failure; } return napi_ok; @@ -155,11 +157,12 @@ napi_value JsPanel::Show(napi_env env, napi_callback_info info) jsQueue_.Push(ctxt->info); return napi_ok; }; - auto exec = [env, ctxt](AsyncCall::Context *ctx) { + auto exec = [ctxt](AsyncCall::Context *ctx) { jsQueue_.Wait(ctxt->info); if (ctxt->selectionPanel == nullptr) { SELECTION_HILOGE("selectionPanel is nullptr!"); jsQueue_.Pop(); + ctxt->SetErrorCode(SFErrorCode::EXCEPTION_PANEL_DESTROYED); return; } auto code = SelectionAbility::GetInstance()->ShowPanel(ctxt->selectionPanel); @@ -169,7 +172,6 @@ napi_value JsPanel::Show(napi_env env, napi_callback_info info) return; } ctxt->SetErrorCode(code); - JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to show", TYPE_NONE); }; ctxt->SetAction(std::move(input)); // 1 means JsAPI:show has 1 param at most. @@ -187,11 +189,12 @@ napi_value JsPanel::Hide(napi_env env, napi_callback_info info) jsQueue_.Push(ctxt->info); return napi_ok; }; - auto exec = [env, ctxt](AsyncCall::Context *ctx) { + auto exec = [ctxt](AsyncCall::Context *ctx) { jsQueue_.Wait(ctxt->info); if (ctxt->selectionPanel == nullptr) { SELECTION_HILOGE("selectionPanel is nullptr!"); jsQueue_.Pop(); + ctxt->SetErrorCode(SFErrorCode::EXCEPTION_PANEL_DESTROYED); return; } auto code = SelectionAbility::GetInstance()->HidePanel(ctxt->selectionPanel); @@ -201,7 +204,6 @@ napi_value JsPanel::Hide(napi_env env, napi_callback_info info) return; } ctxt->SetErrorCode(code); - JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to hide", TYPE_NONE); }; ctxt->SetAction(std::move(input)); // 1 means JsAPI:hide has 1 param at most. @@ -211,27 +213,34 @@ napi_value JsPanel::Hide(napi_env env, napi_callback_info info) napi_value JsPanel::StartMoving(napi_env env, napi_callback_info info) { - napi_value self = nullptr; - NAPI_CALL(env, napi_get_cb_info(env, info, 0, nullptr, &self, nullptr)); - RESULT_CHECK_RETURN(env, (self != nullptr), JsUtils::Convert(ErrorCode::ERROR_SELECTION_SERVICE), - "", TYPE_NONE, JsUtil::Const::Null(env)); - void *native = nullptr; - NAPI_CALL(env, napi_unwrap(env, self, &native)); - RESULT_CHECK_RETURN(env, (native != nullptr), JsUtils::Convert(ErrorCode::ERROR_SELECTION_SERVICE), - "", TYPE_NONE, JsUtil::Const::Null(env)); - auto selectionPanel = reinterpret_cast(native)->GetNative(); - if (selectionPanel == nullptr) { - SELECTION_HILOGE("selectionPanel is nullptr!"); - JsUtils::ThrowException(env, JsUtils::Convert(ErrorCode::ERROR_SELECTION_SERVICE), - "failed to start moving, selectionPanel is nullptr", TYPE_NONE); - return JsUtil::Const::Null(env); - } + SELECTION_HILOGD("StartMoving start!"); + auto ctxt = std::make_shared(env, info); + auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + ctxt->info = { std::chrono::system_clock::now(), JsEvent::START_MOVING }; + jsQueue_.Push(ctxt->info); + return napi_ok; + }; - auto ret = selectionPanel->StartMoving(); - if (ret != ErrorCode::NO_ERROR) { - JsUtils::ThrowException(env, JsUtils::Convert(ret), "failed to start moving", TYPE_NONE); - } - return JsUtil::Const::Null(env); + auto exec = [ctxt](AsyncCall::Context *ctx) { + jsQueue_.Wait(ctxt->info); + if (ctxt->selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr!"); + jsQueue_.Pop(); + ctxt->SetErrorCode(SFErrorCode::EXCEPTION_PANEL_DESTROYED); + return; + } + auto code = ctxt->selectionPanel->StartMoving(); + jsQueue_.Pop(); + if (code != ErrorCode::NO_ERROR) { + ctxt->SetErrorCode(code); + return; + } + ctxt->SetState(napi_ok); + }; + ctxt->SetAction(std::move(input)); + + AsyncCall asyncCall(env, info, ctxt, 1); + return asyncCall.Call(env, exec, "startMoving"); } napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info) @@ -247,24 +256,28 @@ napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info) // 1 means the second param y PARAM_CHECK_RETURN(env, JsUtils::GetValue(env, argv[1], ctxt->y) == napi_ok, "y type must be number", TYPE_NONE, status); + PARAM_CHECK_RETURN(env, ctxt->x >= 0 && ctxt->y >= 0, "x/y must be positive", + TYPE_NONE, status); ctxt->info = { std::chrono::system_clock::now(), JsEvent::MOVE_TO }; jsQueue_.Push(ctxt->info); return napi_ok; }; - auto exec = [env, ctxt](AsyncCall::Context *ctx) { + auto exec = [ctxt](AsyncCall::Context *ctx) { int64_t start = duration_cast(system_clock::now().time_since_epoch()).count(); jsQueue_.Wait(ctxt->info); PrintEditorQueueInfoIfTimeout(start, ctxt->info); if (ctxt->selectionPanel == nullptr) { SELECTION_HILOGE("selectionPanel is nullptr!"); jsQueue_.Pop(); + ctxt->SetErrorCode(SFErrorCode::EXCEPTION_PANEL_DESTROYED); return; } auto code = ctxt->selectionPanel->MoveTo(ctxt->x, ctxt->y); jsQueue_.Pop(); if(code != ErrorCode::NO_ERROR) { - JsUtils::ThrowException(env, JsUtils::Convert(code), "failed to moveTo", TYPE_NONE); + ctxt->SetErrorCode(code); + return; } ctxt->SetState(napi_ok); }; @@ -301,6 +314,7 @@ napi_value JsPanel::Subscribe(napi_env env, napi_callback_info info) !EventChecker::IsValidEventType(EventSubscribeModule::PANEL, type) || JsUtil::GetType(env, argv[1]) != napi_function) { SELECTION_HILOGE("subscribe failed, type: %{public}s!", type.c_str()); + JsUtils::ThrowException(env, SFErrorCode::EXCEPTION_PARAMCHECK, "", TYPE_NONE); return nullptr; } SELECTION_HILOGD("subscribe type: %{public}s.", type.c_str()); diff --git a/frameworks/js/napi/selection_ability/js_panel.h b/frameworks/js/napi/selection_ability/js_panel.h index 24bf326..8558d7c 100644 --- a/frameworks/js/napi/selection_ability/js_panel.h +++ b/frameworks/js/napi/selection_ability/js_panel.h @@ -39,6 +39,7 @@ enum class JsEvent : uint32_t { GET_DISPLAYID, SET_IMMERSIVE_MODE, GET_IMMERSIVE_MODE, + START_MOVING, EVENT_END, }; diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 627beda..90d34cf 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -28,6 +28,7 @@ #include "napi_base_context.h" #include "js_panel.h" #include "js_selection_utils.h" +#include "selection_app_validator.h" using namespace OHOS; namespace OHOS { @@ -45,15 +46,13 @@ std::shared_ptr JsSelectionEngineSetting::handler_{ nu sptr JsSelectionEngineSetting::listenerStub_ { nullptr }; sptr JsSelectionEngineSetting::abilityManager_ { nullptr }; -napi_value JsSelectionEngineSetting::GetSelectionAbility(napi_env env, napi_callback_info info) -{ - SELECTION_HILOGI("SelectionEngineSetting---GetSelectionAbility"); - - return GetSEInstance(env, info); -} - napi_value JsSelectionEngineSetting::Subscribe(napi_env env, napi_callback_info info) { + if (!SelectionAppValidator::GetInstance().Validate()) { + JsUtils::ThrowException(env, JsUtils::Convert(ErrorCode::ERROR_INVALID_OPERATION), + "BundleName is invalid", TYPE_NONE); + return nullptr; + } size_t argc = ARGC_TWO; napi_value argv[ARGC_TWO] = { nullptr }; napi_value thisVar = nullptr; @@ -65,6 +64,7 @@ napi_value JsSelectionEngineSetting::Subscribe(napi_env env, napi_callback_info !EventChecker::IsValidEventType(EventSubscribeModule::SELECTION_METHOD_ABILITY, type) || JsUtil::GetType(env, argv[1]) != napi_function) { SELECTION_HILOGE("subscribe failed, type: %{public}s!", type.c_str()); + JsUtils::ThrowException(env, SFErrorCode::EXCEPTION_PARAMCHECK, "", TYPE_NONE); return nullptr; } SELECTION_HILOGI("subscribe type: %{public}s.", type.c_str()); @@ -92,6 +92,7 @@ napi_value JsSelectionEngineSetting::UnSubscribe(napi_env env, napi_callback_inf if (argc < 1 || !JsUtil::GetValue(env, argv[0], type) || !EventChecker::IsValidEventType(EventSubscribeModule::SELECTION_METHOD_ABILITY, type)) { SELECTION_HILOGE("unsubscribe failed, type: %{public}s!", type.c_str()); + JsUtils::ThrowException(env, SFErrorCode::EXCEPTION_PARAMCHECK, "", TYPE_NONE); return nullptr; } @@ -142,9 +143,7 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf napi_typeof(env, argv[0], &valueType); PARAM_CHECK_RETURN(env, valueType == napi_object, "ctx type must be BaseContext.", TYPE_NONE, napi_invalid_arg); napi_status status = GetContext(env, argv[0], ctxt->context); - if (status != napi_ok) { - return status; - } + PARAM_CHECK_RETURN(env, status == napi_ok, "js param context covert failed.", TYPE_NONE, napi_invalid_arg); // 1 means parameter of info napi_typeof(env, argv[1], &valueType); PARAM_CHECK_RETURN(env, valueType == napi_object, "param info type must be PanelInfo.", TYPE_NONE, @@ -154,14 +153,17 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", static_cast(ctxt->panelInfo.panelType), ctxt->panelInfo.x, ctxt->panelInfo.y, ctxt->panelInfo.width, ctxt->panelInfo.height); PARAM_CHECK_RETURN(env, status == napi_ok, "js param info covert failed!", TYPE_NONE, napi_invalid_arg); + PARAM_CHECK_RETURN(env, ctxt->panelInfo.x >= 0 && ctxt->panelInfo.y >= 0 && ctxt->panelInfo.width > 0 && + ctxt->panelInfo.height > 0, "js param is invalid: x/y cannot be negative, width/height must be positive!", + TYPE_NONE, napi_invalid_arg); return status; }; - auto exec = [env, ctxt](AsyncCall::Context *ctx) { + auto exec = [ctxt](AsyncCall::Context *ctx) { auto ret = SelectionAbility::GetInstance()->CreatePanel(ctxt->context, ctxt->panelInfo, ctxt->panel); - if(ret != ErrorCode::NO_ERROR) { + if (ret != ErrorCode::NO_ERROR) { ctxt->SetErrorCode(ret); - JsUtils::ThrowException(env, JsUtils::Convert(ret), "CreatePanel failed!", TYPE_NONE); + return; } ctxt->SetState(napi_ok); }; @@ -201,10 +203,10 @@ napi_value JsSelectionEngineSetting::DestroyPanel(napi_env env, napi_callback_in CHECK_RETURN(constructor != nullptr, "failed to get panel constructor.", napi_invalid_arg); napi_status status = napi_instanceof(env, argv[0], constructor, &isPanel); CHECK_RETURN((status == napi_ok) && isPanel, "param verification failed, it's not expected panel instance!", - status); + napi_invalid_arg); JsPanel *jsPanel = nullptr; status = napi_unwrap(env, argv[0], (void **)(&jsPanel)); - CHECK_RETURN((status == napi_ok) && (jsPanel != nullptr), "failed to unwrap JsPanel!", status); + CHECK_RETURN((status == napi_ok) && (jsPanel != nullptr), "failed to unwrap JsPanel!", napi_invalid_arg); ctxt->panel = jsPanel->GetNative(); CHECK_RETURN((ctxt->panel != nullptr), "panel is nullptr!", napi_invalid_arg); return status; @@ -217,7 +219,7 @@ napi_value JsSelectionEngineSetting::DestroyPanel(napi_env env, napi_callback_in auto errCode = SelectionAbility::GetInstance()->DestroyPanel(ctxt->panel); if (errCode != ErrorCode::NO_ERROR) { SELECTION_HILOGE("DestroyPanel failed, errCode: %{public}d!", JsUtils::Convert(errCode)); - JsUtils::ThrowException(env, JsUtils::Convert(errCode), "DestroyPanel failed!", TYPE_NONE); + ctxt->SetErrorCode(errCode); return napi_generic_failure; } ctxt->panel = nullptr; @@ -301,25 +303,10 @@ void JsSelectionEngineSetting::UnRegisterListener(napi_value callback, std::stri SELECTION_HILOGE("selection system ability or listenerStub_ is nullptr!"); return; } - proxy->UnregisterListener(listenerStub_->AsObject()); + proxy->UnregisterListener(listenerStub_); listenerStub_ = nullptr; } -napi_value JsSelectionEngineSetting::GetSEInstance(napi_env env, napi_callback_info info) -{ - napi_value instance = nullptr; - napi_value cons = nullptr; - if (napi_get_reference_value(env, KDSRef_, &cons) != napi_ok) { - SELECTION_HILOGI("failed to get reference value."); - return nullptr; - } - if (napi_new_instance(env, cons, 0, nullptr, &instance) != napi_ok) { - SELECTION_HILOGI("failed to new instance."); - return nullptr; - } - return instance; -} - std::shared_ptr JsSelectionEngineSetting::GetJsSelectionEngineSetting() { if (selectionDelegate_ == nullptr) { @@ -340,38 +327,42 @@ std::shared_ptr JsSelectionEngineSetting::GetJsSelecti return selectionDelegate_; } -void JsSelectionEngineSetting::RegisterListerToService(std::shared_ptr &selectionEnging) +SFErrorCode JsSelectionEngineSetting::RegisterListenerToService( + std::shared_ptr &selectionEnging) { auto proxy = GetSelectionSystemAbility(); if (proxy == nullptr) { SELECTION_HILOGE("selection system ability is nullptr!"); - return; + return EXCEPTION_SELECTION_SERVICE; } listenerStub_ = new (std::nothrow) SelectionListenerImpl(selectionEnging); if (listenerStub_ == nullptr) { SELECTION_HILOGE("Failed to create SelectionListenerImpl instance."); - return; + return EXCEPTION_SELECTION_SERVICE; } SELECTION_HILOGI("Begin calling SA RegisterListener!"); - proxy->RegisterListener(listenerStub_->AsObject()); + if (proxy->RegisterListener(listenerStub_) != ERR_OK) { + return EXCEPTION_SELECTION_SERVICE; + } + + return EXCEPTION_SUCCESS; } -SFErrorCode JsSelectionEngineSetting::Register() +SFErrorCode JsSelectionEngineSetting::Register(napi_env env) { auto delegate = GetJsSelectionEngineSetting(); if (delegate == nullptr) { SELECTION_HILOGE("failed to get delegate!"); return EXCEPTION_SELECTION_SERVICE; } - RegisterListerToService(delegate); - return EXCEPTION_SUCCESS; + + return RegisterListenerToService(delegate); }; napi_value JsSelectionEngineSetting::Init(napi_env env, napi_value exports) { SELECTION_HILOGI("napi init"); napi_property_descriptor descriptor[] = { - DECLARE_NAPI_FUNCTION("getSelectionAbility", GetSelectionAbility), DECLARE_NAPI_FUNCTION("on", Subscribe), DECLARE_NAPI_FUNCTION("off", UnSubscribe), DECLARE_NAPI_FUNCTION("createPanel", CreatePanel), @@ -379,10 +370,11 @@ napi_value JsSelectionEngineSetting::Init(napi_env env, napi_value exports) }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor)); - if (Register() != EXCEPTION_SUCCESS) { + if (Register(env) != EXCEPTION_SUCCESS) { SELECTION_HILOGE("regist lister to service failed!"); return nullptr; } + SelectionAppValidator::GetInstance().SetValid(); return exports; } @@ -435,7 +427,6 @@ int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionInfo &selectio { SELECTION_HILOGD("OnSelectionEvent begin"); std::string type = "selectionCompleted"; - auto entry = GetEntry(type, [&selectionInfo](SelectionEntry &entry) {entry.selectionInfo = selectionInfo; }); if (entry == nullptr) { SELECTION_HILOGE("failed to get SelectionEntry entry!"); @@ -448,7 +439,7 @@ int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionInfo &selectio return 1; } - SELECTION_HILOGI("selection text is [%{public}s]", entry->selectionInfo.text.c_str()); + SELECTION_HILOGI("selection text length is [%{public}lu]", entry->selectionInfo.text.length()); auto task = [entry]() { auto paramGetter = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { if (argc == 0) { diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index 38010bb..2417574 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -32,7 +32,6 @@ #include "async_call.h" #include "selection_panel.h" #include "panel_info.h" -#include "context.h" namespace OHOS { namespace SelectionFwk { @@ -82,14 +81,14 @@ private: JsSelectionEngineSetting() = default; static napi_value GetSEInstance(napi_env env, napi_callback_info info); - static SFErrorCode Register(); + static SFErrorCode Register(napi_env env); static napi_value Write(napi_env env, const SelectionInfo &selectionInfo); static napi_status GetContext(napi_env env, napi_value in, std::shared_ptr &context); static std::shared_ptr GetJsSelectionEngineSetting(); void RegisterListener(napi_value callback, std::string type, std::shared_ptr callbackObj); void UnRegisterListener(napi_value callback, std::string type); static sptr GetSelectionSystemAbility(); - static void RegisterListerToService(std::shared_ptr &selectionEnging); + static SFErrorCode RegisterListenerToService(std::shared_ptr &selectionEnging); static std::shared_ptr GetEventHandler(); using EntrySetter = std::function; std::shared_ptr GetEntry(const std::string &type, EntrySetter entrySetter = nullptr); diff --git a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp index 147241b..828b729 100644 --- a/frameworks/js/napi/selection_ability/panel_listener_impl.cpp +++ b/frameworks/js/napi/selection_ability/panel_listener_impl.cpp @@ -57,7 +57,7 @@ void PanelListenerImpl::OnPanelStatus(uint32_t windowId, const std::string& stat } CallbackVector callBacks = GetCallback(windowId, status); if (callBacks.empty()) { - SELECTION_HILOGE("callBack is nullptr!"); + SELECTION_HILOGE("callBacks is empty!"); return; } SELECTION_HILOGI("OnPanelStatus status: %{public}s", status.c_str()); @@ -144,7 +144,8 @@ void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId) }); } -void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId, std::shared_ptr cbObject) +void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId, + std::shared_ptr cbObject) { callbacks_.ComputeIfPresent(windowId, [&type, cbObject](auto windowId, TypeMap& cbs) { auto it = cbs.find(type); diff --git a/frameworks/js/napi/selection_extension_context/BUILD.gn b/frameworks/js/napi/selection_extension_context/BUILD.gn index 3045f29..35383a2 100644 --- a/frameworks/js/napi/selection_extension_context/BUILD.gn +++ b/frameworks/js/napi/selection_extension_context/BUILD.gn @@ -1,61 +1,61 @@ -# 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/config/components/ets_frontend/es2abc_config.gni") - -import("//build/ohos.gni") - -es2abc_gen_abc("gen_selection_extension_context_abc") { - src_js = rebase_path("selection_extension_context.js") - dst_file = rebase_path(target_out_dir + "/selection_extension_context.abc") - in_puts = [ "selection_extension_context.js" ] - out_puts = [ target_out_dir + "/selection_extension_context.abc" ] - extra_args = [ "--module" ] -} - -gen_js_obj("selection_extension_context_js") { - input = "selection_extension_context.js" - output = target_out_dir + "/selection_extension_context.o" -} - -gen_js_obj("selection_extension_context_abc") { - input = - get_label_info(":gen_selection_extension_context_abc", - "target_out_dir") + "/selection_extension_context.abc" - output = target_out_dir + "/selection_extension_context_abc.o" - dep = ":gen_selection_extension_context_abc" -} - -ohos_shared_library("selectionextensioncontext_napi") { - branch_protector_ret = "pac_ret" - sanitize = { - boundary_sanitize = true - cfi = true - cfi_cross_dso = true - debug = false - integer_overflow = true - ubsan = true - } - sources = [ "selection_extension_context_module.cpp" ] - - deps = [ - ":selection_extension_context_abc", - ":selection_extension_context_js", - ] - - external_deps = [ "napi:ace_napi" ] - - relative_install_dir = "module/selectioninput" - subsystem_name = "systemabilitymgr" - part_name = "selectionfwk" -} +# 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/config/components/ets_frontend/es2abc_config.gni") + +import("//build/ohos.gni") + +es2abc_gen_abc("gen_selection_extension_context_abc") { + src_js = rebase_path("selection_extension_context.js") + dst_file = rebase_path(target_out_dir + "/selection_extension_context.abc") + in_puts = [ "selection_extension_context.js" ] + out_puts = [ target_out_dir + "/selection_extension_context.abc" ] + extra_args = [ "--module" ] +} + +gen_js_obj("selection_extension_context_js") { + input = "selection_extension_context.js" + output = target_out_dir + "/selection_extension_context.o" +} + +gen_js_obj("selection_extension_context_abc") { + input = + get_label_info(":gen_selection_extension_context_abc", + "target_out_dir") + "/selection_extension_context.abc" + output = target_out_dir + "/selection_extension_context_abc.o" + dep = ":gen_selection_extension_context_abc" +} + +ohos_shared_library("selectionextensioncontext_napi") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + sources = [ "selection_extension_context_module.cpp" ] + + deps = [ + ":selection_extension_context_abc", + ":selection_extension_context_js", + ] + + external_deps = [ "napi:ace_napi" ] + + relative_install_dir = "module/selectioninput" + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/frameworks/js/napi/selection_extension_context/selection_extension_context.js b/frameworks/js/napi/selection_extension_context/selection_extension_context.js index b3e5cf3..82e0042 100644 --- a/frameworks/js/napi/selection_extension_context/selection_extension_context.js +++ b/frameworks/js/napi/selection_extension_context/selection_extension_context.js @@ -1,25 +1,29 @@ -/* - * 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. - */ - -const ExtensionContext = requireNapi('application.ExtensionContext'); - -class SelectionExtensionContext extends ExtensionContext { - constructor(obj) { - super(obj); - this.extensionAbilityInfo = obj.extensionAbilityInfo; - } -} - +/* + * 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. + */ + +const ExtensionContext = requireNapi('application.ExtensionContext'); + +class SelectionExtensionContext extends ExtensionContext { + constructor(obj) { + super(obj); + this.extensionAbilityInfo = obj.extensionAbilityInfo; + } + + startAbility(want) { + return this.__context_impl__.startAbility(want); + } +} + export default SelectionExtensionContext; \ No newline at end of file diff --git a/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp b/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp index e287dcf..1f2cd8b 100644 --- a/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp +++ b/frameworks/js/napi/selection_extension_context/selection_extension_context_module.cpp @@ -1,55 +1,55 @@ -/* - * 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 "native_engine/native_engine.h" - -extern const char _binary_selection_extension_context_js_start[]; -extern const char _binary_selection_extension_context_js_end[]; -extern const char _binary_selection_extension_context_abc_start[]; -extern const char _binary_selection_extension_context_abc_end[]; - -static napi_module g_ExtensionContextModule = { - .nm_version = 0, - .nm_filename = "libselectionextensioncontext_napi.so/selection_extension_context.js", - .nm_modname = "selectionInput.SelectionExtensionContext", -}; - -extern "C" __attribute__((constructor)) void NAPI_selectionInput_SelectionExtensionContext_AutoRegister() -{ - napi_module_register(&g_ExtensionContextModule); -} - -extern "C" __attribute__((visibility("default"))) void NAPI_selectionInput_SelectionExtensionContext_GetJSCode( - const char **buf, int *bufLen) -{ - if (buf != nullptr) { - *buf = _binary_selection_extension_context_js_start; - } - if (bufLen != nullptr) { - *bufLen = _binary_selection_extension_context_js_end - _binary_selection_extension_context_js_start; - } -} - -// ability_context JS register -extern "C" __attribute__((visibility("default"))) void NAPI_selectionInput_SelectionExtensionContext_GetABCCode( - const char **buf, int *buflen) -{ - if (buf != nullptr) { - *buf = _binary_selection_extension_context_abc_start; - } - if (buflen != nullptr) { - *buflen = _binary_selection_extension_context_abc_end - _binary_selection_extension_context_abc_start; - } -} +/* + * 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 "native_engine/native_engine.h" + +extern const char _binary_selection_extension_context_js_start[]; +extern const char _binary_selection_extension_context_js_end[]; +extern const char _binary_selection_extension_context_abc_start[]; +extern const char _binary_selection_extension_context_abc_end[]; + +static napi_module g_ExtensionContextModule = { + .nm_version = 0, + .nm_filename = "libselectionextensioncontext_napi.so/selection_extension_context.js", + .nm_modname = "selectionInput.SelectionExtensionContext", +}; + +extern "C" __attribute__((constructor)) void NAPI_selectionInput_SelectionExtensionContext_AutoRegister() +{ + napi_module_register(&g_ExtensionContextModule); +} + +extern "C" __attribute__((visibility("default"))) void NAPI_selectionInput_SelectionExtensionContext_GetJSCode( + const char **buf, int *bufLen) +{ + if (buf != nullptr) { + *buf = _binary_selection_extension_context_js_start; + } + if (bufLen != nullptr) { + *bufLen = _binary_selection_extension_context_js_end - _binary_selection_extension_context_js_start; + } +} + +// ability_context JS register +extern "C" __attribute__((visibility("default"))) void NAPI_selectionInput_SelectionExtensionContext_GetABCCode( + const char **buf, int *buflen) +{ + if (buf != nullptr) { + *buf = _binary_selection_extension_context_abc_start; + } + if (buflen != nullptr) { + *buflen = _binary_selection_extension_context_abc_end - _binary_selection_extension_context_abc_start; + } +} diff --git a/frameworks/js/napi/selection_panel/BUILD.gn b/frameworks/js/napi/selection_panel/BUILD.gn new file mode 100644 index 0000000..debdfe5 --- /dev/null +++ b/frameworks/js/napi/selection_panel/BUILD.gn @@ -0,0 +1,59 @@ +# 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/systemabilitymgr/selectionfwk/selection_service.gni") + +config("selection_panel_config") { + visibility = [ ":*" ] + include_dirs = [ + "./", + "${selection_fwk_root_path}/utils/include", + "${selection_fwk_root_path}/common", + "${selection_fwk_root_path}/frameworks/native/selection_ability/include", + ] +} + +ohos_shared_library("selectionpanel_napi") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + sources = [ + "selection_panel_module.cpp", + "js_selection_panel.cpp", + ] + + configs = [ ":selection_panel_config" ] + + deps = [ + "${selection_fwk_root_path}/common:selection_common", + "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_ability", + ] + + external_deps = [ + "ability_runtime:runtime", + "c_utils:utils", + "hilog:libhilog", + "napi:ace_napi", + ] + + relative_install_dir = "module/selectioninput" + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/frameworks/js/napi/selection_panel/js_selection_panel.cpp b/frameworks/js/napi/selection_panel/js_selection_panel.cpp new file mode 100644 index 0000000..45f592e --- /dev/null +++ b/frameworks/js/napi/selection_panel/js_selection_panel.cpp @@ -0,0 +1,49 @@ +/* + * 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_selection_panel.h" + +#include "js_runtime_utils.h" +#include "util.h" +#include "panel_info.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { +napi_value JsSelectionPanel::Init(napi_env env, napi_value exports) +{ + napi_set_named_property(env, exports, "PanelType", GetJsPanelTypeProperty(env)); + return exports; +} + +napi_value JsSelectionPanel::GetJsPanelTypeProperty(napi_env env) +{ + napi_value obj = nullptr; + NAPI_CALL(env, napi_create_object(env, &obj)); + + auto ret = JsUtil::Object::WriteProperty(env, obj, "MENU_PANEL", static_cast(PanelType::MENU_PANEL)); + if (!ret) { + SELECTION_HILOGE("Failed to init module selectionInput.SelectionPanel.PanelType as MENU_PANEL"); + return nullptr; + } + ret = JsUtil::Object::WriteProperty(env, obj, "MAIN_PANEL", static_cast(PanelType::MAIN_PANEL)); + if (!ret) { + SELECTION_HILOGE("Failed to init module selectionInput.SelectionPanel.PanelType as MAIN_PANEL"); + return nullptr; + } + return obj; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/selection_panel/js_selection_panel.h b/frameworks/js/napi/selection_panel/js_selection_panel.h new file mode 100644 index 0000000..5e2f821 --- /dev/null +++ b/frameworks/js/napi/selection_panel/js_selection_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 INTERFACE_JS_SELECTION_PANEL +#define INTERFACE_JS_SELECTION_PANEL + +#include "napi/native_api.h" + +namespace OHOS { +namespace SelectionFwk { +class JsSelectionPanel { +public: + JsSelectionPanel() = default; + ~JsSelectionPanel() = default; + static napi_value Init(napi_env env, napi_value exports); + +private: + static napi_value GetJsPanelTypeProperty(napi_env env); +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // INTERFACE_JS_SELECTION_PANEL \ No newline at end of file diff --git a/frameworks/js/napi/selection_panel/selection_panel_module.cpp b/frameworks/js/napi/selection_panel/selection_panel_module.cpp new file mode 100644 index 0000000..5be47cd --- /dev/null +++ b/frameworks/js/napi/selection_panel/selection_panel_module.cpp @@ -0,0 +1,47 @@ +/* + * 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_selection_panel.h" +#include "napi/native_api.h" + +EXTERN_C_START +/* + * function for module exports + */ +static napi_value Init(napi_env env, napi_value exports) +{ + OHOS::SelectionFwk::JsSelectionPanel::Init(env, exports); + return exports; +} +EXTERN_C_END +/* + * module define + */ +static napi_module _module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "selectionInput.SelectionPanel", + .nm_priv = ((void *)0), + .reserved = { 0 } +}; +/* + * module register + */ +extern "C" __attribute__((constructor)) void NAPI_selectionInput_SelectionPanel_AutoRegister() +{ + napi_module_register(&_module); +} \ No newline at end of file diff --git a/frameworks/native/selection_ability/BUILD.gn b/frameworks/native/selection_ability/BUILD.gn index db5a25e..856965f 100644 --- a/frameworks/native/selection_ability/BUILD.gn +++ b/frameworks/native/selection_ability/BUILD.gn @@ -12,7 +12,6 @@ # limitations under the License. import("//build/ohos.gni") -import("//build/config/components/idl_tool/idl.gni") import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") config("selection_listener_config") { @@ -25,39 +24,6 @@ config("selection_listener_config") { ] } -idl_interface_sources = [ - "${target_gen_dir}/selection_listener_proxy.cpp", - "${target_gen_dir}/selection_listener_stub.cpp", -] - -idl_gen_interface("selection_listener_interface") { - src_idl = rebase_path("ISelectionListener.idl") - dst_file = string_join(",", idl_interface_sources) -} - -ohos_source_set("selection_listener_proxy") { - sanitize = { - cfi = true - cfi_cross_dso = true - debug = false - } - include_dirs = [ - "${target_gen_dir}", - ] - - public_configs = [":selection_listener_config"] - output_values = get_target_outputs(":selection_listener_interface") - sources = filter_include(output_values, [ "*_proxy.cpp" ]) - deps = [ ":selection_listener_interface" ] - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - "ipc:ipc_single", - ] - part_name = "selectionfwk" - subsystem_name = "systemabilitymgr" -} - ohos_shared_library("selection_ability") { branch_protector_ret = "pac_ret" sanitize = { @@ -70,7 +36,6 @@ ohos_shared_library("selection_ability") { ubsan = true } configs = [ ":selection_listener_config", ] - output_values = get_target_outputs(":selection_listener_interface") sources = [ "src/selection_ability.cpp", @@ -78,11 +43,13 @@ ohos_shared_library("selection_ability") { "src/selection_panel.cpp", "src/task_manager.cpp", "src/tasks/task.cpp", + "src/selection_app_validator.cpp", + "src/selection_panel_manager.cpp", ] - sources += filter_include(output_values, [ "*.cpp" ]) deps = [ "${selection_fwk_root_path}/common:selection_common", - ":selection_listener_interface", + "${selection_fwk_root_path}/interfaces/idl:selection_listener_interface", + "${selection_fwk_root_path}/interfaces/idl:selection_listener_stub", ] external_deps = [ @@ -92,6 +59,7 @@ ohos_shared_library("selection_ability") { "ability_base:configuration", "ability_base:want", "ability_runtime:ability_context_native", + "ability_runtime:app_context", "bundle_framework:appexecfwk_base", "config_policy:configpolicy_util", "eventhandler:libeventhandler", @@ -103,6 +71,7 @@ ohos_shared_library("selection_ability") { "samgr:samgr_proxy", "window_manager:libdm", "window_manager:libwsutils", + "ability_runtime:ability_manager", ] public_external_deps = [ "window_manager:libwm" ] diff --git a/frameworks/native/selection_ability/include/panel_common.h b/frameworks/native/selection_ability/include/panel_common.h index f00ba99..5bd533f 100644 --- a/frameworks/native/selection_ability/include/panel_common.h +++ b/frameworks/native/selection_ability/include/panel_common.h @@ -38,7 +38,7 @@ struct HotArea { static std::string ToString(const std::vector &areas) { std::string areasStr = "["; - for (const auto area : areas) { + for (const auto& area : areas) { areasStr.append(area.ToString()); } areasStr.append("]"); diff --git a/frameworks/native/selection_ability/include/panel_info.h b/frameworks/native/selection_ability/include/panel_info.h index 47ff030..5bebfb8 100644 --- a/frameworks/native/selection_ability/include/panel_info.h +++ b/frameworks/native/selection_ability/include/panel_info.h @@ -20,56 +20,17 @@ namespace OHOS { namespace SelectionFwk { -enum PanelType { +enum class PanelType: uint32_t { MENU_PANEL = 1, MAIN_PANEL = 2, }; -struct PanelInfo : public Parcelable { - PanelType panelType = MAIN_PANEL; +struct PanelInfo { + PanelType panelType{}; int32_t x = 0; int32_t y = 0; int32_t width = 0; int32_t height = 0; - - bool ReadFromParcel(Parcel &in) - { - int32_t panelTypeData = in.ReadInt32(); - panelType = static_cast(panelTypeData); - x = in.ReadInt32(); - y = in.ReadInt32(); - width = in.ReadInt32(); - height = in.ReadInt32(); - return true; - } - bool Marshalling(Parcel &out) const - { - if (!out.WriteInt32(static_cast(panelType))) { - return false; - } - if (!out.WriteInt32(x)) { - return false; - } - if (!out.WriteInt32(y)) { - return false; - } - if (!out.WriteInt32(width)) { - return false; - } - if (!out.WriteInt32(height)) { - return false; - } - return true; - } - static PanelInfo *Unmarshalling(Parcel &in) - { - PanelInfo *data = new (std::nothrow) PanelInfo(); - if (data && !data->ReadFromParcel(in)) { - delete data; - data = nullptr; - } - return data; - } }; enum class ImmersiveMode : int32_t { diff --git a/frameworks/native/selection_ability/include/selection_ability.h b/frameworks/native/selection_ability/include/selection_ability.h index 7b85c9c..a361419 100644 --- a/frameworks/native/selection_ability/include/selection_ability.h +++ b/frameworks/native/selection_ability/include/selection_ability.h @@ -42,8 +42,6 @@ private: static std::mutex instanceLock_; static sptr instance_; - std::mutex dataChannelLock_; - ConcurrentMap> panels_ {}; std::atomic_bool isShowAfterCreate_ { false }; diff --git a/frameworks/native/selection_ability/include/selection_app_validator.h b/frameworks/native/selection_ability/include/selection_app_validator.h new file mode 100644 index 0000000..1a1af25 --- /dev/null +++ b/frameworks/native/selection_ability/include/selection_app_validator.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 SELECTION_NATIVE_APP_VALIDATOR_H +#define SELECTION_NATIVE_APP_VALIDATOR_H + +#include +#include +#include + +namespace OHOS::SelectionFwk { +class SelectionAppValidator { +public: + static SelectionAppValidator& GetInstance(); + void SetValid(); + bool Validate() const; + +private: + SelectionAppValidator() = default; + SelectionAppValidator(const SelectionAppValidator&) = delete; + SelectionAppValidator(SelectionAppValidator&&) = delete; + SelectionAppValidator& operator= (const SelectionAppValidator&) = delete; + SelectionAppValidator& operator= (SelectionAppValidator&&) = delete; + +private: + bool isValid_ = false; +}; + +} // namespace OHOS::SelectionFwk +#endif // SELECTION_NATIVE_APP_VALIDATOR_H \ No newline at end of file diff --git a/frameworks/native/selection_ability/include/selection_attribute.h b/frameworks/native/selection_ability/include/selection_attribute.h index 3680218..911b8f8 100644 --- a/frameworks/native/selection_ability/include/selection_attribute.h +++ b/frameworks/native/selection_ability/include/selection_attribute.h @@ -42,7 +42,7 @@ struct InputAttribute { bool GetSecurityFlag() const { return inputPattern == PATTERN_PASSWORD || inputPattern == PATTERN_PASSWORD_SCREEN_LOCK || - PATTERN_PASSWORD_NUMBER == inputPattern || PATTERN_NEWPASSWORD == inputPattern; + inputPattern == PATTERN_PASSWORD_NUMBER || inputPattern == PATTERN_NEWPASSWORD; } bool operator==(const InputAttribute &info) const @@ -55,10 +55,10 @@ struct InputAttribute { { std::stringstream ss; ss << "[" << "inputPattern:" << inputPattern - << "enterKeyType:" << enterKeyType << "inputOption:" << inputOption - << "isTextPreviewSupported:" << isTextPreviewSupported << "bundleName:" << bundleName - << "immersiveMode:" << immersiveMode << "windowId:" << windowId - << "callingDisplayId:" << callingDisplayId << "]"; + << ", enterKeyType:" << enterKeyType << ", inputOption:" << inputOption + << ", isTextPreviewSupported:" << isTextPreviewSupported << ", bundleName:" << bundleName + << ", immersiveMode:" << immersiveMode << ", windowId:" << windowId + << ", callingDisplayId:" << callingDisplayId << "]"; return ss.str(); } }; diff --git a/frameworks/native/selection_ability/include/selection_listener_impl.h b/frameworks/native/selection_ability/include/selection_listener_impl.h index dc2775f..224f098 100644 --- a/frameworks/native/selection_ability/include/selection_listener_impl.h +++ b/frameworks/native/selection_ability/include/selection_listener_impl.h @@ -26,7 +26,8 @@ public: SelectionListenerImpl(std::shared_ptr selectionI) : selectionI_(selectionI) {} ~SelectionListenerImpl() override = default; ErrCode OnSelectionChange(const SelectionInfoData& SelectionInfoData) override; - ErrCode FocusChange(uint32_t windowID, uint32_t windowType)override; + ErrCode FocusChange(const SelectionFocusChangeInfo& focusChangeInfo) override; + private: std::shared_ptr selectionI_; }; diff --git a/frameworks/native/selection_ability/include/selection_panel.h b/frameworks/native/selection_ability/include/selection_panel.h index 2bccb6e..871659a 100644 --- a/frameworks/native/selection_ability/include/selection_panel.h +++ b/frameworks/native/selection_ability/include/selection_panel.h @@ -30,11 +30,16 @@ #include "wm_common.h" #include "window.h" #include "ui/rs_surface_node.h" -#include "selection_window_info.h" #include "panel_status_listener.h" namespace OHOS { namespace SelectionFwk { +enum class SelectionWindowStatus : uint32_t { + HIDDEN, + DESTROYED, + NONE +}; + class SelectionPanel { public: static constexpr uint32_t INVALID_WINDOW_ID = 0; @@ -53,7 +58,7 @@ public: bool IsDestroyed() const; bool SetPanelStatusListener(std::shared_ptr statusListener, const std::string &type); void ClearPanelListener(const std::string &type); - int32_t GetWindowId(); + uint32_t GetWindowId(); uint32_t windowId_ = INVALID_WINDOW_ID; @@ -67,6 +72,7 @@ private: static uint32_t GenerateSequenceId(); void PanelStatusChange(const SelectionWindowStatus &status); bool MarkListener(const std::string &type, bool isRegister); + bool IsPanelListenerClearable(); PanelType panelType_ = PanelType::MENU_PANEL; int32_t x_ = 0; @@ -84,8 +90,8 @@ private: std::atomic isWaitSetUiContent_ { true }; std::shared_ptr panelStatusListener_ = nullptr; bool destroyedRegistered_ = false; - bool hiddedRegistered_ = false; - + bool hiddenRegistered_ = false; + SelectionWindowStatus windowStatus_ = SelectionWindowStatus::NONE; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/frameworks/native/selection_ability/include/selection_panel_manager.h b/frameworks/native/selection_ability/include/selection_panel_manager.h new file mode 100644 index 0000000..9e68b65 --- /dev/null +++ b/frameworks/native/selection_ability/include/selection_panel_manager.h @@ -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. + */ + + +#ifndef SELECTION_PANEL_MANAGER_H +#define SELECTION_PANEL_MANAGER_H +#include +#include +#include +#include +#include + +#include "selection_panel.h" + +namespace OHOS { +namespace SelectionFwk { +class SelectionPanelManager { +public: + static SelectionPanelManager& GetInstance(); + + ~SelectionPanelManager() = default; + void AddSelectionPanel(uint32_t id, std::shared_ptr &obj); + std::shared_ptr GetSelectionPanel(uint32_t id) const; + bool FindWindowID(uint32_t id) const; + void Dispose(); + +private: + SelectionPanelManager() = default; + + SelectionPanelManager(const SelectionPanelManager& other) = delete; + SelectionPanelManager& operator=(const SelectionPanelManager& other) = delete; + +private: + std::unordered_map> storage_; + mutable std::mutex mutex_; +}; +} // namespace SelectionFwk +} // namespace OHOS +#endif // SELECTION_PANEL_MANAGER_H diff --git a/frameworks/native/selection_ability/include/task_manager.h b/frameworks/native/selection_ability/include/task_manager.h index 16445e0..bf73c20 100644 --- a/frameworks/native/selection_ability/include/task_manager.h +++ b/frameworks/native/selection_ability/include/task_manager.h @@ -59,7 +59,7 @@ public: int32_t WaitExec(uint64_t seqId, uint32_t timeoutMs, std::function); private: - friend class SlectionAbility; + friend class SelectionAbility; friend class TaskAmsInit; void SetInited(bool flag); diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index 449196d..1642fc0 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -19,7 +19,8 @@ #include #include "selection_panel.h" #include "selection_log.h" -#include "selection_panel_manger.h" +#include "selection_panel_manager.h" +#include "selection_app_validator.h" namespace OHOS { namespace SelectionFwk { @@ -52,22 +53,35 @@ sptr SelectionAbility::GetInstance() int32_t SelectionAbility::CreatePanel(const std::shared_ptr &context, const PanelInfo &panelInfo, std::shared_ptr &selectionPanel) { - SELECTION_HILOGI("SelectionAbility CreatePanel start."); + SELECTION_HILOGI("enter CreatePanel, panelInfo: {panelType: %{public}d}", panelInfo.panelType); + std::ostringstream buffer; + panels_.ForEach([&](const PanelType &panelType, auto &) { + buffer << static_cast(panelType) << ","; + return false; + }); + auto panelTypes = buffer.str(); + SELECTION_HILOGI("panels_: %{public}s", panelTypes.c_str()); - auto flag = panels_.ComputeIfAbsent(panelInfo.panelType, - [&panelInfo, &context, &selectionPanel]( + if (!SelectionAppValidator::GetInstance().Validate()) { + SELECTION_HILOGE("bundleName is not valid"); + return ErrorCode::ERROR_INVALID_OPERATION; + } + + int32_t result = ErrorCode::NO_ERROR; + panels_.ComputeIfAbsent(panelInfo.panelType, + [&result, &panelInfo, &context, &selectionPanel] ( const PanelType &panelType, std::shared_ptr &panel) { selectionPanel = std::make_shared(); - auto ret = selectionPanel->CreatePanel(context, panelInfo); - if (ret == ErrorCode::NO_ERROR) { + result = selectionPanel->CreatePanel(context, panelInfo); + if (result == ErrorCode::NO_ERROR) { panel = selectionPanel; - SelectionPanelManger::GetInstance().AddSelectionPanel(selectionPanel->GetWindowId(), selectionPanel); + SelectionPanelManager::GetInstance().AddSelectionPanel(selectionPanel->GetWindowId(), selectionPanel); return true; } selectionPanel = nullptr; return false; }); - return flag ? ErrorCode::NO_ERROR : ErrorCode::ERROR_SELECTION_SERVICE; + return result; } int32_t SelectionAbility::DestroyPanel(const std::shared_ptr &selectionPanel) diff --git a/frameworks/native/selection_ability/src/selection_app_validator.cpp b/frameworks/native/selection_ability/src/selection_app_validator.cpp new file mode 100644 index 0000000..22302fb --- /dev/null +++ b/frameworks/native/selection_ability/src/selection_app_validator.cpp @@ -0,0 +1,37 @@ +/* + * 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 "selection_app_validator.h" +#include "selection_log.h" + + +namespace OHOS::SelectionFwk { + +SelectionAppValidator& SelectionAppValidator::GetInstance() +{ + static SelectionAppValidator instance; + return instance; +} + +void SelectionAppValidator::SetValid() +{ + isValid_ = true; +} + +bool SelectionAppValidator::Validate() const +{ + return isValid_; +} +} // namespace OHOS::SelectionFwk \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index c604d31..465ce9b 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -16,8 +16,10 @@ #include "selection_listener_impl.h" #include "selection_log.h" #include "selection_data_inner.h" -#include "selection_panel_manger.h" - +#include "selection_panel_manager.h" +#include "selection_ability.h" +#include "wm_common.h" +#include "window.h" namespace OHOS { namespace SelectionFwk { @@ -29,7 +31,7 @@ static void CopySelectionData(const SelectionInfoData& src, SelectionInfo& dst) ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionInfoData& selectionInfoData) { - SELECTION_HILOGI("Recveive selection data: %{public}s", selectionInfoData.data.text.c_str()); + SELECTION_HILOGI("Recveive selection data length: %{public}lu", selectionInfoData.data.text.length()); SelectionInfo selectionInfo; CopySelectionData(selectionInfoData, selectionInfo); if (selectionI_ == nullptr) { @@ -40,35 +42,26 @@ ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionInfoData& select return 0; } -ErrCode SelectionListenerImpl::FocusChange(uint32_t windowID, uint32_t windowType) +ErrCode SelectionListenerImpl::FocusChange(const SelectionFocusChangeInfo& focusChangeInfo) { - SELECTION_HILOGI("Recveive windowID: %{public}d", windowID); - if (selectionI_ == nullptr) { - SELECTION_HILOGE("selectionI_ is nullptr"); - return 1; - } - - auto& panelManager = SelectionPanelManger::GetInstance(); - if (!panelManager.FindWindowID(windowID)) { - return 0; + SELECTION_HILOGI("Recveive FocusChange: %{public}s.", focusChangeInfo.ToString().c_str()); + if (!focusChangeInfo.isFocused_) { + return NO_ERROR; } - auto selectionPanel = panelManager.GetSelectionPanel(windowID); - if (selectionPanel == nullptr) { - SELECTION_HILOGE("get selectionPanel is nullptr, windowID: %{public}d", windowID); - return 1; - } - if (selectionPanel->GetPanelType() == PanelType::MENU_PANEL) { - SELECTION_HILOGI("hide windowID: %{public}d", windowID); - panelManager.GetSelectionPanel(windowID)->HidePanel(); + auto selectionAppPid = getpid(); + if (selectionAppPid == focusChangeInfo.pid_) { + SELECTION_HILOGI("No need to hide or destory selection panel because window of selection app is focused."); + return NO_ERROR; } - if (selectionPanel->GetPanelType() == PanelType::MAIN_PANEL) { - SELECTION_HILOGI("destroy windowID: %{public}d", windowID); - panelManager.GetSelectionPanel(windowID)->DestroyPanel(); - panelManager.RemoveSelectionPanel(windowID); + auto& panelManager = SelectionPanelManager::GetInstance(); + if (!panelManager.FindWindowID(focusChangeInfo.windowId_)) { + SELECTION_HILOGI("The focus window is not a selection window, hide or destroy selection panels."); + panelManager.Dispose(); + return NO_ERROR; } - return 0; -} + return NO_ERROR; +} } // namespace SelectionFramework } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_panel.cpp b/frameworks/native/selection_ability/src/selection_panel.cpp index c757e49..1c8fb98 100644 --- a/frameworks/native/selection_ability/src/selection_panel.cpp +++ b/frameworks/native/selection_ability/src/selection_panel.cpp @@ -23,7 +23,7 @@ #include "scene_board_judgement.h" #include "selection_log.h" #include "selectionmethod_trace.h" -#include "selection_panel_manger.h" +#include "selection_panel_manager.h" namespace OHOS { namespace SelectionFwk { @@ -33,9 +33,13 @@ using namespace Rosen; using WindowGravity = OHOS::Rosen::WindowGravity; using WindowState = OHOS::Rosen::WindowState; std::atomic SelectionPanel::sequenceId_ { 0 }; -constexpr int32_t MAXWAITTIME = 30; -constexpr int32_t WAITTIME = 10; +constexpr int32_t MAXWAITTIMES = 3; +constexpr int32_t WAITTIME = 100000; std::mutex SelectionPanel::windowMutex_; +static std::map windowTypeToName = { + {PanelType::MAIN_PANEL, "SelectionMainFwkWindow"}, + {PanelType::MENU_PANEL, "SelectionMenuFwkWindow"} +}; SelectionPanel::~SelectionPanel() = default; int32_t SelectionPanel::CreatePanel( @@ -51,55 +55,18 @@ int32_t SelectionPanel::CreatePanel( "start , panelType/x/y/width/height: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", static_cast(panelType_), x_, y_, width_, height_); - // winOption_ = new (std::nothrow) OHOS::Rosen::WindowOption(); - // if (winOption_ == nullptr) { - // return ErrorCode::ERROR_SELECTION_SERVICE; - // } - // winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DYNAMIC); - // winOption_->SetWindowRect(OHOS::Rosen::Rect{10, 10, 80, 50}); - // WMError wmError = WMError::WM_OK; - // window_ = OHOS::Rosen::Window::Create(GeneratePanelName(), winOption_, context, wmError); - // if (wmError == WMError::WM_ERROR_INVALID_PERMISSION || wmError == WMError::WM_ERROR_NOT_SYSTEM_APP) { - // SELECTION_HILOGE("create window failed, permission denied, %{public}d!", wmError); - // return ErrorCode::ERROR_NOT_IME; - // } - // if (window_ == nullptr || wmError != WMError::WM_OK) { - // SELECTION_HILOGE("create window failed: %{public}d!", wmError); - // return ErrorCode::ERROR_SELECTION_SERVICE; - // } - // isScbEnable_ = Rosen::SceneBoardJudgement::IsSceneBoardEnabled(); - // if (SetPanelProperties() != ErrorCode::NO_ERROR) { - // wmError = window_->Destroy(); - // SELECTION_HILOGI("destroy window end, wmError is %{public}d.", wmError); - // return ErrorCode::ERROR_SELECTION_SERVICE; - // } - // windowId_ = window_->GetWindowId(); - // SELECTION_HILOGI("success, type/flag/windowId/isScbEnable_: %{public}d/%{public}d/%{public}u/%{public}d.", - // static_cast(panelType_), static_cast(panelFlag_), windowId_, isScbEnable_); - // // if (panelInfo.panelType == SOFT_KEYBOARD && isScbEnable_) { - // // RegisterKeyboardPanelInfoChangeListener(); - // // } - // window_->RaiseToAppTop(); - // SELECTION_HILOGI("selectionPanel RaiseToAppTop 2."); - // window_->Resize(80, 50); - // window_->SetBackgroundColor("green"); - // window_->Show(); - // window_->Resize(80, 50); - // window_->SetBackgroundColor("green"); - // SELECTION_HILOGI("selectionPanel show."); - OHOS::Rosen::Rect baseWindowRect = { 150, 150, 400, 600 }; sptr baseOp = new Rosen::WindowOption(); - baseOp->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); - baseOp->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FULLSCREEN); - baseOp->SetWindowRect(baseWindowRect); - baseOp->SetZIndex(1980); - auto displayId = Rosen::DisplayManager::GetInstance().GetDefaultDisplayId(); - baseOp->SetDisplayId(displayId); - - sptr window = Rosen::Window::Create("Demo_SSW_BaseWindow", baseOp, nullptr); + baseOp->SetWindowType(Rosen::WindowType::WINDOW_TYPE_SELECTION); + baseOp->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING); + OHOS::Rosen::Rect windowRect = {x_, y_, width_, height_}; + baseOp->SetWindowRect(windowRect); + WMError wmError = WMError::WM_OK; + auto windowName = windowTypeToName[panelInfo.panelType]; + sptr window = Rosen::Window::Create(windowName, baseOp, context, wmError); + SELECTION_HILOGI("Window creation returns %{public}d", wmError); if (!window) { SELECTION_HILOGE("Window creation failed"); - return ErrorCode::NO_ERROR; + return ErrorCode::ERROR_SELECTION_SERVICE; } window_ = window; SELECTION_HILOGI("Window::Create Success"); @@ -109,7 +76,7 @@ int32_t SelectionPanel::CreatePanel( std::string SelectionPanel::GeneratePanelName() { uint32_t sequenceId = GenerateSequenceId(); - std::string windowName = panelType_ == MENU_PANEL ? "menuPanel" + std::to_string(sequenceId) : + std::string windowName = panelType_ == PanelType::MENU_PANEL ? "menuPanel" + std::to_string(sequenceId) : "mainPanel" + std::to_string(sequenceId); SELECTION_HILOGD("SelectionPanel, windowName: %{public}s.", windowName.c_str()); return windowName; @@ -141,6 +108,10 @@ int32_t SelectionPanel::SetPanelProperties() int32_t SelectionPanel::DestroyPanel() { + if (windowStatus_ == SelectionWindowStatus::DESTROYED) { + SELECTION_HILOGE("window has destroyed!"); + return ErrorCode::NO_ERROR; + } auto ret = HidePanel(); if (ret != ErrorCode::NO_ERROR) { SELECTION_HILOGE("SelectionPanel, hide panel failed, ret: %{public}d!", ret); @@ -150,36 +121,35 @@ int32_t SelectionPanel::DestroyPanel() return ErrorCode::ERROR_SELECTION_SERVICE; } auto result = window_->Destroy(); + window_ = nullptr; SELECTION_HILOGI("destroy ret: %{public}d", result); + windowStatus_ = SelectionWindowStatus::DESTROYED; PanelStatusChange(SelectionWindowStatus::DESTROYED); return ErrorCode::NO_ERROR; } uint32_t SelectionPanel::GenerateSequenceId() { - uint32_t seqId = ++sequenceId_; - if (seqId == std::numeric_limits::max()) { - return ++sequenceId_; - } - return seqId; + uint32_t seqId = sequenceId_.fetch_add(1, std::memory_order_seq_cst); + return seqId % std::numeric_limits::max(); } int32_t SelectionPanel::SetUiContent(const std::string &contentInfo, napi_env env) { if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr, can not SetUiContent!"); - return ErrorCode::ERROR_SELECTION_SERVICE; + return ErrorCode::ERROR_PANEL_DESTROYED; } - if(IsDestroyed()) { + if (IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); - return ErrorCode::ERROR_PANEL_DESTORYED; + return ErrorCode::ERROR_PANEL_DESTROYED; } WMError ret = WMError::WM_OK; - window_->NapiSetUIContent(contentInfo, env, nullptr); + ret = window_->NapiSetUIContent(contentInfo, env, nullptr); WMError wmError = window_->SetTransparent(true); - if (isWaitSetUiContent_) { - isWaitSetUiContent_ = false; + if (isWaitSetUiContent_.load()) { + isWaitSetUiContent_.store(false); } SELECTION_HILOGI("SetTransparent ret: %{public}u.", wmError); SELECTION_HILOGI("NapiSetUIContent ret: %{public}d.", ret); @@ -194,20 +164,26 @@ PanelType SelectionPanel::GetPanelType() int32_t SelectionPanel::ShowPanel() { SELECTION_HILOGD("SelectionPanel start."); - int32_t waitTime = 0; - while (isWaitSetUiContent_ && waitTime < MAXWAITTIME) { - std::this_thread::sleep_for(std::chrono::milliseconds(WAITTIME)); - waitTime += WAITTIME; - SELECTION_HILOGI("SelectionPanel show pannel waitTime %{public}d.", waitTime); - } if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_SELECTION_SERVICE; + return ErrorCode::ERROR_PANEL_DESTROYED; } - if(IsDestroyed()) { + if (IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); - return ErrorCode::ERROR_PANEL_DESTORYED; + return ErrorCode::ERROR_PANEL_DESTROYED; } + int32_t iCounter = 0; + while (isWaitSetUiContent_.load() && iCounter < MAXWAITTIMES) { + usleep(WAITTIME); + iCounter++; + SELECTION_HILOGI("SelectionPanel show pannel waitTime %{public}d.", iCounter); + } + + if (isWaitSetUiContent_.load()) { + SELECTION_HILOGE("isWaitSetUiContent_ is true!"); + return ErrorCode::ERROR_SELECTION_SERVICE; + } + if (IsShowing()) { SELECTION_HILOGI("panel already shown."); return ErrorCode::NO_ERROR; @@ -215,13 +191,14 @@ int32_t SelectionPanel::ShowPanel() auto ret = WMError::WM_OK; { SelectionMethodSyncTrace tracer("SelectionPanel_ShowPanel"); - ret = window_->Show(); + ret = window_->Show(0, false, false); } if (ret != WMError::WM_OK) { SELECTION_HILOGE("ShowPanel error, err = %{public}d", ret); return ErrorCode::ERROR_SELECTION_SERVICE; } SELECTION_HILOGI("Selection panel shown successfully."); + windowStatus_ = SelectionWindowStatus::NONE; return ErrorCode::NO_ERROR; } @@ -241,27 +218,40 @@ bool SelectionPanel::IsShowing() void SelectionPanel::PanelStatusChange(const SelectionWindowStatus &status) { - if (panelStatusListener_ != nullptr) { - SELECTION_HILOGD("panelStatusListener_ is not nullptr."); - if (status == SelectionWindowStatus::HIDDEN && hiddedRegistered_ ) { - panelStatusListener_->OnPanelStatus(windowId_, panelStatusMap_.at(status)); - } - if (status == SelectionWindowStatus::DESTROYED && destroyedRegistered_ ) { - panelStatusListener_->OnPanelStatus(windowId_, panelStatusMap_.at(status)); - } + if (panelStatusListener_ == nullptr) { + SELECTION_HILOGE("panelStatusListener_ is nullptr."); + return; + } + + auto itr = panelStatusMap_.find(status); + if (itr == panelStatusMap_.end()) { + SELECTION_HILOGE("wrong status."); + return; + } + + if (status == SelectionWindowStatus::HIDDEN && hiddenRegistered_) { + panelStatusListener_->OnPanelStatus(windowId_, itr->second); + } + if (status == SelectionWindowStatus::DESTROYED && destroyedRegistered_) { + panelStatusListener_->OnPanelStatus(windowId_, itr->second); } } int32_t SelectionPanel::HidePanel() { SELECTION_HILOGD("SelectionPanel start"); + if (windowStatus_ == SelectionWindowStatus::HIDDEN) { + SELECTION_HILOGE("window has hidden!"); + return ErrorCode::NO_ERROR; + } + if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_SELECTION_SERVICE; + return ErrorCode::ERROR_PANEL_DESTROYED; } - if(IsDestroyed()) { + if (IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); - return ErrorCode::ERROR_PANEL_DESTORYED; + return ErrorCode::ERROR_PANEL_DESTROYED; } if (IsHidden()) { SELECTION_HILOGI("panel already hidden."); @@ -278,6 +268,7 @@ int32_t SelectionPanel::HidePanel() } SELECTION_HILOGI("success, panelType/x/y/width/height: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d.", static_cast(panelType_), x_, y_, width_, height_); + windowStatus_ = SelectionWindowStatus::HIDDEN; PanelStatusChange(SelectionWindowStatus::HIDDEN); return ErrorCode::NO_ERROR; } @@ -301,11 +292,11 @@ int32_t SelectionPanel::StartMoving() { if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_SELECTION_SERVICE; + return ErrorCode::ERROR_PANEL_DESTROYED; } - if(IsDestroyed()) { + if (IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); - return ErrorCode::ERROR_PANEL_DESTORYED; + return ErrorCode::ERROR_PANEL_DESTROYED; } auto ret = window_->StartMoveWindow(); if (ret == WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT) { @@ -325,11 +316,11 @@ int32_t SelectionPanel::MoveTo(int32_t x, int32_t y) SELECTION_HILOGD("moveto start!"); if (window_ == nullptr) { SELECTION_HILOGE("window_ is nullptr!"); - return ErrorCode::ERROR_SELECTION_SERVICE; + return ErrorCode::ERROR_PANEL_DESTROYED; } - if(IsDestroyed()) { + if (IsDestroyed()) { SELECTION_HILOGE("window is destroyed!"); - return ErrorCode::ERROR_PANEL_DESTORYED; + return ErrorCode::ERROR_PANEL_DESTROYED; } auto ret = window_->MoveTo(x, y); SELECTION_HILOGI("x/y: %{public}d/%{public}d, ret = %{public}d", x, y, ret); @@ -355,10 +346,12 @@ bool SelectionPanel::SetPanelStatusListener(std::shared_ptr bool SelectionPanel::MarkListener(const std::string &type, bool isRegister) { - if (type == panelStatusMap_.at(SelectionWindowStatus::DESTROYED)) { + if (panelStatusMap_.find(SelectionWindowStatus::DESTROYED) != panelStatusMap_.end() && + type == panelStatusMap_.at(SelectionWindowStatus::DESTROYED)) { destroyedRegistered_ = isRegister; - } else if (type == panelStatusMap_.at(SelectionWindowStatus::HIDDEN)) { - hiddedRegistered_ = isRegister; + } else if (panelStatusMap_.find(SelectionWindowStatus::HIDDEN) != panelStatusMap_.end() && + type == panelStatusMap_.at(SelectionWindowStatus::HIDDEN)) { + hiddenRegistered_ = isRegister; } else { SELECTION_HILOGE("type error!"); return false; @@ -376,18 +369,21 @@ void SelectionPanel::ClearPanelListener(const std::string &type) SELECTION_HILOGD("panelStatusListener_ not set, don't need to remove."); return; } - if (destroyedRegistered_ || hiddedRegistered_) { + if (IsPanelListenerClearable()) { return; } panelStatusListener_ = nullptr; } -int32_t SelectionPanel::GetWindowId() +bool SelectionPanel::IsPanelListenerClearable() +{ + return (destroyedRegistered_ || hiddenRegistered_); +} + +uint32_t SelectionPanel::GetWindowId() { std::lock_guard lock(windowMutex_); return window_->GetWindowId(); - } - } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_ability/src/selection_panel_manager.cpp b/frameworks/native/selection_ability/src/selection_panel_manager.cpp new file mode 100644 index 0000000..20fc5ea --- /dev/null +++ b/frameworks/native/selection_ability/src/selection_panel_manager.cpp @@ -0,0 +1,73 @@ +/* + * 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 "selection_panel_manager.h" +#include "selection_ability.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { + +SelectionPanelManager& SelectionPanelManager::GetInstance() +{ + static SelectionPanelManager instance; + return instance; +} + +void SelectionPanelManager::AddSelectionPanel(uint32_t id, std::shared_ptr &obj) +{ + std::lock_guard lock(mutex_); + if (obj == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr"); + return; + } + storage_[id] = obj; +} + +std::shared_ptr SelectionPanelManager::GetSelectionPanel(uint32_t id) const +{ + std::lock_guard lock(mutex_); + auto it = storage_.find(id); + return (it != storage_.end()) ? it->second : nullptr; +} + +bool SelectionPanelManager::FindWindowID(uint32_t id) const +{ + std::lock_guard lock(mutex_); + return storage_.find(id) != storage_.end(); +} + +void SelectionPanelManager::Dispose() +{ + std::lock_guard lock(mutex_); + for (auto iter = storage_.begin(); iter != storage_.end();) { + auto selectionPanel = iter->second; + if (selectionPanel == nullptr) { + SELECTION_HILOGE("selectionPanel is nullptr"); + ++iter; + continue; + } + if (selectionPanel->GetPanelType() == PanelType::MENU_PANEL) { + selectionPanel->HidePanel(); + } else if (selectionPanel->GetPanelType() == PanelType::MAIN_PANEL) { + SelectionAbility::GetInstance()->DestroyPanel(selectionPanel); + iter = storage_.erase(iter); + continue; + } + ++iter; + } +} +} // namespace SelectionFwk +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/selection_client/selection_client.cpp b/frameworks/native/selection_client/selection_client.cpp new file mode 100644 index 0000000..b737991 --- /dev/null +++ b/frameworks/native/selection_client/selection_client.cpp @@ -0,0 +1,50 @@ +/* + * 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 "selection_client.h" + +#include "iselection_service.h" +#include "iservice_registry.h" +#include "selection_log.h" +#include "system_ability_definition.h" + +using namespace OHOS; +using namespace OHOS::SelectionFwk; + +SelectionClient& SelectionClient::GetInstance() +{ + static SelectionClient instance; + return instance; +} + +bool SelectionClient::IsCurrentSelectionApp(int pid) +{ + SELECTION_HILOGI("SelectionClient::IsCurrentSelectionApp"); + bool result = false; + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + SELECTION_HILOGE("system ability manager is nullptr!"); + return result; + } + sptr systemAbility = nullptr; + systemAbility = systemAbilityManager->GetSystemAbility(SELECTION_FWK_SA_ID); + if (systemAbility == nullptr) { + SELECTION_HILOGE("get system ability is nullptr!"); + return result; + } + auto abilityManager = iface_cast(systemAbility); + abilityManager->IsCurrentSelectionApp(pid, result); + return result; +} \ No newline at end of file diff --git a/frameworks/native/selection_extension/include/selection_extension_context.h b/frameworks/native/selection_extension/include/selection_extension_context.h index b0a22b4..6ea410f 100644 --- a/frameworks/native/selection_extension/include/selection_extension_context.h +++ b/frameworks/native/selection_extension/include/selection_extension_context.h @@ -26,6 +26,18 @@ public: SelectionExtensionContext() = default; virtual ~SelectionExtensionContext() = default; + /** + * @brief Starts a new ability. + * An ability using the AbilityInfo.AbilityType.SERVICE or AbilityInfo.AbilityType.PAGE template uses this method + * to start a specific ability. The system locates the target ability from installed abilities based on the value + * of the want parameter and then starts it. You can specify the ability to start using the want parameter. + * + * @param want Indicates the Want containing information about the target ability to start. + * + * @return errCode ERR_OK on success, others on failure. + */ + ErrCode StartAbility(const AAFwk::Want& want) const; + static const size_t CONTEXT_TYPE_ID; protected: diff --git a/frameworks/native/selection_extension/src/js_selection_extension.cpp b/frameworks/native/selection_extension/src/js_selection_extension.cpp index b64c814..36e8bac 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension.cpp @@ -40,7 +40,8 @@ napi_value AttachSelectionExtensionContext(napi_env env, void* value, void*) return nullptr; } napi_value object = CreateJsSelectionExtensionContext(env, ptr); - auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "selectionInput.SelectionExtensionContext", &object, 1); + auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "selectionInput.SelectionExtensionContext", + &object, 1); if (systemModule == nullptr) { SELECTION_HILOGE("failed to load system module by engine!"); return nullptr; @@ -148,6 +149,11 @@ napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const { SELECTION_HILOGI("JsSelectionExtension::CallObjectMethod(%{public}s), start.", methodName); + if (argc > 0 && argv == nullptr) { + SELECTION_HILOGE("argc > 0 && argv == nullptr."); + return nullptr; + } + if (jsObj_ == nullptr) { SELECTION_HILOGE("not found JsSelectionExtension.js."); return nullptr; @@ -178,21 +184,23 @@ napi_value JsSelectionExtension::CallObjectMethod(const char* methodName, const void JsSelectionExtension::GetSrcPath(std::string& srcPath) { if (!Extension::abilityInfo_->isModuleJson) { - /* temporary compatibility api8 + config.json */ - srcPath.append(Extension::abilityInfo_->package); - srcPath.append("/assets/js/"); + std::filesystem::path modulePath(Extension::abilityInfo_->package); + modulePath /= "assets/js"; + if (!Extension::abilityInfo_->srcPath.empty()) { - srcPath.append(Extension::abilityInfo_->srcPath); + modulePath /= Extension::abilityInfo_->srcPath; } - srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc"); + + modulePath /= (Extension::abilityInfo_->name + ".abc"); + srcPath = modulePath.string(); return; } if (!Extension::abilityInfo_->srcEntrance.empty()) { - srcPath.append(Extension::abilityInfo_->moduleName + "/"); - srcPath.append(Extension::abilityInfo_->srcEntrance); - srcPath.erase(srcPath.rfind('.')); - srcPath.append(".abc"); + std::filesystem::path modulePath(Extension::abilityInfo_->moduleName); + modulePath /= Extension::abilityInfo_->srcEntrance; + modulePath.replace_extension(".abc"); + srcPath = modulePath.string(); } } @@ -206,7 +214,8 @@ void JsSelectionExtension::BindContext(napi_env env, napi_value obj) } SELECTION_HILOGD("JsSelectionExtension::Init CreateJsSelectionExtensionContext."); napi_value contextObj = CreateJsSelectionExtensionContext(env, context); - auto shellContextRef = jsRuntime_.LoadSystemModule("selectionInput.SelectionExtensionContext", &contextObj, ARGC_ONE); + auto shellContextRef = jsRuntime_.LoadSystemModule("selectionInput.SelectionExtensionContext", + &contextObj, ARGC_ONE); if (shellContextRef == nullptr) { SELECTION_HILOGE("shellContextRef is nullptr!"); return; @@ -221,13 +230,17 @@ void JsSelectionExtension::BindContext(napi_env env, napi_value obj) SELECTION_HILOGE("workContext is nullptr!"); return; } - napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachSelectionExtensionContext, - workContext, nullptr); + napi_status status = napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, + AttachSelectionExtensionContext, workContext, nullptr); + if (status != napi_ok) { + SELECTION_HILOGE("napi_coerce_to_native_binding_object failed!"); + return; + } SELECTION_HILOGD("JsSelectionExtension::Init Bind."); context->Bind(jsRuntime_, shellContextRef.release()); SELECTION_HILOGD("JsSelectionExtension::SetProperty."); napi_set_named_property(env, obj, "context", contextObj); - napi_status status = napi_wrap( + status = napi_wrap( env, contextObj, workContext, [](napi_env, void* data, void*) { SELECTION_HILOGI("Finalizer for weak_ptr input method extension context is called."); diff --git a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp index 713f2b7..875cabe 100644 --- a/frameworks/native/selection_extension/src/js_selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/js_selection_extension_context.cpp @@ -25,6 +25,9 @@ namespace OHOS::AbilityRuntime { using namespace OHOS::SelectionFwk; namespace { +constexpr int32_t INDEX_ZERO = 0; +constexpr int32_t ERROR_CODE_ONE = 1; +constexpr size_t ARGC_ONE = 1; class JsSelectionExtensionContext final { public: @@ -41,8 +44,54 @@ public: std::unique_ptr(static_cast(data)); } + static napi_value StartAbility(napi_env env, napi_callback_info info) + { + GET_CB_INFO_AND_CALL(env, info, JsSelectionExtensionContext, OnStartAbility); + } + private: std::weak_ptr context_; + + napi_value OnStartAbility(napi_env env, size_t argc, napi_value* argv) + { + SELECTION_HILOGI("SelectionExtensionContext OnStartAbility."); + // only support one params + PARAM_CHECK_RETURN(env, argc == ARGC_ONE, "number of param should in 1", TYPE_NONE, CreateJsUndefined(env)); + PARAM_CHECK_RETURN(env, JsUtil::GetType(env, argv[0]) == napi_object, "param want type must be Want", TYPE_NONE, + JsUtil::Const::Null(env)); + decltype(argc) unwrapArgc = 0; + AAFwk::Want want; + OHOS::AppExecFwk::UnwrapWant(env, argv[INDEX_ZERO], want); + SELECTION_HILOGI("%{public}s bundleName: %{public}s abilityName: %{public}s.", __func__, + want.GetBundle().c_str(), want.GetElement().GetAbilityName().c_str()); + unwrapArgc++; + napi_value lastParam = argc > unwrapArgc ? argv[unwrapArgc] : nullptr; + napi_value result = nullptr; + std::unique_ptr napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result); + auto asyncTask = [weak = context_, want, unwrapArgc, env, task = napiAsyncTask.get()]() { + SELECTION_HILOGI("startAbility start."); + auto context = weak.lock(); + if (context == nullptr) { + SELECTION_HILOGW("context is released."); + task->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "Context is released")); + delete task; + return; + } + ErrCode errcode = (unwrapArgc == 1) ? context->StartAbility(want) : ERR_INVALID_VALUE; + if (errcode == 0) { + task->Resolve(env, CreateJsUndefined(env)); + } else { + task->Reject(env, CreateJsErrorByNativeErr(env, errcode)); + } + delete task; + }; + if (napi_send_event(env, asyncTask, napi_eprio_high) != napi_status::napi_ok) { + napiAsyncTask->Reject(env, CreateJsError(env, ERROR_CODE_ONE, "send event failed")); + } else { + napiAsyncTask.release(); + } + return result; + } }; } // namespace @@ -57,6 +106,9 @@ napi_value CreateJsSelectionExtensionContext(napi_env env, std::shared_ptr jsContext = std::make_unique(context); napi_wrap(env, objValue, jsContext.release(), JsSelectionExtensionContext::Finalizer, nullptr, nullptr); + + const char* moduleName = "JsSelectionExtensionContext"; + BindNativeFunction(env, objValue, "startAbility", moduleName, JsSelectionExtensionContext::StartAbility); return objValue; } } // namespace OHOS::AbilityRuntime diff --git a/frameworks/native/selection_extension/src/selection_extension_context.cpp b/frameworks/native/selection_extension/src/selection_extension_context.cpp index 9d8ec12..d0163c7 100644 --- a/frameworks/native/selection_extension/src/selection_extension_context.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_context.cpp @@ -19,4 +19,17 @@ namespace OHOS::AbilityRuntime { const size_t SelectionExtensionContext::CONTEXT_TYPE_ID(std::hash {}("SelectionExtensionContext")); +int32_t SelectionExtensionContext::ILLEGAL_REQUEST_CODE(-1); + +ErrCode SelectionExtensionContext::StartAbility(const AAFwk::Want& want) const +{ + SELECTION_HILOGD("%{public}s begin.", __func__); + ErrCode err = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want, token_, ILLEGAL_REQUEST_CODE); + SELECTION_HILOGD("%{public}s ret=%{public}d", __func__, err); + if (err != ERR_OK) { + SELECTION_HILOGE("SelectionExtensionContext::StartAbility failed: %{public}d", err); + } + return err; +} + } // namespace OHOS::AbilityRuntime \ No newline at end of file diff --git a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp index c60c1cd..f4c24a8 100644 --- a/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp +++ b/frameworks/native/selection_extension/src/selection_extension_module_loader.cpp @@ -29,7 +29,7 @@ Extension* SelectionExtensionModuleLoader::Create(const std::unique_ptr std::map SelectionExtensionModuleLoader::GetParams() { // type means extension type in ExtensionAbilityType of extension_ability_info.h - return {{"type", "46"}, {"name", "SelectionExtensionAbility"}}; + return {{"type", "31"}, {"name", "SelectionExtensionAbility"}}; } extern "C" __attribute__((visibility("default"))) void* OHOS_EXTENSION_GetExtensionModule() diff --git a/interfaces/idl/BUILD.gn b/interfaces/idl/BUILD.gn new file mode 100644 index 0000000..eca108f --- /dev/null +++ b/interfaces/idl/BUILD.gn @@ -0,0 +1,136 @@ +# 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("//build/config/components/idl_tool/idl.gni") +import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") + +idl_gen_interface("selection_listener_interface") { + src_idl = rebase_path("ISelectionListener.idl") +} + +idl_gen_interface("selection_service_interface") { + src_idl = rebase_path("ISelectionService.idl") +} + +config("selection_listener_config") { + include_dirs = [ + "include", + "${selection_fwk_root_path}/common", + "${target_gen_dir}", + ] +} + +config("selection_service_config") { + include_dirs = [ + "include", + "${selection_fwk_root_path}/common", + "${target_gen_dir}", + ] +} + +ohos_source_set("selection_listener_proxy") { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + include_dirs = [ + "${target_gen_dir}", + ] + + public_configs = [":selection_listener_config"] + output_values = get_target_outputs(":selection_listener_interface") + sources = filter_include(output_values, [ "*_proxy.cpp" ]) + deps = [ ":selection_listener_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} + +ohos_source_set("selection_listener_stub") { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + include_dirs = [ + "${target_gen_dir}", + ] + + public_configs = [":selection_listener_config"] + output_values = get_target_outputs(":selection_listener_interface") + sources = filter_include(output_values, [ "*_stub.cpp" ]) + deps = [ ":selection_listener_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} + +ohos_source_set("selection_service_proxy") { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + include_dirs = [ + "${target_gen_dir}", + ] + + public_configs = [":selection_service_config"] + output_values = get_target_outputs(":selection_service_interface") + sources = filter_include(output_values, [ "*_proxy.cpp" ]) + deps = [ ":selection_service_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} + +ohos_source_set("selection_service_stub") { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + include_dirs = [ + "${target_gen_dir}", + ] + + public_configs = [":selection_service_config"] + output_values = get_target_outputs(":selection_service_interface") + sources = filter_include(output_values, [ "*_stub.cpp" ]) + deps = [ ":selection_service_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} diff --git a/interfaces/idl/ISelectionListener.idl b/interfaces/idl/ISelectionListener.idl new file mode 100644 index 0000000..febdb02 --- /dev/null +++ b/interfaces/idl/ISelectionListener.idl @@ -0,0 +1,22 @@ +/* + * 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. + */ + +sequenceable selection_data_inner..OHOS.SelectionFwk.SelectionInfoData; +sequenceable selection_data_inner..OHOS.SelectionFwk.SelectionFocusChangeInfo; + +interface OHOS.SelectionFwk.ISelectionListener { + void OnSelectionChange([in] SelectionInfoData selectionInfoData); + void FocusChange([in] SelectionFocusChangeInfo focusChangeInfo); +} diff --git a/interfaces/idl/ISelectionService.idl b/interfaces/idl/ISelectionService.idl new file mode 100644 index 0000000..c64f3b2 --- /dev/null +++ b/interfaces/idl/ISelectionService.idl @@ -0,0 +1,22 @@ +/* + * 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. + */ + +interface OHOS.SelectionFwk.ISelectionListener; + +interface OHOS.SelectionFwk.ISelectionService { + void RegisterListener([in] ISelectionListener listener); + void UnregisterListener([in] ISelectionListener listener); + void IsCurrentSelectionApp([in] int pid, [out] boolean resultValue); +} \ No newline at end of file diff --git a/interfaces/inner_kits/selection_client/BUILD.gn b/interfaces/inner_kits/selection_client/BUILD.gn new file mode 100644 index 0000000..21713c0 --- /dev/null +++ b/interfaces/inner_kits/selection_client/BUILD.gn @@ -0,0 +1,75 @@ +# 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/systemabilitymgr/selectionfwk/selection_service.gni") + + +config("selection_client_native_public_config") { + visibility = [ + "./*", + "//foundation/systemabilitymgr/selectionfwk/interfaces/inner_kits/selection_client/*", + ] + include_dirs = [ + "include", + ] +} + +ohos_shared_library("selection_client") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + integer_overflow = true + ubsan = true + } + + version_script = "selection_client.versionscript" + + innerapi_tags = [ "platformsdk" ] + + include_dirs = [ + "include", + "../../../utils/include", + ] + + sources = [ + "../../../frameworks/native/selection_client/selection_client.cpp", + ] + + deps = [ + "${selection_fwk_root_path}/interfaces/idl:selection_service_proxy", + "${selection_fwk_root_path}/interfaces/idl:selection_listener_proxy", + ] + + cflags_cc = [ "-std=c++17" ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "ipc:ipc_single", + "ffrt:libffrt", + "samgr:samgr_proxy", + ] + + public_configs = [ + ":selection_client_native_public_config", + ] + + subsystem_name = "systemabilitymgr" + part_name = "selectionfwk" +} diff --git a/interfaces/inner_kits/selection_client/include/selection_client.h b/interfaces/inner_kits/selection_client/include/selection_client.h new file mode 100644 index 0000000..f249bb4 --- /dev/null +++ b/interfaces/inner_kits/selection_client/include/selection_client.h @@ -0,0 +1,27 @@ +/* + * 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 SELECTION_CLIENT_H +#define SELECTION_CLIENT_H + +#include "visibility.h" + +class SelectionClient { +public: + SELECTION_API static SelectionClient& GetInstance(); + bool IsCurrentSelectionApp(int pid); +}; + +#endif // SELECTION_CLIENT_H \ No newline at end of file diff --git a/interfaces/inner_kits/selection_client/include/visibility.h b/interfaces/inner_kits/selection_client/include/visibility.h new file mode 100644 index 0000000..f50aad3 --- /dev/null +++ b/interfaces/inner_kits/selection_client/include/visibility.h @@ -0,0 +1,23 @@ +/* + * 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 OH_SELECTION_VISIBILITY_H +#define OH_SELECTION_VISIBILITY_H + +#ifndef SELECTION_API +#define SELECTION_API __attribute__((visibility("default"))) +#endif + +#endif // OH_SELECTION_VISIBILITY_H diff --git a/interfaces/inner_kits/selection_client/selection_client.versionscript b/interfaces/inner_kits/selection_client/selection_client.versionscript new file mode 100644 index 0000000..217b0dc --- /dev/null +++ b/interfaces/inner_kits/selection_client/selection_client.versionscript @@ -0,0 +1,19 @@ +# 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. + +1.0 { + global: + *SelectionClient*; + local: + *; +}; diff --git a/service/BUILD.gn b/service/BUILD.gn index 9136972..b830460 100644 --- a/service/BUILD.gn +++ b/service/BUILD.gn @@ -12,11 +12,9 @@ # limitations under the License. import("//build/ohos.gni") -import("//build/config/components/idl_tool/idl.gni") import("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") config("selection_sa_config") { - # visibility = [ ":*" ] include_dirs = [ "include", "../utils/include", @@ -24,40 +22,6 @@ config("selection_sa_config") { ] } -idl_interface_sources = [ - "${target_gen_dir}/selection_service_proxy.cpp", - "${target_gen_dir}/selection_service_stub.cpp", -] - -idl_gen_interface("selection_service_interface") { - src_idl = rebase_path("ISelectionService.idl") - dst_file = string_join(",", idl_interface_sources) -} - -ohos_source_set("selection_service_proxy") { - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - include_dirs = [ - "${target_gen_dir}", - ] - - public_configs = [":selection_sa_config"] - output_values = get_target_outputs(":selection_service_interface") - sources = filter_include(output_values, [ "*_proxy.cpp" ]) - deps = [ ":selection_service_interface" ] - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - "ipc:ipc_single", - ] - part_name = "selectionfwk" - subsystem_name = "systemabilitymgr" -} - ohos_shared_library("selection_service") { branch_protector_ret = "pac_ret" sanitize = { @@ -76,7 +40,6 @@ ohos_shared_library("selection_service") { "-std=c++17", ] configs = [ ":selection_sa_config", ] - output_values = get_target_outputs(":selection_service_interface") include_dirs = [ "./focus_monitor/include", @@ -88,21 +51,24 @@ ohos_shared_library("selection_service") { "src/selection_input_monitor.cpp", "focus_monitor/src/focus_change_listener.cpp", "focus_monitor/src/focus_monitor_manager.cpp", + "src/selection_app_validator.cpp", "src/selection_config.cpp", "src/selection_config_database.cpp", "src/sys_selection_config_repository.cpp", "src/selection_config_comparator.cpp", + "src/selection_common.cpp", ] - sources += filter_include(output_values, [ "*.cpp" ]) deps = [ - ":selection_service_interface", + "${selection_fwk_root_path}/interfaces/idl:selection_service_interface", "${selection_fwk_root_path}/common:selection_common", - "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_listener_proxy", + "${selection_fwk_root_path}/interfaces/idl:selection_service_stub", + "${selection_fwk_root_path}/interfaces/idl:selection_listener_proxy", ] external_deps = [ "ability_base:want", "ability_runtime:ability_manager", + "access_token:libaccesstoken_sdk", "c_utils:utils", "napi:ace_napi", "hilog:libhilog", @@ -112,7 +78,6 @@ ohos_shared_library("selection_service") { "pasteboard:pasteboard_client", "safwk:system_ability_fwk", "samgr:samgr_proxy", - "screenlock_mgr:screenlock_client", "input:libmmi-client", "window_manager:libdm_lite", "window_manager:libwsutils", diff --git a/service/focus_monitor/include/focus_monitor_manager.h b/service/focus_monitor/include/focus_monitor_manager.h index 2b78646..18d813e 100644 --- a/service/focus_monitor/include/focus_monitor_manager.h +++ b/service/focus_monitor/include/focus_monitor_manager.h @@ -17,17 +17,26 @@ #define SELECTION_FOCUS_MONITOR_MANAGER_H #include +#include "focus_change_info.h" +#ifdef SCENE_BOARD_ENABLE +#include "window_manager_lite.h" +#else +#include "window_manager.h" +#endif namespace OHOS { namespace SelectionFwk { -using FocusHandle = std::function; +using FocusHandle = std::function &focusChangeInfo, bool)>; class FocusMonitorManager { public: static FocusMonitorManager &GetInstance(); void RegisterFocusChangedListener(const FocusHandle &handle); + void UnregisterFocusChangedListener(); private: FocusMonitorManager() = default; +private: + sptr focusListener_ = nullptr; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/service/focus_monitor/src/focus_change_listener.cpp b/service/focus_monitor/src/focus_change_listener.cpp index 3c59f84..a365f9d 100644 --- a/service/focus_monitor/src/focus_change_listener.cpp +++ b/service/focus_monitor/src/focus_change_listener.cpp @@ -27,10 +27,9 @@ void FocusChangedListener::OnFocused(const sptr &focusCh SELECTION_HILOGE("error nullptr"); return; } - SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64 " pid: %{public}d, uid: %{public}d", - focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->pid_, focusChangeInfo->uid_); - uint32_t windowType = static_cast(focusChangeInfo->windowType_); - focusHandle_(true, focusChangeInfo->windowId_, windowType); + SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64, + focusChangeInfo->windowId_, focusChangeInfo->displayId_); + focusHandle_(focusChangeInfo, true); } void FocusChangedListener::OnUnfocused(const sptr &focusChangeInfo) @@ -41,8 +40,7 @@ void FocusChangedListener::OnUnfocused(const sptr &focus } SELECTION_HILOGI("windowId:%{public}d displayId: %{public}" PRIu64 " Windowtype: %{public}d", focusChangeInfo->windowId_, focusChangeInfo->displayId_, focusChangeInfo->windowType_); - uint32_t windowType = static_cast(focusChangeInfo->windowType_); - focusHandle_(false, focusChangeInfo->windowId_, windowType); + focusHandle_(focusChangeInfo, false); } } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/service/focus_monitor/src/focus_monitor_manager.cpp b/service/focus_monitor/src/focus_monitor_manager.cpp index 1bda8e3..ce3f149 100644 --- a/service/focus_monitor/src/focus_monitor_manager.cpp +++ b/service/focus_monitor/src/focus_monitor_manager.cpp @@ -15,11 +15,6 @@ #include "focus_change_listener.h" #include "selection_log.h" -#ifdef SCENE_BOARD_ENABLE -#include "window_manager_lite.h" -#else -#include "window_manager.h" -#endif namespace OHOS { namespace SelectionFwk { @@ -32,17 +27,37 @@ FocusMonitorManager &FocusMonitorManager::GetInstance() void FocusMonitorManager::RegisterFocusChangedListener(const FocusHandle &handle) { - sptr listener = new (std::nothrow) FocusChangedListener(handle); - if (listener == nullptr) { - SELECTION_HILOGE("failed to create listener"); + if (focusListener_ != nullptr) { + SELECTION_HILOGE("focusListener_ has been registered by others."); + return; + } + + focusListener_ = sptr::MakeSptr(handle); + if (focusListener_ == nullptr) { + SELECTION_HILOGE("failed to create focusListener_"); + return; + } +#ifdef SCENE_BOARD_ENABLE + WMError ret = WindowManagerLite::GetInstance().RegisterFocusChangedListener(focusListener_); +#else + WMError ret = WindowManager::GetInstance().RegisterFocusChangedListener(focusListener_); +#endif + SELECTION_HILOGI("register focus changed focusListener_ ret: %{public}d", ret); +} + +void FocusMonitorManager::UnregisterFocusChangedListener() +{ + if (focusListener_ == nullptr) { + SELECTION_HILOGE("focusListener_ is nullptr"); return; } #ifdef SCENE_BOARD_ENABLE - WMError ret = WindowManagerLite::GetInstance().RegisterFocusChangedListener(listener); + WMError ret = WindowManagerLite::GetInstance().UnregisterFocusChangedListener(focusListener_); #else - WMError ret = WindowManager::GetInstance().RegisterFocusChangedListener(listener); + WMError ret = WindowManager::GetInstance().UnregisterFocusChangedListener(focusListener_); #endif - SELECTION_HILOGI("register focus changed listener ret: %{public}d", ret); + SELECTION_HILOGI("Unregister focus changed focusListener_ ret: %{public}d", ret); + focusListener_ = nullptr; } } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/service/include/db_selection_config_repository.h b/service/include/db_selection_config_repository.h index d4c9e02..d2a0a81 100644 --- a/service/include/db_selection_config_repository.h +++ b/service/include/db_selection_config_repository.h @@ -47,7 +47,7 @@ private: int32_t primaryKeyIndex; int32_t uidIndex; int32_t enableIndex; - int32_t bundleNameIndex; + int32_t applicationInfoIndex; int32_t triggerIndex; int32_t shortcutKeysIndex; }; diff --git a/service/include/selection_app_validator.h b/service/include/selection_app_validator.h new file mode 100644 index 0000000..e28848f --- /dev/null +++ b/service/include/selection_app_validator.h @@ -0,0 +1,41 @@ +/* + * 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 SELECTION_APP_VALIDATOR_H +#define SELECTION_APP_VALIDATOR_H + +#include +#include +#include + +namespace OHOS::SelectionFwk { +class SelectionAppValidator { +public: + static SelectionAppValidator& GetInstance(); + bool Validate() const; + +private: + SelectionAppValidator() = default; + SelectionAppValidator(const SelectionAppValidator&) = delete; + SelectionAppValidator(SelectionAppValidator&&) = delete; + SelectionAppValidator& operator= (const SelectionAppValidator&) = delete; + SelectionAppValidator& operator= (SelectionAppValidator&&) = delete; + + std::optional GetCurrentBundleName() const; + std::optional GetBundleNameFromSys() const; +}; + +} // namespace OHOS::SelectionFwk +#endif // SELECTION_APP_VALIDATOR_H \ No newline at end of file diff --git a/service/include/selection_common.h b/service/include/selection_common.h new file mode 100644 index 0000000..82e65e2 --- /dev/null +++ b/service/include/selection_common.h @@ -0,0 +1,21 @@ +/* + * 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 SELECTION_COMMON_H +#define SELECTION_COMMON_H + +bool isNumber(const std::string& str); + +#endif // SELECTION_COMMON_H \ No newline at end of file diff --git a/service/include/selection_config.h b/service/include/selection_config.h index cccd3b9..d64b52f 100644 --- a/service/include/selection_config.h +++ b/service/include/selection_config.h @@ -17,28 +17,29 @@ #define SELECTION_CONFIG_H #include +#include #include "selection_config.h" namespace OHOS { namespace SelectionFwk { class SelectionConfig { public: - int IsEnabled() const; - int IsTriggered() const; + bool GetEnable() const; + bool GetTriggered() const; int GetUid() const; - std::string GetBundleName() const; - void SetEnabled(int enabled); - void SetTriggered(int isTriggered); - void SetBundleName(const std::string &bundleName); + std::string GetApplicationInfo() const; + void SetEnabled(bool enabled); + void SetTriggered(bool isTriggered); + void SetApplicationInfo(const std::string &applicationInfo); void SetUid(int uid); std::string ToString() const; private: - int isEnabled_ = 1; - int isTriggered_ = 1; + bool isEnabled_ = true; + bool isTriggered_ = true; int uid_ = 0; - std::string bundleName_ = "com.hm.youdao/ExtensionAbility"; + std::string applicationInfo_ = "com.hm.youdao/ExtensionAbility"; }; @@ -47,17 +48,18 @@ public: static MemSelectionConfig &GetInstance(); SelectionConfig &GetSelectionConfig(); void SetSelectionConfig(const SelectionConfig &config); - int IsEnabled() const; - int IsTriggered() const; - std::string GetBundleName() const; - void SetEnabled(int enabled); - void SetTriggered(int isTriggered); - void SetBundleName(const std::string &bundleName); + bool GetEnable() const; + bool GetTriggered() const; + std::string GetApplicationInfo() const; + void SetEnabled(bool enabled); + void SetTriggered(bool isTriggered); + void SetApplicationInfo(const std::string &applicationInfo); private: MemSelectionConfig() = default; ~MemSelectionConfig() = default; SelectionConfig delegate_; + mutable std::mutex mutex_; }; } // namespace SelectionFwk } // namespace OHOS diff --git a/service/include/selection_config_database.h b/service/include/selection_config_database.h index 96f8654..3d8125e 100644 --- a/service/include/selection_config_database.h +++ b/service/include/selection_config_database.h @@ -29,7 +29,6 @@ namespace OHOS { namespace SelectionFwk { - static std::string SELECTION_CONFIG_DB_PATH = "/data/service/el1/public/selection_service/"; constexpr const char *SELECTION_CONFIG_DB_NAME = "selection_config.db"; @@ -66,9 +65,11 @@ public: int32_t RollBack(); private: - SelectionConfigDataBase(); + SelectionConfigDataBase(const std::shared_ptr& store); DISALLOW_COPY_AND_MOVE(SelectionConfigDataBase); + static std::shared_ptr CreateStore(); + static std::shared_ptr instance_; std::shared_ptr store_; }; diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h index bc1fc73..3d36520 100644 --- a/service/include/selection_input_monitor.h +++ b/service/include/selection_input_monitor.h @@ -19,14 +19,15 @@ #include #include #include "selection_interface.h" -#include "PasteboardDisposableObserver.h" +#include "pasteboard_disposable_observer.h" namespace OHOS::SelectionFwk { using namespace MMI; using namespace OHOS::MiscServices; constexpr const uint32_t DOUBLE_CLICK_TIME = 500; +constexpr const uint32_t MAX_PASTERBOARD_TEXT_LENGTH = 2000; -typedef enum { +enum class SelectInputState: uint32_t { SELECT_INPUT_INITIAL = 0, SELECT_INPUT_WORD_BEGIN = 1, SELECT_INPUT_WAIT_LEFT_MOVE = 2, @@ -35,15 +36,15 @@ typedef enum { SELECT_INPUT_WAIT_TRIPLE_CLICK = 5, SELECT_INPUT_DOUBLE_CLICKED = 6, SELECT_INPUT_TRIPLE_CLICKED = 7, -} SelectInputState; +}; -typedef enum { +enum class SelectInputSubState: uint32_t { SUB_INITIAL = 0, SUB_WAIT_POINTER_ACTION_BUTTON_DOWN = 1, SUB_WAIT_POINTER_ACTION_BUTTON_UP = 2, SUB_WAIT_KEY_CTRL_DOWN = 3, SUB_WAIT_KEY_CTRL_UP = 4, -} SelectInputSubState; +}; class BaseSelectionInputMonitor : public IInputEventConsumer { public: @@ -78,49 +79,45 @@ private: bool IsSelectionDone() const; private: - mutable uint32_t curSelectState = SELECT_INPUT_INITIAL; - mutable uint32_t subSelectState = SUB_INITIAL; + mutable SelectInputState curSelectState = SelectInputState::SELECT_INPUT_INITIAL; + mutable SelectInputSubState subSelectState = SelectInputSubState::SUB_INITIAL; mutable int64_t lastClickTime = 0; mutable bool isTextSelected_ = false; mutable SelectionInfo selectionInfo_; }; -class SelectionInputMonitor; - class SelectionPasteboardDisposableObserver : public PasteboardDisposableObserver { public: - SelectionPasteboardDisposableObserver(std::shared_ptr pInputMonitor) - : pInputMonitor_(pInputMonitor) { + SelectionPasteboardDisposableObserver(const std::shared_ptr &baseInputMonitor) + : baseInputMonitor_(baseInputMonitor) { } virtual ~SelectionPasteboardDisposableObserver() = default; void OnTextReceived(const std::string &text, int32_t errCode) override; private: - std::shared_ptr pInputMonitor_; + std::shared_ptr baseInputMonitor_; }; -class SelectionInputMonitor : public IInputEventConsumer, public std::enable_shared_from_this { +class SelectionInputMonitor : public IInputEventConsumer { public: SelectionInputMonitor() { - delegate_ = std::make_shared(); + baseInputMonitor_ = std::make_shared(); } virtual void OnInputEvent(std::shared_ptr keyEvent) const; virtual void OnInputEvent(std::shared_ptr pointerEvent) const; virtual void OnInputEvent(std::shared_ptr axisEvent) const; - void OnSelectionTriggered(const std::string &text) const; private: void FinishedWordSelection() const; void InjectCtrlC() const; - void SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) const; + void HandleWindowFocused(std::shared_ptr pointerEvent) const; private: - std::shared_ptr delegate_; - mutable std::shared_ptr pasteboardObserver_; + std::shared_ptr baseInputMonitor_; + mutable sptr pasteboardObserver_; }; - } #endif // SELECTION_INPUT_MONITOR_H \ No newline at end of file diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 65e429f..48be5fe 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -21,6 +21,7 @@ #include "ability_connect_callback_stub.h" #include "callback_object.h" +#include "focus_change_info.h" #include "iselection_listener.h" #include "selection_service_stub.h" #include "refbase.h" @@ -44,8 +45,6 @@ public: void OnAbilityConnectDone( const OHOS::AppExecFwk::ElementName &element, const sptr &remoteObject, int resultCode) override; void OnAbilityDisconnectDone(const OHOS::AppExecFwk::ElementName &element, int resultCode) override; -private: - sptr remoteObject_; }; class SelectionService : public SystemAbility, public SelectionServiceStub { @@ -57,8 +56,9 @@ public: SelectionService(int32_t saId, bool runOnCreate); ~SelectionService(); - ErrCode RegisterListener(const sptr &listener) override; - ErrCode UnregisterListener(const sptr &listener) override; + ErrCode RegisterListener(const sptr& listener) override; + ErrCode UnregisterListener(const sptr& listener) override; + ErrCode IsCurrentSelectionApp(int pid, bool &resultValue) override; int32_t Dump(int32_t fd, const std::vector &args) override; int32_t ConnectNewExtAbility(const std::string& bundleName, const std::string& abilityName); void DisconnectCurrentExtAbility(); @@ -76,18 +76,19 @@ private: void InputMonitorCancel(); void WatchParams(); void InitFocusChangedMonitor(); - void HandleFocusChanged(bool isOnFocused, uint32_t windowId, uint32_t windowType); + void CancelFocusChangedMonitor(); + void HandleFocusChanged(const sptr &focusChangeInfo, bool isFocused); void SynchronizeSelectionConfig(); void GetAccountLocalId(); int32_t inputMonitorId_ {-1}; - static sptr instance_; - static std::shared_mutex adminLock_; mutable std::mutex mutex_; - static sptr listenerStub_; + static sptr listener_; sptr connectInner_ {nullptr}; - int userId_ = -1; - bool isExistUid_ = false; + std::mutex connectInnerMutex_; + std::atomic pid_ = -1; + std::atomic userId_ = -1; + std::atomic isExistUid_ = false; }; } diff --git a/service/include/sys_selection_config_repository.h b/service/include/sys_selection_config_repository.h index e09a49a..ba8217c 100644 --- a/service/include/sys_selection_config_repository.h +++ b/service/include/sys_selection_config_repository.h @@ -29,14 +29,14 @@ public: void DisableSAService(); private: - void SetEnabled(int enabled); - void SetTriggered(int isTriggered); + void SetEnabled(bool enabled); + void SetTriggered(bool isTriggered); void SetUid(int uid); - void SetBundleName(const std::string &bundleName); - int IsEnabled(); - int IsTriggered(); + void SetApplicationInfo(const std::string &applicationInfo); + int GetEnable(); + int GetTriggered(); int GetUid(); - std::string GetBundleName(); + std::string GetApplicationInfo(); static std::shared_ptr instance_; }; } // namespace SelectionFwk diff --git a/service/libselection_service.map b/service/libselection_service.map index 95bd01d..31f9719 100644 --- a/service/libselection_service.map +++ b/service/libselection_service.map @@ -1,9 +1,9 @@ { global: extern "C++" { - OHOS::SelectionFwk::SelectionService::AddVolume*; OHOS::SelectionFwk::SelectionService::RegisterListener*; OHOS::SelectionFwk::SelectionService::UnregisterListener*; + OHOS::SelectionFwk::SelectionService::IsCurrentSelectionApp*; }; local: *; diff --git a/service/src/db_selection_config_repository.cpp b/service/src/db_selection_config_repository.cpp index e60665e..671bf4f 100644 --- a/service/src/db_selection_config_repository.cpp +++ b/service/src/db_selection_config_repository.cpp @@ -53,9 +53,9 @@ int DbSelectionConfigRepository::Save(int uid, const SelectionConfig &info) ValuesBucket values; values.Clear(); values.PutInt("uid", uid); - values.PutInt("enable", info.IsEnabled()); - values.PutInt("trigger", info.IsTriggered()); - values.PutString("bundleName", info.GetBundleName()); + values.PutInt("enable", info.GetEnable()); + values.PutInt("trigger", info.GetTriggered()); + values.PutString("bundleName", info.GetApplicationInfo()); int ret = selectionDatabase_->BeginTransaction(); if (ret < SELECTION_CONFIG_OK) { SELECTION_HILOGE("BeginTransaction error: %{public}d", ret); @@ -86,8 +86,8 @@ int DbSelectionConfigRepository::Save(int uid, const SelectionConfig &info) (void)selectionDatabase_->RollBack(); return ret; } - SELECTION_HILOGI("add success: uid=%{public}d enable=%{public}d trigger=%{public}d bundleName=%{public}s", - uid, info.IsEnabled(), info.IsTriggered(), info.GetBundleName().c_str()); + SELECTION_HILOGI("add success: enable=%{public}d trigger=%{public}d applicationInfo=%{public}s", + info.GetEnable(), info.GetTriggered(), info.GetApplicationInfo().c_str()); return ret; } @@ -101,8 +101,8 @@ std::optional DbSelectionConfigRepository::GetOneByUserId(int u if (GetConfigFromDatabase(rdbPredicates, columns, info) != SELECTION_CONFIG_OK) { return std::nullopt; } - SELECTION_HILOGI("uid=%{public}d enable=%{public}d trigger=%{public}d bundleName=%{public}s", - uid, info.IsEnabled(), info.IsTriggered(), info.GetBundleName().c_str()); + SELECTION_HILOGI("enable=%{public}d trigger=%{public}d applicationInfo=%{public}s", + info.GetEnable(), info.GetTriggered(), info.GetApplicationInfo().c_str()); return info; } @@ -151,7 +151,7 @@ int DbSelectionConfigRepository::ProcessQueryResult(const std::shared_ptrGetInt(table.enableIndex, enable) == E_OK && - resultSet->GetString(table.bundleNameIndex, bundleName) == E_OK && + resultSet->GetString(table.applicationInfoIndex, applicationInfo) == E_OK && resultSet->GetInt(table.triggerIndex, trigger) == E_OK && resultSet->GetInt(table.uidIndex, uid) == E_OK) { - info.SetEnabled(enable); - info.SetTriggered(trigger); - info.SetBundleName(bundleName); + info.SetEnabled(enable == 1? true : false); + info.SetTriggered(trigger == 1? true: false); + info.SetApplicationInfo(applicationInfo); info.SetUid(uid); } - SELECTION_HILOGI("enable=%{public}d trigger=%{public}d bundleName=%{public}s uid=%{public}d", - enable, trigger, bundleName.c_str(), uid); + SELECTION_HILOGI("enable=%{public}d trigger=%{public}d applicationInfo=%{public}s", + enable, trigger, applicationInfo.c_str()); } int position = 0; @@ -209,7 +209,7 @@ int DbSelectionConfigRepository::RetrieveResultSetMetadata( table.enableIndex = i; } if (columnName == "bundleName") { - table.bundleNameIndex = i; + table.applicationInfoIndex = i; } if (columnName == "trigger") { table.triggerIndex = i; @@ -221,7 +221,7 @@ int DbSelectionConfigRepository::RetrieveResultSetMetadata( table.rowCount = rowCount; table.columnCount = columnCount; SELECTION_HILOGI("info[%{public}d/%{public}d]: %{public}d/%{public}d/%{public}d/%{public}d/%{public}d/%{public}d", - rowCount, columnCount, table.primaryKeyIndex, table.uidIndex, table.enableIndex, table.bundleNameIndex, + rowCount, columnCount, table.primaryKeyIndex, table.uidIndex, table.enableIndex, table.applicationInfoIndex, table.triggerIndex, table.shortcutKeysIndex); return SELECTION_CONFIG_OK; } diff --git a/service/src/selection_app_validator.cpp b/service/src/selection_app_validator.cpp new file mode 100644 index 0000000..7961385 --- /dev/null +++ b/service/src/selection_app_validator.cpp @@ -0,0 +1,79 @@ +/* + * 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 "selection_app_validator.h" + +#include +#include "accesstoken_kit.h" +#include "parameter.h" +#include "param_wrapper.h" +#include "selection_log.h" + +namespace OHOS::SelectionFwk { + +static const char* SELECTION_APPLICATION = "sys.selection.app"; + +SelectionAppValidator& SelectionAppValidator::GetInstance() +{ + static SelectionAppValidator instance; + return instance; +} + +bool SelectionAppValidator::Validate() const +{ + auto currentBundleName = GetCurrentBundleName(); + if (!currentBundleName.has_value()) { + SELECTION_HILOGE("Failed to GetCurrentBundleName"); + return false; + } + auto bundleNameFromSys = GetBundleNameFromSys(); + if (!bundleNameFromSys.has_value()) { + SELECTION_HILOGE("Failed to GetBundleNameFromSys"); + return false; + } + SELECTION_HILOGI("Validate bundleName: [%{public}s] with bundleName: [%{public}s] from sys", + currentBundleName.value().c_str(), bundleNameFromSys.value().c_str()); + return currentBundleName.value() == bundleNameFromSys.value(); +} + +std::optional SelectionAppValidator::GetCurrentBundleName() const +{ + auto callingTokenId = IPCSkeleton::GetCallingTokenID(); + OHOS::Security::AccessToken::HapTokenInfo hapTokenInfoRes; + int32_t ret = OHOS::Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callingTokenId, hapTokenInfoRes); + if (ret != 0) { + SELECTION_HILOGE("Failed to GetHapTokenInfo, ret = %{public}d.", ret); + return std::nullopt; + } + return hapTokenInfoRes.bundleName; +} + +std::optional SelectionAppValidator::GetBundleNameFromSys() const +{ + std::string selectionApp; + if (OHOS::system::GetStringParameter(SELECTION_APPLICATION, selectionApp) != 0) { + SELECTION_HILOGE("GetStringParameter failed for SELECTION_APPLICATION"); + return std::nullopt; + } + + const auto pos = selectionApp.find('/'); + if (pos == std::string::npos) { + SELECTION_HILOGE("%{public}s: [%{public}s] is invalid", SELECTION_APPLICATION, selectionApp.c_str()); + return std::nullopt; + } + return selectionApp.substr(0, pos); +} + +} // namespace OHOS::SelectionFwk \ No newline at end of file diff --git a/service/src/selection_common.cpp b/service/src/selection_common.cpp new file mode 100644 index 0000000..a21e1c6 --- /dev/null +++ b/service/src/selection_common.cpp @@ -0,0 +1,36 @@ +/* + * 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 + +bool isNumber(const std::string& str) { + if (str.empty()) { + return false; + } + + size_t i = 0; + if (str[i] == '+' || str[i] == '-') { + i++; + } + + if (i != 0 && str.length() == 1) { + return false; + } + + if (std::all_of(str.begin() + i, str.end(), [](unsigned char c) { return std::isdigit(c); })) { + return true; + } + + return false; +} \ No newline at end of file diff --git a/service/src/selection_config.cpp b/service/src/selection_config.cpp index 6322202..d206d54 100644 --- a/service/src/selection_config.cpp +++ b/service/src/selection_config.cpp @@ -16,15 +16,16 @@ #include "selection_config.h" #include +#include namespace OHOS { namespace SelectionFwk { -int SelectionConfig::IsEnabled() const +bool SelectionConfig::GetEnable() const { return isEnabled_; } -int SelectionConfig::IsTriggered() const +bool SelectionConfig::GetTriggered() const { return isTriggered_; } @@ -34,17 +35,17 @@ int SelectionConfig::GetUid() const return uid_; } -std::string SelectionConfig::GetBundleName() const +std::string SelectionConfig::GetApplicationInfo() const { - return bundleName_; + return applicationInfo_; } -void SelectionConfig::SetEnabled(int enabled) +void SelectionConfig::SetEnabled(bool enabled) { isEnabled_ = enabled; } -void SelectionConfig::SetTriggered(int isTriggered) +void SelectionConfig::SetTriggered(bool isTriggered) { isTriggered_ = isTriggered; } @@ -54,15 +55,16 @@ void SelectionConfig::SetUid(int uid) uid_ = uid; } -void SelectionConfig::SetBundleName(const std::string &bundleName) +void SelectionConfig::SetApplicationInfo(const std::string &applicationInfo) { - bundleName_ = bundleName; + applicationInfo_ = applicationInfo; } std::string SelectionConfig::ToString() const { - std::string str = "uid: " + std::to_string(uid_) + ", enable: " + std::to_string(isEnabled_) + ", trigger: " + - std::to_string(isTriggered_) + ", bundleName: " + bundleName_; - return str; + std::ostringstream oss; + oss << "enable: " << isEnabled_ << ", trigger: " + << isTriggered_ << ", applicationInfo: " << applicationInfo_; + return oss.str(); } MemSelectionConfig& MemSelectionConfig::GetInstance() @@ -73,42 +75,50 @@ MemSelectionConfig& MemSelectionConfig::GetInstance() void MemSelectionConfig::SetSelectionConfig(const SelectionConfig &config) { + std::lock_guard lock(mutex_); delegate_ = config; } SelectionConfig& MemSelectionConfig::GetSelectionConfig() { + std::lock_guard lock(mutex_); return delegate_; } -int MemSelectionConfig::IsEnabled() const +bool MemSelectionConfig::GetEnable() const { - return delegate_.IsEnabled(); + std::lock_guard lock(mutex_); + return delegate_.GetEnable(); } -int MemSelectionConfig::IsTriggered() const +bool MemSelectionConfig::GetTriggered() const { - return delegate_.IsTriggered(); + std::lock_guard lock(mutex_); + return delegate_.GetTriggered(); } -std::string MemSelectionConfig::GetBundleName() const +std::string MemSelectionConfig::GetApplicationInfo() const { - return delegate_.GetBundleName(); + std::lock_guard lock(mutex_); + return delegate_.GetApplicationInfo(); } -void MemSelectionConfig::SetEnabled(int enabled) +void MemSelectionConfig::SetEnabled(bool enabled) { + std::lock_guard lock(mutex_); delegate_.SetEnabled(enabled); } -void MemSelectionConfig::SetTriggered(int isTriggered) +void MemSelectionConfig::SetTriggered(bool isTriggered) { + std::lock_guard lock(mutex_); delegate_.SetTriggered(isTriggered); } -void MemSelectionConfig::SetBundleName(const std::string &bundleName) +void MemSelectionConfig::SetApplicationInfo(const std::string &applicationInfo) { - delegate_.SetBundleName(bundleName); + std::lock_guard lock(mutex_); + delegate_.SetApplicationInfo(applicationInfo); } } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/service/src/selection_config_comparator.cpp b/service/src/selection_config_comparator.cpp index cc4eeff..ebb32c9 100644 --- a/service/src/selection_config_comparator.cpp +++ b/service/src/selection_config_comparator.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #include "selection_config_comparator.h" #include "selection_log.h" @@ -20,21 +21,21 @@ namespace OHOS { namespace SelectionFwk { std::string ComparisionResult::ToString() const { - std::string result = ""; - result = "ComparisionResult: shouldCreate: " + std::to_string(shouldCreate) + " shouldStop: " + - std::to_string(shouldStop) + " direction: " + std::to_string(static_cast(direction)) + - " selectionConfig: [ " + selectionConfig.ToString() + "]"; - return result; + std::ostringstream oss; + oss << "ComparisionResult: shouldCreate: " << shouldCreate + << " shouldStop: " << shouldStop + << " direction: " << static_cast(direction) + << " selectionConfig: [ " << selectionConfig.ToString() << "]"; + return oss.str(); } ComparisionResult SelectionConfigComparator::Compare(int uid, const SelectionConfig &sysSelectionConfig, std::optional &dbSelectionConfig) { - SELECTION_HILOGI("sysSelectionConfig: %{public}s", sysSelectionConfig.ToString().c_str()); if (dbSelectionConfig.has_value()) { - SELECTION_HILOGI("dbSelectionConfig: %{public}s", dbSelectionConfig->ToString().c_str()); + SELECTION_HILOGI("dbSelectionConfig has value"); } else { - SELECTION_HILOGE("dbSelectionConfig is nullopt!"); + SELECTION_HILOGI("dbSelectionConfig is nullopt!"); } auto result = DoCompare(uid, sysSelectionConfig, dbSelectionConfig); SELECTION_HILOGI("result: %{public}s", result.ToString().c_str()); @@ -51,7 +52,7 @@ ComparisionResult SelectionConfigComparator::DoCompare(int uid, const SelectionC return result; } - if (dbSelectionConfig.value().IsEnabled()) { + if (dbSelectionConfig.value().GetEnable()) { if (sysSelectionConfig.GetUid() != uid) { result.direction = FromDbToSys; result.selectionConfig = dbSelectionConfig.value(); @@ -59,7 +60,7 @@ ComparisionResult SelectionConfigComparator::DoCompare(int uid, const SelectionC } result.direction = FromSysToDb; result.selectionConfig = sysSelectionConfig; - if (!sysSelectionConfig.IsEnabled()) { + if (!sysSelectionConfig.GetEnable()) { result.shouldStop = true; } return result; @@ -73,7 +74,7 @@ ComparisionResult SelectionConfigComparator::DoCompare(int uid, const SelectionC result.direction = FromSysToDb; result.selectionConfig = sysSelectionConfig; - if (!sysSelectionConfig.IsEnabled()) { + if (!sysSelectionConfig.GetEnable()) { result.shouldStop = true; } diff --git a/service/src/selection_config_database.cpp b/service/src/selection_config_database.cpp index 2d01695..c1ca6b8 100644 --- a/service/src/selection_config_database.cpp +++ b/service/src/selection_config_database.cpp @@ -23,20 +23,9 @@ namespace SelectionFwk { std::shared_ptr SelectionConfigDataBase::instance_ = nullptr; -SelectionConfigDataBase::SelectionConfigDataBase() +SelectionConfigDataBase::SelectionConfigDataBase(const std::shared_ptr& store) + : store_(store) { - std::string selectiontDatabaseName = SELECTION_CONFIG_DB_PATH + SELECTION_CONFIG_DB_NAME; - int32_t errCode = OHOS::NativeRdb::E_OK; - OHOS::NativeRdb::RdbStoreConfig config(selectiontDatabaseName); - config.SetSecurityLevel(NativeRdb::SecurityLevel::S1); - SelectionConfigDataBaseCallBack sqliteOpenHelperCallback; - store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION, sqliteOpenHelperCallback, errCode); - if (errCode != OHOS::NativeRdb::E_OK) { - SELECTION_HILOGE("GetRdbStore errCode :%{public}d", errCode); - - } else { - SELECTION_HILOGE("GetRdbStore success :%{public}d", errCode); - } } std::shared_ptr SelectionConfigDataBase::GetInstance() @@ -45,7 +34,10 @@ std::shared_ptr SelectionConfigDataBase::GetInstance() std::lock_guard guard(instanceMutex); if (instance_ == nullptr) { SELECTION_HILOGI("reset to new SelectionConfigDataBase instance"); - instance_.reset(new SelectionConfigDataBase()); + auto store = SelectionConfigDataBase::CreateStore(); + if (store != nullptr) { + instance_.reset(new SelectionConfigDataBase(store)); + } return instance_; } return instance_; @@ -101,11 +93,11 @@ int64_t SelectionConfigDataBase::Insert(const OHOS::NativeRdb::ValuesBucket &ins } int64_t outRowId = 0; int32_t ret = store_->Insert(outRowId, SELECTION_CONFIG_TABLE_NAME, insertValues); - SELECTION_HILOGI("Insert id=%{public}" PRIu64 "", outRowId); if (ret != OHOS::NativeRdb::E_OK) { SELECTION_HILOGE("Insert ret :%{public}d", ret); return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; } + SELECTION_HILOGI("Insert id=%{public}" PRIu64 "", outRowId); return outRowId; } @@ -169,7 +161,8 @@ int32_t SelectionConfigDataBase::Delete( return SELECTION_CONFIG_OK; } -int32_t SelectionConfigDataBase::ExecuteSql(const std::string &sql, const std::vector &bindArgs) +int32_t SelectionConfigDataBase::ExecuteSql(const std::string &sql, + const std::vector &bindArgs) { if (store_ == nullptr) { SELECTION_HILOGE("ExecuteSql store_ is nullptr"); @@ -203,6 +196,22 @@ std::shared_ptr SelectionConfigDataBase::Query( return store_->Query(predicates, columns); } +std::shared_ptr SelectionConfigDataBase::CreateStore() { + std::string selectionDatabaseName = SELECTION_CONFIG_DB_PATH + SELECTION_CONFIG_DB_NAME; + int32_t errCode = OHOS::NativeRdb::E_OK; + OHOS::NativeRdb::RdbStoreConfig config(selectionDatabaseName); + config.SetSecurityLevel(NativeRdb::SecurityLevel::S1); + SelectionConfigDataBaseCallBack sqliteOpenHelperCallback; + auto store = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION, + sqliteOpenHelperCallback, errCode); + if (errCode != OHOS::NativeRdb::E_OK) { + SELECTION_HILOGE("GetRdbStore errCode :%{public}d", errCode); + } else { + SELECTION_HILOGI("GetRdbStore success :%{public}d", errCode); + } + return store; +} + int32_t SelectionConfigDataBaseCallBack::OnCreate(OHOS::NativeRdb::RdbStore &store) { std::string sql = CREATE_SELECTION_CONFIG_TABLE; @@ -215,7 +224,8 @@ int32_t SelectionConfigDataBaseCallBack::OnCreate(OHOS::NativeRdb::RdbStore &sto return SELECTION_CONFIG_OK; } -int32_t SelectionConfigDataBaseCallBack::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion) +int32_t SelectionConfigDataBaseCallBack::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, + int32_t newVersion) { SELECTION_HILOGI("DB OnUpgrade Enter %{public}d => %{public}d", oldVersion, newVersion); if (oldVersion >= newVersion) { @@ -225,13 +235,14 @@ int32_t SelectionConfigDataBaseCallBack::OnUpgrade(OHOS::NativeRdb::RdbStore &st std::string sql = SQL_ADD_TOKEN_ID; int32_t ret = store.ExecuteSql(sql); if (ret != OHOS::NativeRdb::E_OK) { - // ignore sql error when tokenId is already exists - SELECTION_HILOGW("DB OnUpgrade failed: %{public}d", ret); + SELECTION_HILOGE("DB OnUpgrade failed: %{public}d", ret); + return SELECTION_CONFIG_RDB_EXECUTE_FAILTURE; } return SELECTION_CONFIG_OK; } -int32_t SelectionConfigDataBaseCallBack::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion) +int32_t SelectionConfigDataBaseCallBack::OnDowngrade(OHOS::NativeRdb::RdbStore &store, int32_t oldVersion, + int32_t newVersion) { SELECTION_HILOGI("DB OnDowngrade Enter"); (void)store; diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index 88e8b9a..a498409 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -18,8 +18,8 @@ #include "selection_log.h" #include #include "common_event_manager.h" +#include "pasteboard_client.h" #include "selection_input_monitor.h" -#include "screenlock_manager.h" #include "window_manager.h" using namespace OHOS; @@ -29,6 +29,7 @@ using namespace OHOS::MMI; using namespace OHOS::EventFwk; bool BaseSelectionInputMonitor::ctrlSelectFlag = false; +std::atomic selSeqId = 0; static int64_t GetCurrentTimeMillis() { auto now = std::chrono::system_clock::now(); @@ -36,6 +37,11 @@ static int64_t GetCurrentTimeMillis() { return std::chrono::duration_cast(duration).count(); } +uint32_t GenerateSequenceId() +{ + return selSeqId.fetch_add(1, std::memory_order_seq_cst); +} + bool BaseSelectionInputMonitor::IsTextSelected() const { return isTextSelected_; } @@ -50,39 +56,40 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) return; } - if (subSelectState != SUB_WAIT_KEY_CTRL_DOWN && subSelectState != SUB_WAIT_KEY_CTRL_UP) { + if (subSelectState != SelectInputSubState::SUB_WAIT_KEY_CTRL_DOWN && + subSelectState != SelectInputSubState::SUB_WAIT_KEY_CTRL_UP) { return; } int32_t keyCode = keyEvent->GetKeyCode(); int32_t action = keyEvent->GetKeyAction(); if (keyCode != KeyEvent::KEYCODE_CTRL_LEFT && keyCode != KeyEvent::KEYCODE_CTRL_RIGHT) { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_INITIAL; + subSelectState = SelectInputSubState::SUB_INITIAL; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); return; } SELECTION_HILOGI("[SelectionService] Processed ctrl key."); - if (subSelectState == SUB_WAIT_KEY_CTRL_DOWN && action == KeyEvent::KEY_ACTION_DOWN) { - subSelectState = SUB_WAIT_KEY_CTRL_UP; + if (subSelectState == SelectInputSubState::SUB_WAIT_KEY_CTRL_DOWN && action == KeyEvent::KEY_ACTION_DOWN) { + subSelectState = SelectInputSubState::SUB_WAIT_KEY_CTRL_UP; return; } - if (subSelectState == SUB_WAIT_KEY_CTRL_UP && action == KeyEvent::KEY_ACTION_UP) { - if (curSelectState == SELECT_INPUT_WAIT_LEFT_MOVE) { - curSelectState = SELECT_INPUT_LEFT_MOVE; + if (subSelectState == SelectInputSubState::SUB_WAIT_KEY_CTRL_UP && action == KeyEvent::KEY_ACTION_UP) { + if (curSelectState == SelectInputState::SELECT_INPUT_WAIT_LEFT_MOVE) { + curSelectState = SelectInputState::SELECT_INPUT_LEFT_MOVE; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_LEFT_MOVE."); - } else if (curSelectState == SELECT_INPUT_WAIT_DOUBLE_CLICK) { - curSelectState = SELECT_INPUT_DOUBLE_CLICKED; + } else if (curSelectState == SelectInputState::SELECT_INPUT_WAIT_DOUBLE_CLICK) { + curSelectState = SelectInputState::SELECT_INPUT_DOUBLE_CLICKED; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); - } else if (curSelectState == SELECT_INPUT_WAIT_TRIPLE_CLICK) { - curSelectState = SELECT_INPUT_TRIPLE_CLICKED; + } else if (curSelectState == SelectInputState::SELECT_INPUT_WAIT_TRIPLE_CLICK) { + curSelectState = SelectInputState::SELECT_INPUT_TRIPLE_CLICKED; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_DOUBLE_CLICKED."); } - subSelectState = SUB_INITIAL; + subSelectState = SelectInputSubState::SUB_INITIAL; } else { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_INITIAL; + subSelectState = SelectInputSubState::SUB_INITIAL; SELECTION_HILOGI("[SelectionService] Set curSelectState SELECT_INPUT_INITIAL."); } FinishedWordSelection(); @@ -91,12 +98,14 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { - bool screenLockedFlag = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked(); - if (screenLockedFlag) { - SELECTION_HILOGD("It is not screen on."); - return; - } int32_t buttonId = pointerEvent->GetButtonId(); + if (subSelectState == SelectInputSubState::SUB_WAIT_KEY_CTRL_DOWN || + subSelectState == SelectInputSubState::SUB_WAIT_KEY_CTRL_UP) { + int32_t action = pointerEvent->GetPointerAction(); + if (buttonId == PointerEvent::BUTTON_NONE && action == PointerEvent::POINTER_ACTION_MOVE) { + return; + } + } if (buttonId != PointerEvent::MOUSE_BUTTON_LEFT) { ResetState(); } @@ -104,27 +113,27 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr point switch (curSelectState) { - case SELECT_INPUT_INITIAL: + case SelectInputState::SELECT_INPUT_INITIAL: InputInitialProcess(pointerEvent); break; - case SELECT_INPUT_WORD_BEGIN: + case SelectInputState::SELECT_INPUT_WORD_BEGIN: InputWordBeginProcess(pointerEvent); break; - case SELECT_INPUT_WAIT_LEFT_MOVE: + case SelectInputState::SELECT_INPUT_WAIT_LEFT_MOVE: InputWordWaitLeftMoveProcess(pointerEvent); break; - case SELECT_INPUT_WAIT_DOUBLE_CLICK: + case SelectInputState::SELECT_INPUT_WAIT_DOUBLE_CLICK: InputWordWaitDoubleClickProcess(pointerEvent); break; - case SELECT_INPUT_DOUBLE_CLICKED: + case SelectInputState::SELECT_INPUT_DOUBLE_CLICKED: InputWordJudgeTripleClickProcess(pointerEvent); break; - case SELECT_INPUT_WAIT_TRIPLE_CLICK: + case SelectInputState::SELECT_INPUT_WAIT_TRIPLE_CLICK: InputWordWaitTripleClickProcess(pointerEvent); break; @@ -143,8 +152,8 @@ void BaseSelectionInputMonitor::OnInputEvent(std::shared_ptr axisEven void BaseSelectionInputMonitor::ResetProcess(std::shared_ptr pointerEvent) const { - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_INITIAL; + subSelectState = SelectInputSubState::SUB_INITIAL; OnInputEvent(pointerEvent); } @@ -172,17 +181,19 @@ void BaseSelectionInputMonitor::SaveSelectionStartInfo(std::shared_ptrwindowMetaInfo.bundleName.c_str()); + SELECTION_HILOGI("ListWindowInfo bundleName: %{public}s, windowtype:%{public}d, width:%{public}d, \ + height:%{public}d", info->windowMetaInfo.bundleName.c_str(), info->windowMetaInfo.windowType, + info->windowLayoutInfo.rect.width_, info->windowLayoutInfo.rect.height_); } if (ret == Rosen::WMError::WM_OK && infos.size() > 0) { selectionInfo_.bundleName = infos[0]->windowMetaInfo.bundleName; } - } void BaseSelectionInputMonitor::SaveSelectionEndInfo(std::shared_ptr pointerEvent) const { - if (curSelectState != SELECT_INPUT_LEFT_MOVE && curSelectState != SELECT_INPUT_WAIT_LEFT_MOVE) { + if (curSelectState != SelectInputState::SELECT_INPUT_LEFT_MOVE && + curSelectState != SelectInputState::SELECT_INPUT_WAIT_LEFT_MOVE) { return; } int32_t pointerId = pointerEvent->GetPointerId(); @@ -197,15 +208,15 @@ void BaseSelectionInputMonitor::SaveSelectionEndInfo(std::shared_ptrGetPointerAction(); int32_t buttonId = pointerEvent->GetButtonId(); if (action == PointerEvent::POINTER_ACTION_BUTTON_DOWN && buttonId == PointerEvent::MOUSE_BUTTON_LEFT) { - curSelectState = SELECT_INPUT_WORD_BEGIN; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_WORD_BEGIN; + subSelectState = SelectInputSubState::SUB_INITIAL; lastClickTime = GetCurrentTimeMillis(); SaveSelectionStartInfo(pointerEvent); SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); @@ -240,12 +252,12 @@ void BaseSelectionInputMonitor::InputWordBeginProcess(std::shared_ptrGetPointerAction(); if (action == PointerEvent::POINTER_ACTION_MOVE) { - curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; + curSelectState = SelectInputState::SELECT_INPUT_WAIT_LEFT_MOVE; + subSelectState = SelectInputSubState::SUB_WAIT_POINTER_ACTION_BUTTON_UP; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); } else if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { - curSelectState = SELECT_INPUT_WAIT_DOUBLE_CLICK; - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_DOWN; + curSelectState = SelectInputState::SELECT_INPUT_WAIT_DOUBLE_CLICK; + subSelectState = SelectInputSubState::SUB_WAIT_POINTER_ACTION_BUTTON_DOWN; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_DOUBLE_CLICK."); } return; @@ -256,10 +268,10 @@ void BaseSelectionInputMonitor::InputWordWaitLeftMoveProcess(std::shared_ptrGetPointerAction(); if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + subSelectState = SelectInputSubState::SUB_WAIT_KEY_CTRL_DOWN; SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); } else { - curSelectState = SELECT_INPUT_LEFT_MOVE; + curSelectState = SelectInputState::SELECT_INPUT_LEFT_MOVE; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_LEFT_MOVE."); } SaveSelectionEndInfo(pointerEvent); @@ -274,12 +286,12 @@ void BaseSelectionInputMonitor::JudgeTripleClick() const { auto curTime = GetCurrentTimeMillis(); if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { - curSelectState = SELECT_INPUT_WAIT_TRIPLE_CLICK; - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; + curSelectState = SelectInputState::SELECT_INPUT_WAIT_TRIPLE_CLICK; + subSelectState = SelectInputSubState::SUB_WAIT_POINTER_ACTION_BUTTON_UP; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_TRIPLE_CLICK."); } else { - curSelectState = SELECT_INPUT_WORD_BEGIN; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_WORD_BEGIN; + subSelectState = SelectInputSubState::SUB_INITIAL; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); } lastClickTime = curTime; @@ -288,37 +300,39 @@ void BaseSelectionInputMonitor::JudgeTripleClick() const void BaseSelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + if (subSelectState == SelectInputSubState::SUB_WAIT_POINTER_ACTION_BUTTON_DOWN && + action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { auto curTime = GetCurrentTimeMillis(); if (curTime - lastClickTime < DOUBLE_CLICK_TIME) { - subSelectState = SUB_WAIT_POINTER_ACTION_BUTTON_UP; + subSelectState = SelectInputSubState::SUB_WAIT_POINTER_ACTION_BUTTON_UP; SELECTION_HILOGI("set subSelectState to SUB_WAIT_POINTER_ACTION_BUTTON_UP."); } else { - curSelectState = SELECT_INPUT_WORD_BEGIN; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_WORD_BEGIN; + subSelectState = SelectInputSubState::SUB_INITIAL; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WORD_BEGIN."); } lastClickTime = curTime; return; } - if (subSelectState == SUB_WAIT_POINTER_ACTION_BUTTON_UP) { + if (subSelectState == SelectInputSubState::SUB_WAIT_POINTER_ACTION_BUTTON_UP) { if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + subSelectState = SelectInputSubState::SUB_WAIT_KEY_CTRL_DOWN; SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); } else { - curSelectState = SELECT_INPUT_DOUBLE_CLICKED; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_DOUBLE_CLICKED; + subSelectState = SelectInputSubState::SUB_INITIAL; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_DOUBLE_CLICKED."); } SaveSelectionEndInfo(pointerEvent); } else if (action == PointerEvent::POINTER_ACTION_MOVE) { - curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + curSelectState = SelectInputState::SELECT_INPUT_WAIT_LEFT_MOVE; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); } return; } - if (subSelectState == SUB_WAIT_KEY_CTRL_DOWN && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + if (subSelectState == SelectInputSubState::SUB_WAIT_KEY_CTRL_DOWN && + action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { JudgeTripleClick(); } return; @@ -327,7 +341,7 @@ void BaseSelectionInputMonitor::InputWordWaitDoubleClickProcess(std::shared_ptr< void BaseSelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - if (subSelectState == SUB_INITIAL && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { + if (subSelectState == SelectInputSubState::SUB_INITIAL && action == PointerEvent::POINTER_ACTION_BUTTON_DOWN) { SELECTION_HILOGI("Begin JudgeTripleClick."); JudgeTripleClick(); } else { @@ -339,21 +353,21 @@ void BaseSelectionInputMonitor::InputWordJudgeTripleClickProcess(std::shared_ptr void BaseSelectionInputMonitor::InputWordWaitTripleClickProcess(std::shared_ptr pointerEvent) const { int32_t action = pointerEvent->GetPointerAction(); - if (subSelectState != SUB_WAIT_POINTER_ACTION_BUTTON_UP) { + if (subSelectState != SelectInputSubState::SUB_WAIT_POINTER_ACTION_BUTTON_UP) { return; } if (action == PointerEvent::POINTER_ACTION_BUTTON_UP) { if (ctrlSelectFlag) { - subSelectState = SUB_WAIT_KEY_CTRL_DOWN; + subSelectState = SelectInputSubState::SUB_WAIT_KEY_CTRL_DOWN; SELECTION_HILOGI("set subSelectState to SUB_WAIT_KEY_CTRL_DOWN."); } else { - curSelectState = SELECT_INPUT_TRIPLE_CLICKED; - subSelectState = SUB_INITIAL; + curSelectState = SelectInputState::SELECT_INPUT_TRIPLE_CLICKED; + subSelectState = SelectInputSubState::SUB_INITIAL; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_TRIPLE_CLICKED."); } SaveSelectionEndInfo(pointerEvent); } else if (action == PointerEvent::POINTER_ACTION_MOVE) { - curSelectState = SELECT_INPUT_WAIT_LEFT_MOVE; + curSelectState = SelectInputState::SELECT_INPUT_WAIT_LEFT_MOVE; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_WAIT_LEFT_MOVE."); } else { SELECTION_HILOGI("Action reset. subSelectState is %{public}d, action is %{public}d.", subSelectState, action); @@ -367,14 +381,17 @@ void BaseSelectionInputMonitor::FinishedWordSelection() const if (!IsSelectionDone()) { return; } + GenerateSequenceId(); + SELECTION_HILOGI("[selectevent] curSelectState:%{public}d. Selection event id is %{public}u.", curSelectState, + selSeqId.load()); isTextSelected_ = true; SaveSelectionType(); } void BaseSelectionInputMonitor::ResetFinishedState() const { - if (curSelectState != SELECT_INPUT_DOUBLE_CLICKED) { - curSelectState = SELECT_INPUT_INITIAL; + if (curSelectState != SelectInputState::SELECT_INPUT_DOUBLE_CLICKED) { + curSelectState = SelectInputState::SELECT_INPUT_INITIAL; SELECTION_HILOGI("set curSelectState to SELECT_INPUT_INITIAL"); } isTextSelected_ = false; @@ -383,99 +400,156 @@ void BaseSelectionInputMonitor::ResetFinishedState() const void BaseSelectionInputMonitor::ResetState() const { isTextSelected_ = false; - curSelectState = SELECT_INPUT_INITIAL; - subSelectState = SUB_INITIAL; - SELECTION_HILOGI("ResetFinishedState."); + curSelectState = SelectInputState::SELECT_INPUT_INITIAL; + subSelectState = SelectInputSubState::SUB_INITIAL; + SELECTION_HILOGD("ResetFinishedState."); } void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { - delegate_->OnInputEvent(keyEvent); + baseInputMonitor_->OnInputEvent(keyEvent); FinishedWordSelection(); } void SelectionInputMonitor::OnInputEvent(std::shared_ptr pointerEvent) const { - delegate_->OnInputEvent(pointerEvent); + HandleWindowFocused(pointerEvent); + baseInputMonitor_->OnInputEvent(pointerEvent); FinishedWordSelection(); } void SelectionInputMonitor::OnInputEvent(std::shared_ptr axisEvent) const { - delegate_->OnInputEvent(axisEvent); -}; + baseInputMonitor_->OnInputEvent(axisEvent); +} -void SelectionInputMonitor::FinishedWordSelection() const +void SelectionInputMonitor::HandleWindowFocused(std::shared_ptr pointerEvent) const { - if (!delegate_->IsTextSelected()) { + int32_t action = pointerEvent->GetPointerAction(); + if (action != PointerEvent::POINTER_ACTION_BUTTON_DOWN) { return; } - delegate_->ResetFinishedState(); - if (pasteboardObserver_ == nullptr) { - pasteboardObserver_ = std::make_shared(shared_from_this()); - } - // TODO 调用剪贴板 - // uint64_t tokenId = IPCSkeleton::GetCallingTokenID(); - // int32_t ret = PasteboardClient::GetInstance()->SubscribeDisposableObserver(pasteboardObserver_, - // static_cast(tokenId), DisposableType::PLAIN_TEXT, 100); - // if (ret != ERR_OK) { - // SELECTION_HILOGE("SubscribeDisposableObserver failed ret is %{public}d.", ret); - // } - InjectCtrlC(); - SELECTION_HILOGI("End Inject Ctrl + C."); - // TODO DELETE - std::string test = "Hello World eeee"; - pasteboardObserver_->OnTextReceived(test, 0); -} - -void SelectionInputMonitor::OnSelectionTriggered(const std::string &text) const -{ - auto selectionInfo = delegate_->GetSelectionInfo(); - selectionInfo.text = text; - SelectionInfoData dataInner; - dataInner.data = selectionInfo; - SELECTION_HILOGI("selectionInfo: %{public}s.", dataInner.ToString().c_str()); + auto windowId = pointerEvent->GetTargetWindowId(); + Rosen::FocusChangeInfo focusInfo; + Rosen::WindowManager::GetInstance().GetFocusWindowInfo(focusInfo); + auto windowType = static_cast(focusInfo.windowType_); + if (windowId != focusInfo.windowId_) { + SELECTION_HILOGI("Clicked window is not focused, focus-changed event will dispose selection panel later"); + return; + } + SelectionFocusChangeInfo focusChangeInfo(focusInfo.windowId_, focusInfo.displayId_, focusInfo.pid_, + focusInfo.uid_, windowType, true, FocusChangeSource::InputManager); sptr listener = SelectionService::GetInstance()->GetListener(); if (listener == nullptr) { - SELECTION_HILOGE("get listener is null"); + SELECTION_HILOGE("Selection listener is nullptr"); return; } - listener->OnSelectionChange(dataInner); - return; + ErrCode errCode = listener->FocusChange(focusChangeInfo); + if (errCode != NO_ERROR) { + SELECTION_HILOGE("Failed to call ISelectionListener::FocusChange, error code: %{public}d.", errCode); + } } -void SelectionInputMonitor::InjectCtrlC() const +void SelectionInputMonitor::FinishedWordSelection() const { - std::this_thread::sleep_for(std::chrono::milliseconds(20)); - SimulateKeyWithCtrl(KeyEvent::KEYCODE_C, KeyEvent::KEY_ACTION_DOWN); - SimulateKeyWithCtrl(KeyEvent::KEYCODE_C, KeyEvent::KEY_ACTION_UP); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); + if (!baseInputMonitor_->IsTextSelected()) { + return; + } + baseInputMonitor_->ResetFinishedState(); + if (pasteboardObserver_ == nullptr) { + pasteboardObserver_ = sptr::MakeSptr(baseInputMonitor_); + } + auto selectionInfo = baseInputMonitor_->GetSelectionInfo(); + int32_t ret = PasteboardClient::GetInstance()->SubscribeDisposableObserver(pasteboardObserver_, + selectionInfo.bundleName, DisposableType::PLAIN_TEXT, MAX_PASTERBOARD_TEXT_LENGTH); + SELECTION_HILOGI("[selectevent] Call pasteboard interface. Selection event id is %{public}u. \ + Error code is %{public}d.", selSeqId.load(), ret); + if (ret != ERR_OK) { + SELECTION_HILOGE("Failed to SubscribeDisposableObserver, ret: %{public}d.", ret); + return; + } + + InjectCtrlC(); + SELECTION_HILOGI("[selectevent] Inject Ctrl+C. Selection event id is %{public}u.", selSeqId.load()); } -void SelectionInputMonitor::SimulateKeyWithCtrl(int32_t keyCode, int32_t keyAction) const +void SelectionInputMonitor::InjectCtrlC() const { - auto KeyEvent = KeyEvent::Create(); - KeyEvent->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - KeyEvent->SetKeyAction(keyAction); + // 创建KeyEvent对象 + auto keyEvent1 = KeyEvent::Create(); + + // 设置Ctrl键按下 + keyEvent1->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + keyEvent1->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyEvent1->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); KeyEvent::KeyItem item1; - KeyEvent::KeyItem item2; - item1.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); item1.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); - item2.SetPressed(keyAction == KeyEvent::KEY_ACTION_DOWN); - item2.SetKeyCode(keyCode); - KeyEvent->AddKeyItem(item1); - KeyEvent->AddKeyItem(item2); - InputManager::GetInstance()->SimulateInputEvent(KeyEvent); + item1.SetPressed(true); + keyEvent1->AddKeyItem(item1); + InputManager::GetInstance()->SimulateInputEvent(keyEvent1); + + // 设置C键按下 + auto keyEvent2 = KeyEvent::Create(); + keyEvent2->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + keyEvent2->SetKeyCode(KeyEvent::KEYCODE_C); + keyEvent2->SetKeyAction(KeyEvent::KEY_ACTION_DOWN); + KeyEvent::KeyItem item2; + item2.SetKeyCode(KeyEvent::KEYCODE_C); + item2.SetPressed(true); + keyEvent2->AddKeyItem(item1); + keyEvent2->AddKeyItem(item2); + InputManager::GetInstance()->SimulateInputEvent(keyEvent2); + + // 设置C键释放 + auto keyEvent3 = KeyEvent::Create(); + keyEvent3->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + keyEvent3->SetKeyCode(KeyEvent::KEYCODE_C); + keyEvent3->SetKeyAction(KeyEvent::KEY_ACTION_UP); + KeyEvent::KeyItem item3; + item3.SetKeyCode(KeyEvent::KEYCODE_C); + item3.SetPressed(false); + keyEvent3->AddKeyItem(item1); + keyEvent3->AddKeyItem(item3); + InputManager::GetInstance()->SimulateInputEvent(keyEvent3); + + // 设置Ctrl键释放 + auto keyEvent4 = KeyEvent::Create(); + keyEvent4->AddFlag(InputEvent::EVENT_FLAG_NO_INTERCEPT); + keyEvent4->SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + keyEvent4->SetKeyAction(KeyEvent::KEY_ACTION_UP); + KeyEvent::KeyItem item4; + item4.SetKeyCode(KeyEvent::KEYCODE_CTRL_LEFT); + item4.SetPressed(false); + keyEvent4->AddKeyItem(item4); + InputManager::GetInstance()->SimulateInputEvent(keyEvent4); } void SelectionPasteboardDisposableObserver::OnTextReceived(const std::string &text, int32_t errCode) { - if (errCode == 0) { - SELECTION_HILOGI("Text received: %{public}s.", text.c_str()); - if (pInputMonitor_) { - pInputMonitor_->OnSelectionTriggered(text); - } - } else { - SELECTION_HILOGI("Error receiving text: errCode: %{public}d", errCode); + SELECTION_HILOGI("[selectevent] Pasteboard call sa. Selection event id is %{public}u.", selSeqId.load()); + if (errCode != 0) { + SELECTION_HILOGI("Error receiving text, errCode: %{public}d", errCode); + return; } -} \ No newline at end of file + SELECTION_HILOGI("Text received length: %{public}lu.", text.length()); + if (!baseInputMonitor_) { + return; + } + + if (text.empty()) { + SELECTION_HILOGI("Received empty text."); + return; + } + + auto selectionInfo = baseInputMonitor_->GetSelectionInfo(); + selectionInfo.text = text; + SelectionInfoData infoData; + infoData.data = selectionInfo; + SELECTION_HILOGI("SelectionInfoData length: %{public}lu.", infoData.ToString().length()); + sptr listener = SelectionService::GetInstance()->GetListener(); + if (listener == nullptr) { + SELECTION_HILOGE("Selection listener is nullptr"); + return; + } + listener->OnSelectionChange(infoData); +} diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 67d58e7..9df33dd 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -15,6 +15,10 @@ #include "selection_service.h" +#include +#include +#include + #include "ability_manager_client.h" #include "db_selection_config_repository.h" #include "iremote_object.h" @@ -24,17 +28,19 @@ #include "selection_log.h" #include #include "parameter.h" -#include #include "common_event_manager.h" #include "selection_config_comparator.h" #include "selection_input_monitor.h" #include "selection_interface.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" -#include "screenlock_manager.h" #include "focus_monitor_manager.h" #include "os_account_manager.h" #include "sys_selection_config_repository.h" +#include "selection_app_validator.h" + +#define SELECTION_MAX_TRY_TIMES 50 +#define SELECTION_SLEEP_TIME 100 using namespace OHOS; using namespace OHOS::SelectionFwk; @@ -43,9 +49,7 @@ using namespace OHOS::MMI; using namespace OHOS::EventFwk; const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(SelectionService::GetInstance().GetRefPtr()); -std::shared_mutex SelectionService::adminLock_; -sptr SelectionService::instance_; -sptr SelectionService::listenerStub_ { nullptr }; +sptr SelectionService::listener_ { nullptr }; void SelectionExtensionAbilityConnection::OnAbilityConnectDone( const ElementName &element, const sptr &remoteObject, int resultCode) @@ -57,19 +61,19 @@ void SelectionExtensionAbilityConnection::OnAbilityDisconnectDone(const ElementN { SELECTION_HILOGI("OnAbilityDisconnectDone, bundle = %{public}s,ability = %{public}s, resultCode = %{public}d", element.GetBundleName().c_str(), element.GetAbilityName().c_str(), resultCode); - remoteObject_ = nullptr; + auto disconnectAppInfo = element.GetBundleName() + "/" + element.GetAbilityName(); + auto curAppInfo = MemSelectionConfig::GetInstance().GetSelectionConfig().GetApplicationInfo(); + if (curAppInfo == disconnectAppInfo) { + auto ret = SelectionService::GetInstance()->ConnectNewExtAbility(element.GetBundleName(), + element.GetAbilityName()); + SELECTION_HILOGD("Reconnect extension ability ret = %{public}d", ret); + } } sptr SelectionService::GetInstance() { - if (instance_ == nullptr) { - std::unique_lock autoLock(adminLock_); - if (instance_ == nullptr) { - SELECTION_HILOGI("SelectionService:GetInstance instance = new SelectionService()"); - instance_ = new (std::nothrow) SelectionService(); - } - } - return instance_; + static sptr instance = new (std::nothrow) SelectionService(); + return instance; } SelectionService::SelectionService() : SystemAbility(SELECTION_FWK_SA_ID, true) @@ -87,37 +91,43 @@ SelectionService::~SelectionService() SELECTION_HILOGI("[~SelectionService]"); } -ErrCode SelectionService::UnregisterListener(const sptr &listener) -{ - listenerStub_ = nullptr; - return 0; -} - sptr SelectionService::GetListener() { std::lock_guard lock(mutex_); - return listenerStub_; + return listener_; } -ErrCode SelectionService::RegisterListener(const sptr &listener) +ErrCode SelectionService::RegisterListener(const sptr& listener) { + if (!SelectionAppValidator::GetInstance().Validate()) { + return SESSION_UNAUTHENTICATED_ERR; + } + + pid_.store(IPCSkeleton::GetCallingPid()); SELECTION_HILOGI("Enter RegisterListener"); if (listener == nullptr) { SELECTION_HILOGE("RegisterListener: selection listener is nullptr."); - return 1; + return ERR_INVALID_DATA; } - auto listenerStub = iface_cast(listener); - if (listenerStub == nullptr) { - SELECTION_HILOGE("RegisterListener: Failed to cast listener to ISelectionListener."); - return 1; + { + std::lock_guard lock(mutex_); + listener_ = listener; } - if (listenerStub_ && listenerStub_ == listenerStub) { - SELECTION_HILOGW("RegisterListener: Listener already registered."); - return 0; - } + return 0; +} - listenerStub_ = listenerStub; +ErrCode SelectionService::UnregisterListener(const sptr& listener) +{ + std::lock_guard lock(mutex_); + listener_ = nullptr; + return 0; +} + +ErrCode SelectionService::IsCurrentSelectionApp(int pid, bool &resultValue) +{ + resultValue = (pid_.load() != -1 && pid == pid_.load()); + SELECTION_HILOGI("Checking IsCurrentSelectionApp: %{public}d", resultValue); return 0; } @@ -130,15 +140,16 @@ int32_t SelectionService::Dump(int32_t fd, const std::vector &ar static void WatchEnableSwitch(const char *key, const char *value, void *context) { SelectionService *selectionService = static_cast(context); - SELECTION_HILOGI("WatchEnableSwitch begin"); SELECTION_HILOGI("%{public}s: value=[%{public}s], DEFAULT_SWITCH =[%{public}s]", key, value, DEFAULT_SWITCH); - int isEnabledValue = strcmp(value, DEFAULT_SWITCH) == 0 ? 1 : 0; + bool isEnabledValue = (strcmp(value, DEFAULT_SWITCH) == 0); SELECTION_HILOGI("isEnabledValue is %{public}d", isEnabledValue); MemSelectionConfig::GetInstance().SetEnabled(isEnabledValue); auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); - SELECTION_HILOGI("selectionConfig.selectionConfig is %{public}d", selectionConfig.IsEnabled()); + SELECTION_HILOGI("selectionConfig.selectionConfig is %{public}d", selectionConfig.GetEnable()); int ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); - SELECTION_HILOGI("ADD Database ret = %{public}d", ret); + if (ret != SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); + } } static void WatchTriggerMode(const char *key, const char *value, void *context) @@ -150,11 +161,13 @@ static void WatchTriggerMode(const char *key, const char *value, void *context) BaseSelectionInputMonitor::ctrlSelectFlag = (triggerCmpResult == 0); SELECTION_HILOGI("ctrlSelectFlag is %{public}d", BaseSelectionInputMonitor::ctrlSelectFlag); - int triggerValue = triggerCmpResult == 0 ? 1 : 0; + bool triggerValue = (triggerCmpResult == 0); MemSelectionConfig::GetInstance().SetTriggered(triggerValue); auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); int ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); - SELECTION_HILOGI("ADD Database ret = %{public}d", ret); + if (ret != SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); + } } static void WatchAppSwitch(const char *key, const char *value, void *context) @@ -168,6 +181,12 @@ static void WatchAppSwitch(const char *key, const char *value, void *context) } const std::string appInfo = value; + char target = '/'; + int count = std::count(appInfo.begin(), appInfo.end(), target); + if (count != 1) { + SELECTION_HILOGE("/ is not only one."); + return; + } auto pos = appInfo.find('/'); if (appInfo.empty() || pos == std::string::npos || pos + 1 >= appInfo.size()) { SELECTION_HILOGE("app info: %{public}s is invalid!", appInfo.c_str()); @@ -175,25 +194,32 @@ static void WatchAppSwitch(const char *key, const char *value, void *context) } const std::string bundleName = appInfo.substr(0, pos); const std::string extName = appInfo.substr(pos + 1); - SELECTION_HILOGD("bundleName: %{public}s, extName: %{public}s", bundleName.c_str(), extName.c_str()); + if (bundleName.length() == 0 || extName.length() == 0) { + SELECTION_HILOGE("bundleName or extName is empty"); + return; + } + MemSelectionConfig::GetInstance().SetApplicationInfo(appInfo); selectionService->DisconnectCurrentExtAbility(); auto ret = selectionService->ConnectNewExtAbility(bundleName, extName); SELECTION_HILOGD("StartExtensionAbility ret = %{public}d", ret); - MemSelectionConfig::GetInstance().SetBundleName(appInfo); auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); - SELECTION_HILOGI("ADD Database ret = %{public}d", ret); + if (ret != SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); + } } bool SelectionService::IsExistUid() { - return isExistUid_; + return isExistUid_.load(); } void SelectionService::DisconnectCurrentExtAbility() { + pid_.store(-1); SELECTION_HILOGD("Disconnect current extensionAbility"); + std::lock_guard lockGuard(connectInnerMutex_); if (connectInner_ == nullptr) { SELECTION_HILOGE("connectInner_ is null"); return; @@ -204,6 +230,7 @@ void SelectionService::DisconnectCurrentExtAbility() SELECTION_HILOGE("DisconnectServiceAbility failed, ret: %{public}d", ret); return; } + connectInner_ = nullptr; } int32_t SelectionService::ConnectNewExtAbility( const std::string& bundleName, const std::string& abilityName) @@ -212,14 +239,19 @@ int32_t SelectionService::ConnectNewExtAbility( const std::string& bundleName, c abilityName.c_str()); AAFwk::Want want; want.SetElementName(bundleName, abilityName); - connectInner_ = new(std::nothrow) SelectionExtensionAbilityConnection(); + std::lock_guard lockGuard(connectInnerMutex_); + connectInner_ = sptr::MakeSptr(); + if (connectInner_ == nullptr) { + SELECTION_HILOGE("new(std::nothrow) SelectionExtensionAbilityConnection() failed!"); + return SELECTION_CONFIG_FAILURE; + } auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want, connectInner_, -1); if (ret != 0) { - SELECTION_HILOGE("StartExtensionAbility failed %{public}d", ret); + SELECTION_HILOGE("[selectevent] StartExtensionAbility failed. error code is %{public}d.", ret); return ret; } - SELECTION_HILOGD("StartExtensionAbility success"); + SELECTION_HILOGI("[selectevent] StartExtensionAbility success."); return 0; } @@ -234,35 +266,41 @@ void SelectionService::WatchParams() int SelectionService::GetUserId() { - return userId_; + return userId_.load(); } void SelectionService::GetAccountLocalId() { int32_t userId = -1; int32_t ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); - while (ret != 0) { - sleep(1); + auto iCounter = 0; + while (ret != 0 && iCounter < SELECTION_MAX_TRY_TIMES) { + iCounter++; + std::this_thread::sleep_for(std::chrono::milliseconds(SELECTION_SLEEP_TIME)); ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); } - SELECTION_HILOGI("GetForegroundOsAccountLocalId userId = %{public}d", userId); - userId_ = userId; + SELECTION_HILOGI("GetForegroundOsAccountLocalId userId."); + userId_.store(userId); } void SelectionService::SynchronizeSelectionConfig() { GetAccountLocalId(); SelectionConfig sysSelectionConfig = SysSelectionConfigRepository::GetInstance()->GetSysParameters(); - SELECTION_HILOGI("sysSelectionConfig: uid=%{public}d enable=%{public}d trigger=%{public}d bundleName=%{public}s", - sysSelectionConfig.GetUid(), sysSelectionConfig.IsEnabled(), sysSelectionConfig.IsTriggered(), sysSelectionConfig.GetBundleName().c_str()); - auto dbSelectionConfig = DbSelectionConfigRepository::GetInstance()->GetOneByUserId(userId_); - auto result = SelectionConfigComparator::Compare(userId_, sysSelectionConfig, dbSelectionConfig); + SELECTION_HILOGI("sysSelectionConfig: enable=%{public}d trigger=%{public}d applicationInfo=%{public}s", + sysSelectionConfig.GetEnable(), sysSelectionConfig.GetTriggered(), + sysSelectionConfig.GetApplicationInfo().c_str()); + auto dbSelectionConfig = DbSelectionConfigRepository::GetInstance()->GetOneByUserId(userId_.load()); + auto result = SelectionConfigComparator::Compare(userId_.load(), sysSelectionConfig, dbSelectionConfig); MemSelectionConfig::GetInstance().SetSelectionConfig(result.selectionConfig); if (result.shouldCreate) { SELECTION_HILOGI("result.shouldCreate"); - DbSelectionConfigRepository::GetInstance()->Save(userId_, result.selectionConfig); - SELECTION_HILOGI("result.selectionConfig.isEnable = %{public}d", result.selectionConfig.IsEnabled()); + auto ret = DbSelectionConfigRepository::GetInstance()->Save(userId_.load(), result.selectionConfig); + if (ret != SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); + } + SELECTION_HILOGI("result.selectionConfig.isEnable = %{public}d", result.selectionConfig.GetEnable()); SysSelectionConfigRepository::GetInstance()->SetSysParameters(result.selectionConfig); return; } @@ -273,7 +311,10 @@ void SelectionService::SynchronizeSelectionConfig() SysSelectionConfigRepository::GetInstance()->SetSysParameters(result.selectionConfig); } else if (result.direction == SyncDirection::FromSysToDb) { SELECTION_HILOGI("result.direction == SyncDirection::FromSysToDb"); - DbSelectionConfigRepository::GetInstance()->Save(userId_, result.selectionConfig); + auto ret = DbSelectionConfigRepository::GetInstance()->Save(userId_.load(), result.selectionConfig); + if (ret != SELECTION_CONFIG_OK) { + SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); + } } if (result.shouldStop) { @@ -284,20 +325,21 @@ void SelectionService::SynchronizeSelectionConfig() void SelectionService::OnStart() { - SELECTION_HILOGI("[SelectionService][OnStart]begin"); + SELECTION_HILOGI("[selectevent][SelectionService][OnStart]begin"); Publish(SelectionService::GetInstance()); InputMonitorInit(); SynchronizeSelectionConfig(); WatchParams(); InitFocusChangedMonitor(); - SELECTION_HILOGI("[SelectionService][OnStart]end"); + SELECTION_HILOGI("[selectevent][SelectionService][OnStart]end."); } void SelectionService::OnStop() { - SELECTION_HILOGI("[SelectionService][OnStop]begin"); + SELECTION_HILOGI("[selectevent][SelectionService][OnStop]begin"); InputMonitorCancel(); - SELECTION_HILOGI("[SelectionService][OnStop]end"); + CancelFocusChangedMonitor(); + SELECTION_HILOGI("[selectevent][SelectionService][OnStop]end."); } void SelectionService::InputMonitorInit() @@ -310,11 +352,19 @@ void SelectionService::InputMonitorInit() auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); auto remoteObj = sam->CheckSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); - while (remoteObj == nullptr) { + auto iCounter = 0; + while (remoteObj == nullptr && iCounter < SELECTION_MAX_TRY_TIMES) { SELECTION_HILOGI("CheckSystemAbility MULTIMODAL_INPUT_SERVICE_ID failed. wait..."); + iCounter++; sleep(1); remoteObj = sam->CheckSystemAbility(MULTIMODAL_INPUT_SERVICE_ID); } + + if (remoteObj == nullptr) { + SELECTION_HILOGE("CheckSystemAbility MULTIMODAL_INPUT_SERVICE_ID failed."); + return; + } + SELECTION_HILOGI("CheckSystemAbility MULTIMODAL_INPUT_SERVICE_ID succeed."); inputMonitorId_ = InputManager::GetInstance()->AddMonitor(inputMonitor); SELECTION_HILOGI("[SelectionService] input monitor init end"); @@ -334,17 +384,29 @@ void SelectionService::InitFocusChangedMonitor() { SELECTION_HILOGI("[SelectionService] init focus changed monitor"); FocusMonitorManager::GetInstance().RegisterFocusChangedListener( - [this](bool isOnFocused, int32_t windowId, uint32_t windowType) { - HandleFocusChanged(isOnFocused, windowId, windowType); + [this](const sptr &focusChangeInfo, bool isFocused) { + HandleFocusChanged(focusChangeInfo, isFocused); }); } -void SelectionService::HandleFocusChanged(bool isOnFocused, uint32_t windowId, uint32_t windowType) +void SelectionService::CancelFocusChangedMonitor() +{ + SELECTION_HILOGI("[SelectionService] cancel focus changed monitor"); + FocusMonitorManager::GetInstance().UnregisterFocusChangedListener(); +} + +void SelectionService::HandleFocusChanged(const sptr &focusChangeInfo, bool isFocused) { SELECTION_HILOGI("[SelectionService] handle focus changed"); - if (!isOnFocused && listenerStub_ != nullptr) { - listenerStub_->FocusChange(windowId, windowType); + std::lock_guard lock(mutex_); + if (listener_ == nullptr || focusChangeInfo == nullptr) { + SELECTION_HILOGE("listener_ or focusChangeInfo is nullptr."); + return; } + auto windowType = static_cast(focusChangeInfo->windowType_); + SelectionFocusChangeInfo selectionFocusChangeInfo(focusChangeInfo->windowId_, focusChangeInfo->displayId_, + focusChangeInfo->pid_, focusChangeInfo->uid_, windowType, isFocused, FocusChangeSource::WindowManager); + listener_->FocusChange(selectionFocusChangeInfo); } void SelectionService::HandleKeyEvent(int32_t keyCode) @@ -353,4 +415,4 @@ void SelectionService::HandleKeyEvent(int32_t keyCode) void SelectionService::HandlePointEvent(int32_t type) { -} +} \ No newline at end of file diff --git a/service/src/sys_selection_config_repository.cpp b/service/src/sys_selection_config_repository.cpp index 34c22db..6b7f3fc 100644 --- a/service/src/sys_selection_config_repository.cpp +++ b/service/src/sys_selection_config_repository.cpp @@ -16,7 +16,9 @@ #include "sys_selection_config_repository.h" #include #include "parameter.h" +#include "param_wrapper.h" #include "selection_log.h" +#include "selection_common.h" namespace OHOS { namespace SelectionFwk { @@ -26,6 +28,8 @@ static const char *SELECTION_APPLICATION = "sys.selection.app"; static const char *SELECTION_UID = "sys.selection.uid"; static const int BUFFER_LEN = 200; +#define SELECTION_MAX_UID_LENGTH 11 + std::shared_ptr SysSelectionConfigRepository::instance_ = nullptr; std::shared_ptr SysSelectionConfigRepository::GetInstance() @@ -41,10 +45,9 @@ std::shared_ptr SysSelectionConfigRepository::GetI int SysSelectionConfigRepository::SetSysParameters(const SelectionConfig &info) { - SELECTION_HILOGI("info.uid = %{public}d", info.GetUid()); - SetEnabled(info.IsEnabled()); - SetTriggered(info.IsTriggered()); - SetBundleName(info.GetBundleName()); + SetEnabled(info.GetEnable()); + SetTriggered(info.GetTriggered()); + SetApplicationInfo(info.GetApplicationInfo()); SetUid(info.GetUid()); return 0; } @@ -52,9 +55,9 @@ int SysSelectionConfigRepository::SetSysParameters(const SelectionConfig &info) SelectionConfig SysSelectionConfigRepository::GetSysParameters() { SelectionConfig info; - info.SetEnabled(IsEnabled()); - info.SetTriggered(IsTriggered()); - info.SetBundleName(GetBundleName()); + info.SetEnabled(GetEnable()); + info.SetTriggered(GetTriggered()); + info.SetApplicationInfo(GetApplicationInfo()); info.SetUid(GetUid()); return info; } @@ -64,7 +67,7 @@ void SysSelectionConfigRepository::DisableSAService() SetParameter(SELECTION_SWITCH, "off"); } -int SysSelectionConfigRepository::IsEnabled() +int SysSelectionConfigRepository::GetEnable() { char value[BUFFER_LEN]; GetParameter(SELECTION_SWITCH, "", value, BUFFER_LEN); @@ -74,7 +77,7 @@ int SysSelectionConfigRepository::IsEnabled() return 0; } -int SysSelectionConfigRepository::IsTriggered() +int SysSelectionConfigRepository::GetTriggered() { char value[BUFFER_LEN]; GetParameter(SELECTION_TRIGGER, "", value, BUFFER_LEN); @@ -86,46 +89,74 @@ int SysSelectionConfigRepository::IsTriggered() int SysSelectionConfigRepository::GetUid() { - char value[BUFFER_LEN]; - GetParameter(SELECTION_UID, "", value, BUFFER_LEN); - return std::atoi(value); + std::string uidStr; + if (OHOS::system::GetStringParameter(SELECTION_UID, uidStr) != 0) { + SELECTION_HILOGE("GetStringParameter failed for SELECTION_UID"); + return -1; + } + + if (!isNumber(uidStr)) { + SELECTION_HILOGE("uidStr maybe not all of digit!"); + return -1; + } + + size_t maxLen = (uidStr[0] == '-') ? SELECTION_MAX_UID_LENGTH : SELECTION_MAX_UID_LENGTH - 1; + + if (uidStr.length() > maxLen) { + SELECTION_HILOGE("uidStr exceeds the range of int!"); + return -1; + } + + if ((uidStr.length() == maxLen) && + ((uidStr[0] != '-' && uidStr > "2147483647") || + (uidStr[0] == '-' && uidStr > "-2147483648"))) { + SELECTION_HILOGE("uidStr exceeds the range of int!"); + return -1; + } + + int uid = std::stoi(uidStr); + return uid; } -std::string SysSelectionConfigRepository::GetBundleName() +std::string SysSelectionConfigRepository::GetApplicationInfo() { - char value[BUFFER_LEN]; - GetParameter(SELECTION_APPLICATION, "", value, BUFFER_LEN); - return value; + std::string appinfo; + if (OHOS::system::GetStringParameter(SELECTION_APPLICATION, appinfo) != 0) { + SELECTION_HILOGE("GetStringParameter failed for SELECTION_APPLICATION"); + return ""; + } + + return appinfo; } -void SysSelectionConfigRepository::SetEnabled(int enabled) +void SysSelectionConfigRepository::SetEnabled(bool enabled) { - SELECTION_HILOGI("[XYING6]enabled: %{public}d", enabled); - if (enabled == 1) { + SELECTION_HILOGI("enabled: %{public}d", enabled); + if (enabled) { SetParameter(SELECTION_SWITCH, "on"); - } else if (enabled == 0) { + } else { SetParameter(SELECTION_SWITCH, "off"); } } -void SysSelectionConfigRepository::SetTriggered(int isTriggered) +void SysSelectionConfigRepository::SetTriggered(bool isTriggered) { - if (isTriggered == 1) { + if (isTriggered) { SetParameter(SELECTION_TRIGGER, "ctrl"); - } else if (isTriggered == 0) { + } else { SetParameter(SELECTION_TRIGGER, ""); } } void SysSelectionConfigRepository::SetUid(int uid) { - SELECTION_HILOGI("uid = %{public}d", uid); - SetParameter(SELECTION_UID, std::to_string(uid).c_str()); + std::string uidStr = std::to_string(uid); + SetParameter(SELECTION_UID, uidStr.c_str()); } -void SysSelectionConfigRepository::SetBundleName(const std::string &bundleName) +void SysSelectionConfigRepository::SetApplicationInfo(const std::string &applicationInfo) { - SetParameter(SELECTION_APPLICATION, bundleName.c_str()); + SetParameter(SELECTION_APPLICATION, applicationInfo.c_str()); } } // namespace SelectionFwk } // namespace OHOS \ No newline at end of file diff --git a/test/fuzztest/BUILD.gn b/test/fuzztest/BUILD.gn index edad0ff..a6e951d 100644 --- a/test/fuzztest/BUILD.gn +++ b/test/fuzztest/BUILD.gn @@ -18,5 +18,6 @@ group("selection_service_fuzztest") { deps = [ "selectioninputability_fuzzer:fuzztest", + "selectioninputlistener_fuzzer:listenerfuzztest", ] } diff --git a/test/fuzztest/selectioninputability_fuzzer/BUILD.gn b/test/fuzztest/selectioninputability_fuzzer/BUILD.gn index 70d38fb..2e5b497 100644 --- a/test/fuzztest/selectioninputability_fuzzer/BUILD.gn +++ b/test/fuzztest/selectioninputability_fuzzer/BUILD.gn @@ -44,7 +44,6 @@ ohos_fuzztest("SelectionInputAbilityFuzzTest") { deps = [ "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_ability", "${selection_fwk_root_path}/frameworks/native/selection_extension:selection_extension_ability_native", - "${selection_fwk_root_path}/service:selection_service_proxy", "${selection_fwk_root_path}/service:selection_service", ] diff --git a/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp b/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp index 42640e9..cc9f5c8 100644 --- a/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp +++ b/test/fuzztest/selectioninputability_fuzzer/selectioninputability_fuzzer.cpp @@ -46,6 +46,10 @@ sptr GetSelectionSystemAbility() void TestSendRequest(uint32_t code) { sptr systemAbility = GetSelectionSystemAbility(); + if (systemAbility == nullptr) { + SELECTION_HILOGE("get system ability is nullptr!"); + return; + } MessageParcel data; MessageParcel reply; MessageOption option; diff --git a/test/fuzztest/selectioninputlistener_fuzzer/BUILD.gn b/test/fuzztest/selectioninputlistener_fuzzer/BUILD.gn new file mode 100644 index 0000000..258850e --- /dev/null +++ b/test/fuzztest/selectioninputlistener_fuzzer/BUILD.gn @@ -0,0 +1,70 @@ +# 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("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") + +import("//build/config/features.gni") +import("//build/ohos.gni") +import("//build/test.gni") + +ohos_fuzztest("SelectionInputListenerFuzzTest") { + module_out_path = "selectionfwk/selectionfwk" + + fuzz_config_file = + "//foundation/systemabilitymgr/selectionfwk/test/fuzztest/selectioninputlistener_fuzzer" + + include_dirs = [ + "${selection_fwk_root_path}/frameworks/native/selection_ability/include", + "${selection_fwk_root_path}/utils/include", + "${target_gen_dir}", + "${selection_fwk_root_path}/common", + "${selection_fwk_root_path}/service/include", + ] + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ "selectioninputlistener_fuzzer.cpp" ] + + deps = [ + "${selection_fwk_root_path}/service:selection_service", + "${selection_fwk_root_path}/interfaces/idl:selection_service_interface", + "${selection_fwk_root_path}/common:selection_common", + "${selection_fwk_root_path}/interfaces/idl:selection_service_proxy", + "${selection_fwk_root_path}/interfaces/idl:selection_listener_proxy", + ] + + external_deps = [ + "ability_runtime:ability_manager", + "ability_runtime:runtime", + "c_utils:utils", + "hilog:libhilog", + "input:libmmi-client", + "ipc:ipc_single", + "napi:ace_napi", + "window_manager:libdm", + "samgr:samgr_proxy", + "window_manager:libdm_lite", + "window_manager:libwsutils", + ] +} + +group("listenerfuzztest") { + testonly = true + deps = [] + deps += [ ":SelectionInputListenerFuzzTest" ] +} diff --git a/test/fuzztest/selectioninputlistener_fuzzer/corpus/init b/test/fuzztest/selectioninputlistener_fuzzer/corpus/init new file mode 100644 index 0000000..65af8ee --- /dev/null +++ b/test/fuzztest/selectioninputlistener_fuzzer/corpus/init @@ -0,0 +1,14 @@ +# 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. + +FUZZ \ No newline at end of file diff --git a/test/fuzztest/selectioninputlistener_fuzzer/project.xml b/test/fuzztest/selectioninputlistener_fuzzer/project.xml new file mode 100644 index 0000000..66e1dca --- /dev/null +++ b/test/fuzztest/selectioninputlistener_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 300 + + 4096 + + diff --git a/test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.cpp b/test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.cpp new file mode 100644 index 0000000..21d8fea --- /dev/null +++ b/test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.cpp @@ -0,0 +1,107 @@ +/* + * 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 "selectioninputlistener_fuzzer.h" +#include "system_ability_definition.h" +#include "selection_data_inner.h" +#include "iselection_listener.h" +#include +#include "selection_log.h" +#include "iservice_registry.h" +#include +#include +#include + +namespace OHOS { +namespace SelectionFwk { +sptr GetSelectionSystemAbility() +{ + auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + SELECTION_HILOGE("system ability manager is nullptr!"); + return nullptr; + } + + sptr systemAbility = nullptr; + systemAbility = systemAbilityManager->GetSystemAbility(SELECTION_FWK_SA_ID); + if (systemAbility == nullptr) { + SELECTION_HILOGE("get system ability is nullptr!"); + return nullptr; + } + + return systemAbility; +} + +void TestOnSelectionChange(std::string fuzzedString, int32_t fuzzedInt32, uint32_t fuzzedUInt32) +{ + auto remote = GetSelectionSystemAbility(); + auto listener = iface_cast(remote); + + if (listener == nullptr) { + SELECTION_HILOGE("get listener is null"); + return; + } + + SelectionInfoData dataInner; + dataInner.data.selectionType = MOVE_SELECTION; + dataInner.data.text = fuzzedString; + dataInner.data.startDisplayX = fuzzedInt32; + dataInner.data.startDisplayY = fuzzedInt32; + dataInner.data.endDisplayX = fuzzedInt32; + dataInner.data.endDisplayY = fuzzedInt32; + dataInner.data.startWindowX = fuzzedInt32; + dataInner.data.startWindowY = fuzzedInt32; + dataInner.data.endWindowX = fuzzedInt32; + dataInner.data.endWindowY = fuzzedInt32; + dataInner.data.displayId = fuzzedUInt32; + dataInner.data.windowId = fuzzedUInt32; + + listener->OnSelectionChange(dataInner); +} + +void TestFocusChange(uint32_t fuzzedUInt32) +{ + auto remote = GetSelectionSystemAbility(); + auto listener = iface_cast(remote); + + if (listener == nullptr) { + SELECTION_HILOGE("get listener is null"); + return; + } + SelectionFocusChangeInfo selectionFocusChangeInfo; + selectionFocusChangeInfo.windowId_ = fuzzedUInt32; + selectionFocusChangeInfo.windowType_ = fuzzedUInt32; + + listener->FocusChange(selectionFocusChangeInfo); +} +} // namespace SelectionFwk +} // namespace OHOS + +/* Fuzzer entry point */ +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(uint32_t)) { + return 0; + } + + std::string fuzzedString(reinterpret_cast(data), size); + auto fuzzedUInt32 = static_cast(size); + auto fuzzedInt32 = static_cast(size); + + OHOS::SelectionFwk::TestOnSelectionChange(fuzzedString, fuzzedInt32, fuzzedUInt32); + OHOS::SelectionFwk::TestFocusChange(fuzzedUInt32); + + return 0; +} \ No newline at end of file diff --git a/test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.h b/test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.h new file mode 100644 index 0000000..02b391d --- /dev/null +++ b/test/fuzztest/selectioninputlistener_fuzzer/selectioninputlistener_fuzzer.h @@ -0,0 +1,19 @@ +/* + * 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 SELECTION_INPUT_LISTENER_FUZZER +#define SELECTION_INPUT_LISTENER_FUZZER +#define FUZZ_PROJECT_NAME "selectioninputlistener_fuzzer" + +#endif // SELECTION_INPUT_LISTENER_FUZZER \ No newline at end of file diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index c6e0a19..f442e19 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -43,9 +43,9 @@ ohos_unittest("selection_service_unit_test") { "ipc:ipc_single", "init:libbeget_proxy", "input:libmmi-client", + "pasteboard:pasteboard_client", "safwk:system_ability_fwk", "samgr:samgr_proxy", - "screenlock_mgr:screenlock_client", ] part_name = "selectionfwk" subsystem_name = "systemabilitymgr" @@ -54,6 +54,9 @@ ohos_unittest("selection_service_unit_test") { group("selection_manager_ut") { testonly = true deps = [ - "systemapi_js_test:SystemApiJsTest", + ":selection_service_unit_test", + "resource/ohos_test:copy_ohos_test", + "selection_manager_js_test:SelectionManagerJsTest", + "selection_manager_invalid_operation_js_test:SelectionManagerInvalidOperationJsTest", ] } \ No newline at end of file diff --git a/test/unittest/resource/ohos_test/BUILD.gn b/test/unittest/resource/ohos_test/BUILD.gn new file mode 100644 index 0000000..11b66e5 --- /dev/null +++ b/test/unittest/resource/ohos_test/BUILD.gn @@ -0,0 +1,19 @@ +# 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") + +ohos_copy("copy_ohos_test") { + sources = [ "./ohos_test.xml" ] + outputs = [ "$root_out_dir/tests/unittest/selectionfwk/selectionfwk/resource/ohos_test.xml" ] +} diff --git a/test/unittest/resource/ohos_test/ohos_test.xml b/test/unittest/resource/ohos_test/ohos_test.xml new file mode 100644 index 0000000..b4801c5 --- /dev/null +++ b/test/unittest/resource/ohos_test/ohos_test.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/test/unittest/selection_config_comparator_test.cpp b/test/unittest/selection_config_comparator_test.cpp index 738af92..2794a47 100644 --- a/test/unittest/selection_config_comparator_test.cpp +++ b/test/unittest/selection_config_comparator_test.cpp @@ -19,7 +19,6 @@ #define private public #include "selection_config_comparator.h" -#include "screenlock_manager.h" #include "selection_config.h" namespace OHOS { @@ -55,9 +54,15 @@ void SelectionConfigComparatorTest::TearDown() std::cout << "SelectionConfigComparatorTest TearDown" << std::endl; } +void SetSelectionConfig(SelectionConfig& dbSelectionConfig, int uid, bool bEnable) +{ + dbSelectionConfig.SetUid(uid); + dbSelectionConfig.SetEnabled(bEnable); +} + /** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event + * @tc.name: SelectionConfigComparator001 + * @tc.desc: database testcase 001 * @tc.type: FUNC */ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator001, TestSize.Level1) @@ -69,77 +74,70 @@ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator001, TestSize.L ASSERT_TRUE(result.shouldCreate); } - /** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event + * @tc.name: SelectionConfigComparator002 + * @tc.desc: database testcase 002 * @tc.type: FUNC */ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator002, TestSize.Level1) { int uid = 100; SelectionConfig dbSelectionConfig; - dbSelectionConfig.SetUid(100); - dbSelectionConfig.SetEnabled(true); + SetSelectionConfig(dbSelectionConfig, uid, true); std::optional dbSelectionConfigOpt = dbSelectionConfig; SelectionConfig sysSelectionConfig; auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); ASSERT_EQ(result.direction, SyncDirection::FromDbToSys); ASSERT_EQ(result.selectionConfig.GetUid(), 100); - ASSERT_TRUE(result.selectionConfig.IsEnabled()); + ASSERT_TRUE(result.selectionConfig.GetEnable()); } /** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event + * @tc.name: SelectionConfigComparator003 + * @tc.desc: database testcase 003 * @tc.type: FUNC */ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator003, TestSize.Level1) { int uid = 100; SelectionConfig dbSelectionConfig; - dbSelectionConfig.SetUid(100); - dbSelectionConfig.SetEnabled(true); + SetSelectionConfig(dbSelectionConfig, uid, true); std::optional dbSelectionConfigOpt = dbSelectionConfig; SelectionConfig sysSelectionConfig; - sysSelectionConfig.SetUid(100); - sysSelectionConfig.SetEnabled(false); + SetSelectionConfig(sysSelectionConfig, uid, false); auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); ASSERT_TRUE(result.shouldStop); - ASSERT_FALSE(result.selectionConfig.IsEnabled()); + ASSERT_FALSE(result.selectionConfig.GetEnable()); } /** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event + * @tc.name: SelectionConfigComparator004 + * @tc.desc: database testcase 004 * @tc.type: FUNC */ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator004, TestSize.Level1) { int uid = 100; SelectionConfig dbSelectionConfig; - dbSelectionConfig.SetUid(100); - dbSelectionConfig.SetEnabled(true); + SetSelectionConfig(dbSelectionConfig, uid, true); std::optional dbSelectionConfigOpt = dbSelectionConfig; SelectionConfig sysSelectionConfig; - sysSelectionConfig.SetUid(100); - sysSelectionConfig.SetEnabled(true); + SetSelectionConfig(sysSelectionConfig, uid, true); auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); } /** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event + * @tc.name: SelectionConfigComparator005 + * @tc.desc: database testcase 005 * @tc.type: FUNC */ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator005, TestSize.Level1) { int uid = 100; SelectionConfig dbSelectionConfig; - dbSelectionConfig.SetUid(100); - dbSelectionConfig.SetEnabled(false); + SetSelectionConfig(dbSelectionConfig, uid, false); std::optional dbSelectionConfigOpt = dbSelectionConfig; SelectionConfig sysSelectionConfig; auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); @@ -148,43 +146,39 @@ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator005, TestSize.L } /** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event + * @tc.name: SelectionConfigComparator006 + * @tc.desc: database testcase 006 * @tc.type: FUNC */ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator006, TestSize.Level1) { int uid = 100; SelectionConfig dbSelectionConfig; - dbSelectionConfig.SetUid(100); - dbSelectionConfig.SetEnabled(false); + SetSelectionConfig(dbSelectionConfig, uid, false); std::optional dbSelectionConfigOpt = dbSelectionConfig; SelectionConfig sysSelectionConfig; - sysSelectionConfig.SetUid(100); - sysSelectionConfig.SetEnabled(false); + SetSelectionConfig(sysSelectionConfig, uid, false); auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); ASSERT_TRUE(result.shouldStop); } /** - * @tc.name: param check samgr ready event - * @tc.desc: param check samgr ready event + * @tc.name: SelectionConfigComparator007 + * @tc.desc: database testcase 007 * @tc.type: FUNC */ HWTEST_F(SelectionConfigComparatorTest, SelectionConfigComparator007, TestSize.Level1) { int uid = 100; SelectionConfig dbSelectionConfig; - dbSelectionConfig.SetUid(100); - dbSelectionConfig.SetEnabled(false); + SetSelectionConfig(dbSelectionConfig, uid, false); std::optional dbSelectionConfigOpt = dbSelectionConfig; SelectionConfig sysSelectionConfig; - sysSelectionConfig.SetUid(100); - sysSelectionConfig.SetEnabled(true); + SetSelectionConfig(sysSelectionConfig, uid, true); auto result = SelectionConfigComparator::Compare(uid, sysSelectionConfig, dbSelectionConfigOpt); ASSERT_EQ(result.direction, SyncDirection::FromSysToDb); - ASSERT_TRUE(result.selectionConfig.IsEnabled()); + ASSERT_TRUE(result.selectionConfig.GetEnable()); } } } \ No newline at end of file diff --git a/test/unittest/selection_input_monitor_test.cpp b/test/unittest/selection_input_monitor_test.cpp index 00e2ea8..59368ee 100644 --- a/test/unittest/selection_input_monitor_test.cpp +++ b/test/unittest/selection_input_monitor_test.cpp @@ -17,7 +17,6 @@ #include #include -#include "screenlock_manager.h" #include "selection_input_monitor.h" namespace OHOS { @@ -169,6 +168,7 @@ void BaseSelectionInputMonitorTest::TearDown() HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) { std::cout << " SelectInputMonitor001 start " << std::endl; + BaseSelectionInputMonitor::ctrlSelectFlag = false; LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_MOVE(inputMonitor); @@ -182,7 +182,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor001, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) { std::cout << " SelectInputMonitor002 start " << std::endl; - LEFT_BUTTON_CLICK(inputMonitor); LEFT_BUTTON_CLICK(inputMonitor); @@ -195,7 +194,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor002, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) { std::cout << " SelectInputMonitor003 start " << std::endl; - LEFT_BUTTON_CLICK(inputMonitor); LEFT_BUTTON_CLICK(inputMonitor); LEFT_BUTTON_CLICK(inputMonitor); @@ -209,7 +207,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor003, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor004, TestSize.Level1) { std::cout << " SelectInputMonitor004 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -223,7 +220,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor004, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor005, TestSize.Level1) { std::cout << " SelectInputMonitor005 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -239,7 +235,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor005, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor006, TestSize.Level1) { std::cout << " SelectInputMonitor006 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -260,7 +255,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor006, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor007, TestSize.Level1) { std::cout << " SelectInputMonitor007 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -281,7 +275,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor007, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor008, TestSize.Level1) { std::cout << " SelectInputMonitor008 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -302,7 +295,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor008, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor009, TestSize.Level1) { std::cout << " SelectInputMonitor009 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -319,7 +311,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor009, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor010, TestSize.Level1) { std::cout << " SelectInputMonitor010 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -339,7 +330,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor010, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor011, TestSize.Level1) { std::cout << " SelectInputMonitor011 start " << std::endl; - LEFT_BUTTON_DOWN(inputMonitor); LEFT_BUTTON_MOVE(inputMonitor); LEFT_BUTTON_UP(inputMonitor); @@ -356,7 +346,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor011, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor012, TestSize.Level1) { std::cout << " SelectInputMonitor012 start " << std::endl; - CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -373,7 +362,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor012, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor013, TestSize.Level1) { std::cout << " SelectInputMonitor013 start " << std::endl; - CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -392,7 +380,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor013, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor014, TestSize.Level1) { std::cout << " SelectInputMonitor014 start " << std::endl; - CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -414,7 +401,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor014, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor015, TestSize.Level1) { std::cout << " SelectInputMonitor015 start " << std::endl; - CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); @@ -425,7 +411,6 @@ HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor015, TestSize.Level1) HWTEST_F(BaseSelectionInputMonitorTest, SelectInputMonitor016, TestSize.Level1) { std::cout << " SelectInputMonitor016 start " << std::endl; - CTRL_DOWN(inputMonitor); CTRL_UP(inputMonitor); diff --git a/test/unittest/selection_manager_invalid_operation_js_test/BUILD.gn b/test/unittest/selection_manager_invalid_operation_js_test/BUILD.gn new file mode 100644 index 0000000..40e0be0 --- /dev/null +++ b/test/unittest/selection_manager_invalid_operation_js_test/BUILD.gn @@ -0,0 +1,21 @@ +# 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/test.gni") + +module_output_path = "selectionfwk/selectionfwk" +ohos_js_unittest("SelectionManagerInvalidOperationJsTest") { + module_out_path = module_output_path + hap_profile = "./config.json" + certificate_profile = "./openharmony_sx.p7b" +} diff --git a/test/unittest/selection_manager_invalid_operation_js_test/InvalidOperationTest.js b/test/unittest/selection_manager_invalid_operation_js_test/InvalidOperationTest.js new file mode 100644 index 0000000..a9ce1cc --- /dev/null +++ b/test/unittest/selection_manager_invalid_operation_js_test/InvalidOperationTest.js @@ -0,0 +1,76 @@ +/* + * 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 selectionManager from '@ohos.selectionInput.selectionManager' +import { describe, beforeAll, afterAll, it, expect } from 'deccjsunit/index' +import { PanelType } from '@ohos.selectionInput.SelectionPanel'; + +describe("SelectionManagerInvalidOperationJsTest", function () { + beforeAll(function () { + console.info('beforeAll called'); + }) + + afterAll(function () { + console.info('AfterAll called'); + }) + + /* + * @tc.number selectionfwk_on_selectionCompleted_invalid_operation_001 + * @tc.name Test should throw BusinessError 33600003 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_invalid_operation_001', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_invalid_operation_001*************'); + try { + selectionManager.on('selectionCompleted', (info) => { + console.info(`selectionfwk_on_selectionCompleted_invalid_operation_001 is failed`); + expect(false).assertTrue(); + }) + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_invalid_operation_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(33600003); + } + console.info('************* selectionfwk_on_selectionCompleted_invalid_operation_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_invalid_operation_001 + * @tc.name Test should throw BusinessError 33600003 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_invalid_operation_001', 0, async function (done) { + console.info('************* selectionfwk_createPanel_invalid_operation_001 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MENU_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + await selectionManager.createPanel({stageMode : false}, panelInfo) + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_invalid_operation_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(33600003); + } + console.info('************* selectionfwk_createPanel_invalid_operation_001 Test end*************'); + done(); + }); +}); diff --git a/test/unittest/selection_manager_invalid_operation_js_test/config.json b/test/unittest/selection_manager_invalid_operation_js_test/config.json new file mode 100644 index 0000000..77f79be --- /dev/null +++ b/test/unittest/selection_manager_invalid_operation_js_test/config.json @@ -0,0 +1,63 @@ +{ + "app": { + "bundleName": "com.example.selectioninvalidoperationtest", + "vendor": "example", + "version": { + "code": 1, + "name": "1.0" + }, + "apiVersion": { + "compatible": 20, + "target": 20 + } + }, + "deviceConfig": {}, + "module": { + "reqPermissions": [], + "package": "com.example.selectioninvalidoperationtest", + "name": ".MyApplication", + "deviceType": [ + "default", + "tablet", + "2in1" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry" + }, + "abilities": [ + { + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "name": "com.example.selectioninvalidoperationtest.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "PermissionJsTest", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "pages": [ + "pages/index/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} diff --git a/test/unittest/selection_manager_js_test/BUILD.gn b/test/unittest/selection_manager_js_test/BUILD.gn new file mode 100644 index 0000000..136931e --- /dev/null +++ b/test/unittest/selection_manager_js_test/BUILD.gn @@ -0,0 +1,21 @@ +# Copyright (c) 2024 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/test.gni") + +module_output_path = "selectionfwk/selectionfwk" +ohos_js_unittest("SelectionManagerJsTest") { + module_out_path = module_output_path + hap_profile = "./config.json" + certificate_profile = "./openharmony_sx.p7b" +} diff --git a/test/unittest/selection_manager_js_test/PermissionJsTest.js b/test/unittest/selection_manager_js_test/PermissionJsTest.js new file mode 100644 index 0000000..9ba641f --- /dev/null +++ b/test/unittest/selection_manager_js_test/PermissionJsTest.js @@ -0,0 +1,1848 @@ +/* + * 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 selectionManager from '@ohos.selectionInput.selectionManager' +import { describe, beforeAll, afterAll, it, expect } from 'deccjsunit/index' +import { PanelType } from '@ohos.selectionInput.SelectionPanel'; + +describe("SelectionManagerJsTest", function () { + beforeAll(function () { + console.info('beforeAll called'); + }) + + afterAll(function () { + console.info('AfterAll called'); + }) + + async function createSelectionPanel() + { + let panelInfo = { + panelType: PanelType.MENU_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + return await selectionManager.createPanel({stageMode : false}, panelInfo); + } + + async function destroySelectionPanel(panel) + { + await selectionManager.destroyPanel(panel); + } + + /* + * @tc.number selectionfwk_on_selectionCompleted_001 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_001', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_001*************'); + try { + selectionManager.on('selectionCompletedtest', (info) => { + console.info(`selectionfwk_on_selectionCompleted_001 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_on_selectionCompleted_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_on_selectionCompleted_002 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_002', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_002*************'); + try { + selectionManager.on('selectionCompleted'); + console.info(`selectionfwk_on_selectionCompleted_002 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_on_selectionCompleted_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_on_selectionCompleted_003 + * @tc.name Test should success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_003', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_003*************'); + try { + selectionManager.on('selectionCompleted', (info) => { + console.info(`selectionfwk_on_selectionCompleted_003 callback enter`); + expect(true).assertTrue(); + }); + console.info(`selectionfwk_on_selectionCompleted_003 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_003 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + console.info('************* selectionfwk_on_selectionCompleted_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_on_selectionCompleted_004 + * @tc.name Test 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_004', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_004*************'); + try { + selectionManager.on(null, (info) => { + console.info(`selectionfwk_on_selectionCompleted_004 callback enter`); + expect(false).assertTrue(); + }); + console.info(`selectionfwk_on_selectionCompleted_004 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_on_selectionCompleted_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_on_selectionCompleted_005 + * @tc.name Test 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_005', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_005*************'); + try { + selectionManager.on(undefined, (info) => { + console.info(`selectionfwk_on_selectionCompleted_005 callback enter`); + expect(false).assertTrue(); + }); + console.info(`selectionfwk_on_selectionCompleted_005 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_on_selectionCompleted_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_on_selectionCompleted_006 + * @tc.name Test 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_006', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_006*************'); + try { + selectionManager.on('selectionCompleted', null); + console.info(`selectionfwk_on_selectionCompleted_006 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_006 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_on_selectionCompleted_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_on_selectionCompleted_007 + * @tc.name Test 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_on_selectionCompleted_007', 0, async function (done) { + console.info('************* selectionfwk_on_selectionCompleted_007*************'); + try { + selectionManager.on('selectionCompleted', undefined); + console.info(`selectionfwk_on_selectionCompleted_007 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_on_selectionCompleted_007 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_on_selectionCompleted_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_off_selectionCompleted_001 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_off_selectionCompleted_001', 0, async function (done) { + console.info('************* selectionfwk_off_selectionCompleted_001*************'); + try { + selectionManager.off('selectionCompletedtest', (info) => { + console.info(`selectionfwk_off_selectionCompleted_001 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_off_selectionCompleted_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_off_selectionCompleted_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_off_selectionCompleted_002 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_off_selectionCompleted_002', 0, async function (done) { + console.info('************* selectionfwk_off_selectionCompleted_002*************'); + try { + selectionManager.off(); + console.info(`selectionfwk_off_selectionCompleted_002 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_off_selectionCompleted_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_off_selectionCompleted_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_off_selectionCompleted_003 + * @tc.name Test should success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_off_selectionCompleted_003', 0, async function (done) { + console.info('************* selectionfwk_off_selectionCompleted_003*************'); + try { + selectionManager.on('selectionCompleted', (info) => { + console.info(`selectionfwk_on_selectionCompleted_003 callback enter`); + expect(true).assertTrue(); + }); + selectionManager.off('selectionCompleted'); + console.info(`selectionfwk_off_selectionCompleted_003 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_off_selectionCompleted_003 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + console.info('************* selectionfwk_off_selectionCompleted_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_off_selectionCompleted_004 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_off_selectionCompleted_004', 0, async function (done) { + console.info('************* selectionfwk_off_selectionCompleted_004*************'); + try { + selectionManager.on('selectionCompleted', (info) => { + console.info(`selectionfwk_off_selectionCompleted_004 callback enter`); + expect(true).assertTrue(); + }); + selectionManager.off(null); + console.info(`selectionfwk_off_selectionCompleted_004 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_off_selectionCompleted_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_off_selectionCompleted_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_off_selectionCompleted_005 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_off_selectionCompleted_005', 0, async function (done) { + console.info('************* selectionfwk_off_selectionCompleted_005*************'); + try { + selectionManager.on('selectionCompleted', (info) => { + console.info(`selectionfwk_off_selectionCompleted_005 callback enter`); + expect(true).assertTrue(); + }); + selectionManager.off(undefined); + console.info(`selectionfwk_off_selectionCompleted_005 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_off_selectionCompleted_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_off_selectionCompleted_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_off_selectionCompleted_006 + * @tc.name Test return success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_off_selectionCompleted_006', 0, async function (done) { + console.info('************* selectionfwk_off_selectionCompleted_006*************'); + try { + selectionManager.on('selectionCompleted', (info) => { + console.info(`selectionfwk_off_selectionCompleted_006 callback enter`); + expect(true).assertTrue(); + }); + selectionManager.off('selectionCompleted', null); + console.info(`selectionfwk_off_selectionCompleted_006 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_off_selectionCompleted_006 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + console.info('************* selectionfwk_off_selectionCompleted_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_off_selectionCompleted_007 + * @tc.name Test return sucess, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_off_selectionCompleted_007', 0, async function (done) { + console.info('************* selectionfwk_off_selectionCompleted_007*************'); + try { + selectionManager.on('selectionCompleted', (info) => { + console.info(`selectionfwk_off_selectionCompleted_007 callback enter`); + expect(true).assertTrue(); + }); + selectionManager.off('selectionCompleted', undefined); + console.info(`selectionfwk_off_selectionCompleted_007 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_off_selectionCompleted_007 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + console.info('************* selectionfwk_off_selectionCompleted_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_001 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_001', 0, async function (done) { + console.info('************* selectionfwk_createPanel_001 Test start*************'); + try { + await selectionManager.createPanel({stageMode : false}); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_002 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_002', 0, async function (done) { + console.info('************* selectionfwk_createPanel_002 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MENU_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + await selectionManager.createPanel(selectionManager.Context, panelInfo); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_003 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_003', 0, async function (done) { + console.info('************* selectionfwk_createPanel_003 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MENU_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + await selectionManager.createPanel({stageMode : true}, panelInfo); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_003 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_004 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_004', 0, async function (done) { + console.info('************* selectionfwk_createPanel_004 Test start*************'); + let panelTemp; + try { + let panelInfo = { + panelType: PanelType.MENU_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + await selectionManager.createPanel({stageMode : false}, panelInfo) + .then((panel) => { + panelTemp = panel; + expect(true).assertTrue(); + }) + await destroySelectionPanel(panelTemp); + } catch (error) { + console.info(`selectionfwk_createPanel_004 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + console.info('************* selectionfwk_createPanel_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_005 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_005', 0, async function (done) { + console.info('************* selectionfwk_createPanel_005 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MAIN_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + let panelTemp = await selectionManager.createPanel({stageMode : false}, panelInfo); + await destroySelectionPanel(panelTemp); + } catch (error) { + console.info(`selectionfwk_createPanel_005 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + console.info('************* selectionfwk_createPanel_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_006 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_006', 0, async function (done) { + console.info('************* selectionfwk_createPanel_006 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MAIN_PANEL, + x: -1, + y: 0, + width: 100, + height: 100 + } + await selectionManager.createPanel({stageMode : false}, panelInfo); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_006 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_007 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_007', 0, async function (done) { + console.info('************* selectionfwk_createPanel_007 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MAIN_PANEL, + x: 0, + y: -1, + width: 100, + height: 100 + } + await selectionManager.createPanel({stageMode : false}, panelInfo); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_007 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_008 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_008', 0, async function (done) { + console.info('************* selectionfwk_createPanel_008 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MAIN_PANEL, + x: 0, + y: 0, + width: -1, + height: 100 + } + await selectionManager.createPanel({stageMode : false}, panelInfo) + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_008 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_008 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_009 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_009', 0, async function (done) { + console.info('************* selectionfwk_createPanel_009 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MAIN_PANEL, + x: 0, + y: 0, + width: 100, + height: -1 + } + await selectionManager.createPanel({stageMode : false}, panelInfo) + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_009 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_009 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_010 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_010', 0, async function (done) { + console.info('************* selectionfwk_createPanel_010 Test start*************'); + try { + await selectionManager.createPanel({stageMode : false}, null); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_010 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_010 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_010 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_011', 0, async function (done) { + console.info('************* selectionfwk_createPanel_011 Test start*************'); + try { + await selectionManager.createPanel({stageMode : false}, undefined); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_011 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_011 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_012 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_012', 0, async function (done) { + console.info('************* selectionfwk_createPanel_012 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MAIN_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + await selectionManager.createPanel(null, panelInfo) + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_012 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_012 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_createPanel_013 + * @tc.name verify method of createPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_createPanel_013', 0, async function (done) { + console.info('************* selectionfwk_createPanel_013 Test start*************'); + try { + let panelInfo = { + panelType: PanelType.MAIN_PANEL, + x: 0, + y: 0, + width: 100, + height: 100 + } + await selectionManager.createPanel(undefined, panelInfo) + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_createPanel_013 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_createPanel_013 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_destroyPanel_001 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_destroyPanel_001', 0, async function (done) { + console.info('************* selectionfwk_destroyPanel_001 Test start*************'); + try { + await selectionManager.destroyPanel(); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_destroyPanel_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_destroyPanel_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_destroyPanel_002 + * @tc.name Test should throw BusinessError 401 when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_destroyPanel_002', 0, async function (done) { + console.info('************* selectionfwk_destroyPanel_002 Test start*************'); + try { + let panel = 1; + await selectionManager.destroyPanel(panel); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_destroyPanel_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_destroyPanel_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_destroyPanel_003 + * @tc.name verify method of destroyPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_destroyPanel_003', 0, async function (done) { + console.info('************* selectionfwk_destroyPanel_003 Test start*************'); + let panel = await createSelectionPanel(); + try { + await selectionManager.destroyPanel(panel); + console.info(`selectionfwk_destroyPanel_003 promise success`); + expect(true).assertTrue(); + } catch (error) { + console.info(`selectionfwk_destroyPanel_003 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + console.info('************* selectionfwk_destroyPanel_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_destroyPanel_004 + * @tc.name verify method of destroyPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_destroyPanel_004', 0, async function (done) { + console.info('************* selectionfwk_destroyPanel_004 Test start*************'); + try { + await selectionManager.destroyPanel(null); + console.info(`selectionfwk_destroyPanel_004 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_destroyPanel_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_destroyPanel_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_destroyPanel_005 + * @tc.name verify method of destroyPanel. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_destroyPanel_005', 0, async function (done) { + console.info('************* selectionfwk_destroyPanel_005 Test start*************'); + try { + await selectionManager.destroyPanel(undefined); + console.info(`selectionfwk_destroyPanel_005 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_destroyPanel_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + console.info('************* selectionfwk_destroyPanel_005 Test end*************'); + done(); + }); + + /* + * @tc.number selection_panel_setUiContent_001 + * @tc.name verify ERROR code 401 of setUiContent. + * @tc.desc Function test + * @tc.level 0 + */ + it('selection_panel_setUiContent_001', 0, async function (done) { + console.info('************* selection_panel_setUiContent_001 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.setUiContent(); + console.info(`selection_panel_setUiContent_001 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selection_panel_setUiContent_001 result: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selection_panel_setUiContent_001 Test end*************'); + done(); + }); + + /* + * @tc.number selection_panel_setUiContent_002 + * @tc.name verify ERROR code 401 of setUiContent. + * @tc.desc Function test + * @tc.level 0 + */ + it('selection_panel_setUiContent_002', 0, async function (done) { + console.info('************* selection_panel_setUiContent_002 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.setUiContent(20); + console.info(`selection_panel_setUiContent_002 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selection_panel_setUiContent_002 result: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selection_panel_setUiContent_002 Test end*************'); + done(); + }); + + /* + * @tc.number selection_panel_setUiContent_003 + * @tc.name verify ERROR code 33600002 of setUiContent. + * @tc.desc Function test + * @tc.level 0 + */ + it('selection_panel_setUiContent_003', 0, async function (done) { + console.info('************* selection_panel_setUiContent_003 Test start*************'); + let panel = await createSelectionPanel(); + await destroySelectionPanel(panel); + try { + await panel.setUiContent('pages/index/index'); + expect(false).assertTrue(); + } catch (error) { + console.info(`selection_panel_setUiContent_003 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(33600002); + } + console.info('************* selection_panel_setUiContent_003 Test end*************'); + done(); + }); + + /* + * @tc.number selection_panel_setUiContent_004 + * @tc.name verify ERROR code 401 of setUiContent. + * @tc.desc Function test + * @tc.level 0 + */ + it('selection_panel_setUiContent_004', 0, async function (done) { + console.info('************* selection_panel_setUiContent_004 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.setUiContent(null); + expect(false).assertTrue(); + } catch (error) { + console.info(`selection_panel_setUiContent_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selection_panel_setUiContent_004 Test end*************'); + done(); + }); + + /* + * @tc.number selection_panel_setUiContent_005 + * @tc.name verify ERROR code 401 of setUiContent. + * @tc.desc Function test + * @tc.level 0 + */ + it('selection_panel_setUiContent_005', 0, async function (done) { + console.info('************* selection_panel_setUiContent_005 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.setUiContent(undefined); + expect(false).assertTrue(); + } catch (error) { + console.info(`selection_panel_setUiContent_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selection_panel_setUiContent_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_001 + * @tc.name verify ERROR code 401 of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_001', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_001 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(20); + console.info(`selectionfwk_panel_moveTo_001 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_002 + * @tc.name verify ERROR code 401 of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_002', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_002 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(20, '20'); + console.info(`selectionfwk_panel_moveTo_002 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_003 + * @tc.name verify ERROR code 33600002 the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_003', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_003 Test start*************'); + let panel = await createSelectionPanel(); + await destroySelectionPanel(panel); + try { + await panel.moveTo(20, 20); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_003 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(33600002); + } + console.info('************* selectionfwk_panel_moveTo_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_004 + * @tc.name verify method of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_004', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_004 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(50, 50); + console.info(`selectionfwk_panel_moveTo_004 promise success`); + expect(true).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_004 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_005 + * @tc.name verify method of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_005', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_005 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(-1, 50); + console.info(`selectionfwk_panel_moveTo_005 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_006 + * @tc.name verify method of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_006', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_006 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(50, -1); + console.info(`selectionfwk_panel_moveTo_006 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_006 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_007 + * @tc.name verify method of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_007', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_007 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(null, 50); + console.info(`selectionfwk_panel_moveTo_007 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_007 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_008 + * @tc.name verify method of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_008', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_008 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(undefined, 50); + console.info(`selectionfwk_panel_moveTo_008 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_008 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_008 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_009 + * @tc.name verify method of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_009', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_009 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(50, null); + console.info(`selectionfwk_panel_moveTo_009 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_009 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_009 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_moveTo_010 + * @tc.name verify method of the panel moveTo. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_moveTo_010', 0, async function (done) { + console.info('************* selectionfwk_panel_moveTo_010 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.moveTo(50, undefined); + console.info(`selectionfwk_panel_moveTo_010 promise success`); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_moveTo_010 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_moveTo_010 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_show_001 + * @tc.name verify ERROR code 33600002 of the panel show. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_show_001', 0, async function (done) { + console.info('************* selectionfwk_panel_show_001 Test start*************'); + let panel = await createSelectionPanel(); + await destroySelectionPanel(panel); + try { + await panel.show(); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_show_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(33600002); + } + console.info('************* selectionfwk_panel_show_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_destroyed_001 + * @tc.name verify ERROR code 401 of the panel on destroyed. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_destroyed_001', 0, async function (done) { + console.info('************* selectionfwk_panel_on_destroyed_001*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyedTest', (info) => { + console.info(`selectionfwk_panel_on_destroyed_001 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_panel_on_destroyed_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_destroyed_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_destroyed_002 + * @tc.name verify ERROR code 401 of the panel on destroyed. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_destroyed_002', 0, async function (done) { + console.info('************* selectionfwk_panel_on_destroyed_002*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed'); + console.info(`selectionfwk_panel_on_destroyed_002 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_destroyed_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_destroyed_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_destroyed_003 + * @tc.name Test should success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_destroyed_003', 0, async function (done) { + console.info('************* selectionfwk_panel_on_destroyed_003*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', (info) => { + console.info(`selectionfwk_panel_on_destroyed_003 callback enter`); + expect(true).assertTrue(); + }); + console.info(`selectionfwk_panel_on_destroyed_003 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_destroyed_003 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_destroyed_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_destroyed_004 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_destroyed_004', 0, async function (done) { + console.info('************* selectionfwk_panel_on_destroyed_004*************'); + let panel = await createSelectionPanel(); + try { + panel.on(null, (info) => { + console.info(`selectionfwk_panel_on_destroyed_004 callback enter`); + expect(false).assertTrue(); + }); + console.info(`selectionfwk_panel_on_destroyed_004 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_destroyed_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_destroyed_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_destroyed_005 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_destroyed_005', 0, async function (done) { + console.info('************* selectionfwk_panel_on_destroyed_005*************'); + let panel = await createSelectionPanel(); + try { + panel.on(undefined, (info) => { + console.info(`selectionfwk_panel_on_destroyed_005 callback enter`); + expect(false).assertTrue(); + }); + console.info(`selectionfwk_panel_on_destroyed_005 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_destroyed_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_destroyed_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_destroyed_006 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_destroyed_006', 0, async function (done) { + console.info('************* selectionfwk_panel_on_destroyed_006*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', null); + console.info(`selectionfwk_panel_on_destroyed_006 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_destroyed_006 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_destroyed_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_destroyed_007 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_destroyed_007', 0, async function (done) { + console.info('************* selectionfwk_panel_on_destroyed_007*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', undefined); + console.info(`selectionfwk_panel_on_destroyed_007 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_destroyed_007 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_destroyed_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_destroyed_001 + * @tc.name verify ERROR code 401 of the panel off destroyed. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_destroyed_001', 0, async function (done) { + console.info('************* selectionfwk_panel_off_destroyed_001*************'); + let panel = await createSelectionPanel(); + try { + panel.off('destroyedTest', (info) => { + console.info(`selectionfwk_panel_off_destroyed_001 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_panel_off_destroyed_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_destroyed_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_destroyed_002 + * @tc.name verify ERROR code 401 of the panel on destroyed. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_destroyed_002', 0, async function (done) { + console.info('************* selectionfwk_panel_off_destroyed_002*************'); + let panel = await createSelectionPanel(); + try { + panel.off(() => { + console.info(`selectionfwk_panel_off_destroyed_002 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_panel_off_destroyed_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_destroyed_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_destroyed_003 + * @tc.name Test should success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_destroyed_003', 0, async function (done) { + console.info('************* selectionfwk_panel_off_destroyed_003*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', (info) => { + console.info(`selectionfwk_panel_off_destroyed_003 callback enter`); + expect(true).assertTrue(); + }); + panel.off('destroyed'); + console.info(`selectionfwk_panel_off_destroyed_003 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_destroyed_003 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_destroyed_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_destroyed_004 + * @tc.name Test reurn 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_destroyed_004', 0, async function (done) { + console.info('************* selectionfwk_panel_off_destroyed_004*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', (info) => { + console.info(`selectionfwk_panel_off_destroyed_004 callback enter`); + expect(true).assertTrue(); + }); + panel.off(null); + console.info(`selectionfwk_panel_off_destroyed_004 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_destroyed_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_destroyed_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_destroyed_005 + * @tc.name Test reurn 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_destroyed_005', 0, async function (done) { + console.info('************* selectionfwk_panel_off_destroyed_005*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', (info) => { + console.info(`selectionfwk_panel_off_destroyed_005 callback enter`); + expect(true).assertTrue(); + }); + panel.off(undefined); + console.info(`selectionfwk_panel_off_destroyed_005 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_destroyed_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_destroyed_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_destroyed_006 + * @tc.name Test return success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_destroyed_006', 0, async function (done) { + console.info('************* selectionfwk_panel_off_destroyed_006*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', (info) => { + console.info(`selectionfwk_panel_off_destroyed_006 callback enter`); + expect(true).assertTrue(); + }); + panel.off('destroyed', null); + console.info(`selectionfwk_panel_off_destroyed_006 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_destroyed_006 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_destroyed_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_destroyed_007 + * @tc.name Test return success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_destroyed_007', 0, async function (done) { + console.info('************* selectionfwk_panel_off_destroyed_007*************'); + let panel = await createSelectionPanel(); + try { + panel.on('destroyed', (info) => { + console.info(`selectionfwk_panel_off_destroyed_007 callback enter`); + expect(true).assertTrue(); + }); + panel.off('destroyed', undefined); + console.info(`selectionfwk_panel_off_destroyed_007 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_destroyed_007 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_destroyed_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_hidden_001 + * @tc.name verify ERROR code 401 of the panel on hidden. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_hidden_001', 0, async function (done) { + console.info('************* selectionfwk_panel_on_hidden_001*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hiddenTest', (info) => { + console.info(`selectionfwk_panel_on_hidden_001 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_panel_on_hidden_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_hidden_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_hidden_002 + * @tc.name verify ERROR code 401 of the panel on hidden. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_hidden_002', 0, async function (done) { + console.info('************* selectionfwk_panel_on_hidden_002*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden'); + console.info(`selectionfwk_panel_on_hidden_002 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_hidden_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_hidden_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_hidden_003 + * @tc.name Test should success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_hidden_003', 0, async function (done) { + console.info('************* selectionfwk_panel_on_hidden_003*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', (info) => { + console.info(`selectionfwk_panel_on_hidden_003 callback enter`); + expect(true).assertTrue(); + }); + console.info(`selectionfwk_panel_on_hidden_003 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_hidden_003 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_hidden_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_hidden_004 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_hidden_004', 0, async function (done) { + console.info('************* selectionfwk_panel_on_hidden_004*************'); + let panel = await createSelectionPanel(); + try { + panel.on(null, (info) => { + console.info(`selectionfwk_panel_on_hidden_004 callback enter`); + expect(false).assertTrue(); + }); + console.info(`selectionfwk_panel_on_hidden_004 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_hidden_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_hidden_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_hidden_005 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_hidden_005', 0, async function (done) { + console.info('************* selectionfwk_panel_on_hidden_005*************'); + let panel = await createSelectionPanel(); + try { + panel.on(undefined, (info) => { + console.info(`selectionfwk_panel_on_hidden_005 callback enter`); + expect(false).assertTrue(); + }); + console.info(`selectionfwk_panel_on_hidden_005 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_hidden_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_hidden_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_hidden_006 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_hidden_006', 0, async function (done) { + console.info('************* selectionfwk_panel_on_hidden_006*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', null); + console.info(`selectionfwk_panel_on_hidden_006 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_hidden_006 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_hidden_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_on_hidden_007 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_on_hidden_007', 0, async function (done) { + console.info('************* selectionfwk_panel_on_hidden_007*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', undefined); + console.info(`selectionfwk_panel_on_hidden_007 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_on_hidden_007 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_on_hidden_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_hidden_001 + * @tc.name verify ERROR code 401 of the panel off hidden. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_hidden_001', 0, async function (done) { + console.info('************* selectionfwk_panel_off_hidden_001*************'); + let panel = await createSelectionPanel(); + try { + panel.off('hiddenTest', (info) => { + console.info(`selectionfwk_panel_off_hidden_001 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_panel_off_hidden_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_hidden_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_hidden_002 + * @tc.name verify ERROR code 401 of the panel on hidden. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_hidden_002', 0, async function (done) { + console.info('************* selectionfwk_panel_off_hidden_002*************'); + let panel = await createSelectionPanel(); + try { + panel.off(() => { + console.info(`selectionfwk_panel_off_hidden_002 is failed`); + expect(false).assertTrue(); + }) + } catch(error) { + console.info(`selectionfwk_panel_off_hidden_002 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_hidden_002 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_hidden_003 + * @tc.name Test should success, when parameters are valid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_hidden_003', 0, async function (done) { + console.info('************* selectionfwk_panel_off_hidden_003*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', (info) => { + console.info(`selectionfwk_panel_off_hidden_003 callback enter`); + expect(true).assertTrue(); + }); + panel.off('hidden'); + console.info(`selectionfwk_panel_off_hidden_003 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_hidden_003 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_hidden_003 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_hidden_004 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_hidden_004', 0, async function (done) { + console.info('************* selectionfwk_panel_off_hidden_004*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', (info) => { + console.info(`selectionfwk_panel_off_hidden_004 callback enter`); + expect(true).assertTrue(); + }); + panel.off(null); + console.info(`selectionfwk_panel_off_hidden_004 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_hidden_004 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_hidden_004 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_hidden_005 + * @tc.name Test return 401, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_hidden_005', 0, async function (done) { + console.info('************* selectionfwk_panel_off_hidden_005*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', (info) => { + console.info(`selectionfwk_panel_off_hidden_005 callback enter`); + expect(true).assertTrue(); + }); + panel.off(undefined); + console.info(`selectionfwk_panel_off_hidden_005 is failed`); + expect(false).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_hidden_005 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(401); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_hidden_005 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_hidden_006 + * @tc.name Test return success, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_hidden_006', 0, async function (done) { + console.info('************* selectionfwk_panel_off_hidden_006*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', (info) => { + console.info(`selectionfwk_panel_off_hidden_006 callback enter`); + expect(true).assertTrue(); + }); + panel.off('hidden', null); + console.info(`selectionfwk_panel_off_hidden_006 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_hidden_006 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_hidden_006 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_off_hidden_007 + * @tc.name Test return success, when parameters are invalid. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_off_hidden_007', 0, async function (done) { + console.info('************* selectionfwk_panel_off_hidden_007*************'); + let panel = await createSelectionPanel(); + try { + panel.on('hidden', (info) => { + console.info(`selectionfwk_panel_off_hidden_007 callback enter`); + expect(true).assertTrue(); + }); + panel.off('hidden', undefined); + console.info(`selectionfwk_panel_off_hidden_007 is success`); + expect(true).assertTrue(); + } catch(error) { + console.info(`selectionfwk_panel_off_hidden_007 throw error: ${JSON.stringify(error)}`); + expect(false).assertTrue(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_off_hidden_007 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_hide_001 + * @tc.name verify ERROR code 33600002 of the panel hide. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_hide_001', 0, async function (done) { + console.info('************* selectionfwk_panel_hide_001 Test start*************'); + let panel = await createSelectionPanel(); + await destroySelectionPanel(panel); + try { + await panel.hide(); + expect(false).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_hide_001 throw error: ${JSON.stringify(error)}`); + expect(error.code).assertEqual(33600002); + } + console.info('************* selectionfwk_panel_hide_001 Test end*************'); + done(); + }); + + /* + * @tc.number selectionfwk_panel_hide_002 + * @tc.name verify method of the panel hide. + * @tc.desc Function test + * @tc.level 0 + */ + it('selectionfwk_panel_hide_002', 0, async function (done) { + console.info('************* selectionfwk_panel_hide_002 Test start*************'); + let panel = await createSelectionPanel(); + try { + await panel.hide(); + console.info(`selectionfwk_panel_hide_002 promise success`); + expect(true).assertTrue(); + } catch (error) { + console.info(`selectionfwk_panel_hide_002 throw error: ${JSON.stringify(error)}`); + expect().assertFail(); + } + await destroySelectionPanel(panel); + console.info('************* selectionfwk_panel_hide_002 Test end*************'); + done(); + }); +}); diff --git a/test/unittest/selection_manager_js_test/config.json b/test/unittest/selection_manager_js_test/config.json new file mode 100644 index 0000000..46ca512 --- /dev/null +++ b/test/unittest/selection_manager_js_test/config.json @@ -0,0 +1,63 @@ +{ + "app": { + "bundleName": "com.example.selectionmanagertest", + "vendor": "example", + "version": { + "code": 1, + "name": "1.0" + }, + "apiVersion": { + "compatible": 20, + "target": 20 + } + }, + "deviceConfig": {}, + "module": { + "reqPermissions": [], + "package": "com.example.selectionmanagertest", + "name": ".MyApplication", + "deviceType": [ + "default", + "tablet", + "2in1" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry" + }, + "abilities": [ + { + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "name": "com.example.selectionmanagertest.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "PermissionJsTest", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "pages": [ + "pages/index/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} diff --git a/utils/include/selection_log.h b/utils/include/selection_log.h index 8b52cc7..fa52463 100644 --- a/utils/include/selection_log.h +++ b/utils/include/selection_log.h @@ -27,8 +27,8 @@ extern "C" { #undef LOG_DOMAIN #define LOG_DOMAIN 0xD002901 -#ifndef SELETION_DEBUG_ENABLE -#define SELETION_DEBUG_ENABLE 0 +#ifndef SELECTION_DEBUG_ENABLE +#define SELECTION_DEBUG_ENABLE 0 #endif #define __BASE_FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) @@ -57,7 +57,7 @@ enum { ERROR_PARAMETER_CHECK_FAILED, ERROR_SELECTION_SERVICE, - ERROR_PANEL_DESTORYED, + ERROR_PANEL_DESTROYED, ERROR_INVALID_OPERATION }; }; // namespace ErrorCode -- Gitee From 01391752fa0fff3521f6370c59f68892d3d6bb10 Mon Sep 17 00:00:00 2001 From: Sunjiamei <939650669@qq.com> Date: Mon, 7 Jul 2025 17:33:59 +0800 Subject: [PATCH 91/93] =?UTF-8?q?=E6=9C=AC=E5=9C=B0=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=80=9A=E8=BF=87=EF=BC=8C=E6=8F=90=E4=BA=A4=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- .../js_selection_engine_setting.cpp | 2 +- .../src/selection_listener_impl.cpp | 2 +- service/src/selection_input_monitor.cpp | 4 +- .../openharmony_sx.p7b | Bin 0 -> 3637 bytes .../openharmony_sx.p7b | Bin test/unittest/systemapi_js_test/BUILD.gn | 21 -- .../systemapi_js_test/PermissionJsTest.js | 339 ------------------ test/unittest/systemapi_js_test/config.json | 64 ---- 8 files changed, 4 insertions(+), 428 deletions(-) create mode 100644 test/unittest/selection_manager_invalid_operation_js_test/openharmony_sx.p7b rename test/unittest/{systemapi_js_test => selection_manager_js_test}/openharmony_sx.p7b (100%) delete mode 100644 test/unittest/systemapi_js_test/BUILD.gn delete mode 100644 test/unittest/systemapi_js_test/PermissionJsTest.js delete mode 100644 test/unittest/systemapi_js_test/config.json diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 90d34cf..0cf6242 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -439,7 +439,7 @@ int32_t JsSelectionEngineSetting::OnSelectionEvent(const SelectionInfo &selectio return 1; } - SELECTION_HILOGI("selection text length is [%{public}lu]", entry->selectionInfo.text.length()); + SELECTION_HILOGI("selection text length is [%{public}u]", entry->selectionInfo.text.length()); auto task = [entry]() { auto paramGetter = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool { if (argc == 0) { diff --git a/frameworks/native/selection_ability/src/selection_listener_impl.cpp b/frameworks/native/selection_ability/src/selection_listener_impl.cpp index 465ce9b..9a03e5a 100644 --- a/frameworks/native/selection_ability/src/selection_listener_impl.cpp +++ b/frameworks/native/selection_ability/src/selection_listener_impl.cpp @@ -31,7 +31,7 @@ static void CopySelectionData(const SelectionInfoData& src, SelectionInfo& dst) ErrCode SelectionListenerImpl::OnSelectionChange(const SelectionInfoData& selectionInfoData) { - SELECTION_HILOGI("Recveive selection data length: %{public}lu", selectionInfoData.data.text.length()); + SELECTION_HILOGI("Recveive selection data length: %{public}u", selectionInfoData.data.text.length()); SelectionInfo selectionInfo; CopySelectionData(selectionInfoData, selectionInfo); if (selectionI_ == nullptr) { diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index a498409..eaed658 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -531,7 +531,7 @@ void SelectionPasteboardDisposableObserver::OnTextReceived(const std::string &te SELECTION_HILOGI("Error receiving text, errCode: %{public}d", errCode); return; } - SELECTION_HILOGI("Text received length: %{public}lu.", text.length()); + SELECTION_HILOGI("Text received length: %{public}u.", text.length()); if (!baseInputMonitor_) { return; } @@ -545,7 +545,7 @@ void SelectionPasteboardDisposableObserver::OnTextReceived(const std::string &te selectionInfo.text = text; SelectionInfoData infoData; infoData.data = selectionInfo; - SELECTION_HILOGI("SelectionInfoData length: %{public}lu.", infoData.ToString().length()); + SELECTION_HILOGI("SelectionInfoData length: %{public}u.", infoData.ToString().length()); sptr listener = SelectionService::GetInstance()->GetListener(); if (listener == nullptr) { SELECTION_HILOGE("Selection listener is nullptr"); diff --git a/test/unittest/selection_manager_invalid_operation_js_test/openharmony_sx.p7b b/test/unittest/selection_manager_invalid_operation_js_test/openharmony_sx.p7b new file mode 100644 index 0000000000000000000000000000000000000000..9af661cd0638e36d3f6ca6e3b65c8809b122fd19 GIT binary patch literal 3637 zcmcgvYj6|S6}BEWF~-JVf`KMr1i>^Qb61vZ$!Q+D(rUHBtCv@{WlYUVT1jiKcGuF% zD~mvgXef`6l)P|w#k`?B(jf$g&IHn=fs&A9NGQ`uAt@oW38i^7zB?CWOQ3?nJC`_?d|j*>rtZy_=s>n)qFSYbia}99;k+dd6|K># zRUn)H_H{>9Z#MrGZ8rb#d|elvNHRR9=cqWXtJ4{(Ko!uy&yr>V-5k4WW3z;lNbB)PhGSAG}sfb7?WOI$#Vyvx}%?oDg z1`s4@mZp-lyjU>Bg;`q9a1mZvFHCpQEHBUreGZXZpg9MXi1S>x>^o#HAvz&45hg^5 z%9ixX4?!{9RbfSaByPv8Fp1`@tsH^lRw84y!a+I;OE>~Yag=gfXJu?KfkdO7v5t1P z$LqDhk{>28B5lpUP9*ATMBo4kcevd03O=udMgz7+uXi>oiJlPFm}0$X(QWF zKY`%=xMDfnoM}0*(nAMCKGP=v4JL#o^6BU{XPWQ$~nLd zUZ`CPVQC>?umei21#Wk;L3zI+gI{VQVG@ak2C9oAN~K%5{#p|VBDt(EOa=pPtJfTsL%RnFqc%Qi_u(xN-5gK51DOV_m2*l&Bz2Oeaz?wv`L{5O2~MmO?F^^(hPQ z@;62)0+ukVwG(R~j21cChInBc1;bK{7f-`ZkpdpCK``3z)GQ&{%GDF$daEt!HTfM7 z3lO6RiyJK@c{wHi%+9tc52ps+yW z*A|qituAN`7_AJ3mlX|CL})xHSFA;4rGu;$Bu&MkDPXcPr74>*cuI!LDvBv1tgymh zVtKIv0tR4!4D#31QeJGdK!$2)U zRRi_VsD^2fJZ;lk>c1b{w(kSD^U$rw9-F>qkG*zranB^xM|KWv{lMer(*So54>?@BO-_&p`j*MHg*#|sek__keDcW&h?4mJ$Uec!<`^Tb< zv-{56G5_G_`3pAbF;Jp7j8v)qqt$BE!xn+tm2ru7tai-n)W8%cq_3O?XLV-SP3% z=Qf*4(>t#w7oPuct^epI{m{|*cwW4LM350O z4b$)E9{HczJs=4pwVGu^8?iWjf@wAgv%>U92-5FDR9|De8TUDt~j z0)Z2A)^55l`|W{u0$OYZf%OPaAzOF%UOL!zncOy_O*9XL)j(>IDxo*NmUi5;di|;9{g3Xg+%|mWTO(emJ2>&7MR%Gq zty?$Vrr&V#RbD%V2~>(})nMwbslVjs?w&HtH)hMqOT7;R=e^ywf2Gj#!j`V}>n?%S zo$giLr?!`$oU!dqY}}H3nMah&qw@ninn=HN_fRA^@$?3X5oD@14CawCyg7>a0~DIP z;gh55pDj1-S^nCVw!eK0-%+VOH{qEt-VqmD_wFe8YR{*Y6J9^{c=2yvsNJ$qXkK=7 z;ZKBpUE2;E_kpJU@2;L+<9WXC*_YQ&Shw|yWy?yxIMFkC**6c&+dpH{Hy4hbedJrc ze{%>>L&WKOIr4vS?0dy+$PJ^3xy{rY_dD^JvY6bB9Wgo+>-H zAX4f+@9@9BY|;2wAO6pi7y52}`@*SFvRECtg_m~LB{ur{rs*#~-@NG<;T??0VLZC!I< zVfJ$7#LgKXI7Xl1?^{Ywx$p@Xe(fe#YcYVTC+DqfUwUrC@pGRYbM8NYeOa { - console.info('SystemApi_createPanel_001 promise success'); - this.panel_ = panel; - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_createPanel_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_createPanel_001 Test end*************'); - }); - - /* - * @tc.name:selection_panel_setUiContent_001 - * @tc.desc:verify method of setUiContent - * @tc.type: FUNC - */ - it('selection_panel_setUiContent_001', 0, async function (done) { - console.info('************* selection_panel_setUiContent_001 Test start*************'); - try { - this.panel_.setUiContent('pages/Index') - .then(() => { - console.info('selection_panel_setUiContent_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`selection_panel_setUiContent_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`selection_panel_setUiContent_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* selection_panel_setUiContent_001 Test end*************'); - }); - - /* - * @tc.name:selection_panel_setUiContent_002 - * @tc.desc:verify method of setUiContent - * @tc.type: FUNC - */ - it('selection_panel_setUiContent_002', 0, async function (done) { - console.info('************* selection_panel_setUiContent_002 Test start*************'); - try { - this.panel_.setUiContent('pages/Panel') - .then(() => { - console.info('selection_panel_setUiContent_002 promise success'); - expect(false).assertTrue(); - done(); - }).catch((error) => { - console.info(`selection_panel_setUiContent_002 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`selection_panel_setUiContent_002 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* selection_panel_setUiContent_002 Test end*************'); - }); - - /* - * @tc.name:selection_panel_show_001 - * @tc.desc:verify method of setUiContent - * @tc.type: FUNC - */ - it('selection_panel_show_001', 0, async function (done) { - console.info('************* selection_panel_show_001 Test start*************'); - try { - this.panel_.show() - .then(() => { - console.info('selection_panel_show_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`selection_panel_show_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`selection_panel_show_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* selection_panel_show_001 Test end*************'); - }); - - /* - * @tc.name:SystemApi_hide_001 - * @tc.desc:verify SystemApi of hide - * @tc.type: FUNC - */ - it('SystemApi_hide_001', 0, async function (done) { - console.info('************* SystemApi_hide_001 Test start*************'); - try { - this.panel_.hide().then(() => { - console.info('SystemApi_hide_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_hide_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_hide_001 Test end*************'); - }); - - /* - * @tc.name:SystemApi_startMoving_001 - * @tc.desc:verify SystemApi of startMoving - * @tc.type: FUNC - */ - it('SystemApi_startMoving_001', 0, async function (done) { - console.info('************* SystemApi_startMoving_001 Test start*************'); - try { - this.panel_.startMoving().then(() => { - console.info('SystemApi_startMoving_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_startMoving_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_startMoving_001 Test end*************'); - }); - - /* - * @tc.name:SystemApi_moveTo_001 - * @tc.desc:verify SystemApi of moveTo - * @tc.type: FUNC - */ - it('SystemApi_moveTo_001', 0, async function (done) { - console.info('************* SystemApi_moveTo_001 Test start*************'); - try { - let x = 100; - let y = 100; - this.panel_.moveTo(x, y).then(() => { - console.info('SystemApi_moveTo_001 promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`SystemApi_moveTo_001 result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* SystemApi_moveTo_001 Test end*************'); - }); - - /* - * @tc.number selection_panel_test_off_Hide_001 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_Hide_001', 0, async function (done) { - console.info('************* selection_panel_test_off_Hide_001*************'); - try { - this.panel_.off('hidden', () => { - console.info(`panel on hidde success`); - expect(true).assertTrue(); - done(); - }); - } catch(error) { - console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - }); - - /* - * @tc.number selection_panel_test_off_Hide_002 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_Hide_001', 0, async function (done) { - console.info('************* selection_panel_test_off_Hide_002*************'); - try { - this.panel_.off('hidden'); - } catch(error) { - console.info(`panel on hidden fail result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - }); - - /* - * @tc.number selection_panel_test_on_destroyed_001 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_on_destroyed_001', 0, async function (done) { - console.info('************* selection_panel_test_on_destroyed_001*************'); - try { - this.panel_.on('destroyed', () => { - console.info(`panel on hide success`); - expect(true).assertTrue(); - done(); - }); - } catch(error) { - console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - }); - - /* - * @tc.number selection_panel_test_off_destroyed_001 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_destroyed_001', 0, async function (done) { - console.info('************* selection_panel_test_off_destroyed_001*************'); - try { - this.panel_.off('destroyed', () => { - console.info(`panel on destroyed success`); - expect(true).assertTrue(); - done(); - }); - } catch(error) { - console.info(`panel on destroyed fail result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - }); - - /* - * @tc.number selection_panel_test_off_destroyed_002 - * @tc.name Test whether the register the callback of the panel method is valid. - * @tc.desc Function test - * @tc.level 2 - */ - it('selection_panel_test_off_destroyed_002', 0, async function (done) { - console.info('************* selection_panel_test_off_destroyed_002*************'); - try { - this.panel_.off('destroyed'); - } catch(error) { - console.info(`panel on "hidden fail result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - }); - - /* - * @tc.name:selection_panel_method_destroyPanel_001 - * @tc.desc:verify method of destroyPanel - * @tc.type: FUNC - */ - it('selection_panel_method_destroyPanel_001', 0, async function (done) { - console.info('************* selection_panel_method_destroyPanel_001 Test start*************'); - try { - selectionManager.destroyPanel(this.panel_).then(() => { - console.info('selection_panel_method_destroyPanel promise success'); - expect(true).assertTrue(); - done(); - }).catch((error) => { - console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - }) - } catch (error) { - console.info(`selection_panel_method_destroyPanel result: ${JSON.stringify(error)}`); - expect().assertFail(); - done(); - } - console.info('************* selection_panel_method_destroyPanel Test end*************'); - }); -}); \ No newline at end of file diff --git a/test/unittest/systemapi_js_test/config.json b/test/unittest/systemapi_js_test/config.json deleted file mode 100644 index 065198e..0000000 --- a/test/unittest/systemapi_js_test/config.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "app": { - "bundleName": "com.example.selectionmanagertest", - "vendor": "example", - "version": { - "code": 1, - "name": "1.0" - }, - "apiVersion": { - "compatible": 12, - "target": 12 - } - }, - "deviceConfig": {}, - "module": { - "reqPermissions": [], - "package": "com.example.selectionmanagertest", - "name": ".MyApplication", - "deviceType": [ - "default", - "tablet", - "2in1" - ], - "distro": { - "deliveryWithInstall": true, - "moduleName": "entry", - "moduleType": "entry" - }, - "abilities": [ - { - "visible": true, - "skills": [ - { - "entities": [ - "entity.system.home" - ], - "actions": [ - "action.system.home" - ] - } - ], - "name": "com.example.selectionmanagertest.MainAbility", - "icon": "$media:icon", - "description": "$string:mainability_description", - "label": "PermissionJsTest", - "type": "page", - "launchType": "standard" - } - ], - "js": [ - { - "pages": [ - "pages/index/index" - ], - "name": "default", - "window": { - "designWidth": 720, - "autoDesignWidth": false - } - } - ] - } - } - \ No newline at end of file -- Gitee From 8b15dd44690905ea13a4672d3369df77559d9232 Mon Sep 17 00:00:00 2001 From: Sunjiamei Date: Wed, 9 Jul 2025 10:29:35 +0800 Subject: [PATCH 92/93] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E3=80=81=E5=A2=9E=E5=8A=A0js=E6=8E=A5=E5=8F=A3UT=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- bundle.json | 6 +- common/selection_data_inner.h | 22 +- frameworks/js/napi/selection_ability/BUILD.gn | 2 + .../js/napi/selection_ability/js_panel.cpp | 1 + .../js_selection_engine_setting.cpp | 40 ++- .../js_selection_engine_setting.h | 1 + .../src/selection_ability.cpp | 4 +- hiappevent_agent/BUILD.gn | 44 +++ .../selection_api_event_reporter.cpp | 71 ++++ .../selection_api_event_reporter.h | 65 ++++ service/include/selection_config.h | 7 +- service/include/selection_input_monitor.h | 8 +- service/include/selection_service.h | 9 +- service/src/selection_config_comparator.cpp | 1 + service/src/selection_input_monitor.cpp | 37 +- service/src/selection_service.cpp | 44 +-- .../PermissionJsTest.js | 315 +++++++++--------- 17 files changed, 479 insertions(+), 198 deletions(-) create mode 100644 hiappevent_agent/BUILD.gn create mode 100644 hiappevent_agent/selection_api_event_reporter.cpp create mode 100644 hiappevent_agent/selection_api_event_reporter.h diff --git a/bundle.json b/bundle.json index ef2950f..7583f05 100644 --- a/bundle.json +++ b/bundle.json @@ -49,7 +49,8 @@ "hicollie", "hisysevent", "memmgr", - "resource_schedule_service" + "resource_schedule_service", + "hiappevent" ], "third_party": [ ] @@ -68,7 +69,8 @@ "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_extension:selection_extension_ability_native", "//foundation/systemabilitymgr/selectionfwk/frameworks/js/napi/selection_ability:selectionmanager_napi", "//foundation/systemabilitymgr/selectionfwk/frameworks/native/selection_ability:selection_ability", - "//foundation/systemabilitymgr/selectionfwk/interfaces/inner_kits/selection_client:selection_client" + "//foundation/systemabilitymgr/selectionfwk/interfaces/inner_kits/selection_client:selection_client", + "//foundation/systemabilitymgr/selectionfwk/hiappevent_agent:selection_hiappevent_agent" ], "inner_kits": [ { diff --git a/common/selection_data_inner.h b/common/selection_data_inner.h index 718b230..47d7438 100644 --- a/common/selection_data_inner.h +++ b/common/selection_data_inner.h @@ -100,13 +100,19 @@ struct SelectionInfoData : public Parcelable { std::string ToString() const { std::ostringstream oss; - oss << "SelectionInfo { selectionType: " << data.selectionType << ", text: \"" << data.text << "\" \ - startDisplayX: " << data.startDisplayX << ", startDisplayY: " << data.startDisplayY << ", \ - endDisplayX: " << data.endDisplayX << ", endDisplayY: " << data.endDisplayY << ", \ - startWindowX: " << data.startWindowX << ", startWindowY: " << data.startWindowY << ", \ - endWindowX: " << data.endWindowX << ", endWindowY: " << data.endWindowY << ", \ - displayId: " << data.displayId << ", windowId: " << data.windowId << ", bundleName: \ - " << data.bundleName << "}"; + oss << "SelectionInfo { selectionType: " << data.selectionType << + ", text.length: " << data.text.length() << + ", startDisplayX: " << data.startDisplayX << + ", startDisplayY: " << data.startDisplayY << + ", endDisplayX: " << data.endDisplayX << + ", endDisplayY: " << data.endDisplayY << + ", startWindowX: " << data.startWindowX << + ", startWindowY: " << data.startWindowY << + ", endWindowX: " << data.endWindowX << + ", endWindowY: " << data.endWindowY << + ", displayId: " << data.displayId << + ", windowId: " << data.windowId << + ", bundleName: " << data.bundleName << "}"; return oss.str(); } }; @@ -153,7 +159,7 @@ public: std::string ToString() const { std::ostringstream oss; - oss << "SelectionFocusChangeInfo { windowId: " << windowId_ << ", displayId: \"" << displayId_ << + oss << "SelectionFocusChangeInfo { windowId: " << windowId_ << ", displayId: " << displayId_ << ", windowType: " << windowType_ << ", isFocused: " << isFocused_ << ", source_: " << static_cast(source_) << "}"; return oss.str(); diff --git a/frameworks/js/napi/selection_ability/BUILD.gn b/frameworks/js/napi/selection_ability/BUILD.gn index 35cd941..e0a6461 100644 --- a/frameworks/js/napi/selection_ability/BUILD.gn +++ b/frameworks/js/napi/selection_ability/BUILD.gn @@ -41,10 +41,12 @@ ohos_shared_library("selectionmanager_napi") { "../../../native/selection_ability/include", "../selection_client", "../../../common", + "../../../../hiappevent_agent", ] deps = [ "${selection_fwk_root_path}/common:selection_common", + "${selection_fwk_root_path}/hiappevent_agent:selection_hiappevent_agent", "${selection_fwk_root_path}/interfaces/idl:selection_service_proxy", "${selection_fwk_root_path}/interfaces/idl:selection_listener_proxy", "${selection_fwk_root_path}/frameworks/native/selection_ability:selection_ability", diff --git a/frameworks/js/napi/selection_ability/js_panel.cpp b/frameworks/js/napi/selection_ability/js_panel.cpp index ca08286..02a6c28 100644 --- a/frameworks/js/napi/selection_ability/js_panel.cpp +++ b/frameworks/js/napi/selection_ability/js_panel.cpp @@ -23,6 +23,7 @@ #include "selectionmethod_trace.h" #include "selection_ability.h" #include "event_checker.h" +#include "selection_api_event_reporter.h" namespace OHOS { namespace SelectionFwk { diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp index 0cf6242..90f2d24 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.cpp @@ -29,6 +29,7 @@ #include "js_panel.h" #include "js_selection_utils.h" #include "selection_app_validator.h" +#include "selection_api_event_reporter.h" using namespace OHOS; namespace OHOS { @@ -135,8 +136,9 @@ napi_status JsSelectionEngineSetting::GetContext(napi_env env, napi_value in, napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_info info) { SELECTION_HILOGI("SelectionEngineSetting CreatePanel start."); + auto eventReporter = std::make_shared("createPanel"); auto ctxt = std::make_shared(); - auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + auto inputInner = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { PARAM_CHECK_RETURN(env, argc >= 2, "at least two parameters is required.", TYPE_NONE, napi_invalid_arg); napi_valuetype valueType = napi_undefined; // 0 means parameter of ctx @@ -158,14 +160,24 @@ napi_value JsSelectionEngineSetting::CreatePanel(napi_env env, napi_callback_inf TYPE_NONE, napi_invalid_arg); return status; }; + auto input = [=](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status { + napi_status status = inputInner(env, argc, argv, self); + if (status != napi_ok) { + SELECTION_HILOGI("Check parameter invalid, Report error message to hiappevent"); + eventReporter->WriteEndEvent(SelectionApiEventReporter::API_FAIL, SFErrorCode::EXCEPTION_PARAMCHECK); + } + return status; + }; - auto exec = [ctxt](AsyncCall::Context *ctx) { + auto exec = [eventReporter, ctxt](AsyncCall::Context *ctx) { auto ret = SelectionAbility::GetInstance()->CreatePanel(ctxt->context, ctxt->panelInfo, ctxt->panel); if (ret != ErrorCode::NO_ERROR) { ctxt->SetErrorCode(ret); + eventReporter->WriteEndEvent(SelectionApiEventReporter::API_FAIL, JsUtils::Convert(ret)); return; } ctxt->SetState(napi_ok); + eventReporter->WriteEndEvent(SelectionApiEventReporter::API_SUCCESS, ret); }; auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { @@ -370,6 +382,7 @@ napi_value JsSelectionEngineSetting::Init(napi_env env, napi_value exports) }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor)); + NAPI_CALL(env, napi_set_named_property(env, exports, "SelectionType", GetJsSelectionTypeProperty(env))); if (Register(env) != EXCEPTION_SUCCESS) { SELECTION_HILOGE("regist lister to service failed!"); return nullptr; @@ -378,6 +391,29 @@ napi_value JsSelectionEngineSetting::Init(napi_env env, napi_value exports) return exports; } +napi_value JsSelectionEngineSetting::GetJsSelectionTypeProperty(napi_env env) +{ + napi_value obj = nullptr; + NAPI_CALL(env, napi_create_object(env, &obj)); + + auto ret = JsUtil::Object::WriteProperty(env, obj, "MOUSE_MOVE", static_cast(MOVE_SELECTION)); + if (!ret) { + SELECTION_HILOGE("Failed to init module selectionInput.selectionManager.SelectionType as MOUSE_MOVE"); + return nullptr; + } + ret = JsUtil::Object::WriteProperty(env, obj, "DOUBLE_CLICK", static_cast(DOUBLE_CLICKED_SELECTION)); + if (!ret) { + SELECTION_HILOGE("Failed to init module selectionInput.selectionManager.SelectionType as DOUBLE_CLICK"); + return nullptr; + } + ret = JsUtil::Object::WriteProperty(env, obj, "TRIPLE_CLICK", static_cast(TRIPLE_CLICKED_SELECTION)); + if (!ret) { + SELECTION_HILOGE("Failed to init module selectionInput.selectionManager.SelectionType as TRIPLE_CLICK"); + return nullptr; + } + return obj; +} + std::shared_ptr JsSelectionEngineSetting::GetEventHandler() { std::lock_guard lock(eventHandlerMutex_); diff --git a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h index 2417574..c1661c3 100644 --- a/frameworks/js/napi/selection_ability/js_selection_engine_setting.h +++ b/frameworks/js/napi/selection_ability/js_selection_engine_setting.h @@ -92,6 +92,7 @@ private: static std::shared_ptr GetEventHandler(); using EntrySetter = std::function; std::shared_ptr GetEntry(const std::string &type, EntrySetter entrySetter = nullptr); + static napi_value GetJsSelectionTypeProperty(napi_env env); private: static const std::string KDS_CLASS_NAME; diff --git a/frameworks/native/selection_ability/src/selection_ability.cpp b/frameworks/native/selection_ability/src/selection_ability.cpp index 1642fc0..f5f9b5f 100644 --- a/frameworks/native/selection_ability/src/selection_ability.cpp +++ b/frameworks/native/selection_ability/src/selection_ability.cpp @@ -68,7 +68,7 @@ int32_t SelectionAbility::CreatePanel(const std::shared_ptr &panel) { selectionPanel = std::make_shared(); @@ -81,7 +81,7 @@ int32_t SelectionAbility::CreatePanel(const std::shared_ptr &selectionPanel) diff --git a/hiappevent_agent/BUILD.gn b/hiappevent_agent/BUILD.gn new file mode 100644 index 0000000..de9c599 --- /dev/null +++ b/hiappevent_agent/BUILD.gn @@ -0,0 +1,44 @@ +# 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("//foundation/systemabilitymgr/selectionfwk/selection_service.gni") +import("//build/ohos.gni") + +ohos_shared_library("selection_hiappevent_agent") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + integer_overflow = true + ubsan = true + } + + include_dirs = [ + ".", + "../utils/include", + ] + + sources = [ "selection_api_event_reporter.cpp" ] + + external_deps = [ + "hilog:libhilog", + "hiappevent:hiappevent_innerapi", + "hitrace:hitrace_meter", + "hitrace:libhitracechain", + ] + part_name = "selectionfwk" + subsystem_name = "systemabilitymgr" +} diff --git a/hiappevent_agent/selection_api_event_reporter.cpp b/hiappevent_agent/selection_api_event_reporter.cpp new file mode 100644 index 0000000..6275742 --- /dev/null +++ b/hiappevent_agent/selection_api_event_reporter.cpp @@ -0,0 +1,71 @@ +/* + * 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 "selection_api_event_reporter.h" +#include +#include "app_event.h" +#include "app_event_processor_mgr.h" +#include "selection_log.h" + +namespace OHOS { +namespace SelectionFwk { +static int64_t g_processId = -1; +static std::mutex g_mutex; +static const std::string SDK_NAME("BasicServicesKit"); + +RandomGenerator SelectionApiEventReporter::randomGenerator_; + +SelectionApiEventReporter::SelectionApiEventReporter(const std::string& apiName) : apiName_(apiName) +{ + SELECTION_HILOGI("Create SelectionApiEventReporter object with apiName: %{public}s", apiName.c_str()); + transId_ = GenerateTransId(); + beginTime_ = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + std::unique_lock lock(g_mutex); + if (g_processId == -1) { + HiviewDFX::HiAppEvent::ReportConfig config; + config.name = "ha_app_event"; + config.configName = "SDK_OCG"; + g_processId = HiviewDFX::HiAppEvent::AppEventProcessorMgr::AddProcessor(config); + } +} + +void SelectionApiEventReporter::WriteEndEvent(const int result, const int32_t errCode) +{ + SELECTION_HILOGI("Begin to WriteEndEvent with result: %{public}d, errCode: %{public}d",result, errCode); + int64_t endTime = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + HiviewDFX::HiAppEvent::Event event("api_diagnostic", "api_exec_end", HiviewDFX::HiAppEvent::BEHAVIOR); + event.AddParam("trans_id", transId_); + event.AddParam("api_name", apiName_); + event.AddParam("sdk_name", SDK_NAME); + event.AddParam("begin_time", beginTime_); + event.AddParam("end_time", endTime); + event.AddParam("result", result); + event.AddParam("error_code", errCode); + int32_t ret = Write(event); + SELECTION_HILOGI("WriteEndEvent transId:%{public}s, apiName:%{public}s, sdkName:%{public}s, result:%{public}d, " + "errCode:%{public}d, ret:%{public}d", + transId_.c_str(), apiName_.c_str(), SDK_NAME.c_str(), result, errCode, ret); + if (ret != 0) { + SELECTION_HILOGE("WriteEndEvent HiAppEvent failed, ret: %{public}d", ret); + } +} + +std::string SelectionApiEventReporter::GenerateTransId() const +{ + return std::string("transId_") + std::to_string(randomGenerator_.Generate()); +} +} // SelectionFwk +} // OHOS \ No newline at end of file diff --git a/hiappevent_agent/selection_api_event_reporter.h b/hiappevent_agent/selection_api_event_reporter.h new file mode 100644 index 0000000..014cc66 --- /dev/null +++ b/hiappevent_agent/selection_api_event_reporter.h @@ -0,0 +1,65 @@ +/* + * 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 SELECTION_API_EVENT_REPORTER_H +#define SELECTION_API_EVENT_REPORTER_H + +#include +#include +#include +#include + +namespace OHOS { +namespace SelectionFwk { +class RandomGenerator { +public: + RandomGenerator() { + engine_ = std::make_unique(rd_()); + } + + int Generate() { + std::uniform_int_distribution dist; + std::lock_guard lock(mtx_); + return dist(*engine_); + } + +private: + std::random_device rd_; + std::unique_ptr engine_; + std::mutex mtx_; +}; + +class SelectionApiEventReporter { +public: + explicit SelectionApiEventReporter(const std::string& apiName); + ~SelectionApiEventReporter() = default; + void WriteEndEvent(const int result, const int32_t errCode); + +public: + constexpr static int32_t API_SUCCESS = 0; + constexpr static int32_t API_FAIL = 1; + +private: + std::string GenerateTransId() const; + +private: + static RandomGenerator randomGenerator_; + + std::string transId_; + std::string apiName_; + int64_t beginTime_; +}; +} // SelectionFwk +} // OHOS +#endif // SELECTION_API_EVENT_REPORTER_H diff --git a/service/include/selection_config.h b/service/include/selection_config.h index d64b52f..a092fc8 100644 --- a/service/include/selection_config.h +++ b/service/include/selection_config.h @@ -18,7 +18,6 @@ #include #include -#include "selection_config.h" namespace OHOS { namespace SelectionFwk { @@ -37,9 +36,9 @@ public: private: bool isEnabled_ = true; - bool isTriggered_ = true; - int uid_ = 0; - std::string applicationInfo_ = "com.hm.youdao/ExtensionAbility"; + bool isTriggered_ = false; + int uid_ = -1; + std::string applicationInfo_ = "com.huawei.hmos.vassistant/MiniMenuServiceExtAbility"; }; diff --git a/service/include/selection_input_monitor.h b/service/include/selection_input_monitor.h index 3d36520..1bc5be7 100644 --- a/service/include/selection_input_monitor.h +++ b/service/include/selection_input_monitor.h @@ -17,6 +17,7 @@ #define SELECTION_INPUT_MONITOR_H #include +#include #include #include "selection_interface.h" #include "pasteboard_disposable_observer.h" @@ -26,6 +27,7 @@ using namespace OHOS::MiscServices; constexpr const uint32_t DOUBLE_CLICK_TIME = 500; constexpr const uint32_t MAX_PASTERBOARD_TEXT_LENGTH = 2000; +constexpr const uint32_t BYTES_PER_CHINESE_CHAR = 3; // In UTF-8, common Chinese characters occupy 3 bytes. enum class SelectInputState: uint32_t { SELECT_INPUT_INITIAL = 0, @@ -101,9 +103,7 @@ private: class SelectionInputMonitor : public IInputEventConsumer { public: - SelectionInputMonitor() { - baseInputMonitor_ = std::make_shared(); - } + SelectionInputMonitor(); virtual void OnInputEvent(std::shared_ptr keyEvent) const; virtual void OnInputEvent(std::shared_ptr pointerEvent) const; @@ -113,10 +113,12 @@ private: void FinishedWordSelection() const; void InjectCtrlC() const; void HandleWindowFocused(std::shared_ptr pointerEvent) const; + bool IsAppInBlacklist(const std::string& bundleName) const; private: std::shared_ptr baseInputMonitor_; mutable sptr pasteboardObserver_; + std::vector appBlacklist_; }; } diff --git a/service/include/selection_service.h b/service/include/selection_service.h index 48be5fe..70feea5 100644 --- a/service/include/selection_service.h +++ b/service/include/selection_service.h @@ -63,14 +63,14 @@ public: int32_t ConnectNewExtAbility(const std::string& bundleName, const std::string& abilityName); void DisconnectCurrentExtAbility(); sptr GetListener(); - int GetUserId(); - bool IsExistUid(); + void PersistSelectionConfig(); protected: void OnStart() override; void OnStop() override; void HandleKeyEvent(int32_t keyCode); void HandlePointEvent(int32_t type); + private: void InputMonitorInit(); void InputMonitorCancel(); @@ -79,7 +79,9 @@ private: void CancelFocusChangedMonitor(); void HandleFocusChanged(const sptr &focusChangeInfo, bool isFocused); void SynchronizeSelectionConfig(); - void GetAccountLocalId(); + int GetUserId(); + int LoadAccountLocalId(); + bool IsUserLoggedIn(); int32_t inputMonitorId_ {-1}; mutable std::mutex mutex_; @@ -88,7 +90,6 @@ private: std::mutex connectInnerMutex_; std::atomic pid_ = -1; std::atomic userId_ = -1; - std::atomic isExistUid_ = false; }; } diff --git a/service/src/selection_config_comparator.cpp b/service/src/selection_config_comparator.cpp index ebb32c9..c258479 100644 --- a/service/src/selection_config_comparator.cpp +++ b/service/src/selection_config_comparator.cpp @@ -41,6 +41,7 @@ ComparisionResult SelectionConfigComparator::Compare(int uid, const SelectionCon SELECTION_HILOGI("result: %{public}s", result.ToString().c_str()); return result; } + ComparisionResult SelectionConfigComparator::DoCompare(int uid, const SelectionConfig &sysSelectionConfig, std::optional &dbSelectionConfig) { diff --git a/service/src/selection_input_monitor.cpp b/service/src/selection_input_monitor.cpp index eaed658..1e671c8 100644 --- a/service/src/selection_input_monitor.cpp +++ b/service/src/selection_input_monitor.cpp @@ -19,6 +19,7 @@ #include #include "common_event_manager.h" #include "pasteboard_client.h" +#include "selection_config.h" #include "selection_input_monitor.h" #include "window_manager.h" @@ -405,6 +406,14 @@ void BaseSelectionInputMonitor::ResetState() const SELECTION_HILOGD("ResetFinishedState."); } +SelectionInputMonitor::SelectionInputMonitor() { + baseInputMonitor_ = std::make_shared(); + appBlacklist_ = { + "com.huawei.hmos.hishell", + "com.huawei.hmos.filemanager" + }; +} + void SelectionInputMonitor::OnInputEvent(std::shared_ptr keyEvent) const { baseInputMonitor_->OnInputEvent(keyEvent); @@ -450,6 +459,10 @@ void SelectionInputMonitor::HandleWindowFocused(std::shared_ptr po } } +bool SelectionInputMonitor::IsAppInBlacklist(const std::string& bundleName) const { + return std::find(appBlacklist_.begin(), appBlacklist_.end(), bundleName) != appBlacklist_.end(); +} + void SelectionInputMonitor::FinishedWordSelection() const { if (!baseInputMonitor_->IsTextSelected()) { @@ -459,9 +472,20 @@ void SelectionInputMonitor::FinishedWordSelection() const if (pasteboardObserver_ == nullptr) { pasteboardObserver_ = sptr::MakeSptr(baseInputMonitor_); } + auto selectionInfo = baseInputMonitor_->GetSelectionInfo(); + if (IsAppInBlacklist(selectionInfo.bundleName)) { + SELECTION_HILOGW("The app [%{public}s] is in the blacklist, skip notifying selection info.", + selectionInfo.bundleName.c_str()); + return; + } + if (!MemSelectionConfig::GetInstance().GetEnable()) { + SELECTION_HILOGI("Selection switch is off, skip notifying selection info."); + return; + } + int32_t ret = PasteboardClient::GetInstance()->SubscribeDisposableObserver(pasteboardObserver_, - selectionInfo.bundleName, DisposableType::PLAIN_TEXT, MAX_PASTERBOARD_TEXT_LENGTH); + selectionInfo.bundleName, DisposableType::PLAIN_TEXT, MAX_PASTERBOARD_TEXT_LENGTH * BYTES_PER_CHINESE_CHAR); SELECTION_HILOGI("[selectevent] Call pasteboard interface. Selection event id is %{public}u. \ Error code is %{public}d.", selSeqId.load(), ret); if (ret != ERR_OK) { @@ -527,17 +551,20 @@ void SelectionInputMonitor::InjectCtrlC() const void SelectionPasteboardDisposableObserver::OnTextReceived(const std::string &text, int32_t errCode) { SELECTION_HILOGI("[selectevent] Pasteboard call sa. Selection event id is %{public}u.", selSeqId.load()); + SELECTION_HILOGI("Text received length: %{public}u, errCode: %{public}d.", text.length(), errCode); if (errCode != 0) { SELECTION_HILOGI("Error receiving text, errCode: %{public}d", errCode); return; } - SELECTION_HILOGI("Text received length: %{public}u.", text.length()); if (!baseInputMonitor_) { return; } - if (text.empty()) { - SELECTION_HILOGI("Received empty text."); + auto isAllWhitespace = std::all_of(text.begin(), text.end(), [](unsigned char c) { + return std::isspace(c); + }); + if (isAllWhitespace) { + SELECTION_HILOGI("Received empty text or all whitespaces."); return; } @@ -545,7 +572,7 @@ void SelectionPasteboardDisposableObserver::OnTextReceived(const std::string &te selectionInfo.text = text; SelectionInfoData infoData; infoData.data = selectionInfo; - SELECTION_HILOGI("SelectionInfoData length: %{public}u.", infoData.ToString().length()); + SELECTION_HILOGI("SelectionInfoData: %{public}s.", infoData.ToString().c_str()); sptr listener = SelectionService::GetInstance()->GetListener(); if (listener == nullptr) { SELECTION_HILOGE("Selection listener is nullptr"); diff --git a/service/src/selection_service.cpp b/service/src/selection_service.cpp index 9df33dd..872e8cc 100644 --- a/service/src/selection_service.cpp +++ b/service/src/selection_service.cpp @@ -144,12 +144,8 @@ static void WatchEnableSwitch(const char *key, const char *value, void *context) bool isEnabledValue = (strcmp(value, DEFAULT_SWITCH) == 0); SELECTION_HILOGI("isEnabledValue is %{public}d", isEnabledValue); MemSelectionConfig::GetInstance().SetEnabled(isEnabledValue); - auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); - SELECTION_HILOGI("selectionConfig.selectionConfig is %{public}d", selectionConfig.GetEnable()); - int ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); - if (ret != SELECTION_CONFIG_OK) { - SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); - } + + selectionService->PersistSelectionConfig(); } static void WatchTriggerMode(const char *key, const char *value, void *context) @@ -163,11 +159,8 @@ static void WatchTriggerMode(const char *key, const char *value, void *context) bool triggerValue = (triggerCmpResult == 0); MemSelectionConfig::GetInstance().SetTriggered(triggerValue); - auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); - int ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); - if (ret != SELECTION_CONFIG_OK) { - SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); - } + + selectionService->PersistSelectionConfig(); } static void WatchAppSwitch(const char *key, const char *value, void *context) @@ -203,18 +196,22 @@ static void WatchAppSwitch(const char *key, const char *value, void *context) auto ret = selectionService->ConnectNewExtAbility(bundleName, extName); SELECTION_HILOGD("StartExtensionAbility ret = %{public}d", ret); + selectionService->PersistSelectionConfig(); +} + +void SelectionService::PersistSelectionConfig() +{ + if (!IsUserLoggedIn()) { + SELECTION_HILOGW("Do not save selection config to DB because user is not logged in."); + return; + } auto &selectionConfig = MemSelectionConfig::GetInstance().GetSelectionConfig(); - ret = DbSelectionConfigRepository::GetInstance()->Save(selectionService->GetUserId(), selectionConfig); + int ret = DbSelectionConfigRepository::GetInstance()->Save(GetUserId(), selectionConfig); if (ret != SELECTION_CONFIG_OK) { SELECTION_HILOGE("Add database failed. ret = %{public}d", ret); } } -bool SelectionService::IsExistUid() -{ - return isExistUid_.load(); -} - void SelectionService::DisconnectCurrentExtAbility() { pid_.store(-1); @@ -269,7 +266,7 @@ int SelectionService::GetUserId() return userId_.load(); } -void SelectionService::GetAccountLocalId() +int SelectionService::LoadAccountLocalId() { int32_t userId = -1; int32_t ret = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(userId); @@ -281,11 +278,20 @@ void SelectionService::GetAccountLocalId() } SELECTION_HILOGI("GetForegroundOsAccountLocalId userId."); userId_.store(userId); + return userId; +} + +bool SelectionService::IsUserLoggedIn() +{ + return LoadAccountLocalId() != -1; } void SelectionService::SynchronizeSelectionConfig() { - GetAccountLocalId(); + if (!IsUserLoggedIn()) { + SELECTION_HILOGW("No selection config sync because user is not logged in."); + return; + } SelectionConfig sysSelectionConfig = SysSelectionConfigRepository::GetInstance()->GetSysParameters(); SELECTION_HILOGI("sysSelectionConfig: enable=%{public}d trigger=%{public}d applicationInfo=%{public}s", sysSelectionConfig.GetEnable(), sysSelectionConfig.GetTriggered(), diff --git a/test/unittest/selection_manager_js_test/PermissionJsTest.js b/test/unittest/selection_manager_js_test/PermissionJsTest.js index 9ba641f..534d821 100644 --- a/test/unittest/selection_manager_js_test/PermissionJsTest.js +++ b/test/unittest/selection_manager_js_test/PermissionJsTest.js @@ -14,7 +14,7 @@ */ import selectionManager from '@ohos.selectionInput.selectionManager' -import { describe, beforeAll, afterAll, it, expect } from 'deccjsunit/index' +import { describe, beforeAll, afterAll, beforeEach, afterEach, it, expect } from 'deccjsunit/index' import { PanelType } from '@ohos.selectionInput.SelectionPanel'; describe("SelectionManagerJsTest", function () { @@ -23,9 +23,17 @@ describe("SelectionManagerJsTest", function () { }) afterAll(function () { - console.info('AfterAll called'); + console.info('afterAll called'); }) + beforeEach(function () { + console.info('beforeEach called'); + }); + + afterEach(function () { + console.info('afterEach called'); + }); + async function createSelectionPanel() { let panelInfo = { @@ -55,8 +63,11 @@ describe("SelectionManagerJsTest", function () { selectionManager.on('selectionCompletedtest', (info) => { console.info(`selectionfwk_on_selectionCompleted_001 is failed`); expect(false).assertTrue(); - }) - } catch(error) { + done(); + }); + console.info(`selectionfwk_on_selectionCompleted_001 is failed`); + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_on_selectionCompleted_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -75,8 +86,8 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted'); console.info(`selectionfwk_on_selectionCompleted_002 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_on_selectionCompleted_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -96,12 +107,13 @@ describe("SelectionManagerJsTest", function () { selectionManager.on('selectionCompleted', (info) => { console.info(`selectionfwk_on_selectionCompleted_003 callback enter`); expect(true).assertTrue(); + done(); }); console.info(`selectionfwk_on_selectionCompleted_003 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_on_selectionCompleted_003 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } console.info('************* selectionfwk_on_selectionCompleted_003 Test end*************'); done(); @@ -118,11 +130,11 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on(null, (info) => { console.info(`selectionfwk_on_selectionCompleted_004 callback enter`); - expect(false).assertTrue(); + done(); }); console.info(`selectionfwk_on_selectionCompleted_004 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_on_selectionCompleted_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -141,11 +153,11 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on(undefined, (info) => { console.info(`selectionfwk_on_selectionCompleted_005 callback enter`); - expect(false).assertTrue(); + done(); }); console.info(`selectionfwk_on_selectionCompleted_005 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_on_selectionCompleted_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -164,8 +176,8 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted', null); console.info(`selectionfwk_on_selectionCompleted_006 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_on_selectionCompleted_006 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -184,8 +196,8 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted', undefined); console.info(`selectionfwk_on_selectionCompleted_007 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_on_selectionCompleted_007 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -204,9 +216,10 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.off('selectionCompletedtest', (info) => { console.info(`selectionfwk_off_selectionCompleted_001 is failed`); - expect(false).assertTrue(); - }) - } catch(error) { + done(); + }); + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_off_selectionCompleted_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -225,8 +238,8 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.off(); console.info(`selectionfwk_off_selectionCompleted_002 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_off_selectionCompleted_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -245,14 +258,14 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted', (info) => { console.info(`selectionfwk_on_selectionCompleted_003 callback enter`); - expect(true).assertTrue(); + done(); }); selectionManager.off('selectionCompleted'); console.info(`selectionfwk_off_selectionCompleted_003 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_off_selectionCompleted_003 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } console.info('************* selectionfwk_off_selectionCompleted_003 Test end*************'); done(); @@ -269,12 +282,12 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted', (info) => { console.info(`selectionfwk_off_selectionCompleted_004 callback enter`); - expect(true).assertTrue(); + done(); }); selectionManager.off(null); console.info(`selectionfwk_off_selectionCompleted_004 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_off_selectionCompleted_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -293,12 +306,12 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted', (info) => { console.info(`selectionfwk_off_selectionCompleted_005 callback enter`); - expect(true).assertTrue(); + done(); }); selectionManager.off(undefined); console.info(`selectionfwk_off_selectionCompleted_005 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_off_selectionCompleted_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -317,14 +330,14 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted', (info) => { console.info(`selectionfwk_off_selectionCompleted_006 callback enter`); - expect(true).assertTrue(); + done(); }); selectionManager.off('selectionCompleted', null); console.info(`selectionfwk_off_selectionCompleted_006 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_off_selectionCompleted_006 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } console.info('************* selectionfwk_off_selectionCompleted_006 Test end*************'); done(); @@ -341,14 +354,14 @@ describe("SelectionManagerJsTest", function () { try { selectionManager.on('selectionCompleted', (info) => { console.info(`selectionfwk_off_selectionCompleted_007 callback enter`); - expect(true).assertTrue(); + done(); }); selectionManager.off('selectionCompleted', undefined); console.info(`selectionfwk_off_selectionCompleted_007 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_off_selectionCompleted_007 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } console.info('************* selectionfwk_off_selectionCompleted_007 Test end*************'); done(); @@ -364,7 +377,7 @@ describe("SelectionManagerJsTest", function () { console.info('************* selectionfwk_createPanel_001 Test start*************'); try { await selectionManager.createPanel({stageMode : false}); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -390,7 +403,7 @@ describe("SelectionManagerJsTest", function () { height: 100 } await selectionManager.createPanel(selectionManager.Context, panelInfo); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -416,7 +429,7 @@ describe("SelectionManagerJsTest", function () { height: 100 } await selectionManager.createPanel({stageMode : true}, panelInfo); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_003 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -450,7 +463,7 @@ describe("SelectionManagerJsTest", function () { await destroySelectionPanel(panelTemp); } catch (error) { console.info(`selectionfwk_createPanel_004 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } console.info('************* selectionfwk_createPanel_004 Test end*************'); done(); @@ -476,7 +489,7 @@ describe("SelectionManagerJsTest", function () { await destroySelectionPanel(panelTemp); } catch (error) { console.info(`selectionfwk_createPanel_005 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } console.info('************* selectionfwk_createPanel_005 Test end*************'); done(); @@ -499,7 +512,7 @@ describe("SelectionManagerJsTest", function () { height: 100 } await selectionManager.createPanel({stageMode : false}, panelInfo); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_006 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -525,7 +538,7 @@ describe("SelectionManagerJsTest", function () { height: 100 } await selectionManager.createPanel({stageMode : false}, panelInfo); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_007 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -551,7 +564,7 @@ describe("SelectionManagerJsTest", function () { height: 100 } await selectionManager.createPanel({stageMode : false}, panelInfo) - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_008 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -577,7 +590,7 @@ describe("SelectionManagerJsTest", function () { height: -1 } await selectionManager.createPanel({stageMode : false}, panelInfo) - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_009 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -596,7 +609,7 @@ describe("SelectionManagerJsTest", function () { console.info('************* selectionfwk_createPanel_010 Test start*************'); try { await selectionManager.createPanel({stageMode : false}, null); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_010 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -615,7 +628,7 @@ describe("SelectionManagerJsTest", function () { console.info('************* selectionfwk_createPanel_011 Test start*************'); try { await selectionManager.createPanel({stageMode : false}, undefined); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_011 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -641,7 +654,7 @@ describe("SelectionManagerJsTest", function () { height: 100 } await selectionManager.createPanel(null, panelInfo) - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_012 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -667,7 +680,7 @@ describe("SelectionManagerJsTest", function () { height: 100 } await selectionManager.createPanel(undefined, panelInfo) - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_createPanel_013 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -686,7 +699,7 @@ describe("SelectionManagerJsTest", function () { console.info('************* selectionfwk_destroyPanel_001 Test start*************'); try { await selectionManager.destroyPanel(); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_destroyPanel_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -706,7 +719,7 @@ describe("SelectionManagerJsTest", function () { try { let panel = 1; await selectionManager.destroyPanel(panel); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_destroyPanel_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -730,7 +743,7 @@ describe("SelectionManagerJsTest", function () { expect(true).assertTrue(); } catch (error) { console.info(`selectionfwk_destroyPanel_003 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } console.info('************* selectionfwk_destroyPanel_003 Test end*************'); done(); @@ -747,7 +760,7 @@ describe("SelectionManagerJsTest", function () { try { await selectionManager.destroyPanel(null); console.info(`selectionfwk_destroyPanel_004 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_destroyPanel_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -767,7 +780,7 @@ describe("SelectionManagerJsTest", function () { try { await selectionManager.destroyPanel(undefined); console.info(`selectionfwk_destroyPanel_005 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_destroyPanel_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -788,7 +801,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.setUiContent(); console.info(`selection_panel_setUiContent_001 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selection_panel_setUiContent_001 result: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -810,7 +823,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.setUiContent(20); console.info(`selection_panel_setUiContent_002 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selection_panel_setUiContent_002 result: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -832,7 +845,7 @@ describe("SelectionManagerJsTest", function () { await destroySelectionPanel(panel); try { await panel.setUiContent('pages/index/index'); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selection_panel_setUiContent_003 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(33600002); @@ -852,7 +865,7 @@ describe("SelectionManagerJsTest", function () { let panel = await createSelectionPanel(); try { await panel.setUiContent(null); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selection_panel_setUiContent_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -873,7 +886,7 @@ describe("SelectionManagerJsTest", function () { let panel = await createSelectionPanel(); try { await panel.setUiContent(undefined); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selection_panel_setUiContent_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -895,7 +908,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(20); console.info(`selectionfwk_panel_moveTo_001 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -917,7 +930,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(20, '20'); console.info(`selectionfwk_panel_moveTo_002 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -939,7 +952,7 @@ describe("SelectionManagerJsTest", function () { await destroySelectionPanel(panel); try { await panel.moveTo(20, 20); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_003 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(33600002); @@ -963,7 +976,7 @@ describe("SelectionManagerJsTest", function () { expect(true).assertTrue(); } catch (error) { console.info(`selectionfwk_panel_moveTo_004 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_moveTo_004 Test end*************'); @@ -982,7 +995,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(-1, 50); console.info(`selectionfwk_panel_moveTo_005 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -1004,7 +1017,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(50, -1); console.info(`selectionfwk_panel_moveTo_006 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_006 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -1026,7 +1039,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(null, 50); console.info(`selectionfwk_panel_moveTo_007 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_007 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -1048,7 +1061,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(undefined, 50); console.info(`selectionfwk_panel_moveTo_008 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_008 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -1070,7 +1083,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(50, null); console.info(`selectionfwk_panel_moveTo_009 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_009 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -1092,7 +1105,7 @@ describe("SelectionManagerJsTest", function () { try { await panel.moveTo(50, undefined); console.info(`selectionfwk_panel_moveTo_010 promise success`); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_moveTo_010 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); @@ -1114,7 +1127,7 @@ describe("SelectionManagerJsTest", function () { await destroySelectionPanel(panel); try { await panel.show(); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_show_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(33600002); @@ -1135,9 +1148,10 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyedTest', (info) => { console.info(`selectionfwk_panel_on_destroyed_001 is failed`); - expect(false).assertTrue(); - }) - } catch(error) { + done(); + }); + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_destroyed_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1158,8 +1172,8 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed'); console.info(`selectionfwk_panel_on_destroyed_002 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_destroyed_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1180,13 +1194,13 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', (info) => { console.info(`selectionfwk_panel_on_destroyed_003 callback enter`); - expect(true).assertTrue(); + done(); }); console.info(`selectionfwk_panel_on_destroyed_003 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_on_destroyed_003 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_on_destroyed_003 Test end*************'); @@ -1205,11 +1219,11 @@ describe("SelectionManagerJsTest", function () { try { panel.on(null, (info) => { console.info(`selectionfwk_panel_on_destroyed_004 callback enter`); - expect(false).assertTrue(); + done(); }); console.info(`selectionfwk_panel_on_destroyed_004 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_destroyed_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1230,11 +1244,11 @@ describe("SelectionManagerJsTest", function () { try { panel.on(undefined, (info) => { console.info(`selectionfwk_panel_on_destroyed_005 callback enter`); - expect(false).assertTrue(); + done(); }); console.info(`selectionfwk_panel_on_destroyed_005 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_destroyed_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1255,8 +1269,8 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', null); console.info(`selectionfwk_panel_on_destroyed_006 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_destroyed_006 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1277,8 +1291,8 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', undefined); console.info(`selectionfwk_panel_on_destroyed_007 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_destroyed_007 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1299,9 +1313,10 @@ describe("SelectionManagerJsTest", function () { try { panel.off('destroyedTest', (info) => { console.info(`selectionfwk_panel_off_destroyed_001 is failed`); - expect(false).assertTrue(); - }) - } catch(error) { + done(); + }); + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_off_destroyed_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1322,9 +1337,9 @@ describe("SelectionManagerJsTest", function () { try { panel.off(() => { console.info(`selectionfwk_panel_off_destroyed_002 is failed`); - expect(false).assertTrue(); + expect().assertFail(); }) - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_destroyed_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1345,14 +1360,14 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', (info) => { console.info(`selectionfwk_panel_off_destroyed_003 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off('destroyed'); console.info(`selectionfwk_panel_off_destroyed_003 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_destroyed_003 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_off_destroyed_003 Test end*************'); @@ -1371,12 +1386,12 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', (info) => { console.info(`selectionfwk_panel_off_destroyed_004 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off(null); console.info(`selectionfwk_panel_off_destroyed_004 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_off_destroyed_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1397,12 +1412,12 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', (info) => { console.info(`selectionfwk_panel_off_destroyed_005 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off(undefined); console.info(`selectionfwk_panel_off_destroyed_005 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_off_destroyed_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1423,14 +1438,14 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', (info) => { console.info(`selectionfwk_panel_off_destroyed_006 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off('destroyed', null); console.info(`selectionfwk_panel_off_destroyed_006 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_destroyed_006 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_off_destroyed_006 Test end*************'); @@ -1449,14 +1464,14 @@ describe("SelectionManagerJsTest", function () { try { panel.on('destroyed', (info) => { console.info(`selectionfwk_panel_off_destroyed_007 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off('destroyed', undefined); console.info(`selectionfwk_panel_off_destroyed_007 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_destroyed_007 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_off_destroyed_007 Test end*************'); @@ -1475,9 +1490,10 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hiddenTest', (info) => { console.info(`selectionfwk_panel_on_hidden_001 is failed`); - expect(false).assertTrue(); - }) - } catch(error) { + done(); + }); + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_hidden_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1498,8 +1514,8 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden'); console.info(`selectionfwk_panel_on_hidden_002 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_hidden_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1520,13 +1536,13 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', (info) => { console.info(`selectionfwk_panel_on_hidden_003 callback enter`); - expect(true).assertTrue(); + done(); }); console.info(`selectionfwk_panel_on_hidden_003 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_on_hidden_003 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_on_hidden_003 Test end*************'); @@ -1545,11 +1561,11 @@ describe("SelectionManagerJsTest", function () { try { panel.on(null, (info) => { console.info(`selectionfwk_panel_on_hidden_004 callback enter`); - expect(false).assertTrue(); + done(); }); console.info(`selectionfwk_panel_on_hidden_004 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_hidden_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1570,11 +1586,11 @@ describe("SelectionManagerJsTest", function () { try { panel.on(undefined, (info) => { console.info(`selectionfwk_panel_on_hidden_005 callback enter`); - expect(false).assertTrue(); + done(); }); console.info(`selectionfwk_panel_on_hidden_005 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_hidden_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1595,8 +1611,8 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', null); console.info(`selectionfwk_panel_on_hidden_006 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_hidden_006 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1617,8 +1633,8 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', undefined); console.info(`selectionfwk_panel_on_hidden_007 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_on_hidden_007 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1639,9 +1655,10 @@ describe("SelectionManagerJsTest", function () { try { panel.off('hiddenTest', (info) => { console.info(`selectionfwk_panel_off_hidden_001 is failed`); - expect(false).assertTrue(); - }) - } catch(error) { + done(); + }); + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_off_hidden_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1662,9 +1679,9 @@ describe("SelectionManagerJsTest", function () { try { panel.off(() => { console.info(`selectionfwk_panel_off_hidden_002 is failed`); - expect(false).assertTrue(); + expect().assertFail(); }) - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_hidden_002 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1685,14 +1702,14 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', (info) => { console.info(`selectionfwk_panel_off_hidden_003 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off('hidden'); console.info(`selectionfwk_panel_off_hidden_003 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_hidden_003 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_off_hidden_003 Test end*************'); @@ -1711,12 +1728,12 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', (info) => { console.info(`selectionfwk_panel_off_hidden_004 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off(null); console.info(`selectionfwk_panel_off_hidden_004 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_off_hidden_004 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1737,12 +1754,12 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', (info) => { console.info(`selectionfwk_panel_off_hidden_005 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off(undefined); console.info(`selectionfwk_panel_off_hidden_005 is failed`); - expect(false).assertTrue(); - } catch(error) { + expect().assertFail(); + } catch (error) { console.info(`selectionfwk_panel_off_hidden_005 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(401); } @@ -1763,14 +1780,14 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', (info) => { console.info(`selectionfwk_panel_off_hidden_006 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off('hidden', null); console.info(`selectionfwk_panel_off_hidden_006 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_hidden_006 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_off_hidden_006 Test end*************'); @@ -1789,14 +1806,14 @@ describe("SelectionManagerJsTest", function () { try { panel.on('hidden', (info) => { console.info(`selectionfwk_panel_off_hidden_007 callback enter`); - expect(true).assertTrue(); + done(); }); panel.off('hidden', undefined); console.info(`selectionfwk_panel_off_hidden_007 is success`); expect(true).assertTrue(); - } catch(error) { + } catch (error) { console.info(`selectionfwk_panel_off_hidden_007 throw error: ${JSON.stringify(error)}`); - expect(false).assertTrue(); + expect().assertFail(); } await destroySelectionPanel(panel); console.info('************* selectionfwk_panel_off_hidden_007 Test end*************'); @@ -1815,7 +1832,7 @@ describe("SelectionManagerJsTest", function () { await destroySelectionPanel(panel); try { await panel.hide(); - expect(false).assertTrue(); + expect().assertFail(); } catch (error) { console.info(`selectionfwk_panel_hide_001 throw error: ${JSON.stringify(error)}`); expect(error.code).assertEqual(33600002); -- Gitee From d5b7957c2dab01a3f5ba8a8628df93b5e3e2351f Mon Sep 17 00:00:00 2001 From: Sunjiamei Date: Thu, 10 Jul 2025 18:33:14 +0800 Subject: [PATCH 93/93] =?UTF-8?q?sig=E6=B7=BB=E5=8A=A0patches=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sunjiamei --- patches/patches.json | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 patches/patches.json diff --git a/patches/patches.json b/patches/patches.json new file mode 100644 index 0000000..140a4c8 --- /dev/null +++ b/patches/patches.json @@ -0,0 +1,9 @@ +{ + "patches": [ + { + "project":"productdefine_common", + "path":"productdefine/common", + "pr_url":"https://gitee.com/openharmony/productdefine_common/pulls/1032" + } + ] +} \ No newline at end of file -- Gitee