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