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