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 const std::string TOUCH_EVENTS_PASS_THROUGH = "touch.events.pass.through";
20 namespace {
21 constexpr int32_t PUBLISHER_UID = 7800;
22 } // namespace
23 
SubscribeEvent(int32_t instanceId)24 void EventPassThroughSubscribeProxy::SubscribeEvent(int32_t instanceId)
25 {
26     TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "Subscribe touch.events.pass.through Event");
27     if (eventPassThroughReceiver_ == nullptr) {
28         // create subscribe info
29         MatchingSkills matchingSkills;
30         // add common events
31         matchingSkills.AddEvent(TOUCH_EVENTS_PASS_THROUGH);
32         CommonEventSubscribeInfo subscribeInfo(matchingSkills);
33         subscribeInfo.SetPublisherUid(PUBLISHER_UID);
34         subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::ThreadMode::HANDLER);
35 
36         // init Receiver
37         eventPassThroughReceiver_ = std::make_shared<EventPassThroughSubscriber>(subscribeInfo);
38         eventPassThroughReceiver_->AddInstanceId(instanceId);
39         eventReceiver_ = std::shared_ptr<CommonEventSubscriber>(eventPassThroughReceiver_);
40 
41         // create subscription
42         CommonEventManager::SubscribeCommonEvent(eventReceiver_);
43     } else {
44         eventPassThroughReceiver_->AddInstanceId(instanceId);
45     }
46 }
47 
UnSubscribeEvent()48 void EventPassThroughSubscribeProxy::UnSubscribeEvent()
49 {
50     if (eventReceiver_ != nullptr) {
51         CommonEventManager::UnSubscribeCommonEvent(eventReceiver_);
52         eventReceiver_ = nullptr;
53         eventPassThroughReceiver_ = nullptr;
54     }
55 }
56 
UnSubscribeEvent(int32_t instanceId)57 void EventPassThroughSubscribeProxy::UnSubscribeEvent(int32_t instanceId)
58 {
59     if (eventReceiver_ != nullptr) {
60         if (eventPassThroughReceiver_->EraseContainerAddCheckUnSubscribe(instanceId)) {
61             CommonEventManager::UnSubscribeCommonEvent(eventReceiver_);
62             eventReceiver_ = nullptr;
63             eventPassThroughReceiver_ = nullptr;
64         }
65     }
66 }
67 
OnReceiveEvent(const CommonEventData & data)68 void EventPassThroughSubscriber::OnReceiveEvent(const CommonEventData& data)
69 {
70     auto want = data.GetWant();
71     std::string action = want.GetAction();
72     if (action == TOUCH_EVENTS_PASS_THROUGH) {
73         TAG_LOGI(AceLogTag::ACE_INPUTKEYFLOW, "OnReceiveEvent touch.events.pass.through Event");
74         AceApplicationInfo::GetInstance().SetTouchEventsPassThroughMode(true);
75         for (const auto& instanceId : instanceMap_) {
76             auto container = Platform::AceContainer::GetContainer(instanceId);
77             if (!container) {
78                 continue;
79             }
80             auto taskExecutor = container->GetTaskExecutor();
81             CHECK_NULL_VOID(taskExecutor);
82             taskExecutor->PostTask(
83                 [instanceId]() {
84                     auto container = Platform::AceContainer::GetContainer(instanceId);
85                     CHECK_NULL_VOID(container);
86                     container->SetTouchEventsPassThroughMode(true);
87                 },
88                 TaskExecutor::TaskType::UI, "ArkUIReceiveEventsPassThroughAsync");
89         }
90     }
91 }
92 
AddInstanceId(int32_t instanceId)93 void EventPassThroughSubscriber::AddInstanceId(int32_t instanceId)
94 {
95     instanceMap_.emplace(instanceId);
96 }
97 
EraseContainerAddCheckUnSubscribe(int32_t instanceId)98 bool EventPassThroughSubscriber::EraseContainerAddCheckUnSubscribe(int32_t instanceId)
99 {
100     instanceMap_.erase(instanceId);
101     return instanceMap_.empty();
102 }
103 } // namespace OHOS::Ace
104