• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 const std::string TOUCH_EVENTS_UEGAME_START = "touch.events.uegame.start";
24 } // namespace
25 
SubscribeEvent(int32_t instanceId)26 void EventPassThroughSubscribeProxy::SubscribeEvent(int32_t instanceId)
27 {
28     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "Subscribe touch.events.pass.through Event");
29     std::lock_guard<std::mutex> lock(mutex_);
30     if (eventPassThroughReceiver_ == nullptr) {
31         // create subscribe info
32         MatchingSkills matchingSkills;
33         // add common events
34         matchingSkills.AddEvent(TOUCH_EVENTS_PASS_THROUGH);
35         matchingSkills.AddEvent(GAME_INFO_TO_GAME_RESAMPLE);
36         matchingSkills.AddEvent(TOUCH_EVENTS_UEGAME_START);
37         CommonEventSubscribeInfo subscribeInfo(matchingSkills);
38         subscribeInfo.SetPublisherUid(PUBLISHER_UID);
39         subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::ThreadMode::HANDLER);
40 
41         // init Receiver
42         eventPassThroughReceiver_ = std::make_shared<EventPassThroughSubscriber>(subscribeInfo);
43         eventPassThroughReceiver_->AddInstanceId(instanceId);
44         eventReceiver_ = std::shared_ptr<CommonEventSubscriber>(eventPassThroughReceiver_);
45 
46         // create subscription
47         CommonEventManager::SubscribeCommonEvent(eventReceiver_);
48     } else {
49         eventPassThroughReceiver_->AddInstanceId(instanceId);
50     }
51 }
52 
UnSubscribeEvent()53 void EventPassThroughSubscribeProxy::UnSubscribeEvent()
54 {
55     std::lock_guard<std::mutex> lock(mutex_);
56     if (eventReceiver_ != nullptr) {
57         CommonEventManager::UnSubscribeCommonEvent(eventReceiver_);
58         eventReceiver_ = nullptr;
59         eventPassThroughReceiver_ = nullptr;
60     }
61 }
62 
UnSubscribeEvent(int32_t instanceId)63 void EventPassThroughSubscribeProxy::UnSubscribeEvent(int32_t instanceId)
64 {
65     std::lock_guard<std::mutex> lock(mutex_);
66     if (eventReceiver_ != nullptr) {
67         if (eventPassThroughReceiver_->EraseContainerAddCheckUnSubscribe(instanceId)) {
68             CommonEventManager::UnSubscribeCommonEvent(eventReceiver_);
69             eventReceiver_ = nullptr;
70             eventPassThroughReceiver_ = nullptr;
71         }
72     }
73 }
74 
OnReceiveEvent(const CommonEventData & data)75 void EventPassThroughSubscriber::OnReceiveEvent(const CommonEventData& data)
76 {
77     auto want = data.GetWant();
78     std::string action = want.GetAction();
79     std::string bundleName = want.GetBundle();
80     if (bundleName.empty()) {
81         TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent empty bundleName");
82         return;
83     }
84     bool needPassThrough = false;
85     {
86         std::lock_guard<std::mutex> lock(instanceMapMutex_);
87         for (const auto& instanceId : instanceMap_) {
88             auto container = Platform::AceContainer::GetContainer(instanceId);
89             if (!container) {
90                 continue;
91             }
92             if (container->GetBundleName() == bundleName) {
93                 needPassThrough = true;
94                 break;
95             }
96         }
97     }
98     if (!needPassThrough) {
99         TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent no matched bundleName");
100         return;
101     }
102 
103     if (action == TOUCH_EVENTS_UEGAME_START) {
104         TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent %{public}s", action.c_str());
105         AceApplicationInfo::GetInstance().SetTouchPadIdChanged(true);
106         return;
107     }
108     if (action != TOUCH_EVENTS_PASS_THROUGH && action != GAME_INFO_TO_GAME_RESAMPLE) {
109         return;
110     }
111     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent %{public}s", action.c_str());
112     TouchPassMode mode =
113         (action == TOUCH_EVENTS_PASS_THROUGH) ? TouchPassMode::PASS_THROUGH : TouchPassMode::ACCELERATE;
114     AceApplicationInfo::GetInstance().SetTouchEventPassMode(mode);
115     {
116         std::lock_guard<std::mutex> lock(instanceMapMutex_);
117         for (const auto& instanceId : instanceMap_) {
118             auto container = Platform::AceContainer::GetContainer(instanceId);
119             if (!container) {
120                 continue;
121             }
122             auto taskExecutor = container->GetTaskExecutor();
123             CHECK_NULL_VOID(taskExecutor);
124             taskExecutor->PostTask(
125                 [mode, instanceId]() {
126                     auto container = Platform::AceContainer::GetContainer(instanceId);
127                     CHECK_NULL_VOID(container);
128                     auto pipeline = container->GetPipelineContext();
129                     CHECK_NULL_VOID(pipeline);
130                     if (mode == TouchPassMode::PASS_THROUGH) {
131                         pipeline->SetTouchPassThrough(true);
132                         pipeline->SetTouchAccelarate(false);
133                     } else {
134                         pipeline->SetTouchAccelarate(true);
135                         pipeline->SetTouchPassThrough(false);
136                     }
137                 },
138                 TaskExecutor::TaskType::UI, "ArkUIReceiveEventsPassThroughAsync");
139         }
140     }
141 }
142 
AddInstanceId(int32_t instanceId)143 void EventPassThroughSubscriber::AddInstanceId(int32_t instanceId)
144 {
145     std::lock_guard<std::mutex> lock(instanceMapMutex_);
146     instanceMap_.emplace(instanceId);
147 }
148 
EraseContainerAddCheckUnSubscribe(int32_t instanceId)149 bool EventPassThroughSubscriber::EraseContainerAddCheckUnSubscribe(int32_t instanceId)
150 {
151     std::lock_guard<std::mutex> lock(instanceMapMutex_);
152     instanceMap_.erase(instanceId);
153     return instanceMap_.empty();
154 }
155 } // namespace OHOS::Ace
156