• 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     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