• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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