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 "work_record.h"
17 
18 #include "string_ex.h"
19 
20 namespace OHOS {
21 namespace Location {
22 const int MAX_RECORD_COUNT = 100;
23 
WorkRecord()24 WorkRecord::WorkRecord()
25 {
26     num_ = 0;
27 }
28 
ReadFromParcel(Parcel & parcel)29 void WorkRecord::ReadFromParcel(Parcel& parcel)
30 {
31     int num = parcel.ReadInt32();
32     if (num > MAX_RECORD_COUNT) {
33         num = MAX_RECORD_COUNT;
34     }
35     for (int i = 0; i < num; i++) {
36         int uid = parcel.ReadInt32();
37         int pid = parcel.ReadInt32();
38         std::string name = parcel.ReadString();
39         int timeInterval = parcel.ReadInt32();
40         std::string uuid = parcel.ReadString();
41         int nlpRequestType = parcel.ReadInt32();
42 
43         std::unique_ptr<RequestConfig> requestConfig = std::make_unique<RequestConfig>();
44         requestConfig->SetTimeInterval(timeInterval);
45         std::shared_ptr<Request> request = std::make_shared<Request>();
46         request->SetUid(uid);
47         request->SetPid(pid);
48         request->SetPackageName(name);
49         request->SetRequestConfig(*requestConfig);
50         request->SetUuid(uuid);
51         request->SetNlpRequestType(nlpRequestType);
52         Add(request);
53     }
54     deviceId_ = parcel.ReadString();
55 }
56 
Unmarshalling(Parcel & parcel)57 std::unique_ptr<WorkRecord> WorkRecord::Unmarshalling(Parcel& parcel)
58 {
59     std::unique_ptr<WorkRecord> workRecord = std::make_unique<WorkRecord>();
60     workRecord->ReadFromParcel(parcel);
61     return workRecord;
62 }
63 
Marshalling(Parcel & parcel) const64 bool WorkRecord::Marshalling(Parcel& parcel) const
65 {
66     std::unique_lock<std::mutex> lock(workRecordMutex_);
67     parcel.WriteInt32(num_);
68     for (int i = 0; i < num_; i++) {
69         parcel.WriteInt32(uids_[i]);
70         parcel.WriteInt32(pids_[i]);
71         parcel.WriteString(names_[i]);
72         parcel.WriteInt32(timeInterval_[i]);
73         parcel.WriteString(uuid_[i]);
74         parcel.WriteInt32(nlpRequestType_[i]);
75     }
76     parcel.WriteString(deviceId_);
77     return true;
78 }
79 
MarshallingWorkRecord(Parcel & parcel) const80 bool WorkRecord::MarshallingWorkRecord(Parcel& parcel) const
81 {
82     std::unique_lock<std::mutex> lock(workRecordMutex_);
83     // write numbers
84     parcel.WriteInt32(num_);
85     // write uids
86     parcel.WriteInt32(num_);
87     for (int i = 0; i < num_; i++) {
88         parcel.WriteInt32(uids_[i]);
89     }
90     // write names
91     parcel.WriteInt32(num_);
92     for (int i = 0; i < num_; i++) {
93         parcel.WriteString16(Str8ToStr16(names_[i]));
94     }
95     return true;
96 }
97 
ToString()98 std::string WorkRecord::ToString()
99 {
100     std::unique_lock<std::mutex> lock(workRecordMutex_);
101     std::string result = "[";
102     if (!IsEmpty()) {
103         for (int i = 0; i < num_; i++) {
104             result += std::to_string(uids_[i]);
105             result += ",";
106             result += std::to_string(pids_[i]);
107             result += ",";
108             result += names_[i];
109             result += ",";
110             result += std::to_string(timeInterval_[i]);
111             result += ",";
112             result += uuid_[i];
113             result += "; ";
114         }
115     }
116     result += "]";
117     return result;
118 }
119 
GetName(int index)120 std::string WorkRecord::GetName(int index)
121 {
122     std::unique_lock<std::mutex> lock(workRecordMutex_);
123     if (index >= 0 && index < num_) {
124         return names_[index];
125     }
126     return "";
127 }
128 
GetUid(int index)129 int WorkRecord::GetUid(int index)
130 {
131     std::unique_lock<std::mutex> lock(workRecordMutex_);
132     if (index >= 0 && index < num_) {
133         return uids_[index];
134     }
135     return -1;
136 }
137 
GetPid(int index)138 int WorkRecord::GetPid(int index)
139 {
140     std::unique_lock<std::mutex> lock(workRecordMutex_);
141     if (index >= 0 && index < num_) {
142         return pids_[index];
143     }
144     return -1;
145 }
146 
GetTimeInterval(int index)147 int WorkRecord::GetTimeInterval(int index)
148 {
149     std::unique_lock<std::mutex> lock(workRecordMutex_);
150     if (index >= 0 && index < num_) {
151         return timeInterval_[index];
152     }
153     return -1;
154 }
155 
GetUuid(int index)156 std::string WorkRecord::GetUuid(int index)
157 {
158     std::unique_lock<std::mutex> lock(workRecordMutex_);
159     if (index >= 0 && index < num_) {
160         return uuid_[index];
161     }
162     return "";
163 }
164 
SetDeviceId(std::string deviceId)165 void WorkRecord::SetDeviceId(std::string deviceId)
166 {
167     deviceId_ = deviceId;
168 }
169 
GetDeviceId()170 std::string WorkRecord::GetDeviceId()
171 {
172     return deviceId_;
173 }
174 
Size()175 int WorkRecord::Size()
176 {
177     return num_;
178 }
179 
IsEmpty()180 bool WorkRecord::IsEmpty()
181 {
182     if (num_ == 0) {
183         return true;
184     }
185     return false;
186 }
187 
Add(const std::shared_ptr<Request> & request)188 bool WorkRecord::Add(const std::shared_ptr<Request>& request)
189 {
190     std::unique_lock<std::mutex> lock(workRecordMutex_);
191     uids_.push_back(request->GetUid());
192     pids_.push_back(request->GetPid());
193     names_.push_back(request->GetPackageName());
194     timeInterval_.push_back(request->GetRequestConfig()->GetTimeInterval());
195     uuid_.push_back(request->GetUuid());
196     nlpRequestType_.push_back(request->GetNlpRequestType());
197     num_++;
198     return true;
199 }
200 
Add(WorkRecord & workRecord,int32_t index)201 bool WorkRecord::Add(WorkRecord &workRecord, int32_t index)
202 {
203     std::unique_lock<std::mutex> lock(workRecordMutex_);
204     uids_.push_back(workRecord.GetUid(index));
205     pids_.push_back(workRecord.GetPid(index));
206     names_.push_back(workRecord.GetName(index));
207     timeInterval_.push_back(workRecord.GetTimeInterval(index));
208     uuid_.push_back(workRecord.GetUuid(index));
209     nlpRequestType_.push_back(workRecord.GetNlpRequestType(index));
210     num_++;
211     return true;
212 }
213 
Remove(int uid,int pid,std::string name,std::string uuid)214 bool WorkRecord::Remove(int uid, int pid, std::string name, std::string uuid)
215 {
216     std::unique_lock<std::mutex> lock(workRecordMutex_);
217     if (uids_.size() <= 0) {
218         return false;
219     }
220     unsigned int i = 0;
221     for (auto iterUid = uids_.begin(); iterUid != uids_.end(); iterUid++, i++) {
222         if (*iterUid == uid) {
223             if ((name.compare(names_[i]) == 0) && (uuid.compare(uuid_[i]) == 0)) {
224                 break;
225             }
226         }
227     }
228     if (uids_.size() - i == 0) {
229         return false;
230     }
231     uids_.erase(uids_.begin() + i);
232     pids_.erase(pids_.begin() + i);
233     names_.erase(names_.begin() + i);
234     timeInterval_.erase(timeInterval_.begin() + i);
235     uuid_.erase(uuid_.begin() + i);
236     nlpRequestType_.erase(nlpRequestType_.begin() + i);
237     num_--;
238     return true;
239 }
240 
Remove(std::string name)241 bool WorkRecord::Remove(std::string name)
242 {
243     std::unique_lock<std::mutex> lock(workRecordMutex_);
244     if (uids_.size() <= 0) {
245         return false;
246     }
247     unsigned int i = 0;
248     for (auto iter = names_.begin(); iter != names_.end(); iter++, i++) {
249         if (iter->compare(name) == 0) {
250             break;
251         }
252     }
253     if (names_.size() - i == 0) {
254         return false;
255     }
256     uids_.erase(uids_.begin() + i);
257     pids_.erase(pids_.begin() + i);
258     names_.erase(names_.begin() + i);
259     timeInterval_.erase(timeInterval_.begin() + i);
260     uuid_.erase(uuid_.begin() + i);
261     nlpRequestType_.erase(nlpRequestType_.begin() + i);
262     num_--;
263     return true;
264 }
265 
Find(int uid,std::string name,std::string uuid)266 bool WorkRecord::Find(int uid, std::string name, std::string uuid)
267 {
268     std::unique_lock<std::mutex> lock(workRecordMutex_);
269     if (uids_.size() <= 0) {
270         return false;
271     }
272     int i = 0;
273     for (auto iterUid = uids_.begin(); iterUid != uids_.end(); iterUid++, i++) {
274         if (*iterUid == uid) {
275             if ((name.compare(names_[i]) == 0) && (uuid.compare(uuid_[i]) == 0)) {
276                 return true;
277             }
278         }
279     }
280     return false;
281 }
282 
GetPackageNameByUuid(std::string uuid)283 std::string WorkRecord::GetPackageNameByUuid(std::string uuid)
284 {
285     std::unique_lock<std::mutex> lock(workRecordMutex_);
286     if (uuid_.size() <= 0) {
287         return "";
288     }
289     unsigned i = 0;
290     for (auto iterUuid = uuid_.begin(); iterUuid != uuid_.end(); iterUuid++, i++) {
291         if (uuid.compare(*iterUuid) == 0 && names_.size() > i) {
292             return names_[i];
293         }
294     }
295     return "";
296 }
297 
Clear()298 void WorkRecord::Clear()
299 {
300     std::unique_lock<std::mutex> lock(workRecordMutex_);
301     std::vector<int>().swap(uids_);
302     std::vector<int>().swap(pids_);
303     std::vector<std::string>().swap(names_);
304     std::vector<int>().swap(timeInterval_);
305     std::vector<std::string>().swap(uuid_);
306     std::vector<int>().swap(nlpRequestType_);
307     num_ = 0;
308 }
309 
Set(WorkRecord & workRecord)310 void WorkRecord::Set(WorkRecord &workRecord)
311 {
312     Clear();
313     int num = workRecord.Size();
314     for (int i = 0; i < num; i++) {
315         Add(workRecord, i);
316     }
317 }
318 
GetNlpRequestType(int index)319 int WorkRecord::GetNlpRequestType(int index)
320 {
321     std::unique_lock<std::mutex> lock(workRecordMutex_);
322     if (index >= 0 && index < num_) {
323         return nlpRequestType_[index];
324     }
325     return -1;
326 }
327 } // namespace Location
328 } // namespace OHOS
329