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