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