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