1/*
2 * Copyright (C) 2021 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 "time_service_proxy.h"
17
18#include "iremote_broker.h"
19#include "message_option.h"
20#include "time_common.h"
21#include "time_service_ipc_interface_code.h"
22
23namespace OHOS {
24namespace MiscServices {
25using namespace OHOS::HiviewDFX;
26
27TimeServiceProxy::TimeServiceProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<ITimeService>(object)
28{
29}
30
31int32_t TimeServiceProxy::SetTime(int64_t time, APIVersion apiVersion)
32{
33    MessageParcel data, reply;
34    MessageOption option;
35    if (!data.WriteInterfaceToken(GetDescriptor())) {
36        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
37        return E_TIME_WRITE_PARCEL_ERROR;
38    }
39    if (!data.WriteInt64(time)) {
40        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write time");
41        return E_TIME_WRITE_PARCEL_ERROR;
42    }
43    if (!data.WriteInt8(apiVersion)) {
44        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write apiVersion");
45        return E_TIME_WRITE_PARCEL_ERROR;
46    }
47    int32_t result =
48        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::SET_TIME), data, reply, option);
49    if (result != ERR_NONE) {
50        TIME_HILOGE(TIME_MODULE_CLIENT, "SetTime failed, error code is: %{public}d", result);
51        return result;
52    }
53    return result;
54}
55
56int32_t TimeServiceProxy::CreateTimer(const std::shared_ptr<ITimerInfo> &timerOptions,
57    sptr<IRemoteObject> &timerCallback, uint64_t &timerId)
58{
59    MessageParcel data, reply;
60    MessageOption option;
61    if (!data.WriteInterfaceToken(GetDescriptor())) {
62        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
63        return E_TIME_WRITE_PARCEL_ERROR;
64    }
65    if (!data.WriteInt32(timerOptions->type)) {
66        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write type");
67        return E_TIME_WRITE_PARCEL_ERROR;
68    }
69    if (!data.WriteBool(timerOptions->repeat)) {
70        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write repeat");
71        return E_TIME_WRITE_PARCEL_ERROR;
72    }
73    if (!data.WriteBool(timerOptions->disposable)) {
74        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write disposable");
75        return E_TIME_WRITE_PARCEL_ERROR;
76    }
77    if (!data.WriteUint64(timerOptions->interval)) {
78        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write interval");
79        return E_TIME_WRITE_PARCEL_ERROR;
80    }
81    if (!data.WriteBool(timerOptions->wantAgent != nullptr)) {
82        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write wantAgent status");
83        return E_TIME_WRITE_PARCEL_ERROR;
84    }
85    if (timerOptions->wantAgent != nullptr) {
86        if (!data.WriteParcelable(&(*timerOptions->wantAgent))) {
87            TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write wantAgent");
88            return E_TIME_WRITE_PARCEL_ERROR;
89        }
90    }
91    if (!data.WriteRemoteObject(timerCallback)) {
92        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write timerCallback");
93        return E_TIME_WRITE_PARCEL_ERROR;
94    }
95    if (!data.WriteUint64(timerId)) {
96        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write timerId");
97        return E_TIME_WRITE_PARCEL_ERROR;
98    }
99    auto ret =
100        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::CREATE_TIMER), data, reply, option);
101    if (ret == E_TIME_OK) {
102        timerId = reply.ReadUint64();
103        return E_TIME_OK;
104    }
105    return ret;
106}
107
108int32_t TimeServiceProxy::StartTimer(uint64_t timerId, uint64_t triggerTime)
109{
110    MessageParcel data, reply;
111    MessageOption option;
112    if (!data.WriteInterfaceToken(GetDescriptor())) {
113        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
114        return E_TIME_WRITE_PARCEL_ERROR;
115    }
116    if (!data.WriteUint64(timerId)) {
117        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write timerId");
118        return E_TIME_WRITE_PARCEL_ERROR;
119    }
120    if (!data.WriteUint64(triggerTime)) {
121        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write triggerTime");
122        return E_TIME_WRITE_PARCEL_ERROR;
123    }
124    return Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::START_TIMER), data, reply, option);
125}
126
127int32_t TimeServiceProxy::StopTimer(uint64_t timerId)
128{
129    MessageParcel data, reply;
130    MessageOption option;
131    if (!data.WriteInterfaceToken(GetDescriptor())) {
132        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
133        return E_TIME_WRITE_PARCEL_ERROR;
134    }
135    if (!data.WriteUint64(timerId)) {
136        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write timerId");
137        return E_TIME_WRITE_PARCEL_ERROR;
138    }
139    return Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::STOP_TIMER), data, reply, option);
140}
141
142int32_t TimeServiceProxy::DestroyTimer(uint64_t timerId, bool isAsync)
143{
144    MessageParcel data, reply;
145    MessageOption option;
146    if (!data.WriteInterfaceToken(GetDescriptor())) {
147        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
148        return E_TIME_WRITE_PARCEL_ERROR;
149    }
150    if (!data.WriteUint64(timerId)) {
151        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write timerId");
152        return E_TIME_WRITE_PARCEL_ERROR;
153    }
154
155    if (isAsync) {
156        option.SetFlags(MessageOption::TF_ASYNC);
157    }
158    return Remote()->SendRequest(
159        static_cast<uint32_t>(TimeServiceIpcInterfaceCode::DESTROY_TIMER), data, reply, option);
160}
161
162int32_t TimeServiceProxy::SetTimeZone(const std::string &timeZoneId, APIVersion apiVersion)
163{
164    MessageParcel data, reply;
165    MessageOption option;
166    if (!data.WriteInterfaceToken(GetDescriptor())) {
167        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
168        return E_TIME_WRITE_PARCEL_ERROR;
169    }
170    if (!data.WriteString(timeZoneId)) {
171        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write timeZoneId");
172        return E_TIME_WRITE_PARCEL_ERROR;
173    }
174    if (!data.WriteInt8(apiVersion)) {
175        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write apiVersion");
176        return E_TIME_WRITE_PARCEL_ERROR;
177    }
178    int32_t result =
179        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::SET_TIME_ZONE), data, reply, option);
180    if (result != ERR_NONE) {
181        TIME_HILOGE(TIME_MODULE_CLIENT, "SetTimeZone failed, error code is: %{public}d", result);
182        return result;
183    }
184    return result;
185}
186
187int32_t TimeServiceProxy::GetTimeZone(std::string &timeZoneId)
188{
189    MessageParcel data, reply;
190    MessageOption option;
191    if (!data.WriteInterfaceToken(GetDescriptor())) {
192        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
193        return E_TIME_WRITE_PARCEL_ERROR;
194    }
195    int32_t result =
196        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::GET_TIME_ZONE), data, reply, option);
197    if (result != ERR_NONE) {
198        TIME_HILOGE(TIME_MODULE_CLIENT, "GetTimeZone failed, error code is: %{public}d", result);
199        return result;
200    }
201    timeZoneId = reply.ReadString();
202    return result;
203}
204
205int32_t TimeServiceProxy::GetThreadTimeMs(int64_t &times)
206{
207    MessageParcel data, reply;
208    MessageOption option;
209    if (!data.WriteInterfaceToken(GetDescriptor())) {
210        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
211        return E_TIME_WRITE_PARCEL_ERROR;
212    }
213    int32_t result = Remote()->SendRequest(
214        static_cast<uint32_t>(TimeServiceIpcInterfaceCode::GET_THREAD_TIME_MILLI), data, reply, option);
215    if (result != ERR_NONE) {
216        TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeMs failed, error code is: %{public}d", result);
217        return result;
218    }
219    times = reply.ReadInt64();
220    return result;
221}
222
223int32_t TimeServiceProxy::GetThreadTimeNs(int64_t &times)
224{
225    MessageParcel data, reply;
226    MessageOption option;
227    if (!data.WriteInterfaceToken(GetDescriptor())) {
228        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
229        return E_TIME_WRITE_PARCEL_ERROR;
230    }
231    int32_t result = Remote()->SendRequest(
232        static_cast<uint32_t>(TimeServiceIpcInterfaceCode::GET_THREAD_TIME_NANO), data, reply, option);
233    if (result != ERR_NONE) {
234        TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeNs failed, error code is: %{public}d", result);
235        return result;
236    }
237    times = reply.ReadInt64();
238    return result;
239}
240
241bool TimeServiceProxy::ProxyTimer(int32_t uid, bool isProxy, bool needRetrigger)
242{
243    MessageParcel data, reply;
244    MessageOption option;
245    if (!data.WriteInterfaceToken(GetDescriptor())) {
246        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
247        return false;
248    }
249    if (!data.WriteInt32(uid)) {
250        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write uid");
251        return false;
252    }
253    if (!data.WriteBool(isProxy)) {
254        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write isProxy");
255        return false;
256    }
257    if (!data.WriteBool(needRetrigger)) {
258        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write needRetrigger");
259        return false;
260    }
261
262    int32_t result =
263        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::PROXY_TIMER), data, reply, option);
264    if (result != ERR_NONE) {
265        TIME_HILOGE(TIME_MODULE_CLIENT, "ProxyTimer failed, error code is: %{public}d", result);
266        return false;
267    }
268    return true;
269}
270
271bool TimeServiceProxy::ProxyTimer(std::set<int> pidList, bool isProxy, bool needRetrigger)
272{
273    MessageParcel data, reply;
274    MessageOption option;
275    if (!data.WriteInterfaceToken(GetDescriptor())) {
276        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
277        return false;
278    }
279    if (!data.WriteInt32(pidList.size())) {
280        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write pid size");
281        return false;
282    }
283    for (std::set<int>::iterator pid = pidList.begin(); pid != pidList.end(); ++pid) {
284        if (!data.WriteInt32(*pid)) {
285            TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write pid");
286            return false;
287        }
288    }
289    if (!data.WriteBool(isProxy)) {
290        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write isProxy");
291        return false;
292    }
293    if (!data.WriteBool(needRetrigger)) {
294        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write needRetrigger");
295        return false;
296    }
297
298    int32_t result =
299        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::PID_PROXY_TIMER), data, reply, option);
300    if (result != ERR_NONE) {
301        TIME_HILOGE(TIME_MODULE_CLIENT, "ProxyTimer failed, error code is: %{public}d", result);
302        return false;
303    }
304    return true;
305}
306
307int32_t TimeServiceProxy::AdjustTimer(bool isAdjust, uint32_t interval)
308{
309    MessageParcel data;
310    MessageParcel reply;
311    MessageOption option;
312    if (!data.WriteInterfaceToken(GetDescriptor())) {
313        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
314        return E_TIME_WRITE_PARCEL_ERROR;
315    }
316    if (!data.WriteBool(isAdjust)) {
317        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write adjust state");
318        return E_TIME_WRITE_PARCEL_ERROR;
319    }
320    if (!data.WriteUint32(interval)) {
321        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write interval");
322        return E_TIME_WRITE_PARCEL_ERROR;
323    }
324    int32_t result =
325        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::ADJUST_TIMER), data, reply, option);
326    if (result != ERR_NONE) {
327        TIME_HILOGE(TIME_MODULE_CLIENT, "Adjust Timer failed, error code is: %{public}d", result);
328        return result;
329    }
330    return result;
331}
332
333int32_t TimeServiceProxy::SetTimerExemption(const std::unordered_set<std::string> &nameArr, bool isExemption)
334{
335    MessageParcel data;
336    MessageParcel reply;
337    MessageOption option;
338    if (!data.WriteInterfaceToken(GetDescriptor())) {
339        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
340        return E_TIME_WRITE_PARCEL_ERROR;
341    }
342
343    if (nameArr.empty()) {
344        TIME_HILOGE(TIME_MODULE_CLIENT, "Nothing need cache");
345        return E_TIME_NOT_FOUND;
346    }
347
348    uint32_t size = static_cast<uint32_t>(nameArr.size());
349    if (!data.WriteUint32(size)) {
350        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write size");
351        return E_TIME_WRITE_PARCEL_ERROR;
352    }
353
354    for (auto name : nameArr) {
355        if (!data.WriteString(name)) {
356            TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write name");
357            return E_TIME_WRITE_PARCEL_ERROR;
358        }
359    }
360
361    if (!data.WriteBool(isExemption)) {
362        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write is exemption");
363        return E_TIME_WRITE_PARCEL_ERROR;
364    }
365
366    int32_t result =
367        Remote()->SendRequest(static_cast<uint32_t>(TimeServiceIpcInterfaceCode::SET_TIMER_EXEMPTION),
368            data, reply, option);
369    if (result != ERR_NONE) {
370        TIME_HILOGE(TIME_MODULE_CLIENT, "Set Timer Exemption failed, error code is: %{public}d", result);
371        return result;
372    }
373    return result;
374}
375
376bool TimeServiceProxy::ResetAllProxy()
377{
378    MessageParcel data, reply;
379    MessageOption option;
380    if (!data.WriteInterfaceToken(GetDescriptor())) {
381        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
382        return false;
383    }
384    int32_t result = Remote()->SendRequest(
385        static_cast<uint32_t>(TimeServiceIpcInterfaceCode::RESET_ALL_PROXY), data, reply, option);
386    if (result != ERR_NONE) {
387        TIME_HILOGE(TIME_MODULE_CLIENT, "ProxyTimer failed, error code is: %{public}d", result);
388        return false;
389    }
390    return true;
391}
392
393int32_t TimeServiceProxy::GetNtpTimeMs(int64_t &time)
394{
395    MessageParcel data;
396    MessageParcel reply;
397    MessageOption option;
398    if (!data.WriteInterfaceToken(GetDescriptor())) {
399        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
400        return E_TIME_WRITE_PARCEL_ERROR;
401    }
402    int32_t result = Remote()->SendRequest(
403        static_cast<uint32_t>(TimeServiceIpcInterfaceCode::GET_NTP_TIME_MILLI), data, reply, option);
404    if (result != ERR_NONE) {
405        TIME_HILOGE(TIME_MODULE_CLIENT, "GetNtpTimeMs failed, error code is: %{public}d", result);
406        return result;
407    }
408    time = reply.ReadInt64();
409    return result;
410}
411
412int32_t TimeServiceProxy::GetRealTimeMs(int64_t &time)
413{
414    MessageParcel data;
415    MessageParcel reply;
416    MessageOption option;
417    if (!data.WriteInterfaceToken(GetDescriptor())) {
418        TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor");
419        return E_TIME_WRITE_PARCEL_ERROR;
420    }
421    int32_t result = Remote()->SendRequest(
422        static_cast<uint32_t>(TimeServiceIpcInterfaceCode::GET_REAL_TIME_MILLI), data, reply, option);
423    if (result != ERR_NONE) {
424        TIME_HILOGE(TIME_MODULE_CLIENT, "GetRealTimeMs failed, error code is: %{public}d", result);
425        return result;
426    }
427    time = reply.ReadInt64();
428    return result;
429}
430} // namespace MiscServices
431} // namespace OHOS