• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "connection_state_item.h"
17 
18 #include "hilog_wrapper.h"
19 
20 namespace OHOS {
21 namespace AAFwk {
22 /**
23  * @class ConnectedExtension
24  * ConnectedExtension,This class is used to record a connected extension.
25  */
26 class ConnectedExtension : public std::enable_shared_from_this<ConnectedExtension> {
27 public:
CreateConnectedExtension(const std::shared_ptr<ConnectionRecord> & record)28     static std::shared_ptr<ConnectedExtension> CreateConnectedExtension(const std::shared_ptr<ConnectionRecord> &record)
29     {
30         if (!record) {
31             return nullptr;
32         }
33 
34         auto targetExtension = record->GetAbilityRecord();
35         if (!targetExtension) {
36             return nullptr;
37         }
38 
39         return std::make_shared<ConnectedExtension>(targetExtension);
40     }
41 
ConnectedExtension()42     ConnectedExtension()
43     {
44         extensionType_ = AppExecFwk::ExtensionAbilityType::UNSPECIFIED;
45     }
46 
ConnectedExtension(const std::shared_ptr<AbilityRecord> & target)47     explicit ConnectedExtension(const std::shared_ptr<AbilityRecord> &target)
48     {
49         if (!target) {
50             return;
51         }
52         extensionPid_ = target->GetPid();
53         extensionUid_ = target->GetUid();
54         extensionBundleName_ = target->GetAbilityInfo().bundleName;
55         extensionModuleName_ = target->GetAbilityInfo().moduleName;
56         extensionName_ = target->GetAbilityInfo().name;
57         extensionType_ = target->GetAbilityInfo().extensionAbilityType;
58     }
59 
60     virtual ~ConnectedExtension() = default;
61 
AddConnection(const sptr<IRemoteObject> & connection)62     bool AddConnection(const sptr<IRemoteObject> &connection)
63     {
64         if (!connection) {
65             return false;
66         }
67 
68         bool needNotify = connections_.empty();
69         connections_.emplace(connection);
70 
71         return needNotify;
72     }
73 
RemoveConnection(const sptr<IRemoteObject> & connection)74     bool RemoveConnection(const sptr<IRemoteObject> &connection)
75     {
76         if (!connection) {
77             return false;
78         }
79 
80         connections_.erase(connection);
81         return connections_.empty();
82     }
83 
GenerateExtensionInfo(AbilityRuntime::ConnectionData & data)84     void GenerateExtensionInfo(AbilityRuntime::ConnectionData &data)
85     {
86         data.extensionPid = extensionPid_;
87         data.extensionUid = extensionUid_;
88         data.extensionBundleName = extensionBundleName_;
89         data.extensionModuleName = extensionModuleName_;
90         data.extensionName = extensionName_;
91         data.extensionType = extensionType_;
92     }
93 
94 private:
95     int32_t extensionPid_ = 0;
96     int32_t extensionUid_ = 0;
97     std::string extensionBundleName_;
98     std::string extensionModuleName_;
99     std::string extensionName_;
100     AppExecFwk::ExtensionAbilityType extensionType_;
101     std::set<sptr<IRemoteObject>> connections_; // remote object of IAbilityConnection
102 };
103 
104 /**
105  * @class ConnectedDataAbility
106  * ConnectedDataAbility,This class is used to record a connected data ability.
107  */
108 class ConnectedDataAbility : public std::enable_shared_from_this<ConnectedDataAbility> {
109 public:
CreateConnectedDataAbility(const std::shared_ptr<DataAbilityRecord> & record)110     static std::shared_ptr<ConnectedDataAbility> CreateConnectedDataAbility(
111         const std::shared_ptr<DataAbilityRecord> &record)
112     {
113         if (!record) {
114             return nullptr;
115         }
116 
117         auto targetAbility = record->GetAbilityRecord();
118         if (!targetAbility) {
119             return nullptr;
120         }
121 
122         return std::make_shared<ConnectedDataAbility>(targetAbility);
123     }
124 
ConnectedDataAbility()125     ConnectedDataAbility() {}
126 
ConnectedDataAbility(const std::shared_ptr<AbilityRecord> & target)127     explicit ConnectedDataAbility(const std::shared_ptr<AbilityRecord> &target)
128     {
129         if (!target) {
130             return;
131         }
132 
133         dataAbilityPid_ = target->GetPid();
134         dataAbilityUid_ = target->GetUid();
135         bundleName_ = target->GetAbilityInfo().bundleName;
136         moduleName_ = target->GetAbilityInfo().moduleName;
137         abilityName_ = target->GetAbilityInfo().name;
138     }
139 
140     virtual ~ConnectedDataAbility() = default;
141 
AddCaller(const DataAbilityCaller & caller)142     bool AddCaller(const DataAbilityCaller &caller)
143     {
144         if (!caller.isNotHap && !caller.callerToken) {
145             return false;
146         }
147 
148         bool needNotify = callers_.empty();
149         auto it = find_if(callers_.begin(), callers_.end(), [&caller](const std::shared_ptr<CallerInfo> &info) {
150             if (caller.isNotHap) {
151                 return info && info->IsNotHap() && info->GetCallerPid() == caller.callerPid;
152             } else {
153                 return info && info->GetCallerToken() == caller.callerToken;
154             }
155         });
156         if (it == callers_.end()) {
157             callers_.emplace_back(std::make_shared<CallerInfo>(caller.isNotHap, caller.callerPid, caller.callerToken));
158         }
159 
160         return needNotify;
161     }
162 
RemoveCaller(const DataAbilityCaller & caller)163     bool RemoveCaller(const DataAbilityCaller &caller)
164     {
165         if (!caller.isNotHap && !caller.callerToken) {
166             return false;
167         }
168 
169         auto it = find_if(callers_.begin(), callers_.end(), [&caller](const std::shared_ptr<CallerInfo> &info) {
170             if (caller.isNotHap) {
171                 return info && info->IsNotHap() && info->GetCallerPid() == caller.callerPid;
172             } else {
173                 return info && info->GetCallerToken() == caller.callerToken;
174             }
175         });
176         if (it != callers_.end()) {
177             callers_.erase(it);
178         }
179 
180         return callers_.empty();
181     }
182 
GenerateExtensionInfo(AbilityRuntime::ConnectionData & data)183     void GenerateExtensionInfo(AbilityRuntime::ConnectionData &data)
184     {
185         data.extensionPid = dataAbilityPid_;
186         data.extensionUid = dataAbilityUid_;
187         data.extensionBundleName = bundleName_;
188         data.extensionModuleName = moduleName_;
189         data.extensionName = abilityName_;
190         data.extensionType = AppExecFwk::ExtensionAbilityType::DATASHARE;
191     }
192 
193 private:
194     class CallerInfo : public std::enable_shared_from_this<CallerInfo> {
195     public:
CallerInfo(bool isNotHap,int32_t callerPid,const sptr<IRemoteObject> & callerToken)196         CallerInfo(bool isNotHap, int32_t callerPid, const sptr<IRemoteObject> &callerToken)
197             : isNotHap_(isNotHap), callerPid_(callerPid), callerToken_(callerToken) {}
198 
IsNotHap() const199         bool IsNotHap() const
200         {
201             return isNotHap_;
202         }
203 
GetCallerPid() const204         int32_t GetCallerPid() const
205         {
206             return callerPid_;
207         }
208 
GetCallerToken() const209         sptr<IRemoteObject> GetCallerToken() const
210         {
211             return callerToken_;
212         }
213 
214     private:
215         bool isNotHap_ = false;
216         int32_t callerPid_ = 0;
217         sptr<IRemoteObject> callerToken_ = nullptr;
218     };
219 
220     int32_t dataAbilityPid_ = 0;
221     int32_t dataAbilityUid_ = 0;
222     std::string bundleName_;
223     std::string moduleName_;
224     std::string abilityName_;
225     std::list<std::shared_ptr<CallerInfo>> callers_; // caller infos of this data ability.
226 };
227 
ConnectionStateItem(int32_t callerUid,int32_t callerPid,const std::string & callerName)228 ConnectionStateItem::ConnectionStateItem(int32_t callerUid, int32_t callerPid, const std::string &callerName)
229     : callerUid_(callerUid), callerPid_(callerPid), callerName_(callerName)
230 {
231 }
232 
~ConnectionStateItem()233 ConnectionStateItem::~ConnectionStateItem()
234 {}
235 
CreateConnectionStateItem(const std::shared_ptr<ConnectionRecord> & record)236 std::shared_ptr<ConnectionStateItem> ConnectionStateItem::CreateConnectionStateItem(
237     const std::shared_ptr<ConnectionRecord> &record)
238 {
239     if (!record) {
240         return nullptr;
241     }
242 
243     return std::make_shared<ConnectionStateItem>(record->GetCallerUid(),
244         record->GetCallerPid(), record->GetCallerName());
245 }
246 
CreateConnectionStateItem(const DataAbilityCaller & dataCaller)247 std::shared_ptr<ConnectionStateItem> ConnectionStateItem::CreateConnectionStateItem(
248     const DataAbilityCaller &dataCaller)
249 {
250     return std::make_shared<ConnectionStateItem>(dataCaller.callerUid,
251         dataCaller.callerPid, dataCaller.callerName);
252 }
253 
AddConnection(const std::shared_ptr<ConnectionRecord> & record,AbilityRuntime::ConnectionData & data)254 bool ConnectionStateItem::AddConnection(const std::shared_ptr<ConnectionRecord> &record,
255     AbilityRuntime::ConnectionData &data)
256 {
257     if (!record) {
258         HILOG_ERROR("AddConnection, invalid connection record.");
259         return false;
260     }
261 
262     auto token = record->GetTargetToken();
263     if (!token) {
264         HILOG_ERROR("AddConnection, invalid token.");
265         return false;
266     }
267 
268     sptr<IRemoteObject> connectionObj = record->GetConnection();
269     if (!connectionObj) {
270         HILOG_ERROR("AddConnection, no connection callback for this connect.");
271         return false;
272     }
273 
274     std::shared_ptr<ConnectedExtension> connectedExtension = nullptr;
275     auto it = connectionMap_.find(token);
276     if (it == connectionMap_.end()) {
277         connectedExtension = ConnectedExtension::CreateConnectedExtension(record);
278         if (connectedExtension) {
279             connectionMap_[token] = connectedExtension;
280         }
281     } else {
282         connectedExtension = it->second;
283     }
284 
285     if (!connectedExtension) {
286         HILOG_ERROR("AddConnection, connectedExtension is invalid");
287         return false;
288     }
289 
290     bool needNotify = connectedExtension->AddConnection(connectionObj);
291     if (needNotify) {
292         GenerateConnectionData(connectedExtension, data);
293     }
294 
295     return needNotify;
296 }
297 
RemoveConnection(const std::shared_ptr<ConnectionRecord> & record,AbilityRuntime::ConnectionData & data)298 bool ConnectionStateItem::RemoveConnection(const std::shared_ptr<ConnectionRecord> &record,
299     AbilityRuntime::ConnectionData &data)
300 {
301     if (!record) {
302         HILOG_ERROR("RemoveConnection, invalid connection record.");
303         return false;
304     }
305 
306     auto token = record->GetTargetToken();
307     if (!token) {
308         HILOG_ERROR("RemoveConnection, invalid token.");
309         return false;
310     }
311 
312     sptr<IRemoteObject> connectionObj = record->GetConnection();
313     if (!connectionObj) {
314         HILOG_ERROR("RemoveConnection, no connection callback for this connect.");
315         return false;
316     }
317 
318     auto it = connectionMap_.find(token);
319     if (it == connectionMap_.end()) {
320         HILOG_ERROR("RemoveConnection, no such connectedExtension.");
321         return false;
322     }
323 
324     auto connectedExtension = it->second;
325     if (!connectedExtension) {
326         HILOG_ERROR("RemoveConnection, can not find such connectedExtension");
327         return false;
328     }
329 
330     bool needNotify = connectedExtension->RemoveConnection(connectionObj);
331     if (needNotify) {
332         connectionMap_.erase(it);
333         GenerateConnectionData(connectedExtension, data);
334     }
335 
336     return needNotify;
337 }
338 
AddDataAbilityConnection(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & dataAbility,AbilityRuntime::ConnectionData & data)339 bool ConnectionStateItem::AddDataAbilityConnection(const DataAbilityCaller &caller,
340     const std::shared_ptr<DataAbilityRecord> &dataAbility, AbilityRuntime::ConnectionData &data)
341 {
342     if (!dataAbility) {
343         HILOG_ERROR("invalid dataAbility.");
344         return false;
345     }
346 
347     auto token = dataAbility->GetToken();
348     if (!token) {
349         HILOG_ERROR("invalid dataAbility token.");
350         return false;
351     }
352 
353     std::shared_ptr<ConnectedDataAbility> connectedAbility = nullptr;
354     auto it = dataAbilityMap_.find(token);
355     if (it == dataAbilityMap_.end()) {
356         connectedAbility = ConnectedDataAbility::CreateConnectedDataAbility(dataAbility);
357         if (connectedAbility) {
358             dataAbilityMap_[token] = connectedAbility;
359         }
360     } else {
361         connectedAbility = it->second;
362     }
363 
364     if (!connectedAbility) {
365         HILOG_ERROR("connectedAbility is invalid");
366         return false;
367     }
368 
369     bool needNotify = connectedAbility->AddCaller(caller);
370     if (needNotify) {
371         GenerateConnectionData(connectedAbility, data);
372     }
373 
374     return needNotify;
375 }
376 
RemoveDataAbilityConnection(const DataAbilityCaller & caller,const std::shared_ptr<DataAbilityRecord> & dataAbility,AbilityRuntime::ConnectionData & data)377 bool ConnectionStateItem::RemoveDataAbilityConnection(const DataAbilityCaller &caller,
378     const std::shared_ptr<DataAbilityRecord> &dataAbility, AbilityRuntime::ConnectionData &data)
379 {
380     if (!dataAbility) {
381         HILOG_ERROR("RemoveDataAbilityConnection, invalid data ability record.");
382         return false;
383     }
384 
385     auto token = dataAbility->GetToken();
386     if (!token) {
387         HILOG_ERROR("RemoveDataAbilityConnection, invalid data ability token.");
388         return false;
389     }
390 
391     auto it = dataAbilityMap_.find(token);
392     if (it == dataAbilityMap_.end()) {
393         HILOG_ERROR("RemoveDataAbilityConnection, no such connected data ability.");
394         return false;
395     }
396 
397     auto connectedDataAbility = it->second;
398     if (!connectedDataAbility) {
399         HILOG_ERROR("RemoveDataAbilityConnection, can not find such connectedDataAbility");
400         return false;
401     }
402 
403     bool needNotify = connectedDataAbility->RemoveCaller(caller);
404     if (needNotify) {
405         dataAbilityMap_.erase(it);
406         GenerateConnectionData(connectedDataAbility, data);
407     }
408 
409     return needNotify;
410 }
411 
HandleDataAbilityDied(const sptr<IRemoteObject> & token,AbilityRuntime::ConnectionData & data)412 bool ConnectionStateItem::HandleDataAbilityDied(const sptr<IRemoteObject> &token,
413     AbilityRuntime::ConnectionData &data)
414 {
415     if (!token) {
416         return false;
417     }
418 
419     auto it = dataAbilityMap_.find(token);
420     if (it == dataAbilityMap_.end()) {
421         HILOG_ERROR("HandleDataAbilityDied, no such connected data ability.");
422         return false;
423     }
424 
425     auto connectedDataAbility = it->second;
426     if (!connectedDataAbility) {
427         HILOG_ERROR("HandleDataAbilityDied, can not find such connectedDataAbility");
428         return false;
429     }
430 
431     dataAbilityMap_.erase(it);
432     GenerateConnectionData(connectedDataAbility, data);
433     return true;
434 }
435 
IsEmpty() const436 bool ConnectionStateItem::IsEmpty() const
437 {
438     return connectionMap_.empty() && dataAbilityMap_.empty();
439 }
440 
GenerateAllConnectionData(std::vector<AbilityRuntime::ConnectionData> & datas)441 void ConnectionStateItem::GenerateAllConnectionData(std::vector<AbilityRuntime::ConnectionData> &datas)
442 {
443     AbilityRuntime::ConnectionData data;
444     for (auto it = connectionMap_.begin(); it != connectionMap_.end(); ++it) {
445         GenerateConnectionData(it->second, data);
446         datas.emplace_back(data);
447     }
448 
449     for (auto it = dataAbilityMap_.begin(); it != dataAbilityMap_.end(); ++it) {
450         GenerateConnectionData(it->second, data);
451         datas.emplace_back(data);
452     }
453 }
454 
GenerateConnectionData(const std::shared_ptr<ConnectedExtension> & connectedExtension,AbilityRuntime::ConnectionData & data)455 void ConnectionStateItem::GenerateConnectionData(
456     const std::shared_ptr<ConnectedExtension> &connectedExtension, AbilityRuntime::ConnectionData &data)
457 {
458     if (connectedExtension) {
459         connectedExtension->GenerateExtensionInfo(data);
460     }
461     data.callerUid = callerUid_;
462     data.callerPid = callerPid_;
463     data.callerName = callerName_;
464 }
465 
GenerateConnectionData(const std::shared_ptr<ConnectedDataAbility> & connectedDataAbility,AbilityRuntime::ConnectionData & data)466 void ConnectionStateItem::GenerateConnectionData(const std::shared_ptr<ConnectedDataAbility> &connectedDataAbility,
467     AbilityRuntime::ConnectionData &data)
468 {
469     if (connectedDataAbility) {
470         connectedDataAbility->GenerateExtensionInfo(data);
471     }
472     data.callerUid = callerUid_;
473     data.callerPid = callerPid_;
474     data.callerName = callerName_;
475 }
476 }  // namespace AAFwk
477 }  // namespace OHOS
478