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