• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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