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 "subability_common.h"
17
18 #include "if_system_ability_manager.h"
19 #include "iservice_registry.h"
20 #include "string_ex.h"
21 #include "system_ability_definition.h"
22
23 #include "common_hisysevent.h"
24 #include "common_utils.h"
25 #include "ilocator_service.h"
26 #include "locationhub_ipc_interface_code.h"
27 #include "location_log_event_ids.h"
28 #include "app_identity.h"
29
30 namespace OHOS {
31 namespace Location {
SubAbility()32 SubAbility::SubAbility()
33 {
34 label_ = { LOG_CORE, LOCATION_LOG_DOMAIN, "unknown" };
35 newRecord_ = std::make_unique<WorkRecord>();
36 lastRecord_ = std::make_unique<WorkRecord>();
37 }
38
~SubAbility()39 SubAbility::~SubAbility()
40 {
41 newRecord_ = nullptr;
42 lastRecord_ = nullptr;
43 }
44
SetAbility(std::string name)45 void SubAbility::SetAbility(std::string name)
46 {
47 name_ = name;
48 label_ = CommonUtils::GetLabel(name);
49 capability_ = CommonUtils::GetCapability(name);
50 }
51
StopAllLocationRequests()52 void SubAbility::StopAllLocationRequests()
53 {
54 // When the switch is turned off, all current requests are stopped
55 std::unique_ptr<WorkRecord> emptyRecord = std::make_unique<WorkRecord>();
56 HandleLocalRequest(*emptyRecord);
57 lastRecord_->Clear();
58 }
59
RestartAllLocationRequests()60 void SubAbility::RestartAllLocationRequests()
61 {
62 // When the switch is turned on, all SA requests will be refreshed
63 lastRecord_->Clear();
64 HandleRefrashRequirements();
65 }
66
LocationRequest(WorkRecord & workRecord)67 void SubAbility::LocationRequest(WorkRecord &workRecord)
68 {
69 interval_ = workRecord.GetTimeInterval(0);
70 newRecord_->Clear();
71 newRecord_->Set(workRecord);
72 HandleRefrashRequirements();
73 }
74
HandleRefrashRequirements()75 void SubAbility::HandleRefrashRequirements()
76 {
77 LBSLOGD(label_, "refrash requirements");
78
79 // send local request
80 HandleLocalRequest(*newRecord_);
81 lastRecord_->Clear();
82 lastRecord_->Set(*newRecord_);
83 }
84
GetRequestNum()85 int SubAbility::GetRequestNum()
86 {
87 if (newRecord_ == nullptr) {
88 return 0;
89 }
90 return newRecord_->Size();
91 }
92
HandleLocalRequest(WorkRecord & record)93 void SubAbility::HandleLocalRequest(WorkRecord &record)
94 {
95 HandleRemoveRecord(record);
96 HandleAddRecord(record);
97 }
98
HandleRemoveRecord(WorkRecord & newRecord)99 void SubAbility::HandleRemoveRecord(WorkRecord &newRecord)
100 {
101 for (int i = 0; i < lastRecord_->Size(); i++) {
102 int uid = lastRecord_->GetUid(i);
103 bool isFind = newRecord.Find(uid, lastRecord_->GetName(i), lastRecord_->GetUuid(i));
104 LBSLOGD(label_, "remove record isFind:%{public}d, uid:%{public}d, lastRecord:%{public}s, newRecord:%{public}s",
105 isFind, uid, lastRecord_->ToString().c_str(), newRecord.ToString().c_str());
106 if (!isFind) {
107 std::unique_ptr<WorkRecord> workRecord = std::make_unique<WorkRecord>();
108 workRecord->Add(*lastRecord_, i);
109 workRecord->SetDeviceId(newRecord.GetDeviceId());
110 RequestRecord(*workRecord, false);
111 }
112 }
113 }
114
HandleAddRecord(WorkRecord & newRecord)115 void SubAbility::HandleAddRecord(WorkRecord &newRecord)
116 {
117 for (int i = 0; i < newRecord.Size(); i++) {
118 int uid = newRecord.GetUid(i);
119 bool isFind = lastRecord_->Find(uid, newRecord.GetName(i), newRecord.GetUuid(i));
120 LBSLOGD(label_, "add record isFind:%{public}d, uid:%{public}d, lastRecord:%{public}s, newRecord:%{public}s",
121 isFind, uid, lastRecord_->ToString().c_str(), newRecord.ToString().c_str());
122 if (!isFind) {
123 std::unique_ptr<WorkRecord> workRecord = std::make_unique<WorkRecord>();
124 workRecord->Add(newRecord, i);
125 workRecord->SetDeviceId(newRecord.GetDeviceId());
126 RequestRecord(*workRecord, true);
127 }
128 }
129 }
130
Enable(bool state,const sptr<IRemoteObject> ability)131 void SubAbility::Enable(bool state, const sptr<IRemoteObject> ability)
132 {
133 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
134 if (sam == nullptr) {
135 LBSLOGE(label_, "Enable can not get SystemAbilityManager");
136 return;
137 }
138
139 int saId = CommonUtils::AbilityConvertToId(name_);
140 if (state) {
141 if (sam->CheckSystemAbility(saId) == nullptr) {
142 sam->AddSystemAbility(saId, ability, ISystemAbilityManager::SAExtraProp(false, 1, capability_, u""));
143 LBSLOGI(label_, "enable %{public}s ability", name_.c_str());
144 }
145 } else {
146 if (sam->CheckSystemAbility(saId) != nullptr) {
147 sam->RemoveSystemAbility(saId);
148 LBSLOGI(label_, "disable %{public}s ability", name_.c_str());
149 }
150 }
151 }
152
EnableLocationMock()153 bool SubAbility::EnableLocationMock()
154 {
155 LBSLOGI(label_, "EnableLocationMock current state is %{public}d", mockEnabled_);
156 mockEnabled_ = true;
157 return true;
158 }
159
DisableLocationMock()160 bool SubAbility::DisableLocationMock()
161 {
162 LBSLOGI(label_, "DisableLocationMock current state is %{public}d", mockEnabled_);
163 mockEnabled_ = false;
164 return true;
165 }
166
SetMockedLocations(const int timeInterval,const std::vector<std::shared_ptr<Location>> & location)167 bool SubAbility::SetMockedLocations(const int timeInterval, const std::vector<std::shared_ptr<Location>> &location)
168 {
169 if (!mockEnabled_) {
170 LBSLOGE(label_, "SetMockedLocations current state is %{public}d, need enbale it", mockEnabled_);
171 return false;
172 }
173 CacheLocationMock(location);
174 mockTimeInterval_ = timeInterval;
175 SendReportMockLocationEvent();
176 return true;
177 }
178
CacheLocationMock(const std::vector<std::shared_ptr<Location>> & location)179 void SubAbility::CacheLocationMock(const std::vector<std::shared_ptr<Location>> &location)
180 {
181 int locationSize = static_cast<int>(location.size());
182 ClearLocationMock();
183 std::unique_lock lock(mutex_);
184 for (int i = 0; i < locationSize; i++) {
185 mockLoc_.push_back(std::make_shared<Location>(*location.at(i)));
186 }
187 }
188
IsLocationMocked()189 bool SubAbility::IsLocationMocked()
190 {
191 return mockEnabled_;
192 }
193
GetTimeIntervalMock()194 int SubAbility::GetTimeIntervalMock()
195 {
196 return mockTimeInterval_;
197 }
198
GetLocationMock()199 std::vector<std::shared_ptr<Location>> SubAbility::GetLocationMock()
200 {
201 std::unique_lock lock(mutex_);
202 return mockLoc_;
203 }
204
ClearLocationMock()205 void SubAbility::ClearLocationMock()
206 {
207 std::unique_lock lock(mutex_);
208 mockLoc_.clear();
209 }
210
ReportLocationInfo(const std::string & systemAbility,const std::shared_ptr<Location> location)211 void SubAbility::ReportLocationInfo(const std::string& systemAbility, const std::shared_ptr<Location> location)
212 {
213 sptr<IRemoteObject> objectLocator =
214 CommonUtils::GetRemoteObject(LOCATION_LOCATOR_SA_ID, CommonUtils::InitDeviceId());
215 if (objectLocator == nullptr) {
216 LBSLOGE(label_, "%{public}s get locator sa failed", __func__);
217 return;
218 }
219 sptr<ILocatorService> client = iface_cast<ILocatorService>(objectLocator);
220 if (!client || !client->AsObject()) {
221 LBSLOGE(label_, "%{public}s: get locator service failed.", __func__);
222 return;
223 }
224 client->ReportLocation(systemAbility, *location);
225 }
226
ReportLocationError(int32_t errCode,std::string errMsg,std::string uuid)227 void SubAbility::ReportLocationError(int32_t errCode, std::string errMsg, std::string uuid)
228 {
229 sptr<IRemoteObject> objectLocator =
230 CommonUtils::GetRemoteObject(LOCATION_LOCATOR_SA_ID, CommonUtils::InitDeviceId());
231 if (objectLocator == nullptr) {
232 LBSLOGE(label_, "%{public}s get locator sa failed", __func__);
233 return;
234 }
235 sptr<ILocatorService> client = iface_cast<ILocatorService>(objectLocator);
236 if (!client || !client->AsObject()) {
237 LBSLOGE(label_, "%{public}s: get locator service failed.", __func__);
238 return;
239 }
240 client->ReportLocationError(LOCATING_FAILED_INTERNET_ACCESS_FAILURE, errMsg, uuid);
241 }
242 } // namespace Location
243 } // namespace OHOS
244