1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "interaction_manager.h"
17 #include <future>
18 #include <unistd.h>
19 #include "ability_manager_client.h"
20 #include "common/common_macro.h"
21 #include "common/sharing_log.h"
22 #include "event/event_manager.h"
23 #include "interaction/device_kit/dm_kit.h"
24 #include "interaction/domain/domain_manager.h"
25 #include "interaction/ipc_codec/ipc_msg.h"
26 #include "magic_enum.hpp"
27 #include "utils.h"
28
29 namespace OHOS {
30 namespace Sharing {
31
InteractionManager()32 InteractionManager::InteractionManager()
33 {
34 SHARING_LOGD("trace.");
35 EventManager::GetInstance().AddListener(std::make_shared<InteractionEventListener>());
36 }
37
~InteractionManager()38 InteractionManager::~InteractionManager()
39 {
40 SHARING_LOGD("trace.");
41 std::lock_guard<std::mutex> lock(mutex_);
42 interactions_.clear();
43 sharedFromThis_.reset();
44 }
45
Init()46 void InteractionManager::Init()
47 {
48 SHARING_LOGD("trace.");
49 if (sharedFromThis_ == nullptr) {
50 sharedFromThis_ = Ptr(this, [](InteractionManager *) { SHARING_LOGD("trace."); });
51 }
52 DomainManager::GetInstance()->SetListener(sharedFromThis_);
53 }
54
HandleEvent(SharingEvent & event)55 int32_t InteractionManager::HandleEvent(SharingEvent &event)
56 {
57 SHARING_LOGD("trace.");
58 RETURN_INVALID_IF_NULL(event.eventMsg);
59 SHARING_LOGI("fromMgr: %{public}u, srcId: %{public}u, toMgr: %{public}u, dstId: %{public}u, event: %{public}s.",
60 event.eventMsg->fromMgr, event.eventMsg->srcId, event.eventMsg->toMgr, event.eventMsg->dstId,
61 std::string(magic_enum::enum_name(event.eventMsg->type)).c_str());
62 switch (event.eventMsg->type) {
63 case EVENT_CONFIGURE_INTERACT:
64 break;
65 case EVENT_INTERACTIONMGR_DESTROY_INTERACTION: {
66 auto eventMsg = std::static_pointer_cast<InteractionEventMsg>(event.eventMsg);
67 if (eventMsg) {
68 DestroyInteraction(eventMsg->dstId);
69 } else {
70 SHARING_LOGE("event msg null.");
71 }
72 break;
73 }
74 case EVENT_INTERACTIONMGR_REMOVE_INTERACTION: {
75 auto eventMsg = std::static_pointer_cast<InteractionEventMsg>(event.eventMsg);
76 if (eventMsg) {
77 RemoveInteraction(eventMsg->dstId);
78 } else {
79 SHARING_LOGE("event msg null.");
80 }
81 break;
82 }
83 default: {
84 auto eventMsg = std::static_pointer_cast<InteractionEventMsg>(event.eventMsg);
85 if (eventMsg) {
86 Interaction::Ptr interaction = GetInteraction(eventMsg->dstId);
87 if (interaction) {
88 interaction->HandleEvent(event);
89 } else {
90 SHARING_LOGE("interaction null interactionId: %{public}d.", eventMsg->dstId);
91 }
92 } else {
93 SHARING_LOGE("event msg null.");
94 }
95 break;
96 }
97 }
98
99 return 0;
100 }
101
CreateInteraction(const std::string & className)102 Interaction::Ptr InteractionManager::CreateInteraction(const std::string &className)
103 {
104 SHARING_LOGD("trace.");
105 Interaction::Ptr interaction = std::make_shared<Interaction>();
106 if (interaction->CreateScene(className)) {
107 std::lock_guard<std::mutex> lock(mutex_);
108 interactions_.emplace(interaction->GetId(), interaction);
109 SHARING_LOGI("id: %{public}d size: %{public}zu.", interaction->GetId(), interactions_.size());
110 return interaction;
111 } else {
112 SHARING_LOGE("create scene failed.");
113 return nullptr;
114 }
115 }
116
DestroyInteraction(uint32_t interactionId)117 void InteractionManager::DestroyInteraction(uint32_t interactionId)
118 {
119 SHARING_LOGD("trace.");
120 std::lock_guard<std::mutex> lock(mutex_);
121 auto itr = interactions_.find(interactionId);
122 if (itr != interactions_.end() && itr->second != nullptr) {
123 itr->second->Destroy();
124 }
125 }
126
RemoveInteraction(uint32_t interactionId)127 void InteractionManager::RemoveInteraction(uint32_t interactionId)
128 {
129 SHARING_LOGD("trace.");
130 std::lock_guard<std::mutex> lock(mutex_);
131 auto itr = interactions_.find(interactionId);
132 if (itr != interactions_.end()) {
133 SHARING_LOGI("remove interaction key: %{public}s, id: %{public}u.", itr->second->GetRpcKey().c_str(),
134 interactionId);
135 interactionKeys_.erase(itr->second->GetRpcKey());
136 interactions_.erase(itr);
137 }
138 }
139
GetInteraction(uint32_t interactionId)140 Interaction::Ptr InteractionManager::GetInteraction(uint32_t interactionId)
141 {
142 SHARING_LOGD("trace.");
143 std::lock_guard<std::mutex> lock(mutex_);
144 auto itr = interactions_.find(interactionId);
145 if (itr != interactions_.end()) {
146 return itr->second;
147 }
148
149 return nullptr;
150 }
151
OnDomainMsg(std::shared_ptr<BaseDomainMsg> msg)152 int32_t InteractionManager::OnDomainMsg(std::shared_ptr<BaseDomainMsg> msg)
153 {
154 RETURN_INVALID_IF_NULL(msg);
155 SHARING_LOGD("Finding target key: %{public}s, msgId: %{public}d, pullup app: %{public}d.", msg->toRpcKey.c_str(),
156 msg->GetMsgId(), msg->pullUpApp);
157 if (interactionKeys_.find(msg->toRpcKey) != interactionKeys_.end()) {
158 uint32_t interactionId = GetInteractionId(msg->toRpcKey);
159 Interaction::Ptr interaction = GetInteraction(interactionId);
160 if (interaction) {
161 interaction->OnDomainMsg(msg);
162 } else {
163 SHARING_LOGE("interaction null interactionId: %{public}d.", interactionId);
164 }
165 } else {
166 SHARING_LOGW("interactionKeys_ not find fromDevId: %{public}s.", GetAnonyString(msg->fromDevId).c_str());
167 if (!msg->pullUpApp) {
168 SHARING_LOGW("msgId: %{public}d, don't need to pull up the app.", msg->GetMsgId());
169 return -1;
170 }
171
172 RpcKeyParser parser;
173 parser.ParseKey(msg->toRpcKey);
174 std::string bundleName = parser.GetBundleName();
175 std::string abilityName = parser.GetAbilityName();
176 AAFwk::Want want;
177 AppExecFwk::ElementName element("", bundleName.c_str(), abilityName.c_str());
178 want.SetElement(element);
179 auto ret = AAFwk::AbilityManagerClient::GetInstance()->StartAbility(want);
180 if (ret) {
181 SHARING_LOGE("start app failed, bundleName: %{public}s, abilityName: %{public}s.", bundleName.c_str(),
182 abilityName.c_str());
183 return -1;
184 }
185
186 uint32_t interactionId = 0;
187 uint32_t tryCount = 10;
188 while (tryCount--) {
189 interactionId = GetInteractionId(msg->toRpcKey);
190 if (interactionId != 0) {
191 break;
192 }
193 usleep(300000); // 300000:us
194 }
195
196 Interaction::Ptr interaction = GetInteraction(interactionId);
197 if (interaction) {
198 interaction->OnDomainMsg(msg);
199 } else {
200 SHARING_LOGE("find interaction failed afer app started, key: %{public}s.", msg->toRpcKey.c_str());
201 return -1;
202 }
203 return 0;
204 }
205
206 return 0;
207 }
208
SendDomainMsg(std::shared_ptr<BaseDomainMsg> msg)209 int32_t InteractionManager::SendDomainMsg(std::shared_ptr<BaseDomainMsg> msg)
210 {
211 SHARING_LOGD("trace.");
212 RETURN_INVALID_IF_NULL(msg);
213 std::async(std::launch::async, [this, msg] { DomainManager::GetInstance()->SendDomainRequest(msg->toDevId, msg); });
214
215 return 0;
216 }
217
OnEvent(SharingEvent & event)218 int32_t InteractionEventListener::OnEvent(SharingEvent &event)
219 {
220 SHARING_LOGD("trace.");
221 return InteractionManager::GetInstance().HandleEvent(event);
222 }
223
AddInteractionKey(const std::string & key,uint32_t interactionId)224 void InteractionManager::AddInteractionKey(const std::string &key, uint32_t interactionId)
225 {
226 SHARING_LOGD("trace.");
227 DelInteractionKey(key);
228 std::lock_guard<std::mutex> lock(mutex_);
229 interactionKeys_.emplace(key, interactionId);
230 }
231
DelInteractionKey(const std::string & key)232 void InteractionManager::DelInteractionKey(const std::string &key)
233 {
234 SHARING_LOGD("trace.");
235 std::lock_guard<std::mutex> lock(mutex_);
236 auto itr = interactionKeys_.find(key);
237 if (itr != interactionKeys_.end()) {
238 interactionKeys_.erase(itr);
239 }
240 }
241
GetInteractionId(const std::string & key)242 int32_t InteractionManager::GetInteractionId(const std::string &key)
243 {
244 SHARING_LOGD("trace.");
245 std::lock_guard<std::mutex> lock(mutex_);
246 auto itr = interactionKeys_.find(key);
247 if (itr != interactionKeys_.end()) {
248 return itr->second;
249 }
250
251 return 0;
252 }
253
GetInteraction(const std::string & key)254 Interaction::Ptr InteractionManager::GetInteraction(const std::string &key)
255 {
256 SHARING_LOGD("trace.");
257 std::lock_guard<std::mutex> lock(mutex_);
258 if (interactionKeys_.find(key) != interactionKeys_.end()) {
259 auto itr = interactions_.find(interactionKeys_[key]);
260 if (itr != interactions_.end()) {
261 return itr->second;
262 }
263 }
264
265 return nullptr;
266 }
267
268 } // namespace Sharing
269 } // namespace OHOS