1 /*
2  * Copyright (c) 2020 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 "ability_connect_mission.h"
17 
18 #include <cstring>
19 
20 #include "util/abilityms_log.h"
21 
22 namespace OHOS {
23 
24 namespace {
25     constexpr static uint16_t SERVICE_RECORDS_LIST_CAPACITY = 10240;
26 }
27 
~AbilityConnectMission()28 AbilityConnectMission::~AbilityConnectMission()
29 {
30     for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end(); ++iterator) {
31         auto record = *iterator;
32         delete record;
33     }
34     serviceRecords_.clear();
35     PRINTD("AbilityConnectMission", "Constructor");
36 }
37 
PushServiceRecord(PageAbilityRecord & abilityRecord)38 void AbilityConnectMission::PushServiceRecord(PageAbilityRecord &abilityRecord)
39 {
40     if (serviceRecords_.size() >= SERVICE_RECORDS_LIST_CAPACITY) {
41         return;
42     }
43     serviceRecords_.emplace_back(&abilityRecord);
44 }
45 
FindServiceRecord(uint64_t token) const46 PageAbilityRecord *AbilityConnectMission::FindServiceRecord(uint64_t token) const
47 {
48     for (const auto record : serviceRecords_) {
49         if (record != nullptr && record->GetToken() == token) {
50             return record;
51         }
52     }
53     return nullptr;
54 }
55 
FindServiceRecord(const char * bundleName,const char * abilityName) const56 PageAbilityRecord *AbilityConnectMission::FindServiceRecord(const char *bundleName, const char *abilityName) const
57 {
58     CHECK_NULLPTR_RETURN_PTR(bundleName, "AbilityConnectMission", "invalid argument");
59     CHECK_NULLPTR_RETURN_PTR(abilityName, "AbilityConnectMission", "invalid argument");
60     for (const auto record : serviceRecords_) {
61         if (record != nullptr) {
62             const char *recordBundleName = record->GetAbilityInfo().bundleName;
63             const char *recordAbilityName = record->GetAbilityInfo().name;
64             if (recordBundleName == nullptr || recordAbilityName == nullptr) {
65                 continue;
66             }
67             if (strcmp(recordBundleName, bundleName) == 0 && strcmp(recordAbilityName, abilityName) == 0) {
68                 return record;
69             }
70         }
71     }
72     return nullptr;
73 }
74 
FindServiceRecord(const SvcIdentity & connectSid,uint64_t abilityToken) const75 PageAbilityRecord *AbilityConnectMission::FindServiceRecord(const SvcIdentity &connectSid, uint64_t abilityToken) const
76 {
77     for (const auto record : serviceRecords_) {
78         if (record != nullptr && record->GetConnectRecord(connectSid, abilityToken) != nullptr) {
79             return record;
80         }
81     }
82     return nullptr;
83 }
84 
RemoveServiceRecord(uint64_t token)85 void AbilityConnectMission::RemoveServiceRecord(uint64_t token)
86 {
87     for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end();) {
88         auto record = *iterator;
89         if (record != nullptr && record->GetToken() == token) {
90             iterator = serviceRecords_.erase(iterator);
91             delete record;
92         } else {
93             ++iterator;
94         }
95     }
96 }
97 
RemoveServiceRecord(const char * bundleName)98 void AbilityConnectMission::RemoveServiceRecord(const char *bundleName)
99 {
100     CHECK_NULLPTR_RETURN(bundleName, "AbilityConnectMission", "invalid argument");
101     for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end();) {
102         auto record = *iterator;
103         if (record != nullptr && record->IsSamePageAbility(bundleName)) {
104             AbilityMsStatus status = record->StopAbilityDone();
105             if (!status.IsOk()) {
106                 PRINTW("RemoveServiceRecord", "service disconnectDoneTransaction failed");
107             }
108             iterator = serviceRecords_.erase(iterator);
109             delete record;
110         } else {
111             ++iterator;
112         }
113     }
114 }
115 
CountServiceInApp(const char * bundleName)116 int32_t AbilityConnectMission::CountServiceInApp(const char *bundleName)
117 {
118     if (bundleName == nullptr) {
119         return 0;
120     }
121     int32_t retVal = 0;
122     for (const auto record : serviceRecords_) {
123         if (record == nullptr) {
124             continue;
125         }
126         if (record->GetAbilityInfo().bundleName != nullptr &&
127             strcmp(record->GetAbilityInfo().bundleName, bundleName) == 0) {
128             retVal++;
129         }
130     }
131     return retVal;
132 }
133 
134 #ifdef OHOS_DEBUG
DumpConnectMission() const135 AbilityMsStatus AbilityConnectMission::DumpConnectMission() const
136 {
137     if (serviceRecords_.empty()) {
138         return AbilityMsStatus::DumpStatus("");
139     }
140     std::string connectInfo = "ConnectMission: \n";
141     AbilityMsStatus result = AbilityMsStatus::DumpStatus(connectInfo.c_str());
142     for (const auto target : serviceRecords_) {
143         if (target != nullptr) {
144             result.DumpAppend(target->DumpAbilityRecord());
145         }
146     }
147     return result;
148 }
149 #endif
150 
RemoveConnectRecordByPageToken(uint64_t token,const char * bundleName)151 void AbilityConnectMission::RemoveConnectRecordByPageToken(uint64_t token, const char *bundleName)
152 {
153     CHECK_NULLPTR_RETURN(bundleName, "AbilityConnectMission", "invalid argument");
154     for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end(); ++iterator) {
155         auto record = *iterator;
156         if (record != nullptr && record->GetAbilityInfo().bundleName != nullptr &&
157             strcmp(record->GetAbilityInfo().bundleName, bundleName) != 0) {
158             record->RemoveConnectRecordByPageToken(token);
159         }
160     }
161 }
162 } // namespace OHOS
163