1 /*
2  * Copyright (c) 2023-2024 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 "interfaces/inner_api/ace/uicast/uicast_subscriber.h"
17 
18 #include <dlfcn.h>
19 
20 #include "arkui_log.h"
21 
22 namespace OHOS::Ace {
23 const std::string COMMON_EVENT_UICAST_START = "uicast.start";
24 const std::string COMMON_EVENT_UICAST_STOP = "uicast.stop";
25 const std::string COMMON_EVENT_UICAST_CAST_SESSION_KEY = "uicast.castSessionIdKey";
26 
27 constexpr char UICAST_PROXY_START_FUNC[] = "OHOS_ACE_UICastProxyStart";
28 constexpr char UICAST_PROXY_UPDATE_CONTEXT_FUNC[] = "OHOS_ACE_UICastProxyUpdateContext";
29 
30 using UICastProxyStartFunc = void (*)(int, UIContent*);
31 using UICastProxyUpdateContextFunc = void (*)(UIContent*);
32 
33 #if (defined(__aarch64__) || defined(__x86_64__))
34 const char* DISTRIBUTED_UI_PROXY_SO_PATH = "/system/lib64/libace_uicast_proxy.z.so";
35 #else
36 const char* DISTRIBUTED_UI_PROXY_SO_PATH = "/system/lib/libace_uicast_proxy.z.so";
37 #endif
38 
SubscribeStartEvent(UIContent* context)39 void UICastEventSubscribeProxy::SubscribeStartEvent(UIContent* context)
40 {
41     if (context == nullptr) {
42         LOGE("context is null");
43         return;
44     }
45 
46     if (uicastEventReceiver_ == nullptr) {
47         if (access(DISTRIBUTED_UI_PROXY_SO_PATH, 0) == -1) {
48             LOGI("SubscribeStartEvent libace_uicast_proxy so no exist!");
49             return;
50         }
51 
52         LOGI("SubscribeStartEvent");
53         // create subscribe info
54         MatchingSkills matchingSkills;
55 
56         // add common events
57         matchingSkills.AddEvent(COMMON_EVENT_UICAST_START);
58         matchingSkills.AddEvent(COMMON_EVENT_UICAST_STOP);
59         CommonEventSubscribeInfo subscribeInfo(matchingSkills);
60         subscribeInfo.SetPermission("ohos.permission.CAPTURE_SCREEN");
61         subscribeInfo.SetThreadMode(EventFwk::CommonEventSubscribeInfo::ThreadMode::HANDLER);
62 
63         // init Receiver
64         uicastEventReceiver_ = std::make_shared<UICastEventSubscriber>(subscribeInfo, context);
65         eventReceiver_ = std::shared_ptr<CommonEventSubscriber>(uicastEventReceiver_);
66 
67         // create subscription
68         CommonEventManager::SubscribeCommonEvent(eventReceiver_);
69     } else {
70         LOGI("Already SubscribeStartEvent");
71         uicastEventReceiver_->UICastProxyUpdateContext(context);
72     }
73 }
74 
UnSubscribeStartEvent(void)75 void UICastEventSubscribeProxy::UnSubscribeStartEvent(void)
76 {
77     LOGE("UnSubscribeStartEvent");
78     if (eventReceiver_ != nullptr) {
79         CommonEventManager::UnSubscribeCommonEvent(eventReceiver_);
80         eventReceiver_ = nullptr;
81         uicastEventReceiver_ = nullptr;
82     }
83 }
84 
UICastProxyStart(int castSessionId, UIContent* context)85 void UICastEventSubscriber::UICastProxyStart(int castSessionId, UIContent* context)
86 {
87     if (handle_ == nullptr) {
88         handle_ = dlopen("libace_uicast_proxy.z.so", RTLD_LAZY);
89         if (handle_ == nullptr) {
90             LOGE("dlopen failed: %{public}s", dlerror());
91             return;
92         }
93         LOGI("UICastProxyStart dlopen ok, castSessionId: %{public}d", castSessionId);
94     }
95 
96     auto entry = reinterpret_cast<UICastProxyStartFunc>(dlsym(handle_, UICAST_PROXY_START_FUNC));
97     if (entry == nullptr) {
98         LOGE("find func failed: %{public}s", dlerror());
99         dlclose(handle_);
100         handle_ = nullptr;
101         return;
102     }
103 
104     entry(castSessionId, context);
105     return;
106 }
107 
UICastProxyStop()108 void UICastEventSubscriber::UICastProxyStop()
109 {
110     if (handle_ != nullptr) {
111         LOGI("UICastProxyStop");
112         dlclose(handle_);
113         handle_ = nullptr;
114     }
115     return;
116 }
117 
UICastProxyUpdateContext(UIContent* context)118 void UICastEventSubscriber::UICastProxyUpdateContext(UIContent* context)
119 {
120     if (handle_ == nullptr) {
121         LOGE("handle_ is null");
122         return;
123     }
124     auto entry = reinterpret_cast<UICastProxyUpdateContextFunc>(dlsym(handle_, UICAST_PROXY_UPDATE_CONTEXT_FUNC));
125     if (entry == nullptr) {
126         LOGE("find func failed: %{public}s", dlerror());
127         return;
128     }
129 
130     entry(context);
131     return;
132 }
133 
OnReceiveEvent(const CommonEventData& data)134 void UICastEventSubscriber::OnReceiveEvent(const CommonEventData& data)
135 {
136     auto want = data.GetWant();
137     std::string action = want.GetAction();
138     if (action == COMMON_EVENT_UICAST_START) {
139         int castSessionId = want.GetIntParam(COMMON_EVENT_UICAST_CAST_SESSION_KEY, -1);
140         LOGI("castSessionId: %{public}d", castSessionId);
141         UICastProxyStart(castSessionId, context_);
142     } else if (action == COMMON_EVENT_UICAST_STOP) {
143         LOGI("COMMON_EVENT_UICAST_STOP");
144         UICastProxyStop();
145     }
146 }
147 } // namespace OHOS::Ace
148