1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "adapter/ohos/entrance/event_pass_through_subscriber.h"
17
18 namespace OHOS::Ace {
19 namespace {
20 constexpr int32_t PUBLISHER_UID = 7800;
21 const std::string TOUCH_EVENTS_PASS_THROUGH = "touch.events.pass.through";
22 const std::string GAME_INFO_TO_GAME_RESAMPLE = "touch.events.game.resample";
23 } // namespace
24
SubscribeEvent(int32_t instanceId)25 void EventPassThroughSubscribeProxy::SubscribeEvent(int32_t instanceId)
26 {
27 TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "Subscribe touch.events.pass.through event");
28 if (eventPassThroughReceiver_ == nullptr) {
29 // create subscribe info
30 MatchingSkills matchingSkills;
31 // add common events
32 matchingSkills.AddEvent(TOUCH_EVENTS_PASS_THROUGH);
33 matchingSkills.AddEvent(GAME_INFO_TO_GAME_RESAMPLE);
34 CommonEventSubscribeInfo subscribeInfo(matchingSkills);
35 subscribeInfo.SetPublisherUid(PUBLISHER_UID);
36 subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::ThreadMode::HANDLER);
37
38 // init Receiver
39 eventPassThroughReceiver_ = std::make_shared<EventPassThroughSubscriber>(subscribeInfo);
40 eventPassThroughReceiver_->AddInstanceId(instanceId);
41 eventReceiver_ = std::shared_ptr<CommonEventSubscriber>(eventPassThroughReceiver_);
42
43 // create subscription
44 CommonEventManager::SubscribeCommonEvent(eventReceiver_);
45 } else {
46 eventPassThroughReceiver_->AddInstanceId(instanceId);
47 }
48 }
49
UnSubscribeEvent()50 void EventPassThroughSubscribeProxy::UnSubscribeEvent()
51 {
52 if (eventReceiver_ != nullptr) {
53 CommonEventManager::UnSubscribeCommonEvent(eventReceiver_);
54 eventReceiver_ = nullptr;
55 eventPassThroughReceiver_ = nullptr;
56 }
57 }
58
UnSubscribeEvent(int32_t instanceId)59 void EventPassThroughSubscribeProxy::UnSubscribeEvent(int32_t instanceId)
60 {
61 if (eventReceiver_ != nullptr) {
62 if (eventPassThroughReceiver_->EraseContainerAddCheckUnSubscribe(instanceId)) {
63 CommonEventManager::UnSubscribeCommonEvent(eventReceiver_);
64 eventReceiver_ = nullptr;
65 eventPassThroughReceiver_ = nullptr;
66 }
67 }
68 }
69
OnReceiveEvent(const CommonEventData & data)70 void EventPassThroughSubscriber::OnReceiveEvent(const CommonEventData& data)
71 {
72 auto want = data.GetWant();
73 std::string action = want.GetAction();
74 std::string bundleName = want.GetBundle();
75 if (bundleName.empty()) {
76 TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent empty bundleName");
77 return;
78 }
79 bool needPassThrough = false;
80 for (const auto& instanceId : instanceMap_) {
81 auto container = Platform::AceContainer::GetContainer(instanceId);
82 if (!container) {
83 continue;
84 }
85 if (container->GetBundleName() == bundleName) {
86 needPassThrough = true;
87 break;
88 }
89 }
90 if (!needPassThrough) {
91 TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent no matched bundleName");
92 return;
93 }
94
95 if (action != TOUCH_EVENTS_PASS_THROUGH && action != GAME_INFO_TO_GAME_RESAMPLE) {
96 return;
97 }
98 TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent %{public}s", action.c_str());
99 TouchPassMode mode =
100 (action == TOUCH_EVENTS_PASS_THROUGH) ? TouchPassMode::PASS_THROUGH : TouchPassMode::ACCELERATE;
101 AceApplicationInfo::GetInstance().SetTouchEventPassMode(mode);
102 for (const auto& instanceId : instanceMap_) {
103 auto container = Platform::AceContainer::GetContainer(instanceId);
104 if (!container) {
105 continue;
106 }
107 auto taskExecutor = container->GetTaskExecutor();
108 CHECK_NULL_VOID(taskExecutor);
109 taskExecutor->PostTask(
110 [mode, instanceId]() {
111 auto container = Platform::AceContainer::GetContainer(instanceId);
112 CHECK_NULL_VOID(container);
113 auto pipeline = container->GetPipelineContext();
114 CHECK_NULL_VOID(pipeline);
115 if (mode == TouchPassMode::PASS_THROUGH) {
116 pipeline->SetTouchPassThrough(true);
117 pipeline->SetTouchAccelarate(false);
118 } else {
119 pipeline->SetTouchAccelarate(true);
120 pipeline->SetTouchPassThrough(false);
121 }
122 },
123 TaskExecutor::TaskType::UI, "ArkUIReceiveEventsPassThroughAsync");
124 }
125 }
126
AddInstanceId(int32_t instanceId)127 void EventPassThroughSubscriber::AddInstanceId(int32_t instanceId)
128 {
129 instanceMap_.emplace(instanceId);
130 }
131
EraseContainerAddCheckUnSubscribe(int32_t instanceId)132 bool EventPassThroughSubscriber::EraseContainerAddCheckUnSubscribe(int32_t instanceId)
133 {
134 instanceMap_.erase(instanceId);
135 return instanceMap_.empty();
136 }
137 } // namespace OHOS::Ace
138