From faa58615e777034f8729448586cb07c90d90ebdf Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Wed, 1 Sep 2021 15:29:24 +0800 Subject: [PATCH 1/5] xuyanjun27@163.com Signed-off-by: guduhanyan --- BUILD.gn | 3 +- README.md | 3 +- README_zh.md | 1 + etc/init/timeservice.cfg | 2 +- etc/init/timeservice.rc | 2 +- interfaces/innerkits/include/itimer_info.h | 78 ++ .../innerkits/include/time_service_client.h | 187 +++++ .../js/declaration/api/@ohos.systemTime.d.ts | 23 +- .../js/declaration/api/@ohos.systemTimer.d.ts | 116 +++ interfaces/kits/js/napi/js_systemtime.cpp | 142 ---- .../kits/js/napi/{ => system_time}/BUILD.gn | 14 +- .../napi/system_time/include/js_systemtime.h | 53 ++ .../js/napi/system_time/src/js_systemtime.cpp | 230 ++++++ interfaces/kits/js/napi/system_timer/BUILD.gn | 70 ++ .../napi/system_timer/include/system_timer.h | 56 ++ .../js/napi/system_timer/include/timer_type.h | 28 + .../kits/js/napi/system_timer/src/init.cpp | 61 ++ .../js/napi/system_timer/src/system_timer.cpp | 747 ++++++++++++++++++ .../js/napi/system_timer/src/timer_type.cpp | 45 ++ ohos.build | 2 +- services/BUILD.gn | 48 +- services/include/time_log.h | 76 -- services/include/time_service.h | 60 -- services/include/time_service_manager.h | 51 -- services/src/time_service.cpp | 142 ---- services/src/time_service_manager.cpp | 103 --- services/src/time_service_proxy.cpp | 46 -- services/src/time_service_stub.cpp | 60 -- services/test/unittest/time_service_test.cpp | 59 -- .../time_manager/include/itimer_call_back.h | 45 ++ services/time_manager/include/time_service.h | 100 +++ .../include/time_service_interface.h | 174 ++++ .../include/time_service_notify.h | 49 ++ .../include/time_service_proxy.h | 85 +- .../time_manager/include/time_service_stub.h | 57 ++ .../time_manager/include/time_zone_info.h | 54 ++ .../time_manager/include/timer_call_back.h | 61 ++ .../include/timer_call_back_proxy.h | 42 + .../include/timer_call_back_stub.h | 39 + .../src/itimer_info.cpp} | 66 +- services/time_manager/src/time_service.cpp | 611 ++++++++++++++ .../time_manager/src/time_service_client.cpp | 401 ++++++++++ .../time_manager/src/time_service_notify.cpp | 68 ++ .../time_manager/src/time_service_proxy.cpp | 356 +++++++++ .../time_manager/src/time_service_stub.cpp | 295 +++++++ services/time_manager/src/time_zone_info.cpp | 97 +++ services/time_manager/src/timer_call_back.cpp | 103 +++ .../src/timer_call_back_proxy.cpp | 61 ++ .../time_manager/src/timer_call_back_stub.cpp | 53 ++ services/{ => time_manager}/test/BUILD.gn | 38 +- .../test/unittest/include/timer_test.h | 88 +++ .../test/unittest/src/time_service_test.cpp | 362 +++++++++ services/timer/include/batch.h | 57 ++ services/timer/include/timer_handler.h | 57 ++ services/timer/include/timer_info.h | 66 ++ services/timer/include/timer_manager.h | 104 +++ .../timer/include/timer_manager_interface.h | 64 ++ services/timer/src/batch.cpp | 149 ++++ services/timer/src/timer_handler.cpp | 146 ++++ services/timer/src/timer_info.cpp | 56 ++ services/timer/src/timer_manager.cpp | 487 ++++++++++++ time.gni | 11 +- utils/BUILD.gn | 51 ++ .../mock/include/mock_permission.h | 65 +- utils/mock/src/mock_permission.cpp | 29 + .../native}/include/time_common.h | 90 ++- utils/native/include/time_hilog_wreapper.h | 76 ++ utils/native/include/time_permission.h | 48 ++ utils/native/include/time_rdb_handler.h | 103 +++ utils/native/src/time_permission.cpp | 88 +++ 70 files changed, 6652 insertions(+), 908 deletions(-) create mode 100644 interfaces/innerkits/include/itimer_info.h create mode 100644 interfaces/innerkits/include/time_service_client.h create mode 100644 interfaces/kits/js/declaration/api/@ohos.systemTimer.d.ts delete mode 100755 interfaces/kits/js/napi/js_systemtime.cpp rename interfaces/kits/js/napi/{ => system_time}/BUILD.gn (70%) mode change 100755 => 100644 create mode 100644 interfaces/kits/js/napi/system_time/include/js_systemtime.h create mode 100644 interfaces/kits/js/napi/system_time/src/js_systemtime.cpp create mode 100644 interfaces/kits/js/napi/system_timer/BUILD.gn create mode 100644 interfaces/kits/js/napi/system_timer/include/system_timer.h create mode 100644 interfaces/kits/js/napi/system_timer/include/timer_type.h create mode 100644 interfaces/kits/js/napi/system_timer/src/init.cpp create mode 100644 interfaces/kits/js/napi/system_timer/src/system_timer.cpp create mode 100644 interfaces/kits/js/napi/system_timer/src/timer_type.cpp delete mode 100755 services/include/time_log.h delete mode 100755 services/include/time_service.h delete mode 100755 services/include/time_service_manager.h delete mode 100755 services/src/time_service.cpp delete mode 100755 services/src/time_service_manager.cpp delete mode 100755 services/src/time_service_proxy.cpp delete mode 100755 services/src/time_service_stub.cpp delete mode 100755 services/test/unittest/time_service_test.cpp create mode 100644 services/time_manager/include/itimer_call_back.h create mode 100644 services/time_manager/include/time_service.h create mode 100644 services/time_manager/include/time_service_interface.h create mode 100644 services/time_manager/include/time_service_notify.h rename services/{ => time_manager}/include/time_service_proxy.h (55%) mode change 100755 => 100644 create mode 100644 services/time_manager/include/time_service_stub.h create mode 100644 services/time_manager/include/time_zone_info.h create mode 100644 services/time_manager/include/timer_call_back.h create mode 100644 services/time_manager/include/timer_call_back_proxy.h create mode 100644 services/time_manager/include/timer_call_back_stub.h rename services/{include/time_service_interface.h => time_manager/src/itimer_info.cpp} (58%) mode change 100755 => 100644 create mode 100644 services/time_manager/src/time_service.cpp create mode 100644 services/time_manager/src/time_service_client.cpp create mode 100644 services/time_manager/src/time_service_notify.cpp create mode 100644 services/time_manager/src/time_service_proxy.cpp create mode 100644 services/time_manager/src/time_service_stub.cpp create mode 100644 services/time_manager/src/time_zone_info.cpp create mode 100644 services/time_manager/src/timer_call_back.cpp create mode 100644 services/time_manager/src/timer_call_back_proxy.cpp create mode 100644 services/time_manager/src/timer_call_back_stub.cpp rename services/{ => time_manager}/test/BUILD.gn (51%) mode change 100755 => 100644 create mode 100644 services/time_manager/test/unittest/include/timer_test.h create mode 100644 services/time_manager/test/unittest/src/time_service_test.cpp create mode 100644 services/timer/include/batch.h create mode 100644 services/timer/include/timer_handler.h create mode 100644 services/timer/include/timer_info.h create mode 100644 services/timer/include/timer_manager.h create mode 100644 services/timer/include/timer_manager_interface.h create mode 100644 services/timer/src/batch.cpp create mode 100644 services/timer/src/timer_handler.cpp create mode 100644 services/timer/src/timer_info.cpp create mode 100644 services/timer/src/timer_manager.cpp create mode 100644 utils/BUILD.gn rename services/include/time_service_stub.h => utils/mock/include/mock_permission.h (52%) mode change 100755 => 100644 create mode 100644 utils/mock/src/mock_permission.cpp rename {services => utils/native}/include/time_common.h (66%) mode change 100755 => 100644 create mode 100644 utils/native/include/time_hilog_wreapper.h create mode 100644 utils/native/include/time_permission.h create mode 100644 utils/native/include/time_rdb_handler.h create mode 100644 utils/native/src/time_permission.cpp diff --git a/BUILD.gn b/BUILD.gn index 5664d61..06ad71c 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -20,7 +20,8 @@ group("time_native_packages") { deps = [ "etc/init:timeservice.rc", "interfaces/kits/js/declaration:time", - "interfaces/kits/js/napi:systemtime", + "interfaces/kits/js/napi/system_time:systemtime", + "interfaces/kits/js/napi/system_timer:systemtimer", "profile:miscservices_time_sa_profiles", "services:time_service", ] diff --git a/README.md b/README.md index 5815c65..5683514 100755 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@ The timing and time module provides APIs for managing the system time. ├── etc # Process configuration files ├── figures # Architecture diagram ├── interfaces # APIs for external systems and applications -│ └── kits # APIs +├ └── innerkits # APIs between services +│ └── kits # APIs ├── profile # System service configuration files └── services # Service implementation ``` diff --git a/README_zh.md b/README_zh.md index 47a613d..bdb45a9 100755 --- a/README_zh.md +++ b/README_zh.md @@ -22,6 +22,7 @@ ├── etc # 组件包含的进程的配置文件 ├── figures # 构架图 ├── interfaces # 组件对外提供的接口代码 +├ └── innerkits # 服务间接口 │ └── kits # 对应用提供的接口 ├── profile # 组件包含的系统服务的配置文件 └── services # 时间服务实现 diff --git a/etc/init/timeservice.cfg b/etc/init/timeservice.cfg index 28aac00..3e6510e 100644 --- a/etc/init/timeservice.cfg +++ b/etc/init/timeservice.cfg @@ -11,7 +11,7 @@ "path" : ["/system/bin/sa_main", "/system/profile/time_service.xml"], "uid" : "system", "gid" : ["system", "shell"], - "caps" : ["SYS_TIME"] + "caps" : ["SYS_TIME","WAKE_ALARM"] } ] } diff --git a/etc/init/timeservice.rc b/etc/init/timeservice.rc index c14d8d7..2f22ca4 100755 --- a/etc/init/timeservice.rc +++ b/etc/init/timeservice.rc @@ -17,5 +17,5 @@ service time_service /system/bin/sa_main /system/profile/time_service.xml class z_core user system group system shell - capabilities SYS_TIME + capabilities SYS_TIME WAKE_ALARM seclabel u:r:time_service:s0 diff --git a/interfaces/innerkits/include/itimer_info.h b/interfaces/innerkits/include/itimer_info.h new file mode 100644 index 0000000..334a4e6 --- /dev/null +++ b/interfaces/innerkits/include/itimer_info.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "want_agent.h" + +namespace OHOS { +namespace MiscServices { + +class ITimerInfo { +public: + ITimerInfo(); + ~ITimerInfo(); + + int type; + bool repeat; + uint64_t interval; + std::shared_ptr wantAgent; + + /** + * Indicates the timing policy the timer use, which can be REALTIME or UTC. + */ + const int TIMER_TYPE_REALTIME = 1 << 0; + + /** + * Describes whether a timer will wake the device up. + */ + const int TIMER_TYPE_WAKEUP = 1 << 1; + + /** + * Describes whether a timer will be delivered precisely at a scheduled time. + */ + const int TIMER_TYPE_EXACT = 1 << 2; + + /** + * Indicates whether the timer waking up the system is supported in low-power mode. + */ + const int TIMER_TYPE_IDLE = 1 << 3; + + /** + * SetType set timer type + * @para: type: TIMER_TYPE_REALTIME | TIMER_TYPE_WAKEUP + * + */ + virtual void SetType(const int &type) = 0; + + /** + * SetRepeat set timer repeat or not + * @para: repeat: bool + * + */ + virtual void SetRepeat(bool repeat) = 0; + + /** + * SetInterval set timer repeat interval + * @para: repeat: uint64_t >= 5000ms + * + */ + virtual void SetInterval(const uint64_t &interval) = 0; + virtual void SetWantAgent(std::shared_ptr wantAgent) = 0; + virtual void OnTrigger() = 0; +}; + +} // MiscServices +} // OHOS + diff --git a/interfaces/innerkits/include/time_service_client.h b/interfaces/innerkits/include/time_service_client.h new file mode 100644 index 0000000..c6fcb9b --- /dev/null +++ b/interfaces/innerkits/include/time_service_client.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H +#define SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H + +#include "refbase.h" +#include "time_service_interface.h" +#include "iremote_object.h" +#include "timer_call_back.h" + +#include + +namespace OHOS { +namespace MiscServices { + +constexpr int64_t ERROR_OPREATION_FAILED = -1; + +class TimeSaDeathRecipient : public IRemoteObject::DeathRecipient { +public: + + explicit TimeSaDeathRecipient(); + ~TimeSaDeathRecipient() = default; + + void OnRemoteDied(const wptr &object) override; +private: + DISALLOW_COPY_AND_MOVE(TimeSaDeathRecipient); +}; + +class TimeServiceClient : public RefBase{ +public: + DISALLOW_COPY_AND_MOVE(TimeServiceClient); + + static sptr GetInstance(); + + /** + * SetTime + * + * @descrition + * @param milliseconds int64_t UTC time in milliseconds. + * @return bool true on success, false on failure. + */ + bool SetTime(const int64_t milliseconds); + + /** + * SetTimeZone + * + * @descrition + * @param timeZoneId const std::string time zone. example: "Beijing, China". + * @return bool true on success, false on failure. + */ + bool SetTimeZone(const std::string timeZoneId); + + /** + * GetTimeZone + * + * @descpriton + * @return std::string, time zone example: "Beijing, China", if result length == 0 on failed. + */ + std::string GetTimeZone(); + /** + * GetWallTimeMs + * + * @descpriton get the wall time(the UTC time from 1970 0H:0M:0S) in milliseconds + * @return int64_t, milliseconds in wall time, ret < 0 on failed. + */ + int64_t GetWallTimeMs(); + + /** + * GetWallTimeNs + * + * @descpriton get the wall time(the UTC time from 1970 0H:0M:0S) in nanoseconds + * @return int64_t, nanoseconds in wall time, ret < 0 on failed. + */ + int64_t GetWallTimeNs(); + + /** + * GetBootTimeMs + * + * @descpriton get the time since boot(include time spent in sleep) in milliseconds. + * @return int64_t, milliseconds in boot time, ret < 0 on failed. + */ + int64_t GetBootTimeMs(); + + /** + * GetBootTimeNs + * + * @descpriton // get the time since boot(include time spent in sleep) in nanoseconds. + * @return int64_t, nanoseconds in boot time, ret < 0 on failed. + */ + int64_t GetBootTimeNs(); + + /** + * GetMonotonicTimeMs + * + * @descpriton get the time since boot(exclude time spent in sleep) in milliseconds. + * @return int64_t, milliseconds in Monotonic time, ret < 0 on failed. + */ + int64_t GetMonotonicTimeMs(); + + /** + * GetMonotonicTimeNs + * + * @descpriton get the time since boot(exclude time spent in sleep) in nanoseconds. + * @return int64_t, nanoseconds in Monotonic time, ret < 0 on failed. + */ + int64_t GetMonotonicTimeNs(); + + /** + * GetThreadTimeMs + * + * @descpriton get the Thread-specific CPU-time in milliseconds. + * @return int64_t, milliseconds in Thread-specific CPU-time, ret < 0 on failed. + */ + int64_t GetThreadTimeMs(); + + /** + * GetThreadTimeNs + * + * @descpriton get the Thread-specific CPU-time in nanoseconds. + * @return int64_t, nanoseconds in Thread-specific CPU-time, ret < 0 on failed. + */ + int64_t GetThreadTimeNs(); + + /** + * CreateTimer + * + * @param TimerInfo timer info + * @return uint64_t > 0 on success, == 0 failure. + */ + uint64_t CreateTimer(std::shared_ptr TimerInfo); + + /** + * StartTimer + * + * @param timerId indicate timerId + * @param treggerTime trigger times + * @return bool true on success, false on failure. + */ + bool StartTimer(uint64_t timerId, uint64_t triggerTime); + + /** + * StopTimer + * + * @param timerId indicate timerId + * @return bool true on success, false on failure. + */ + bool StopTimer(uint64_t timerId); + + /** + * DestroyTimer + * + * @param timerId indicate timerId + * @return bool true on success, false on failure. + */ + bool DestroyTimer(uint64_t timerId); + + void OnRemoteSaDied(const wptr &object); + +private: + TimeServiceClient(); + ~TimeServiceClient(); + + + static sptr ConnectService(); + + static std::mutex instanceLock_; + static sptr instance_; + static sptr timeServiceProxy_; + static sptr deathRecipient_; + +}; +} // MiscServices +} // OHOS +#endif // SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H \ No newline at end of file diff --git a/interfaces/kits/js/declaration/api/@ohos.systemTime.d.ts b/interfaces/kits/js/declaration/api/@ohos.systemTime.d.ts index c6d1039..2daeebb 100644 --- a/interfaces/kits/js/declaration/api/@ohos.systemTime.d.ts +++ b/interfaces/kits/js/declaration/api/@ohos.systemTime.d.ts @@ -21,9 +21,30 @@ import { AsyncCallback, ErrorCallback } from './basic'; * @since 6 */ declare namespace systemTime { - // Sets the system time. + /** + * Sets the system time. + * @permission ohos.permission.SET_TIME + * @since 6 + */ function setTime(time : number, callback : AsyncCallback) : void; function setTime(time : number) : Promise; + + /** + * Sets the system time. + * @permission ohos.permission.SET_TIME + * @since 7 + */ + function setDate(date: Date, callback: AsyncCallback): void; + function setDate(date: Date): Promise; + + /** + * Sets the system time zone. + * @permission ohos.permission.SET_TIME_ZONE + * @since 7 + */ + function setTimezone(timezone: string, callback: AsyncCallback): void; + function setTimezone(timezone: string): Promise; + } export default systemTime; diff --git a/interfaces/kits/js/declaration/api/@ohos.systemTimer.d.ts b/interfaces/kits/js/declaration/api/@ohos.systemTimer.d.ts new file mode 100644 index 0000000..4a55a96 --- /dev/null +++ b/interfaces/kits/js/declaration/api/@ohos.systemTimer.d.ts @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { AsyncCallback, ErrorCallback } from './basic'; +import { WantAgent } from './@ohos.wantAgent'; + +/** + * Provides js api for systemTimer + * + * @since 7 + * @devices phone, tablet, tv, wearable + * @systemapi Hide this for inner system use. + */ +declare namespace systemTimer { + /** + * Indicates the timing policy the timer use, which can be REALTIME or UTC. + */ + const TIMER_TYPE_REALTIME: number; + + /** + * Describes whether a timer will wake the device up. + */ + const TIMER_TYPE_WAKEUP: number; + + /** + * Describes whether a timer will be delivered precisely at a scheduled time. + */ + const TIMER_TYPE_EXACT: number; + + /** + * Indicates whether the timer waking up the system is supported in low-power mode. + */ + const TIMER_TYPE_IDLE: number; + + /** + * Creates a timer. + * @since 7 + * @Param options Indicates the timer options. + * @Return timer ID. + * + * @systemapi Hide this for inner system use. + */ + function createTimer(options: TimerOptions, callback: AsyncCallback): void; + function createTimer(options: TimerOptions): Promise; + + /** + * Starts a timer. + *@since 7 + * @Param timer The timer ID. + * @Param triggerTime Indicates the time at which the timer is triggered for the first time, in milliseconds. + * The time will be automatically set to 5000 milliseconds after the current time if the passed + * value is smaller than the current time plus 5000 milliseconds. + * @systemapi Hide this for inner system use. + */ + function startTimer(timer: number, triggerTime: number, callback: AsyncCallback): void; + function startTimer(timer: number, triggerTime: number): Promise; + + /** + * Stops a timer. + * @since 7 + * @Param timer The timer ID. + * @systemapi Hide this for inner system use. + */ + function stopTimer(timer: number, callback: AsyncCallback): void; + function stopTimer(timer: number): Promise; + + /** + * Clears a timer. + * @since 7 + * @Param timer The timer ID. + * @systemapi Hide this for inner system use. + */ + function destroyTimer(timer: number, callback: AsyncCallback): void; + function destroyTimer(timer: number): Promise; + + interface TimerOptions { + /** + * timer type. + */ + type: number; + + /** + * Indicates a repeating timer + */ + repeat: boolean; + + /** + * Indicates the interval between two consecutive triggers, in milliseconds. + * The interval will be set to 5000 milliseconds automatically if the passed value is smaller than 5000. + */ + interval?: number; + + /** + * Indicates the intent to send when the timer goes off. + */ + wantAgent?: WantAgent; + + /** + * Called back when the timer goes off. + */ + callback?: () => void; + } +} + +export default systemTimer; \ No newline at end of file diff --git a/interfaces/kits/js/napi/js_systemtime.cpp b/interfaces/kits/js/napi/js_systemtime.cpp deleted file mode 100755 index 0e76fcd..0000000 --- a/interfaces/kits/js/napi/js_systemtime.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include "time_service_manager.h" -#include "napi/native_api.h" -#include "napi/native_node_api.h" -#include "time_log.h" - -#define GET_PARAMS(env, info, num) \ - size_t argc = num; \ - napi_value argv[num]; \ - napi_value thisVar; \ - void* data; \ - napi_get_cb_info(env, info, &argc, argv, &thisVar, &data) - -typedef struct _SetTimeAsyncContext { - napi_env env; - napi_async_work work; - - int64_t time; - napi_deferred deferred; - napi_ref callbackRef; - - int status; -} SetTimeAsyncContext; - -static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) -{ - TIME_HILOGI("JSSystemTimeSetTime start"); - GET_PARAMS(env, info, 2); - NAPI_ASSERT(env, argc >= 1, "requires 1 parameter"); - - SetTimeAsyncContext* asyncContext = new SetTimeAsyncContext(); - asyncContext->env = env; - - for (size_t i = 0; i < argc; i++) { - napi_valuetype valueType; - napi_typeof(env, argv[i], &valueType); - if (i == 0 && valueType == napi_number) { - napi_get_value_int64(env, argv[i], &asyncContext->time); - } else if (i == 1 && valueType == napi_function) { - napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); - } else { - delete asyncContext; - NAPI_ASSERT(env, false, "type mismatch"); - } - } - - napi_value result = nullptr; - - if (asyncContext->callbackRef == nullptr) { - napi_create_promise(env, &asyncContext->deferred, &result); - } else { - napi_get_undefined(env, &result); - } - - napi_value resource = nullptr; - napi_create_string_utf8(env, "JSSystemTimeSetTime", NAPI_AUTO_LENGTH, &resource); - - napi_create_async_work( - env, nullptr, resource, - [](napi_env env, void* data) { - SetTimeAsyncContext* asyncContext = (SetTimeAsyncContext*)data; - bool setTimeResult = OHOS::MiscServices::TimeServiceManager::GetInstance()->SetTime(asyncContext->time); - if (setTimeResult) { - asyncContext->status = 0; - } else { - asyncContext->status = 1; - } - }, - [](napi_env env, napi_status status, void* data) { - SetTimeAsyncContext* asyncContext = (SetTimeAsyncContext*)data; - napi_value result[2] = { 0 }; - if (!asyncContext->status) { - napi_get_undefined(env, &result[0]); - napi_get_boolean(env, true, &result[1]); - } else { - napi_value message = nullptr; - napi_create_string_utf8(env, "SetTime fail", NAPI_AUTO_LENGTH, &message); - napi_create_error(env, nullptr, message, &result[0]); - napi_get_undefined(env, &result[1]); - } - if (asyncContext->deferred) { - if (!asyncContext->status) { - napi_resolve_deferred(env, asyncContext->deferred, result[1]); - } else { - napi_reject_deferred(env, asyncContext->deferred, result[0]); - } - } else { - napi_value callback = nullptr; - napi_get_reference_value(env, asyncContext->callbackRef, &callback); - // 2 -> result size - napi_call_function(env, nullptr, callback, 2, result, nullptr); - napi_delete_reference(env, asyncContext->callbackRef); - } - napi_delete_async_work(env, asyncContext->work); - delete asyncContext; - }, - (void*)asyncContext, &asyncContext->work); - napi_queue_async_work(env, asyncContext->work); - - return result; -} - -EXTERN_C_START -napi_value SystemTimeExport(napi_env env, napi_value exports) -{ - static napi_property_descriptor desc[] = { - DECLARE_NAPI_FUNCTION("setTime", JSSystemTimeSetTime) - }; - NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); - return exports; -} -EXTERN_C_END - -static napi_module system_time_module = { - .nm_version = 1, - .nm_flags = 0, - .nm_filename = nullptr, - .nm_register_func = SystemTimeExport, - .nm_modname = "systemTime", - .nm_priv = ((void*)0), - .reserved = {0} -}; - -extern "C" __attribute__((constructor)) void SystemTimeRegister() -{ - napi_module_register(&system_time_module); -} \ No newline at end of file diff --git a/interfaces/kits/js/napi/BUILD.gn b/interfaces/kits/js/napi/system_time/BUILD.gn old mode 100755 new mode 100644 similarity index 70% rename from interfaces/kits/js/napi/BUILD.gn rename to interfaces/kits/js/napi/system_time/BUILD.gn index c7c07e5..878efdf --- a/interfaces/kits/js/napi/BUILD.gn +++ b/interfaces/kits/js/napi/system_time/BUILD.gn @@ -11,28 +11,38 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/ohos.gni") +import("//base/miscservices/time/time.gni") ohos_shared_library("systemtime") { include_dirs = [ + "//base/miscservices/time/interfaces/innerkits/include", + "include", "//third_party/node/src", "//foundation/ace/napi/interfaces/kits", ] + configs = [ + "${time_utils_path}:utils_config", + ] + cflags = [ "-fPIC", "-g3", ] - sources = [ "js_systemtime.cpp" ] + sources = [ "src/js_systemtime.cpp" ] deps = [ "//base/miscservices/time/services:time_service", + "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", + "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", "//foundation/ace/napi/:ace_napi", "//utils/native/base:utils", ] external_deps = [ + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", ] diff --git a/interfaces/kits/js/napi/system_time/include/js_systemtime.h b/interfaces/kits/js/napi/system_time/include/js_systemtime.h new file mode 100644 index 0000000..ffae810 --- /dev/null +++ b/interfaces/kits/js/napi/system_time/include/js_systemtime.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef N_JS_SYSTEMTIME_H +#define N_JS_SYSTEMTIME_H + +#include +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "js_native_api.h" + +constexpr int RESOLVED = 1; +constexpr int REJECT = 0; + +constexpr int NONE_PARAMETER = 0; +constexpr int ONE_PARAMETER = 1; +constexpr int TWO_PARAMETER = 2; +constexpr int THREE_PARAMETER = 3; + +constexpr int MAX_TIME_ZONE_ID = 1024; + + +#define GET_PARAMS(env, info, num) \ + size_t argc = num; \ + napi_value argv[num]; \ + napi_value thisVar; \ + void* data; \ + napi_get_cb_info(env, info, &argc, argv, &thisVar, &data) + +typedef struct AsyncContext { + napi_env env; + napi_async_work work; + int64_t time; + std::string timeZone; + napi_deferred deferred; + napi_ref callbackRef; + int status; +} AsyncContext; + + +#endif \ No newline at end of file diff --git a/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp new file mode 100644 index 0000000..92cd584 --- /dev/null +++ b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "js_systemtime.h" + +#include +#include "time_service_client.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "js_native_api.h" + +#include "time_common.h" +#include + + +using namespace OHOS::MiscServices; + +static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) +{ + TIME_HILOGI(TIME_MODULE_JS_NAPI,"JSSystemTimeSetTime start"); + GET_PARAMS(env, info, 2); + NAPI_ASSERT(env, argc == ONE_PARAMETER || argc == TWO_PARAMETER, "type mismatch"); + + AsyncContext* asyncContext = new (std::nothrow)AsyncContext(); + asyncContext->env = env; + + for (size_t i = 0; i < argc; i++) { + napi_valuetype valueType; + napi_typeof(env, argv[i], &valueType); + if (i == 0 && valueType == napi_number) { + napi_get_value_int64(env, argv[i], &asyncContext->time); + } else if (i == 0 && valueType == napi_object){ + bool hasProperty = false; + napi_valuetype resValueType; + NAPI_CALL(env, napi_has_named_property(env, argv[i], "getTime", &hasProperty)); + NAPI_ASSERT(env, hasProperty, "type expected."); + napi_value getTimeFunc = nullptr; + napi_get_named_property(env, argv[i], "getTime", &getTimeFunc); + napi_value getTimeResult = nullptr; + napi_call_function(env, argv[i], getTimeFunc, 0, nullptr, &getTimeResult); + NAPI_CALL(env, napi_typeof(env, getTimeResult, &resValueType)); + NAPI_ASSERT(env, resValueType == napi_number, "type mismatch"); + int64_t dateValue = 0; + napi_get_value_int64(env, getTimeResult, &dateValue); + asyncContext->time = dateValue; + } else if (i == 1 && valueType == napi_function) { + napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); + } else { + delete asyncContext; + NAPI_ASSERT(env, false, "type mismatch"); + } + } + + napi_value result = nullptr; + + if (asyncContext->callbackRef == nullptr) { + napi_create_promise(env, &asyncContext->deferred, &result); + } else { + napi_get_undefined(env, &result); + } + + napi_value resource = nullptr; + napi_create_string_utf8(env, "JSSystemTimeSetTime", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work(env, nullptr, resource,[](napi_env env, void* data) { + AsyncContext* asyncContext = (AsyncContext*)data; + bool setTimeResult; + setTimeResult = TimeServiceClient::GetInstance()->SetTime(asyncContext->time); + + if (setTimeResult) { + asyncContext->status = RESOLVED; + } else { + asyncContext->status = REJECT; + } + }, + [](napi_env env, napi_status status, void* data) { + AsyncContext* asyncContext = (AsyncContext*)data; + napi_value result[2] = { 0 }; + if (asyncContext->status == RESOLVED) { + napi_get_undefined(env, &result[0]); + napi_get_boolean(env, true, &result[1]); + } else { + napi_value message = nullptr; + napi_create_string_utf8(env, "Set fail", NAPI_AUTO_LENGTH, &message); + napi_create_error(env, nullptr, message, &result[0]); + napi_get_undefined(env, &result[1]); + } + if (asyncContext->deferred) { + if (asyncContext->status == RESOLVED) { + napi_resolve_deferred(env, asyncContext->deferred, result[1]); + } else { + napi_reject_deferred(env, asyncContext->deferred, result[0]); + } + } else { + napi_value callback = nullptr; + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + // 2 -> result size + napi_call_function(env, nullptr, callback, 2, result, nullptr); + napi_delete_reference(env, asyncContext->callbackRef); + } + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; + }, + (void*)asyncContext, &asyncContext->work); + napi_queue_async_work(env, asyncContext->work); + + return result; +} + +static napi_value JSSystemTimeSetTimeZone(napi_env env, napi_callback_info info){ + TIME_HILOGI(TIME_MODULE_JS_NAPI,"JSSystemTimeSetTimeZone start"); + GET_PARAMS(env, info, 2); + NAPI_ASSERT(env, argc == ONE_PARAMETER || argc == TWO_PARAMETER, "type mismatch"); + + AsyncContext* asyncContext = new AsyncContext(); + asyncContext->env = env; + + for (size_t i = 0; i < argc; i++) { + napi_valuetype valueType; + napi_typeof(env, argv[i], &valueType); + if (i == 0 && valueType == napi_string) { + char timeZoneChars[MAX_TIME_ZONE_ID]; + size_t timeZoneCharsSize; + if (napi_ok != napi_get_value_string_utf8(env, argv[i], timeZoneChars, MAX_TIME_ZONE_ID-1, &timeZoneCharsSize)){ + delete asyncContext; + NAPI_ASSERT(env, false, "input para invalid"); + } + std::string timeZoneStr(timeZoneChars, timeZoneCharsSize); + asyncContext->timeZone = timeZoneStr; + } else if (i == 1 && valueType == napi_function) { + napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); + } else { + delete asyncContext; + NAPI_ASSERT(env, false, "type mismatch"); + } + } + + napi_value result = nullptr; + + if (asyncContext->callbackRef == nullptr) { + napi_create_promise(env, &asyncContext->deferred, &result); + } else { + napi_get_undefined(env, &result); + } + napi_value resource = nullptr; + napi_create_string_utf8(env, "JSSystemTimeSetTimeZone", NAPI_AUTO_LENGTH, &resource); + + napi_create_async_work(env, nullptr, resource, + [](napi_env env, void* data) { + AsyncContext* asyncContext = (AsyncContext*)data; + auto setTimeResult = TimeServiceClient::GetInstance()->SetTimeZone(asyncContext->timeZone); + if (setTimeResult) { + asyncContext->status = RESOLVED; + } else { + asyncContext->status = REJECT; + } + }, + [](napi_env env, napi_status status, void* data) { + AsyncContext* asyncContext = (AsyncContext*)data; + napi_value result[2] = { 0 }; + if (asyncContext->status == RESOLVED) { + napi_get_undefined(env, &result[0]); + napi_get_boolean(env, true, &result[1]); + } else { + napi_value message = nullptr; + napi_create_string_utf8(env, "Set fail", NAPI_AUTO_LENGTH, &message); + napi_create_error(env, nullptr, message, &result[0]); + napi_get_undefined(env, &result[1]); + } + if (asyncContext->deferred) { + if (asyncContext->status == RESOLVED) { + napi_resolve_deferred(env, asyncContext->deferred, result[1]); + } else { + napi_reject_deferred(env, asyncContext->deferred, result[0]); + } + } else { + napi_value callback = nullptr; + napi_get_reference_value(env, asyncContext->callbackRef, &callback); + // 2 -> result size + napi_call_function(env, nullptr, callback, 2, result, nullptr); + napi_delete_reference(env, asyncContext->callbackRef); + } + napi_delete_async_work(env, asyncContext->work); + delete asyncContext; + }, + (void*)asyncContext, + &asyncContext->work); + napi_queue_async_work(env, asyncContext->work); + return result; +} + +EXTERN_C_START +napi_value SystemTimeExport(napi_env env, napi_value exports) +{ + static napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("setTime", JSSystemTimeSetTime), + DECLARE_NAPI_FUNCTION("setDate", JSSystemTimeSetTime), + DECLARE_NAPI_FUNCTION("setTimezone", JSSystemTimeSetTimeZone) + }; + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + return exports; +} +EXTERN_C_END + +static napi_module system_time_module = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = SystemTimeExport, + .nm_modname = "systemTime", + .nm_priv = ((void*)0), + .reserved = {0} +}; + +extern "C" __attribute__((constructor)) void SystemTimeRegister() +{ + napi_module_register(&system_time_module); +} \ No newline at end of file diff --git a/interfaces/kits/js/napi/system_timer/BUILD.gn b/interfaces/kits/js/napi/system_timer/BUILD.gn new file mode 100644 index 0000000..b6c7431 --- /dev/null +++ b/interfaces/kits/js/napi/system_timer/BUILD.gn @@ -0,0 +1,70 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//base/notification/ces_standard/event.gni") +import("//build/ohos.gni") + +cflags = [] + +config("native_module_config") { + visibility = [ ":*" ] + + include_dirs = [] + + if (target_cpu == "arm") { + cflags += [ "-DBINDER_IPC_32BIT" ] + } + + defines = [ + "EVENT_LOG_TAG = \"SYSTEMTIMER_STANDARD\"", + "LOG_DOMAIN = xxxx", + ] +} + +ohos_shared_library("systemtimer") { + include_dirs = [ + "//base/miscservices/time/interfaces/innerkits/include", + "./include", + "//foundation/ace/napi/interfaces/kits/napi", + "//third_party/node/src", + "//third_party/libuv/include", + ] + + configs = [ ":native_module_config" ] + + sources = [ + "src/init.cpp", + "src/system_timer.cpp", + "src/timer_type.cpp", + ] + + deps = [ + "//base/miscservices/time/services:time_service", + "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", + "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", + "//foundation/aafwk/standard/interfaces/innerkits/base:base", + "//foundation/ace/napi:ace_napi", + "//third_party/libuv:uv_static", + ] + + external_deps = [ + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] + + relative_install_dir = "module" + subsystem_name = "miscservices" + part_name = "time_native" +} diff --git a/interfaces/kits/js/napi/system_timer/include/system_timer.h b/interfaces/kits/js/napi/system_timer/include/system_timer.h new file mode 100644 index 0000000..e6ec446 --- /dev/null +++ b/interfaces/kits/js/napi/system_timer/include/system_timer.h @@ -0,0 +1,56 @@ +/* + * Copyright (c); 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License");; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_TIMER_H +#define SYSTEM_TIMER_H + +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include "time_service_client.h" + +namespace OHOS { +namespace MiscServicesNapi { +using namespace OHOS::MiscServices; + +class ITimerInfoInstance : public ITimerInfo { +public: + ITimerInfoInstance(); + virtual ~ITimerInfoInstance(); + virtual void OnTrigger() override; + virtual void SetType(const int &type) override; + virtual void SetRepeat(bool repeat) override; + virtual void SetInterval(const uint64_t &interval) override; + virtual void SetWantAgent(std::shared_ptr wantAgent) override; + void SetCallbackInfo(const napi_env &env, const napi_ref &ref); + +private: + struct CallbackInfo { + napi_env env; + napi_ref ref; + }; + + CallbackInfo callbackInfo_; +}; + +napi_value SystemtimerInit(napi_env env, napi_value exports); +napi_value CreateTimer(napi_env env, napi_callback_info info); +napi_value StartTimer(napi_env env, napi_callback_info info); +napi_value StopTimer(napi_env env, napi_callback_info info); +napi_value DestroyTimer(napi_env env, napi_callback_info info); + +} // namespace MiscServicesNapi +} // namespace OHOS + +#endif // SYSTEM_TIMER_H \ No newline at end of file diff --git a/interfaces/kits/js/napi/system_timer/include/timer_type.h b/interfaces/kits/js/napi/system_timer/include/timer_type.h new file mode 100644 index 0000000..5147d32 --- /dev/null +++ b/interfaces/kits/js/napi/system_timer/include/timer_type.h @@ -0,0 +1,28 @@ +/* + * Copyright (c); 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License");; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_TIMER_TYPE_H +#define SYSTEM_TIMER_TYPE_H + +#include +#include "napi/native_api.h" + +namespace OHOS { +namespace MiscServicesNapi { +napi_value TimerTypeInit(napi_env env, napi_value exports); +} // namespace MiscServicesNapi +} // namespace OHOS + +#endif // SYSTEM_TIMER_TYPE_H \ No newline at end of file diff --git a/interfaces/kits/js/napi/system_timer/src/init.cpp b/interfaces/kits/js/napi/system_timer/src/init.cpp new file mode 100644 index 0000000..2bca0f2 --- /dev/null +++ b/interfaces/kits/js/napi/system_timer/src/init.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "system_timer.h" +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace MiscServicesNapi { +EXTERN_C_START + +/* + * Module export function + */ +static napi_value Init(napi_env env, napi_value exports) +{ + /* + * Propertise define + */ + SystemtimerInit(env, exports); + + return exports; +} +EXTERN_C_END + +/* + * Module define + */ +static napi_module _module = { + + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "systemtimer", + .nm_priv = ((void *)0), + .reserved = {0} + +}; + +/* + * Module register function + */ +extern "C" __attribute__((constructor)) void RegisterModule(void) +{ + napi_module_register(&_module); +} +} // namespace MiscServicesNapi +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/napi/system_timer/src/system_timer.cpp b/interfaces/kits/js/napi/system_timer/src/system_timer.cpp new file mode 100644 index 0000000..d357ef0 --- /dev/null +++ b/interfaces/kits/js/napi/system_timer/src/system_timer.cpp @@ -0,0 +1,747 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "timer_type.h" +#include "want_agent.h" +#include "securec.h" +#include "system_timer.h" + +namespace OHOS { +namespace MiscServicesNapi { + +const int NO_ERROR = 0; +const int ERROR = -1; +const int CREATE_MAX_PARA = 2; +const int START_MAX_PARA = 3; +const int STOP_MAX_PARA = 2; +const int DESTROY_MAX_PARA = 2; +const int ARGS_TWO = 2; +const int PARAM0 = 0; +const int PARAM1 = 1; + +struct CallbackPromiseInfo { + napi_ref callback = nullptr; + napi_deferred deferred; + bool isCallback = false; + int errorCode = 0; +}; + +struct ReceiveDataWorker { + napi_env env; + napi_ref ref = 0; +}; + +struct AsyncCallbackInfoCreate { + napi_env env; + napi_async_work asyncWork; + napi_ref callback = nullptr; + napi_deferred deferred; + std::shared_ptr iTimerInfoInstance; + uint64_t timerId = 0; + bool isCallback = false; + int errorCode = NO_ERROR; +}; + +struct AsyncCallbackInfoStart { + napi_env env; + napi_async_work asyncWork; + napi_ref callback = nullptr; + napi_deferred deferred; + uint64_t timerId = 0; + uint64_t triggerTime = 0; + bool isOK = false; + bool isCallback = false; + int errorCode = NO_ERROR; +}; + +struct AsyncCallbackInfoStop { + napi_env env; + napi_async_work asyncWork; + napi_ref callback = nullptr; + napi_deferred deferred; + uint64_t timerId = 0; + bool isOK = false; + bool isCallback = false; + int errorCode = NO_ERROR; +}; + +struct AsyncCallbackInfoDestroy { + napi_env env; + napi_async_work asyncWork; + napi_ref callback = nullptr; + napi_deferred deferred; + uint64_t timerId = 0; + bool isOK = false; + bool isCallback = false; + int errorCode = NO_ERROR; +}; + +static std::vector asyncCallbackInfoCreateInfo; + +napi_value NapiGetNull(napi_env env) +{ + napi_value result = 0; + napi_get_null(env, &result); + return result; +} + +napi_value GetCallbackErrorValue(napi_env env, int errCode) +{ + napi_value result = nullptr; + napi_value eCode = nullptr; + NAPI_CALL(env, napi_create_int32(env, errCode, &eCode)); + NAPI_CALL(env, napi_create_object(env, &result)); + NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode)); + return result; +} + +void SetPromise(const napi_env &env, const napi_deferred &deferred, const napi_value &result) +{ + napi_resolve_deferred(env, deferred, result); +} + +void SetCallback(const napi_env &env, const napi_ref &callbackIn, const int &errorCode, const napi_value &result) +{ + napi_value undefined; + napi_get_undefined(env, &undefined); + + napi_value callback; + napi_value resultout; + napi_get_reference_value(env, callbackIn, &callback); + napi_value results[ARGS_TWO] = {0}; + results[PARAM0] = GetCallbackErrorValue(env, errorCode); + results[PARAM1] = result; + NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &results[PARAM0], &resultout)); +} + +napi_value JSParaError(const napi_env &env, const napi_ref &callback) +{ + if (callback) { + return NapiGetNull(env); + } else { + napi_value promise = 0; + napi_deferred deferred = nullptr; + napi_create_promise(env, &deferred, &promise); + SetPromise(env, deferred, NapiGetNull(env)); + return promise; + } +} + +void ReturnCallbackPromise(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result) +{ + if (info.isCallback) { + SetCallback(env, info.callback, info.errorCode, result); + } else { + SetPromise(env, info.deferred, result); + } +} + +ITimerInfoInstance::ITimerInfoInstance() +{} + +ITimerInfoInstance::~ITimerInfoInstance() +{} + +void ITimerInfoInstance::OnTrigger() +{ + if (callbackInfo_.ref == nullptr) { + return; + } + + uv_loop_s *loop = nullptr; +#if NAPI_VERSION >= 2 + napi_get_uv_event_loop(callbackInfo_.env, &loop); +#endif // NAPI_VERSION >= 2 + + ReceiveDataWorker *dataWorker = new (std::nothrow) ReceiveDataWorker(); + if (!dataWorker) { + return; + } + dataWorker->env = callbackInfo_.env; + dataWorker->ref = callbackInfo_.ref; + + uv_work_t *work = new (std::nothrow) uv_work_t; + if (!work) { + return; + } + work->data = (void *)dataWorker; + + uv_queue_work(loop, + work, + [](uv_work_t *work) {}, + [](uv_work_t *work, int status) { + ReceiveDataWorker *dataWorkerData = (ReceiveDataWorker *)work->data; + if (dataWorkerData == nullptr) { + return; + } + + SetCallback(dataWorkerData->env, dataWorkerData->ref, NO_ERROR, NapiGetNull(dataWorkerData->env)); + + delete dataWorkerData; + dataWorkerData = nullptr; + delete work; + work = nullptr; + }); +} + +void ITimerInfoInstance::SetCallbackInfo(const napi_env &env, const napi_ref &ref) +{ + callbackInfo_.env = env; + callbackInfo_.ref = ref; +} + +void ITimerInfoInstance::SetType(const int &_type) +{ + type = _type; +} + +void ITimerInfoInstance::SetRepeat(bool _repeat) +{ + repeat = _repeat; +} +void ITimerInfoInstance::SetInterval(const uint64_t &_interval) +{ + interval = _interval; +} +void ITimerInfoInstance::SetWantAgent(std::shared_ptr _wantAgent) +{ + wantAgent = _wantAgent; +} + +napi_value GetTimerOptions(const napi_env &env, const napi_value &value, + std::shared_ptr &iTimerInfoInstance) +{ + napi_valuetype valuetype; + napi_value result; + OHOS::Notification::WantAgent::WantAgent *wantAgent = nullptr; + bool hasProperty = false; + + // type: number + int type = 0; + NAPI_CALL(env, napi_has_named_property(env, value, "type", &hasProperty)); + NAPI_ASSERT(env, hasProperty, "type expected."); + napi_get_named_property(env, value, "type", &result); + NAPI_CALL(env, napi_typeof(env, result, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected."); + napi_get_value_int32(env, result, &type); + iTimerInfoInstance->SetType(type); + + // repeat: boolean + bool repeat = false; + NAPI_CALL(env, napi_has_named_property(env, value, "repeat", &hasProperty)); + NAPI_ASSERT(env, hasProperty, "repeat expected."); + napi_get_named_property(env, value, "repeat", &result); + NAPI_CALL(env, napi_typeof(env, result, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_boolean, "Wrong argument type. Bool expected."); + napi_get_value_bool(env, result, &repeat); + iTimerInfoInstance->SetRepeat(repeat); + + // interval?: number + int64_t interval = 0; + NAPI_CALL(env, napi_has_named_property(env, value, "interval", &hasProperty)); + if (hasProperty) { + napi_get_named_property(env, value, "interval", &result); + NAPI_CALL(env, napi_typeof(env, result, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected."); + napi_get_value_int64(env, result, &interval); + NAPI_ASSERT(env, interval >= 0, "Wrong argument number. Positive number expected."); + iTimerInfoInstance->SetInterval((uint64_t)interval); + } + + // wantAgent?: WantAgent + NAPI_CALL(env, napi_has_named_property(env, value, "wantAgent", &hasProperty)); + if (hasProperty) { + napi_get_named_property(env, value, "wantAgent", &result); + NAPI_CALL(env, napi_typeof(env, result, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected."); + napi_unwrap(env, result, (void **)&wantAgent); + if (wantAgent == nullptr) { + return nullptr; + } + std::shared_ptr sWantAgent = std::make_shared(*wantAgent); + iTimerInfoInstance->SetWantAgent(sWantAgent); + } + + // callback?: () => void + NAPI_CALL(env, napi_has_named_property(env, value, "callback", &hasProperty)); + if (hasProperty) { + napi_get_named_property(env, value, "callback", &result); + NAPI_CALL(env, napi_typeof(env, result, &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_ref onTriggerCallback; + napi_create_reference(env, result, 1, &onTriggerCallback); + iTimerInfoInstance->SetCallbackInfo(env, onTriggerCallback); + } + + return NapiGetNull(env); +} + +napi_value ParseParametersByCreateTimer(const napi_env &env, const napi_value (&argv)[CREATE_MAX_PARA], + const size_t &argc, std::shared_ptr &iTimerInfoInstance, napi_ref &callback) +{ + NAPI_ASSERT(env, argc >= CREATE_MAX_PARA - 1, "Wrong number of arguments"); + napi_valuetype valuetype; + + // argv[0]: TimerOptions + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument type. Object expected."); + if (GetTimerOptions(env, argv[0], iTimerInfoInstance) == nullptr) { + return nullptr; + } + + // argv[1]:callback + if (argc >= CREATE_MAX_PARA) { + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_create_reference(env, argv[1], 1, &callback); + } + + return NapiGetNull(env); +} + +void PaddingAsyncCallbackInfoIsByCreateTimer( + const napi_env &env, AsyncCallbackInfoCreate *&asynccallbackinfo, const napi_ref &callback, napi_value &promise) +{ + if (callback) { + asynccallbackinfo->callback = callback; + asynccallbackinfo->isCallback = true; + } else { + napi_deferred deferred = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise)); + asynccallbackinfo->deferred = deferred; + asynccallbackinfo->isCallback = false; + } +} + +napi_value CreateTimer(napi_env env, napi_callback_info info) +{ + size_t argc = CREATE_MAX_PARA; + napi_value argv[CREATE_MAX_PARA]; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + + std::shared_ptr iTimerInfoInstance = std::make_shared(); + napi_ref callback = nullptr; + + if (ParseParametersByCreateTimer(env, argv, argc, iTimerInfoInstance, callback) == nullptr) { + return JSParaError(env, callback); + } + AsyncCallbackInfoCreate *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoCreate{.env = env, + .asyncWork = nullptr, + .iTimerInfoInstance = iTimerInfoInstance}; + if (!asynccallbackinfo) { + return JSParaError(env, callback); + } + + napi_value promise = 0; + PaddingAsyncCallbackInfoIsByCreateTimer(env, asynccallbackinfo, callback, promise); + + napi_value resourceName; + napi_create_string_latin1(env, "createTimer", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoCreate *asynccallbackinfo = (AsyncCallbackInfoCreate *)data; + asynccallbackinfo->timerId = + TimeServiceClient::GetInstance()->CreateTimer(asynccallbackinfo->iTimerInfoInstance); + if (asynccallbackinfo->timerId > 0){ + asyncCallbackInfoCreateInfo.emplace_back(asynccallbackinfo); + } + + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoCreate *asynccallbackinfo = (AsyncCallbackInfoCreate *)data; + + CallbackPromiseInfo info; + info.isCallback = asynccallbackinfo->isCallback; + info.callback = asynccallbackinfo->callback; + info.deferred = asynccallbackinfo->deferred; + info.errorCode = asynccallbackinfo->errorCode; + + // timerId: number + napi_value result; + napi_create_int64(env, asynccallbackinfo->timerId, &result); + ReturnCallbackPromise(env, info, result); + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->isCallback) { + return NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParseParametersByStartTimer(const napi_env &env, const napi_value (&argv)[START_MAX_PARA], + const size_t &argc, uint64_t &uintTimerId, uint64_t &uintTriggerTime, napi_ref &callback) +{ + NAPI_ASSERT(env, argc >= START_MAX_PARA - 1, "Wrong number of arguments"); + napi_valuetype valuetype; + + // argv[0]: timer + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected."); + int64_t timerId = 0; + napi_get_value_int64(env, argv[0], &timerId); + NAPI_ASSERT(env, timerId >= 0, "Wrong argument timer. Positive number expected."); + uintTimerId = (uint64_t)timerId; + + // argv[1]: triggerTime + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected."); + int64_t triggerTime = 0; + napi_get_value_int64(env, argv[1], &triggerTime); + NAPI_ASSERT(env, triggerTime >= 0, "Wrong argument triggerTime. Positive number expected."); + uintTriggerTime = (uint64_t)triggerTime; + + // argv[2]:callback + if (argc >= START_MAX_PARA) { + NAPI_CALL(env, napi_typeof(env, argv[2], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_create_reference(env, argv[2], 1, &callback); + } + + return NapiGetNull(env); +} + +void PaddingAsyncCallbackInfoIsByStartTimer( + const napi_env &env, AsyncCallbackInfoStart *&asynccallbackinfo, const napi_ref &callback, napi_value &promise) +{ + if (callback) { + asynccallbackinfo->callback = callback; + asynccallbackinfo->isCallback = true; + } else { + napi_deferred deferred = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise)); + asynccallbackinfo->deferred = deferred; + asynccallbackinfo->isCallback = false; + } +} + +napi_value StartTimer(napi_env env, napi_callback_info info) +{ + size_t argc = START_MAX_PARA; + napi_value argv[START_MAX_PARA]; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + + uint64_t timerId; + uint64_t triggerTime; + napi_ref callback = nullptr; + if (ParseParametersByStartTimer(env, argv, argc, timerId, triggerTime, callback) == nullptr) { + return JSParaError(env, callback); + } + + AsyncCallbackInfoStart *asynccallbackinfo = new (std::nothrow) + AsyncCallbackInfoStart{.env = env, .asyncWork = nullptr, .timerId = timerId, .triggerTime = triggerTime}; + if (!asynccallbackinfo) { + return JSParaError(env, callback); + } + + napi_value promise = 0; + PaddingAsyncCallbackInfoIsByStartTimer(env, asynccallbackinfo, callback, promise); + + napi_value resourceName; + napi_create_string_latin1(env, "startTimer", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoStart *asynccallbackinfo = (AsyncCallbackInfoStart *)data; + + asynccallbackinfo->isOK = TimeServiceClient::GetInstance()->StartTimer( + asynccallbackinfo->timerId, asynccallbackinfo->triggerTime); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoStart *asynccallbackinfo = (AsyncCallbackInfoStart *)data; + + if (!asynccallbackinfo->isOK) { + asynccallbackinfo->errorCode = ERROR; + } + CallbackPromiseInfo info; + info.isCallback = asynccallbackinfo->isCallback; + info.callback = asynccallbackinfo->callback; + info.deferred = asynccallbackinfo->deferred; + info.errorCode = asynccallbackinfo->errorCode; + + // result: bool + napi_value result; + napi_get_boolean(env, asynccallbackinfo->isOK, &result); + ReturnCallbackPromise(env, info, result); + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->isCallback) { + return NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParseParametersByStopTimer(const napi_env &env, const napi_value (&argv)[STOP_MAX_PARA], const size_t &argc, + uint64_t &uintTimerId, napi_ref &callback) +{ + NAPI_ASSERT(env, argc >= STOP_MAX_PARA - 1, "Wrong number of arguments"); + napi_valuetype valuetype; + + // argv[0]: timer + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected."); + int64_t timerId = 0; + napi_get_value_int64(env, argv[0], &timerId); + NAPI_ASSERT(env, timerId >= 0, "Wrong argument timer. Positive number expected."); + uintTimerId = (uint64_t)timerId; + + // argv[1]:callback + if (argc >= STOP_MAX_PARA) { + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_create_reference(env, argv[1], 1, &callback); + } + + return NapiGetNull(env); +} + +void PaddingAsyncCallbackInfoIsByStopTimer( + const napi_env &env, AsyncCallbackInfoStop *&asynccallbackinfo, const napi_ref &callback, napi_value &promise) +{ + if (callback) { + asynccallbackinfo->callback = callback; + asynccallbackinfo->isCallback = true; + } else { + napi_deferred deferred = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise)); + asynccallbackinfo->deferred = deferred; + asynccallbackinfo->isCallback = false; + } +} + +napi_value StopTimer(napi_env env, napi_callback_info info) +{ + size_t argc = STOP_MAX_PARA; + napi_value argv[STOP_MAX_PARA]; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + + uint64_t timerId; + napi_ref callback = nullptr; + if (ParseParametersByStopTimer(env, argv, argc, timerId, callback) == nullptr) { + return JSParaError(env, callback); + } + + AsyncCallbackInfoStop *asynccallbackinfo = + new (std::nothrow) AsyncCallbackInfoStop{.env = env, .asyncWork = nullptr, .timerId = timerId}; + if (!asynccallbackinfo) { + return JSParaError(env, callback); + } + + napi_value promise = 0; + PaddingAsyncCallbackInfoIsByStopTimer(env, asynccallbackinfo, callback, promise); + + napi_value resourceName; + napi_create_string_latin1(env, "stopTimer", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoStop *asynccallbackinfo = (AsyncCallbackInfoStop *)data; + asynccallbackinfo->isOK = TimeServiceClient::GetInstance()->StopTimer(asynccallbackinfo->timerId); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoStop *asynccallbackinfo = (AsyncCallbackInfoStop *)data; + + if (!asynccallbackinfo->isOK) { + asynccallbackinfo->errorCode = ERROR; + } + CallbackPromiseInfo info; + info.isCallback = asynccallbackinfo->isCallback; + info.callback = asynccallbackinfo->callback; + info.deferred = asynccallbackinfo->deferred; + info.errorCode = asynccallbackinfo->errorCode; + + // result: bool + napi_value result; + napi_get_boolean(env, asynccallbackinfo->isOK, &result); + ReturnCallbackPromise(env, info, result); + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->isCallback) { + return NapiGetNull(env); + } else { + return promise; + } +} + +napi_value ParseParametersByDestroyTimer(const napi_env &env, const napi_value (&argv)[DESTROY_MAX_PARA], + const size_t &argc, uint64_t &uintTimerId, napi_ref &callback) +{ + NAPI_ASSERT(env, argc >= DESTROY_MAX_PARA - 1, "Wrong number of arguments"); + napi_valuetype valuetype; + + // argv[0]: timer + NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected."); + int64_t timerId = 0; + napi_get_value_int64(env, argv[0], &timerId); + NAPI_ASSERT(env, timerId >= 0, "Wrong argument timer. Positive number expected."); + uintTimerId = (uint64_t)timerId; + + // argv[1]:callback + if (argc >= DESTROY_MAX_PARA) { + NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype)); + NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected."); + napi_create_reference(env, argv[1], 1, &callback); + } + + return NapiGetNull(env); +} + +void PaddingAsyncCallbackInfoIsByDestroyTimer( + const napi_env &env, AsyncCallbackInfoDestroy *&asynccallbackinfo, const napi_ref &callback, napi_value &promise) +{ + if (callback) { + asynccallbackinfo->callback = callback; + asynccallbackinfo->isCallback = true; + } else { + napi_deferred deferred = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise)); + asynccallbackinfo->deferred = deferred; + asynccallbackinfo->isCallback = false; + } +} + +napi_value DestroyTimer(napi_env env, napi_callback_info info) +{ + size_t argc = DESTROY_MAX_PARA; + napi_value argv[DESTROY_MAX_PARA]; + napi_value thisVar = nullptr; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL)); + + uint64_t timerId; + napi_ref callback = nullptr; + if (ParseParametersByDestroyTimer(env, argv, argc, timerId, callback) == nullptr) { + return JSParaError(env, callback); + } + + AsyncCallbackInfoDestroy *asynccallbackinfo = + new (std::nothrow) AsyncCallbackInfoDestroy{.env = env, .asyncWork = nullptr, .timerId = timerId}; + if (!asynccallbackinfo) { + return JSParaError(env, callback); + } + + napi_value promise = 0; + PaddingAsyncCallbackInfoIsByDestroyTimer(env, asynccallbackinfo, callback, promise); + + napi_value resourceName; + napi_create_string_latin1(env, "destroyTimer", NAPI_AUTO_LENGTH, &resourceName); + // Asynchronous function call + napi_create_async_work(env, + nullptr, + resourceName, + [](napi_env env, void *data) { + AsyncCallbackInfoDestroy *asynccallbackinfo = (AsyncCallbackInfoDestroy *)data; + asynccallbackinfo->isOK = TimeServiceClient::GetInstance()->DestroyTimer(asynccallbackinfo->timerId); + }, + [](napi_env env, napi_status status, void *data) { + AsyncCallbackInfoDestroy *asynccallbackinfo = (AsyncCallbackInfoDestroy *)data; + + if (asynccallbackinfo->isOK) { + for (auto it = asyncCallbackInfoCreateInfo.begin(); it != asyncCallbackInfoCreateInfo.end(); it++) { + if ((*it)->timerId == asynccallbackinfo->timerId) { + it = asyncCallbackInfoCreateInfo.erase(it); + delete (*it); + *it = nullptr; + } + } + } else { + asynccallbackinfo->errorCode = ERROR; + } + CallbackPromiseInfo info; + info.isCallback = asynccallbackinfo->isCallback; + info.callback = asynccallbackinfo->callback; + info.deferred = asynccallbackinfo->deferred; + info.errorCode = asynccallbackinfo->errorCode; + + // result: bool + napi_value result; + napi_get_boolean(env, asynccallbackinfo->isOK, &result); + ReturnCallbackPromise(env, info, result); + + napi_delete_async_work(env, asynccallbackinfo->asyncWork); + if (asynccallbackinfo) { + delete asynccallbackinfo; + asynccallbackinfo = nullptr; + } + }, + (void *)asynccallbackinfo, + &asynccallbackinfo->asyncWork); + + NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork)); + + if (asynccallbackinfo->isCallback) { + return NapiGetNull(env); + } else { + return promise; + } +} + +napi_value SystemtimerInit(napi_env env, napi_value exports) +{ + napi_property_descriptor desc[] = { + DECLARE_NAPI_FUNCTION("createTimer", CreateTimer), + DECLARE_NAPI_FUNCTION("startTimer", StartTimer), + DECLARE_NAPI_FUNCTION("stopTimer", StopTimer), + DECLARE_NAPI_FUNCTION("destroyTimer", DestroyTimer), + }; + + NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); + + OHOS::MiscServicesNapi::TimerTypeInit(env, exports); + return exports; +} + +} // namespace MiscServicesNapi +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/napi/system_timer/src/timer_type.cpp b/interfaces/kits/js/napi/system_timer/src/timer_type.cpp new file mode 100644 index 0000000..283534a --- /dev/null +++ b/interfaces/kits/js/napi/system_timer/src/timer_type.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c); 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License");; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "timer_type.h" + +namespace OHOS { +namespace MiscServicesNapi { +void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName) +{ + napi_value prop = nullptr; + if (napi_create_int32(env, objName, &prop) == napi_ok) { + napi_set_named_property(env, dstObj, propName, prop); + } +} + +napi_value TimerTypeInit(napi_env env, napi_value exports) +{ + napi_value obj = nullptr; + napi_create_object(env, &obj); + + SetNamedPropertyByInteger(env, obj, 1 << 0, "TIMER_TYPE_REALTIME"); + SetNamedPropertyByInteger(env, obj, 1 << 1, "TIMER_TYPE_WAKEUP"); + SetNamedPropertyByInteger(env, obj, 1 << 2, "TIMER_TYPE_EXACT"); + SetNamedPropertyByInteger(env, obj, 1 << 3, "TIMER_TYPE_IDLE"); + + napi_property_descriptor exportFuncs[] = {DECLARE_NAPI_PROPERTY("systemTimer", obj)}; + napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs); + + return exports; +} + +} // namespace MiscServicesNapi +} // namespace OHOS \ No newline at end of file diff --git a/ohos.build b/ohos.build index 759e480..f96f792 100755 --- a/ohos.build +++ b/ohos.build @@ -11,7 +11,7 @@ "//base/miscservices/time:time_native_packages" ], "test_list": [ - "//base/miscservices/time/services/test:TimeServiceTest" + "//base/miscservices/time/services/time_manager/test:TimeServiceTest" ] } } diff --git a/services/BUILD.gn b/services/BUILD.gn index c245679..48af5b6 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -12,39 +12,67 @@ # limitations under the License. import("//base/miscservices/time/time.gni") -import("//build/ohos.gni") config("time_service_config") { visibility = [ ":*" ] include_dirs = [ - "include", + "//base/miscservices/time/interfaces/innerkits/include", + "../utils/native/include", + "time_manager/include", + "timer/include", "//utils/system/safwk/native/include", "//third_party/json/include", + "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb/include/", + "/foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk/include/", ] - cflags_cc = [ "-fexceptions" ] } ohos_shared_library("time_service") { sources = [ - "src/time_service.cpp", - "src/time_service_manager.cpp", - "src/time_service_proxy.cpp", - "src/time_service_stub.cpp", + "time_manager/src/itimer_info.cpp", + "time_manager/src/time_service.cpp", + "time_manager/src/time_service_client.cpp", + "time_manager/src/time_service_notify.cpp", + "time_manager/src/time_service_proxy.cpp", + "time_manager/src/time_service_stub.cpp", + "time_manager/src/time_zone_info.cpp", + "time_manager/src/timer_call_back.cpp", + "time_manager/src/timer_call_back_proxy.cpp", + "time_manager/src/timer_call_back_stub.cpp", + "timer/src/batch.cpp", + "timer/src/timer_handler.cpp", + "timer/src/timer_info.cpp", + "timer/src/timer_manager.cpp", ] + + configs = [ "${time_utils_path}:utils_config" ] + public_configs = [ "//utils/native/base:utils_config", ":time_service_config", ] deps = [ - "//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler", - "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", - "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "${time_utils_path}:time_utils", + "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", + "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk:native_appdatafwk", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_preferences:native_preferences", "//utils/native/base:utils", ] external_deps = [ + "aafwk_standard:base", + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:libeventhandler", + "ces_standard:cesfwk_innerkits", + "hisysevent_native:libhisysevent", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", ] subsystem_name = "miscservices" part_name = "time_native" diff --git a/services/include/time_log.h b/services/include/time_log.h deleted file mode 100755 index c737797..0000000 --- a/services/include/time_log.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef BASE_SMALLSERVICE_TIME_LOG_H -#define BASE_SMALLSERVICE_TIME_LOG_H - -#include - -#define CONFIG_TIME_HILOG -#ifdef CONFIG_TIME_HILOG -#include "hilog/log.h" - -#ifdef TIME_HILOGI -#undef TIME_HILOGI -#endif - -#ifdef TIME_HILOGE -#undef TIME_HILOGE -#endif - -#ifdef TIME_HILOGW -#undef TIME_HILOGW -#endif - -#ifdef TIME_HILOGI -#undef TIME_HILOGI -#endif - -#ifdef TIME_HILOGD -#undef TIME_HILOGD -#endif - -static constexpr OHOS::HiviewDFX::HiLogLabel g_SMALL_SERVICES_LABEL = { - LOG_CORE, - 0xD001C00, - "TimeKit" -}; - - -#define TIME_HILOGD(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Debug(g_SMALL_SERVICES_LABEL, \ - "line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define TIME_HILOGE(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Error(g_SMALL_SERVICES_LABEL, \ - "line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define TIME_HILOGF(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Fatal(g_SMALL_SERVICES_LABEL, \ - "line: %d, function: %s," fmt, __LINE__FILE__, __FUNCTION__, ##__VA_ARGS__) -#define TIME_HILOGI(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Info(g_SMALL_SERVICES_LABEL, \ - "line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__) -#define TIME_HILOGW(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Warn(g_SMALL_SERVICES_LABEL,\ - "line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__) - -#else - -#define TIME_HILOGF(...) -#define TIME_HILOGE(...) -#define TIME_HILOGW(...) -#define TIME_HILOGI(...) -#define TIME_HILOGD(...) -#endif // CONFIG_HILOG - -#define CHECK_RET(bCondition, action, ret) if ((bCondition)) {action; return ret;} -#define CHECK_VOID_RET(bCondition, action) if ((bCondition)) {action; return;} -#define LOG_WRITE_PARCEL_ERROR TIME_HILOGE("write parcel data ret %{public}d", ret); - -#endif // BASE_SMALLSERVICE_TIME_LOG_H diff --git a/services/include/time_service.h b/services/include/time_service.h deleted file mode 100755 index 32ac0d7..0000000 --- a/services/include/time_service.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SERVICES_INCLUDE_TIME_SERVICES_H -#define SERVICES_INCLUDE_TIME_SERVICES_H - -#include -#include "system_ability.h" -#include "time_service_stub.h" -#include "event_handler.h" - -namespace OHOS { -namespace MiscServices { -enum class ServiceRunningState { - STATE_NOT_START, - STATE_RUNNING -}; - -class TimeService : public SystemAbility, public TimeServiceStub { - DECLARE_SYSTEM_ABILITY(TimeService); - -public: - DISALLOW_COPY_AND_MOVE(TimeService); - - TimeService(int32_t systemAbilityId, bool runOnCreate); - TimeService(); - ~TimeService(); - static sptr GetInstance(); - bool SetTime(const int64_t time) override; - -protected: - void OnStart() override; - void OnStop() override; - -private: - int32_t Init(); - ServiceRunningState state_; - - void InitServiceHandler(); - - static std::mutex instanceLock_; - static sptr instance_; - - static std::shared_ptr serviceHandler_; -}; -} // MiscServices -} // OHOS -#endif // SERVICES_INCLUDE_TIME_SERVICES_H diff --git a/services/include/time_service_manager.h b/services/include/time_service_manager.h deleted file mode 100755 index dd5f1f6..0000000 --- a/services/include/time_service_manager.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H -#define SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H - -#include "refbase.h" -#include "time_service_stub.h" -#include "iremote_object.h" - -namespace OHOS { -namespace MiscServices { -class TimeSaDeathRecipient : public IRemoteObject::DeathRecipient { -public: - explicit TimeSaDeathRecipient(); - ~TimeSaDeathRecipient() = default; - - void OnRemoteDied(const wptr &object) override; -}; - -class TimeServiceManager : public RefBase { -public: - TimeServiceManager(); - ~TimeServiceManager(); - static sptr GetInstance(); - bool SetTime(const int64_t time); - void OnRemoteSaDied(const wptr &object); - -private: - static sptr GetTimeServiceProxy(); - - static std::mutex instanceLock_; - static sptr instance_; - static sptr timeServiceProxy_; - static sptr deathRecipient_; -}; -} // MiscServices -} // OHOS -#endif // SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H \ No newline at end of file diff --git a/services/src/time_service.cpp b/services/src/time_service.cpp deleted file mode 100755 index 47dfe76..0000000 --- a/services/src/time_service.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "time_service.h" - -#include -#include -#include -#include -#include "system_ability.h" -#include "system_ability_definition.h" -#include "iservice_registry.h" -#include "time_log.h" -#include "time_common.h" - -namespace OHOS { -namespace MiscServices { -using namespace OHOS::HiviewDFX; - -REGISTER_SYSTEM_ABILITY_BY_ID(TimeService, TIME_SERVICE_ID, true); - -const std::int64_t INIT_INTERVAL = 10000L; -std::mutex TimeService::instanceLock_; -sptr TimeService::instance_; - -std::shared_ptr TimeService::serviceHandler_; - -TimeService::TimeService(int32_t systemAbilityId, bool runOnCreate) - : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START) -{ -} - -TimeService::TimeService() : state_(ServiceRunningState::STATE_NOT_START) -{ -} - -TimeService::~TimeService() -{ -} - -sptr TimeService::GetInstance() -{ - if (instance_ == nullptr) { - std::lock_guard autoLock(instanceLock_); - if (instance_ == nullptr) { - instance_ = new TimeService; - } - } - return instance_; -} - -void TimeService::OnStart() -{ - TIME_HILOGI("Enter OnStart."); - if (state_ == ServiceRunningState::STATE_RUNNING) { - TIME_HILOGI("TimeService is already running."); - return; - } - - InitServiceHandler(); - if (Init() != SUCCESS) { - auto callback = [=]() { Init(); }; - serviceHandler_->PostTask(callback, INIT_INTERVAL); - TIME_HILOGE("Init failed. Try again 10s later"); - return; - } - - TIME_HILOGI("Start TimeService success."); - return; -} - -int32_t TimeService::Init() -{ - bool ret = Publish(TimeService::GetInstance()); - if (!ret) { - TIME_HILOGE("Publish failed."); - return E_PUBLISH_FAIL; - } - TIME_HILOGI("Publish success."); - state_ = ServiceRunningState::STATE_RUNNING; - return SUCCESS; -} - -void TimeService::OnStop() -{ - TIME_HILOGI("OnStop started."); - if (state_ != ServiceRunningState::STATE_RUNNING) { - return; - } - serviceHandler_ = nullptr; - - state_ = ServiceRunningState::STATE_NOT_START; - TIME_HILOGI("OnStop end."); -} - -void TimeService::InitServiceHandler() -{ - TIME_HILOGI("InitServiceHandler started."); - if (serviceHandler_ != nullptr) { - TIME_HILOGI("InitServiceHandler already init."); - return; - } - std::shared_ptr runner = AppExecFwk::EventRunner::Create("TimeService"); - serviceHandler_ = std::make_shared(runner); - - TIME_HILOGI("InitServiceHandler succeeded."); -} - -bool TimeService::SetTime(const int64_t time) -{ - TIME_HILOGI("Setting time of day to milliseconds"); - if (time <= 0 || time / 1000LL >= INT_MAX) { - TIME_HILOGE("SetTime input param error"); - return false; - } - - struct timeval tv; - tv.tv_sec = (time_t) (time / 1000LL); - tv.tv_usec = (suseconds_t) ((time % 1000LL) * 1000LL); - - int result = settimeofday(&tv, NULL); - if (result < 0) { - TIME_HILOGE("settimeofday fail: %{public}s", strerror(errno)); - return false; - } - - return true; -} -} // namespace MiscServices -} // namespace OHOS diff --git a/services/src/time_service_manager.cpp b/services/src/time_service_manager.cpp deleted file mode 100755 index 9f5d578..0000000 --- a/services/src/time_service_manager.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "time_service_manager.h" -#include -#include "system_ability_definition.h" -#include "iservice_registry.h" -#include "time_log.h" - -namespace OHOS { -namespace MiscServices { -std::mutex TimeServiceManager::instanceLock_; -sptr TimeServiceManager::instance_; -sptr TimeServiceManager::timeServiceProxy_; -sptr TimeServiceManager::deathRecipient_; - -TimeServiceManager::TimeServiceManager() -{ -} - -TimeServiceManager::~TimeServiceManager(){} - -sptr TimeServiceManager::GetInstance() -{ - if (instance_ == nullptr) { - std::lock_guard autoLock(instanceLock_); - if (instance_ == nullptr) { - instance_ = new TimeServiceManager; - timeServiceProxy_ = GetTimeServiceProxy(); - } - } - return instance_; -} - -bool TimeServiceManager::SetTime(const int64_t time) -{ - if (timeServiceProxy_ == nullptr) { - TIME_HILOGW("Redo GetTimeServiceProxy"); - timeServiceProxy_ = GetTimeServiceProxy(); - } - - if (timeServiceProxy_ == nullptr) { - TIME_HILOGE("SetTime quit because redoing GetTimeServiceProxy failed."); - return false; - } - - return timeServiceProxy_->SetTime(time); -} - -sptr TimeServiceManager::GetTimeServiceProxy() -{ - sptr systemAbilityManager = - SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (systemAbilityManager == nullptr) { - TIME_HILOGE("Getting SystemAbilityManager failed."); - return nullptr; - } - - auto systemAbility = systemAbilityManager->GetSystemAbility(TIME_SERVICE_ID, ""); - if (systemAbility == nullptr) { - TIME_HILOGE("Get SystemAbility failed."); - return nullptr; - } - deathRecipient_ = new TimeSaDeathRecipient(); - systemAbility->AddDeathRecipient(deathRecipient_); - sptr timeServiceProxy = iface_cast(systemAbility); - if (timeServiceProxy == nullptr) { - TIME_HILOGE("Get TimeServiceProxy from SA failed."); - return nullptr; - } - - TIME_HILOGD("Getting TimeServiceProxy succeeded."); - return timeServiceProxy; -} - -void TimeServiceManager::OnRemoteSaDied(const wptr &remote) -{ - timeServiceProxy_ = GetTimeServiceProxy(); -} - -TimeSaDeathRecipient::TimeSaDeathRecipient() -{ -} - -void TimeSaDeathRecipient::OnRemoteDied(const wptr &object) -{ - TIME_HILOGE("TimeSaDeathRecipient on remote systemAbility died."); - TimeServiceManager::GetInstance()->OnRemoteSaDied(object); -} -} // namespace MiscServices -} // namespace OHOS diff --git a/services/src/time_service_proxy.cpp b/services/src/time_service_proxy.cpp deleted file mode 100755 index 2385992..0000000 --- a/services/src/time_service_proxy.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "time_service_proxy.h" -#include "iremote_broker.h" -#include "time_log.h" -#include "time_common.h" - -namespace OHOS { -namespace MiscServices { -using namespace OHOS::HiviewDFX; - -TimeServiceProxy::TimeServiceProxy(const sptr &object) : IRemoteProxy(object) -{ -} - -bool TimeServiceProxy::SetTime(const int64_t time) -{ - MessageParcel data, reply; - MessageOption option; - - data.WriteInterfaceToken(GetDescriptor()); - data.WriteInt64(time); - - int32_t ret = Remote()->SendRequest(SET_TIME, data, reply, option); - if (ret != SUCCESS) { - TIME_HILOGE("SetTime, ret = %{public}d", ret); - return false; - } - bool result = reply.ReadBool(); - return result; -} -} // namespace MiscServices -} // namespace OHOS \ No newline at end of file diff --git a/services/src/time_service_stub.cpp b/services/src/time_service_stub.cpp deleted file mode 100755 index 167f06b..0000000 --- a/services/src/time_service_stub.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "time_service_stub.h" -#include -#include "parcel.h" -#include "ipc_skeleton.h" -#include "time_log.h" -#include "time_common.h" - -namespace OHOS { -namespace MiscServices { -using namespace OHOS::HiviewDFX; - -int32_t TimeServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, - MessageOption &option) -{ - TIME_HILOGI("OnRemoteRequest started, code = %{public}d", code); - - auto descriptorToken = data.ReadInterfaceToken(); - if (descriptorToken != GetDescriptor()) { - TIME_HILOGE("Remote descriptor not the same as local descriptor."); - return E_TRANSACT_ERROR; - } - - switch (code) { - case SET_TIME: - return OnSetTime(data, reply); - default: - TIME_HILOGE("Default value received, check needed."); - return IPCObjectStub::OnRemoteRequest(code, data, reply, option); - } -} - -int32_t TimeServiceStub::OnSetTime(Parcel& data, Parcel& reply) -{ - int64_t time = data.ReadInt64(); - bool result = SetTime(time); - CHECK_RET((!reply.WriteBool(result)), TIME_HILOGE("WriteBool failed"), E_WRITE_PARCEL_ERROR); - return SUCCESS; -} - -bool TimeServiceStub::SetTime(const int64_t time) -{ - return false; -} -} // namespace MiscServices -} // namespace OHOS \ No newline at end of file diff --git a/services/test/unittest/time_service_test.cpp b/services/test/unittest/time_service_test.cpp deleted file mode 100755 index 50ca131..0000000 --- a/services/test/unittest/time_service_test.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include "time_log.h" -#include "time_service_manager.h" - -using namespace testing::ext; -using namespace OHOS; -using namespace OHOS::MiscServices; - -class TimeServiceTest : public testing::Test { -public: - static void SetUpTestCase(void); - static void TearDownTestCase(void); - void SetUp(); - void TearDown(); -}; - -void TimeServiceTest::SetUpTestCase(void) -{} - -void TimeServiceTest::TearDownTestCase(void) -{} - -void TimeServiceTest::SetUp(void) -{ -} - -void TimeServiceTest::TearDown(void) -{} - -/** -* @tc.name: SetTime001 -* @tc.desc: get system time. -* @tc.type: FUNC -*/ -HWTEST_F(TimeServiceTest, SetTime001, TestSize.Level0) -{ - int64_t time = 1627307312000; - bool result = TimeServiceManager::GetInstance()->SetTime(time); - EXPECT_TRUE(result); -} diff --git a/services/time_manager/include/itimer_call_back.h b/services/time_manager/include/itimer_call_back.h new file mode 100644 index 0000000..da41b63 --- /dev/null +++ b/services/time_manager/include/itimer_call_back.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef I_TIMER_CALL_BACK_H +#define I_TIMER_CALL_BACK_H + +#include "iremote_broker.h" + +namespace OHOS { +namespace MiscServices { + +class ITimerCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimerCallback"); + + /** + * trigger timer by id. + * + * @param timerId timerId + * + */ + virtual void NotifyTimer(const uint64_t timerId) = 0; + + enum Message { + NOTIFY_TIMER = 1 + }; + +}; + +} // namespace MiscServices +} // namespace OHOS + +#endif // I_TIMER_CALL_BACK_H diff --git a/services/time_manager/include/time_service.h b/services/time_manager/include/time_service.h new file mode 100644 index 0000000..0d48dc0 --- /dev/null +++ b/services/time_manager/include/time_service.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SERVICES_INCLUDE_TIME_SERVICES_H +#define SERVICES_INCLUDE_TIME_SERVICES_H + +#include "time_service_stub.h" +#include "time_service_notify.h" +#include "time_rdb_handler.h" +#include "timer_manager.h" +#include "time_permission.h" +#include "system_ability.h" +#include "event_handler.h" +#include "time.h" +#include "securec.h" +#include +#include + +namespace OHOS { +namespace MiscServices { +enum class ServiceRunningState { + STATE_NOT_START, + STATE_RUNNING +}; + + +const int TIMER_TYPE_REALTIME_MASK = 1 << 0; +const int TIMER_TYPE_REALTIME_WAKEUP_MASK = 1 << 1; +const int TIMER_TYPE_EXACT_MASK = 1 << 2; +const int TIMER_TYPE_IDLE_MASK = 1 << 3; + + +class TimeService : public SystemAbility, public TimeServiceStub { + DECLARE_SYSTEM_ABILITY(TimeService); + +public: + DISALLOW_COPY_AND_MOVE(TimeService); + + TimeService(int32_t systemAbilityId, bool runOnCreate); + TimeService(); + ~TimeService(); + static sptr GetInstance(); + int32_t SetTime(const int64_t time) override; + int32_t SetTimeZone(const std::string timezoneId) override; + int32_t GetTimeZone(std::string &timezoneId) override; + int32_t GetWallTimeMs(int64_t ×) override; + int32_t GetWallTimeNs(int64_t ×) override; + int32_t GetBootTimeMs(int64_t ×) override; + int32_t GetBootTimeNs(int64_t ×) override; + int32_t GetMonotonicTimeMs(int64_t ×) override; + int32_t GetMonotonicTimeNs(int64_t ×) override; + int32_t GetThreadTimeMs(int64_t ×) override; + int32_t GetThreadTimeNs(int64_t ×) override; + + uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr &timerCallback) override; + bool StartTimer(uint64_t timerId, uint64_t triggerTime) override; + bool StopTimer(uint64_t timerId) override; + bool DestroyTimer(uint64_t timerId) override; + +protected: + void OnStart() override; + void OnStop() override; + +private: + int32_t Init(); + void InitServiceHandler(); + void InitNotifyHandler(); + void InitTimeZone(); + void InitTimerHandler(); + bool GetTimeByClockid(clockid_t clockID, struct timespec* tv); + int set_rtc_time(time_t sec); + + bool check_rtc(std::string rtc_path, uint32_t rtc_id); + int get_wall_clock_rtc_id(); + + ServiceRunningState state_; + static std::mutex instanceLock_; + static sptr instance_; + const std::string setTimePermName_ = "ohos.permission.SET_TIME"; + const std::string setTimezonePermName_ = "ohos.permission.SET_TIME_ZONE"; + const int rtc_id; + static std::shared_ptr timeServiceNotify_; + static std::shared_ptr serviceHandler_; + static std::shared_ptr timerManagerHandler_; +}; +} // MiscServices +} // OHOS +#endif // SERVICES_INCLUDE_TIME_SERVICES_H diff --git a/services/time_manager/include/time_service_interface.h b/services/time_manager/include/time_service_interface.h new file mode 100644 index 0000000..be96b76 --- /dev/null +++ b/services/time_manager/include/time_service_interface.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H +#define SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H + +#include "iremote_broker.h" +#include "want_agent.h" + +namespace OHOS { +namespace MiscServices { + +class ITimeService : public IRemoteBroker { +public: + + // remote method code + enum { + SET_TIME = 0, + SET_TIME_ZONE = 1, + GET_TIME_ZONE = 2, + GET_WALL_TIME_MILLI = 3, + GET_WALL_TIME_NANO = 4, + GET_BOOT_TIME_MILLI = 5, + GET_BOOT_TIME_NANO = 6, + GET_MONO_TIME_MILLI = 7, + GET_MONO_TIME_NANO = 8, + GET_THREAD_TIME_MILLI = 9, + GET_THREAD_TIME_NANO = 10, + CREATE_TIMER = 11, + START_TIMER = 12, + STOP_TIMER = 13, + DESTORY_TIMER = 14 + }; + /** + * SetTime + * + * @param time int64_t set milliseconds + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t SetTime(const int64_t time) = 0; + + /** + * SetTimeZone + * + * @param timezoneId std::string &timezoneId string + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t SetTimeZone(const std::string timezoneId) = 0; + + /** + * GetTimeZone + * + * @param timezoneId std::string &timezoneId string + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetTimeZone(std::string &timezoneId) = 0; + + /** + * GetWallTimeMs + * + * @param times result of times ,unit: millisecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetWallTimeMs(int64_t ×) = 0; + + /** + * GetWallTimeNs + * + * @param times result of times ,unit: Nanosecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetWallTimeNs(int64_t ×) = 0; + + /** + * GetBootTimeMs + * + * @param times result of times ,unit: millisecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetBootTimeMs(int64_t ×) = 0; + + /** + * GetBootTimeNs + * + * @param times result of times ,unit: millisecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetBootTimeNs(int64_t ×) = 0; + + /** + * GetMonotonicTimeMs + * + * @param times result of times ,unit: millisecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetMonotonicTimeMs(int64_t ×) = 0; + + /** + * GetMonotonicTimeNs + * + * @param times result of times ,unit: Nanosecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetMonotonicTimeNs(int64_t ×) = 0; + + /** + * GetThreadTimeMs + * + * @param times result of times ,unit: millisecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetThreadTimeMs(int64_t ×) = 0; + + /** + * GetThreadTimeNs + * + * @param times result of times ,unit: Nanosecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual int32_t GetThreadTimeNs(int64_t ×) = 0; + + /** + * CreateTimer + * + * @param type timer type + * @param repeat is repeat or not + * @param timerCallback remoteobject + * @return uint64_t > 0 on success, == 0 failure. + */ + virtual uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr &timerCallback) = 0; + + /** + * StartTimer + * + * @param timerId indicate timerId + * @param treggerTime trigger times + * @return bool true on success, false on failure. + */ + virtual bool StartTimer(uint64_t timerId, uint64_t treggerTime) = 0; + + /** + * StopTimer + * + * @param timerId indicate timerId + * @return bool true on success, false on failure. + */ + virtual bool StopTimer(uint64_t timerId) = 0; + + /** + * DestroyTimer + * + * @param timerId indicate timerId + * @return bool true on success, false on failure. + */ + virtual bool DestroyTimer(uint64_t timerId) = 0; + + DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimeService"); +}; + +} // namespace MiscServices +} // namespace OHOS +#endif // SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H \ No newline at end of file diff --git a/services/time_manager/include/time_service_notify.h b/services/time_manager/include/time_service_notify.h new file mode 100644 index 0000000..c2ecc78 --- /dev/null +++ b/services/time_manager/include/time_service_notify.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIME_SERVICE_NOTIFY_H +#define TIME_SERVICE_NOTIFY_H + +#include +#include +#include "time_common.h" + + +namespace OHOS { +namespace MiscServices { + +class TimeServiceNotify { + +public: + TimeServiceNotify() = default; + ~TimeServiceNotify() = default; + void RegisterPublishEvents(); + void PublishTimeChanageEvents(int64_t eventTime); + void PublishTimeZoneChangeEvents(int64_t eventTime); + +private: + using IntentWant = OHOS::AAFwk::Want; + + void PublishEvents(int64_t eventTime, sptr intent); + + sptr timeChangeWant_; + sptr timeZoneChangeWant_; + sptr publishInfo_; +}; + +} // namespace MiscServices +} // namespace OHOS + +#endif // TIME_SERVICE_NOTIFY_H diff --git a/services/include/time_service_proxy.h b/services/time_manager/include/time_service_proxy.h old mode 100755 new mode 100644 similarity index 55% rename from services/include/time_service_proxy.h rename to services/time_manager/include/time_service_proxy.h index b309a4e..870a8a2 --- a/services/include/time_service_proxy.h +++ b/services/time_manager/include/time_service_proxy.h @@ -1,36 +1,51 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SERVICES_INCLUDE_TIME_SERVICE_PROXY_H -#define SERVICES_INCLUDE_TIME_SERVICE_PROXY_H - -#include "iremote_proxy.h" -#include "time_service_interface.h" - -namespace OHOS { -namespace MiscServices { -class TimeServiceProxy : public IRemoteProxy { -public: - explicit TimeServiceProxy(const sptr &object); - ~TimeServiceProxy() = default; - DISALLOW_COPY_AND_MOVE(TimeServiceProxy); - bool SetTime(const int64_t time) override; - -private: - static inline BrokerDelegator delegator_; -}; -} // namespace MiscServices -} // namespace OHOS +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SERVICES_INCLUDE_TIME_SERVICE_PROXY_H +#define SERVICES_INCLUDE_TIME_SERVICE_PROXY_H + +#include "iremote_proxy.h" +#include "time_service_interface.h" + +namespace OHOS { +namespace MiscServices { +class TimeServiceProxy : public IRemoteProxy { +public: + explicit TimeServiceProxy(const sptr &object); + ~TimeServiceProxy() = default; + DISALLOW_COPY_AND_MOVE(TimeServiceProxy); + + int32_t SetTime(const int64_t time) override; + int32_t SetTimeZone(const std::string timeZoneId) override; + int32_t GetTimeZone(std::string &timeZoneId) override; + int32_t GetWallTimeMs(int64_t ×) override; + int32_t GetWallTimeNs(int64_t ×) override; + int32_t GetBootTimeMs(int64_t ×) override; + int32_t GetBootTimeNs(int64_t ×) override; + int32_t GetMonotonicTimeMs(int64_t ×) override; + int32_t GetMonotonicTimeNs(int64_t ×) override; + int32_t GetThreadTimeMs(int64_t ×) override; + int32_t GetThreadTimeNs(int64_t ×) override; + uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr &timerCallback) override; + bool StartTimer(uint64_t timerId, uint64_t treggerTime) override; + bool StopTimer(uint64_t timerId) override; + bool DestroyTimer(uint64_t timerId) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace MiscServices +} // namespace OHOS #endif // SERVICES_INCLUDE_TIME_SERVICE_PROXY_H \ No newline at end of file diff --git a/services/time_manager/include/time_service_stub.h b/services/time_manager/include/time_service_stub.h new file mode 100644 index 0000000..207c46c --- /dev/null +++ b/services/time_manager/include/time_service_stub.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SERVICES_INCLUDE_TIME_SERVICE_STUB_H +#define SERVICES_INCLUDE_TIME_SERVICE_STUB_H + +#include "iremote_stub.h" +#include "time_service_interface.h" +#include "itimer_call_back.h" +#include "ipc_skeleton.h" +#include + +namespace OHOS { +namespace MiscServices { +class TimeServiceStub : public IRemoteStub { +public: + TimeServiceStub(); + ~TimeServiceStub(); + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + using TimeServiceFunc = int32_t (TimeServiceStub::*)(MessageParcel &data, MessageParcel &reply); + int32_t OnSetTime(MessageParcel &data, MessageParcel &reply); + int32_t OnSetTimeZone(MessageParcel &data, MessageParcel &reply); + int32_t OnGetTimeZone(MessageParcel &data, MessageParcel &reply); + int32_t OnGetWallTimeMs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetWallTimeNs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetBootTimeMs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetBootTimeNs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetMonotonicTimeMs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetMonotonicTimeNs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetThreadTimeMs(MessageParcel &data, MessageParcel &reply); + int32_t OnGetThreadTimeNs(MessageParcel &data, MessageParcel &reply); + + int32_t OnCreateTimer(MessageParcel &data, MessageParcel &reply); + int32_t OnStartTimer(MessageParcel &data, MessageParcel &reply); + int32_t OnStopTimer(MessageParcel &data, MessageParcel &reply); + int32_t OnDestoryTimer(MessageParcel &data, MessageParcel &reply); + + std::map memberFuncMap_; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // SERVICES_INCLUDE_TIME_SERVICE_STUB_H \ No newline at end of file diff --git a/services/time_manager/include/time_zone_info.h b/services/time_manager/include/time_zone_info.h new file mode 100644 index 0000000..1865fab --- /dev/null +++ b/services/time_manager/include/time_zone_info.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SERVICES_INCLUDE_TIME_ZONE_INFO_H +#define SERVICES_INCLUDE_TIME_ZONE_INFO_H + +#include +#include +#include "refbase.h" + +namespace OHOS{ +namespace MiscServices{ +using namespace std; + +struct zoneInfoEntry +{ + std::string ID; + std::string alias; + int utcOffsetHours; + std::string description; +}; + +class TimeZoneInfo : public RefBase{ + TimeZoneInfo(); + ~TimeZoneInfo(); + +public: + static sptr GetInstance(); + void Init(); + int32_t GetOffset(const std::string timezoneId, int &offset); + int32_t GetTimezoneId(std::string &timezoneId); + +private: + std::string curTimezoneId_; + int32_t lastOffset_; + static std::mutex instanceLock_; + static sptr instance_; + std::map timezoneInfoMap_; +}; +} // MiscServices +} // OHOS + +#endif // SERVICES_INCLUDE_TIME_ZONE_INFO_H \ No newline at end of file diff --git a/services/time_manager/include/timer_call_back.h b/services/time_manager/include/timer_call_back.h new file mode 100644 index 0000000..520b2bd --- /dev/null +++ b/services/time_manager/include/timer_call_back.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIMER_CALL_BACK_H +#define TIMER_CALL_BACK_H + +#include "timer_call_back_stub.h" +#include "itimer_info.h" +#include "time_common.h" +#include +#include "ability_context.h" +#include "want_agent_helper.h" + +namespace OHOS { +namespace MiscServices { + +class TimerCallback : public TimerCallbackStub { +public: + DISALLOW_COPY_AND_MOVE(TimerCallback); + + static sptr GetInstance(); + + virtual void NotifyTimer(const uint64_t timerId) override; + /** + * Get timer callback info. + * + * @param timerInfo the timer info + * @param timerInfo the timer info + * @return Get timer callback info success or not + */ + bool InsertTimerCallbackInfo(const uint64_t timerId, const std::shared_ptr &timerInfo); + + bool RemoveTimerCallbackInfo(const uint64_t timerId); + +private: + TimerCallback(); + ~TimerCallback(); + + static std::mutex instanceLock_; + static sptr instance_; + + static std::map> TimerInfoMap_; + static std::mutex timerInfoMutex_; +}; + +} // namespace MiscServices +} // namespace OHOS + +#endif // TIMER_CALL_BACK_H \ No newline at end of file diff --git a/services/time_manager/include/timer_call_back_proxy.h b/services/time_manager/include/timer_call_back_proxy.h new file mode 100644 index 0000000..26e9c56 --- /dev/null +++ b/services/time_manager/include/timer_call_back_proxy.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIMER_CALL_BACK_PROXY_H +#define TIMER_CALL_BACK_PROXY_H + +#include +#include + +#include "itimer_call_back.h" +#include "time_common.h" +#include +namespace OHOS { +namespace MiscServices { +class TimerCallbackProxy : public IRemoteProxy { +public: + explicit TimerCallbackProxy(const sptr& impl); + + ~TimerCallbackProxy(); + DISALLOW_COPY_AND_MOVE(TimerCallbackProxy); + virtual void NotifyTimer(uint64_t timerId) override; + +private: + static inline BrokerDelegator delegator_; +}; + +} // namespace PowerMgr +} // namespace OHOS + +#endif // TIMER_CALL_BACK_PROXY_H diff --git a/services/time_manager/include/timer_call_back_stub.h b/services/time_manager/include/timer_call_back_stub.h new file mode 100644 index 0000000..865ff24 --- /dev/null +++ b/services/time_manager/include/timer_call_back_stub.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIMER_CALL_BACK_STUB_H +#define TIMER_CALL_BACK_STUB_H + +#include +#include +#include "time_common.h" +#include "itimer_call_back.h" +#include +namespace OHOS { +namespace MiscServices { + +class TimerCallbackStub : public IRemoteStub { +public: + DISALLOW_COPY_AND_MOVE(TimerCallbackStub); + TimerCallbackStub() = default; + virtual ~TimerCallbackStub() = default; + int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + int OnTriggerStub(MessageParcel& data); +}; +} // namespace MiscServices +} // namespace OHOS +#endif // TIMER_CALL_BACK_STUB_H diff --git a/services/include/time_service_interface.h b/services/time_manager/src/itimer_info.cpp old mode 100755 new mode 100644 similarity index 58% rename from services/include/time_service_interface.h rename to services/time_manager/src/itimer_info.cpp index 2104173..b284023 --- a/services/include/time_service_interface.h +++ b/services/time_manager/src/itimer_info.cpp @@ -1,34 +1,32 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H -#define SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H - -#include "iremote_broker.h" - -namespace OHOS { -namespace MiscServices { -class ITimeService : public IRemoteBroker { -public: - DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimeService"); - virtual bool SetTime(const int64_t time) = 0; -}; - -enum { - SET_TIME = 0 -}; -} // namespace MiscServices -} // namespace OHOS -#endif // SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H \ No newline at end of file +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "itimer_info.h" + +namespace OHOS { +namespace MiscServices { + +ITimerInfo::ITimerInfo() +{ + +} +ITimerInfo::~ITimerInfo() +{ +} + + +} // MiscServices +} // OHOS + diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp new file mode 100644 index 0000000..17dd653 --- /dev/null +++ b/services/time_manager/src/time_service.cpp @@ -0,0 +1,611 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_service.h" +#include "time_zone_info.h" + +#include "time_common.h" + +#include "system_ability.h" +#include "system_ability_definition.h" +#include "iservice_registry.h" + +#include +#include +#include +#include +#include +#include +#include "pthread.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace OHOS { +namespace MiscServices { + +// Unit of measure conversion , BASE: second +static const int MILLI_TO_BASE = 1000LL; +static const int MICR_TO_BASE = 1000000LL; +static const int NANO_TO_BASE = 1000000000LL; +//constexpr int MILLI_TO_NANO = NANO_TO_BASE / MILLI_TO_BASE; +constexpr int MILLI_TO_MICR = MICR_TO_BASE / MILLI_TO_BASE; +//constexpr int MICR_TO_MILLI = MILLI_TO_BASE / MICR_TO_BASE; +constexpr int NANO_TO_MILLI = NANO_TO_BASE / MILLI_TO_BASE; + + +REGISTER_SYSTEM_ABILITY_BY_ID(TimeService, TIME_SERVICE_ID, true); + +const std::int32_t INIT_INTERVAL = 10000L; + +std::mutex TimeService::instanceLock_; +sptr TimeService::instance_; +std::shared_ptr TimeService::serviceHandler_ = nullptr; +std::shared_ptr TimeService::timeServiceNotify_ = nullptr; +std::shared_ptr TimeService::timerManagerHandler_ = nullptr; + +TimeService::TimeService(int32_t systemAbilityId, bool runOnCreate) + : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START), rtc_id(get_wall_clock_rtc_id()) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," TimeService Start."); +} + +TimeService::TimeService() : state_(ServiceRunningState::STATE_NOT_START), rtc_id(get_wall_clock_rtc_id()) +{ + //TODO : Read time zone information from the global and set to kernel; +} + +TimeService::~TimeService() +{ +} + +sptr TimeService::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new TimeService; + } + } + return instance_; +} + +void TimeService::OnStart() +{ + TIME_HILOGI(TIME_MODULE_SERVICE," TimeService OnStart."); + if (state_ == ServiceRunningState::STATE_RUNNING) { + TIME_HILOGE(TIME_MODULE_SERVICE," TimeService is already running."); + return; + } + + InitServiceHandler(); + InitTimerHandler(); + InitNotifyHandler(); + if (Init() != ERR_OK) { + auto callback = [=]() { Init(); }; + serviceHandler_->PostTask(callback, INIT_INTERVAL); + TIME_HILOGE(TIME_MODULE_SERVICE,"Init failed. Try again 10s later."); + return; + } + + TIME_HILOGI(TIME_MODULE_SERVICE,"Start TimeService success."); + return; +} + +int32_t TimeService::Init() +{ + bool ret = Publish(TimeService::GetInstance()); + if (!ret) { + TIME_HILOGE(TIME_MODULE_SERVICE,"Init Failed."); + return E_TIME_PUBLISH_FAIL; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Init Success."); + state_ = ServiceRunningState::STATE_RUNNING; + return ERR_OK; +} + +void TimeService::OnStop() +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnStop Started."); + if (state_ != ServiceRunningState::STATE_RUNNING) { + return; + } + serviceHandler_ = nullptr; + timeServiceNotify_ = nullptr; + state_ = ServiceRunningState::STATE_NOT_START; + TIME_HILOGI(TIME_MODULE_SERVICE,"OnStop End."); +} + +void TimeService::InitTimeZone(){ + TIME_HILOGD(TIME_MODULE_SERVICE,"start"); + std::string timeZoneId; + auto hasTimeZone = GetTimeZoneId(timeZoneId); + if (!hasTimeZone){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Time Zone Not Found."); + return; + } + int gmtOffset; + struct timezone tz; + TIME_HILOGD(TIME_MODULE_SERVICE,"timezone id: %{public}s.", timeZoneId.c_str()); + auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset); + TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone offset: %{public}d.", gmtOffset); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret); + } + tz.tz_minuteswest = gmtOffset * 60; + tz.tz_dsttime = 0; + + int result = settimeofday(NULL, &tz); + if (result < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result); + } +} + +void TimeService::InitNotifyHandler(){ + + TIME_HILOGI(TIME_MODULE_SERVICE,"InitNotify started."); + if (timeServiceNotify_ != nullptr) { + TIME_HILOGE(TIME_MODULE_SERVICE," Already init."); + return; + } + timeServiceNotify_ = std::make_shared(); + timeServiceNotify_->RegisterPublishEvents(); +} + +void TimeService::InitServiceHandler() +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"InitServiceHandler started."); + if (serviceHandler_ != nullptr) { + TIME_HILOGE(TIME_MODULE_SERVICE," Already init."); + return; + } + std::shared_ptr runner = AppExecFwk::EventRunner::Create(TIME_SERVICE_NAME); + serviceHandler_ = std::make_shared(runner); + + TIME_HILOGI(TIME_MODULE_SERVICE,"InitServiceHandler Succeeded."); +} + +void TimeService::InitTimerHandler(){ + + TIME_HILOGI(TIME_MODULE_SERVICE,"Init Timer started."); + if (timerManagerHandler_ != nullptr) { + TIME_HILOGE(TIME_MODULE_SERVICE," Already init."); + return; + } + timerManagerHandler_ = TimerManager::Create(); +} + +uint64_t TimeService::CreateTimer(int32_t type, bool repeat, uint64_t interval, + sptr &obj) +{ + if (obj == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Input nullptr."); + return 0; + } + auto isRealtime = false; + auto isWakeup = false; + int timerType; + int64_t windowLength; + uint64_t intervalOut; + int flag = 0; + if ((type & TIMER_TYPE_REALTIME_MASK) > 0 ){ + isRealtime = true; + } + if ((type & TIMER_TYPE_REALTIME_WAKEUP_MASK) > 0 ){ + isWakeup = true; + } + if ((type & TIMER_TYPE_EXACT_MASK) > 0){ + windowLength = 0; + }else{ + windowLength = -1; + } + + if (isRealtime && isWakeup){ + timerType = 2; // ELAPSED_REALTIME_WAKEUP = 2 + }else if (isRealtime){ + timerType = 3; // ELAPSED_REALTIME = 3 + }else if (isWakeup){ + timerType = 0; // RTC_WAKEUP = 0 + }else{ + timerType = 1; // RTC = 1 + } + if (repeat){ + intervalOut = (interval < 5000) ? 5000 : interval; + }else{ + intervalOut = 0; + } + sptr timerCallback = iface_cast(obj); + if (timerCallback == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"ITimerCallback nullptr."); + return 0; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Start create timer."); + auto callbackFunc = [timerCallback](uint64_t id){ + timerCallback->NotifyTimer(id); + }; + + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr."); + timerManagerHandler_ = TimerManager::Create(); + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed."); + return 0; + } + } + return timerManagerHandler_->CreateTimer(timerType, windowLength, intervalOut, flag, callbackFunc, 0); +} + +bool TimeService::StartTimer(uint64_t timerId, uint64_t triggerTimes) +{ + uint64_t triggerTimesIn; + triggerTimesIn = (triggerTimes < 5000) ? 5000 : triggerTimes; + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr."); + timerManagerHandler_ = TimerManager::Create(); + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed."); + return 0; + } + } + auto ret = timerManagerHandler_->StartTimer(timerId, triggerTimesIn); + if (!ret){ + TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found."); + } + return ret; +} + +bool TimeService::StopTimer(uint64_t timerId) +{ + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr."); + timerManagerHandler_ = TimerManager::Create(); + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed."); + return 0; + } + } + auto ret = timerManagerHandler_->StopTimer(timerId); + if (!ret){ + TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found."); + } + return ret; +} + +bool TimeService::DestroyTimer(uint64_t timerId) +{ + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr."); + timerManagerHandler_ = TimerManager::Create(); + if (timerManagerHandler_ == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed."); + return 0; + } + } + auto ret = timerManagerHandler_->DestroyTimer(timerId); + if (!ret){ + TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found."); + } + return ret; +} + +int32_t TimeService::SetTime(const int64_t time) +{ + pid_t uid = IPCSkeleton::GetCallingUid(); + auto hasPerm = TimePermission::GetInstance()->CheckCallingPermission(uid, setTimePermName_); + if (!hasPerm){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Permission check failed, uid : %{public}d", uid); + return E_TIME_NO_PERMISSION; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}" PRId64 "", time); + if (time <= 0 || time / 1000LL >= INT_MAX) { + TIME_HILOGE(TIME_MODULE_SERVICE, "input param error"); + return E_TIME_PARAMETERS_INVALID; + } + struct timeval tv{}; + tv.tv_sec = (time_t) (time / MILLI_TO_BASE); + tv.tv_usec = (suseconds_t) ((time % MILLI_TO_BASE) * MILLI_TO_MICR); + + int result = settimeofday(&tv, NULL); + if (result < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result); + return E_TIME_DEAL_FAILED; + } + auto ret = set_rtc_time(tv.tv_sec); + if (ret < 0){ + TIME_HILOGE(TIME_MODULE_SERVICE,"set rtc fail: %{public}d.", ret); + return ERR_OK; + } + + int64_t currentTime = 0; + GetWallTimeMs(currentTime); + if (timeServiceNotify_ != nullptr){ + timeServiceNotify_->PublishTimeChanageEvents(currentTime); + } + + return ERR_OK; +} + +int TimeService::set_rtc_time(time_t sec){ + + struct rtc_time rtc{}; + struct tm tm{}; + struct tm *gmtime_res = nullptr; + int fd = 0; + int res; + if (rtc_id < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"invalid rtc id: %{public}s:", strerror(ENODEV)); + return -1; + } + std::stringstream strs; + strs << "/dev/rtc" << rtc_id; + auto rtc_dev = strs.str(); + TIME_HILOGI(TIME_MODULE_SERVICE,"rtc_dev : %{public}s:", rtc_dev.data()); + fd = open(rtc_dev.data(), O_RDWR); + if (fd < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"open failed %{public}s: %{public}s", rtc_dev.data(), strerror(errno)); + return -1; + } + + gmtime_res = gmtime_r(&sec, &tm); + if (gmtime_res) { + rtc.tm_sec = tm.tm_sec; + rtc.tm_min = tm.tm_min; + rtc.tm_hour = tm.tm_hour; + rtc.tm_mday = tm.tm_mday; + rtc.tm_mon = tm.tm_mon; + rtc.tm_year = tm.tm_year; + rtc.tm_wday = tm.tm_wday; + rtc.tm_yday = tm.tm_yday; + rtc.tm_isdst = tm.tm_isdst; + res = ioctl(fd, RTC_SET_TIME, &rtc); + if (res < 0){ + TIME_HILOGE(TIME_MODULE_SERVICE,"ioctl RTC_SET_TIME failed: %{public}s", strerror(errno)); + } + }else{ + TIME_HILOGE(TIME_MODULE_SERVICE,"convert rtc time failed: %{public}s", strerror(errno)); + res = -1; + } + close(fd); + return res; +} + +bool TimeService::check_rtc(std::string rtc_path, uint32_t rtc_id_t) +{ + std::stringstream strs; + strs << rtc_path << "/rtc" << rtc_id_t << "/hctosys"; + auto hctosys_path = strs.str(); + + uint32_t hctosys; + std::fstream file(hctosys_path.data(), std::ios_base::in); + if (file.is_open()) { + file >> hctosys; + } else { + TIME_HILOGE(TIME_MODULE_SERVICE,"failed to open %{public}s", hctosys_path.data()); + return false; + } + return true; +} + +int TimeService::get_wall_clock_rtc_id() +{ + std::string rtc_path = "/sys/class/rtc"; + + std::unique_ptr dir(opendir(rtc_path.c_str()), closedir); + if (!dir.get()) { + TIME_HILOGE(TIME_MODULE_SERVICE,"failed to open %{public}s: %{public}s", rtc_path.c_str(), strerror(errno)); + return -1; + } + + struct dirent *dirent; + while (errno = 0, dirent = readdir(dir.get())) { + unsigned int rtc_id_t; + int matched = sscanf_s(dirent->d_name, "rtc%u", &rtc_id_t, sizeof(int)); + if (matched < 0) { + break; + } else if (matched != 1) { + continue; + } + if (check_rtc(rtc_path, rtc_id_t)) { + TIME_HILOGD(TIME_MODULE_SERVICE,"found wall clock rtc %{public}u", rtc_id_t); + return rtc_id_t; + } + } + + if (errno == 0){ + TIME_HILOGE(TIME_MODULE_SERVICE,"no wall clock rtc found"); + }else{ + TIME_HILOGE(TIME_MODULE_SERVICE,"failed to check rtc: %{public}s", strerror(errno)); + } + return -1; +} + +int32_t TimeService::SetTimeZone(const std::string timeZoneId) +{ + pid_t uid = IPCSkeleton::GetCallingUid(); + auto hasPerm = TimePermission::GetInstance()->CheckCallingPermission(uid, setTimezonePermName_); + if (!hasPerm){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Permission check failed, uid : %{public}d", uid); + return E_TIME_NO_PERMISSION; + } + int gmtOffset; + struct timezone tz; + TIME_HILOGE(TIME_MODULE_SERVICE,"timezone id: %{public}s.", timeZoneId.c_str()); + auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset); + TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone offset: %{public}d.", gmtOffset); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret); + return ret; + } + tz.tz_minuteswest = gmtOffset * 60; + tz.tz_dsttime = 0; + + int result = settimeofday(NULL, &tz); + if (result < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result); + return E_TIME_DEAL_FAILED; + } + int64_t currentTime = 0; + GetWallTimeMs(currentTime); + if (timeServiceNotify_ != nullptr){ + timeServiceNotify_->PublishTimeZoneChangeEvents(currentTime); + } + return ERR_OK; +} + + +int32_t TimeService::GetTimeZone(std::string &timeZoneId) +{ + std::string curTimezone; + auto ret = TimeZoneInfo::GetInstance()->GetTimezoneId(curTimezone); + TIME_HILOGI(TIME_MODULE_SERVICE,"get timezone : %{public}s.", curTimezone.c_str()); + if (ret == ERR_OK){ + timeZoneId = curTimezone; + return ERR_OK; + } + TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret); + return ret; +} + +int32_t TimeService::GetWallTimeMs(int64_t ×) +{ + struct timespec tv{}; + + if(GetTimeByClockid(CLOCK_REALTIME, &tv)){ + times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; + return ERR_OK; + } + + return E_TIME_DEAL_FAILED; +} + +int32_t TimeService::GetWallTimeNs(int64_t ×) +{ + struct timespec tv{}; + + if(GetTimeByClockid(CLOCK_REALTIME, &tv)){ + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + return ERR_OK; + } + + return E_TIME_DEAL_FAILED; +} + +int32_t TimeService::GetBootTimeMs(int64_t ×) +{ + struct timespec tv{}; + + if(GetTimeByClockid(CLOCK_BOOTTIME, &tv)){ + times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; + return ERR_OK; + } + + return E_TIME_DEAL_FAILED; +} + +int32_t TimeService::GetBootTimeNs(int64_t ×) +{ + struct timespec tv{}; + + if(GetTimeByClockid(CLOCK_BOOTTIME, &tv)){ + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + return ERR_OK; + } + + return E_TIME_DEAL_FAILED; +} + +int32_t TimeService::GetMonotonicTimeMs(int64_t ×) +{ + struct timespec tv{}; + + if(GetTimeByClockid(CLOCK_MONOTONIC, &tv)){ + times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; + return ERR_OK; + } + return E_TIME_DEAL_FAILED; +} + + +int32_t TimeService::GetMonotonicTimeNs(int64_t ×) +{ + struct timespec tv{}; + + if(GetTimeByClockid(CLOCK_MONOTONIC, &tv)){ + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + return ERR_OK; + } + + return E_TIME_DEAL_FAILED; +} + + +int32_t TimeService::GetThreadTimeMs(int64_t ×) +{ + struct timespec tv{}; + int ret; + clockid_t cid; + ret = pthread_getcpuclockid(pthread_self(), &cid); + if (ret != 0){ + return E_TIME_PARAMETERS_INVALID; + } + + if(GetTimeByClockid(cid, &tv)){ + times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; + return ERR_OK; + } + + return E_TIME_DEAL_FAILED; +} + +int32_t TimeService::GetThreadTimeNs(int64_t ×) +{ + struct timespec tv{}; + int ret; + clockid_t cid; + ret = pthread_getcpuclockid(pthread_self(), &cid); + if (ret != 0){ + return E_TIME_PARAMETERS_INVALID; + } + + if(GetTimeByClockid(cid, &tv)){ + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + return ERR_OK; + } + + return E_TIME_DEAL_FAILED; +} + + +bool TimeService::GetTimeByClockid(clockid_t clk_id, struct timespec* tv){ + + if (clock_gettime(clk_id, tv) < 0){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Failed clock_gettime."); + return false; + } + return true; +} + + +} // namespace MiscServices +} // namespace OHOS + diff --git a/services/time_manager/src/time_service_client.cpp b/services/time_manager/src/time_service_client.cpp new file mode 100644 index 0000000..17a8b59 --- /dev/null +++ b/services/time_manager/src/time_service_client.cpp @@ -0,0 +1,401 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_service_client.h" +#include "time_common.h" +#include +#include "system_ability_definition.h" +#include "iservice_registry.h" +#include + +namespace OHOS { +namespace MiscServices { + +std::mutex TimeServiceClient::instanceLock_; +sptr TimeServiceClient::instance_; +sptr TimeServiceClient::timeServiceProxy_; +sptr TimeServiceClient::deathRecipient_; + +TimeServiceClient::TimeServiceClient() +{ +} + +TimeServiceClient::~TimeServiceClient() +{ +} + +sptr TimeServiceClient::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new TimeServiceClient; + } + } + return instance_; +} + +sptr TimeServiceClient::ConnectService() +{ + sptr systemAbilityManager = + SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Getting SystemAbilityManager failed."); + return nullptr; + } + + auto systemAbility = systemAbilityManager->GetSystemAbility(TIME_SERVICE_ID); + if (systemAbility == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Get SystemAbility failed."); + return nullptr; + } + deathRecipient_ = new TimeSaDeathRecipient(); + systemAbility->AddDeathRecipient(deathRecipient_); + sptr timeServiceProxy = iface_cast(systemAbility); + if (timeServiceProxy == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Get TimeServiceProxy from SA failed."); + return nullptr; + } + + TIME_HILOGD(TIME_MODULE_CLIENT, "Getting TimeServiceProxy succeeded."); + return timeServiceProxy; +} + +bool TimeServiceClient::TimeServiceClient::SetTime(const int64_t time) +{ + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "SetTime quit because redoing ConnectService failed."); + return false; + } + + if(timeServiceProxy_->SetTime(time) != ERR_OK){ + return false; + } + return true; +} + +bool TimeServiceClient::SetTimeZone(const std::string timezoneId) +{ + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "SetTimeZone quit because redoing ConnectService failed."); + return false; + } + + if(timeServiceProxy_->SetTimeZone(timezoneId) != ERR_OK){ + return false; + } + return true; +} + + +uint64_t TimeServiceClient::CreateTimer(std::shared_ptr TimerOptions) +{ + if (TimerOptions == nullptr){ + TIME_HILOGW(TIME_MODULE_CLIENT, "Input nullptr"); + return 0; + } + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, " quit because redoing ConnectService failed."); + return 0; + } + + auto timerCallbackInfoObject = TimerCallback::GetInstance()->AsObject(); + if (!timerCallbackInfoObject) { + TIME_HILOGE(TIME_MODULE_CLIENT, "New TimerCallback failed"); + return 0; + } + + auto timerId = timeServiceProxy_->CreateTimer(TimerOptions->type, TimerOptions->repeat, TimerOptions->interval, timerCallbackInfoObject); + + if (timerId == 0){ + TIME_HILOGE(TIME_MODULE_CLIENT, "Create timer failed"); + return 0; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"CreateTimer id: %{public}" PRId64 "", timerId); + auto ret = TimerCallback::GetInstance()->InsertTimerCallbackInfo(timerId, TimerOptions); + + if(!ret){ + return 0; + } + return timerId; +} + +bool TimeServiceClient::StartTimer(uint64_t timerId, uint64_t triggerTime) +{ + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "StartTimer quit because redoing ConnectService failed."); + return false; + } + + return timeServiceProxy_->StartTimer(timerId, triggerTime); +} + +bool TimeServiceClient::StopTimer(uint64_t timerId) +{ + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "StopTimer quit because redoing ConnectService failed."); + return false; + } + + return timeServiceProxy_->StopTimer(timerId); +} + +bool TimeServiceClient::DestroyTimer(uint64_t timerId) +{ + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "DestroyTimer quit because redoing ConnectService failed."); + return false; + } + if (timeServiceProxy_->DestroyTimer(timerId)){ + TimerCallback::GetInstance()->RemoveTimerCallbackInfo(timerId); + return true; + } + return false; +} + +std::string TimeServiceClient::GetTimeZone() +{ + std::string timeZoneId; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetTimeZone quit because redoing ConnectService failed."); + return std::string(""); + } + + if(timeServiceProxy_->GetTimeZone(timeZoneId) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return std::string(""); + } + return timeZoneId; +} + +int64_t TimeServiceClient::GetWallTimeMs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeMs quit because redoing ConnectService failed."); + return -1; + } + if(timeServiceProxy_->GetWallTimeMs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + +int64_t TimeServiceClient::GetWallTimeNs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeNs quit because redoing ConnectService failed."); + return -1; + } + + if(timeServiceProxy_->GetWallTimeNs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + +int64_t TimeServiceClient::GetBootTimeMs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeMs quit because redoing ConnectService failed."); + return -1; + } + + if(timeServiceProxy_->GetBootTimeMs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + +int64_t TimeServiceClient::GetBootTimeNs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeNs quit because redoing ConnectService failed."); + return -1; + } + + if(timeServiceProxy_->GetBootTimeNs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + +int64_t TimeServiceClient::GetMonotonicTimeMs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeMs quit because redoing ConnectService failed."); + return -1; + } + + if(timeServiceProxy_->GetMonotonicTimeMs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + +int64_t TimeServiceClient::GetMonotonicTimeNs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeNs quit because redoing ConnectService failed."); + return -1; + } + + if(timeServiceProxy_->GetMonotonicTimeNs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + +int64_t TimeServiceClient::GetThreadTimeMs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeMs quit because redoing ConnectService failed."); + return -1; + } + + if(timeServiceProxy_->GetThreadTimeMs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + +int64_t TimeServiceClient::GetThreadTimeNs() +{ + int64_t times; + if (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeNs quit because redoing ConnectService failed."); + return -1; + } + if(timeServiceProxy_->GetThreadTimeNs(times) != ERR_OK){ + TIME_HILOGE(TIME_MODULE_CLIENT, "get failed."); + return -1; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times); + return times; +} + + +void TimeServiceClient::OnRemoteSaDied(const wptr &remote) +{ + timeServiceProxy_ = ConnectService(); +} + +TimeSaDeathRecipient::TimeSaDeathRecipient() +{ +} + +void TimeSaDeathRecipient::OnRemoteDied(const wptr &object) +{ + TIME_HILOGE(TIME_MODULE_CLIENT, "TimeSaDeathRecipient on remote systemAbility died."); + TimeServiceClient::GetInstance()->OnRemoteSaDied(object); +} + +} // namespace MiscServices +} // namespace OHOS diff --git a/services/time_manager/src/time_service_notify.cpp b/services/time_manager/src/time_service_notify.cpp new file mode 100644 index 0000000..641c789 --- /dev/null +++ b/services/time_manager/src/time_service_notify.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_service_notify.h" + +#include "common_event_data.h" +#include "common_event_manager.h" +#include "common_event_support.h" +#include + +using namespace OHOS::AAFwk; +using namespace OHOS::EventFwk; + +namespace OHOS{ +namespace MiscServices{ + +void TimeServiceNotify::RegisterPublishEvents() +{ + if (publishInfo_ != nullptr) { + return; + } + publishInfo_ = new (std::nothrow)CommonEventPublishInfo(); + publishInfo_->SetOrdered(false); + timeChangeWant_ = new (std::nothrow)IntentWant(); + timeChangeWant_->SetAction(CommonEventSupport::COMMON_EVENT_TIME_CHANGED); + timeZoneChangeWant_ = new (std::nothrow)IntentWant(); + timeZoneChangeWant_->SetAction(CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED); +} + +void TimeServiceNotify::PublishEvents(int64_t eventTime, sptr want) +{ + if ((want == nullptr) || (publishInfo_ == nullptr)) { + TIME_HILOGE(TIME_MODULE_SERVICE, "Invalid parameter"); + return; + } + + TIME_HILOGI(TIME_MODULE_SERVICE, "Start to publish event %{public}s at %{public}lld", + want->GetAction().c_str(), static_cast(eventTime)); + CommonEventData event(*want); + CommonEventManager::PublishCommonEvent(event, *publishInfo_, nullptr); + TIME_HILOGI(TIME_MODULE_SERVICE, "Publish event %{public}s done", want->GetAction().c_str()); +} + +void TimeServiceNotify::PublishTimeChanageEvents(int64_t eventTime) +{ + PublishEvents(eventTime, timeChangeWant_); +} + +void TimeServiceNotify::PublishTimeZoneChangeEvents(int64_t eventTime) +{ + PublishEvents(eventTime, timeZoneChangeWant_); +} + + +} // MiscService +} // OHOS diff --git a/services/time_manager/src/time_service_proxy.cpp b/services/time_manager/src/time_service_proxy.cpp new file mode 100644 index 0000000..14210e9 --- /dev/null +++ b/services/time_manager/src/time_service_proxy.cpp @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is: distributed on an "AS is:"BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_service_proxy.h" +#include "iremote_broker.h" +#include "time_common.h" +#include "time_service_interface.h" + +namespace OHOS { +namespace MiscServices { +using namespace OHOS::HiviewDFX; + +TimeServiceProxy::TimeServiceProxy(const sptr &object) : IRemoteProxy(object) +{ +} + +int32_t TimeServiceProxy::SetTime(const int64_t time) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + if (!data.WriteInt64(time)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + int32_t result = Remote()->SendRequest(SET_TIME, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "SetTime failed, error code is: %{public}d",result); + return result; + } + return result; +} + +uint64_t TimeServiceProxy::CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr &timerCallback) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return 0; + } + + if (!data.WriteInt32(type)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return 0; + } + + if (!data.WriteBool(repeat)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return 0; + } + + if (!data.WriteUint64(interval)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return 0; + } + + if (!data.WriteRemoteObject(timerCallback)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return 0; + } + int32_t result = Remote()->SendRequest(CREATE_TIMER, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "CreateTimer failed, error code is: %{public}d",result); + return 0; + } + auto TimerId = reply.ReadUint64(); + + return TimerId; +} + +bool TimeServiceProxy::StartTimer(uint64_t timerId, uint64_t triggerTimes) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + if (!data.WriteUint64(timerId)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + if (!data.WriteUint64(triggerTimes)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + int32_t result = Remote()->SendRequest(START_TIMER, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "Start failed, error code is: %{public}d",result); + return false; + } + return true; +} + +bool TimeServiceProxy::StopTimer(uint64_t timerId) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + if (!data.WriteUint64(timerId)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + int32_t result = Remote()->SendRequest(STOP_TIMER, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "Stop failed, error code is: %{public}d",result); + return false; + } + + return true; +} +bool TimeServiceProxy::DestroyTimer(uint64_t timerId) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + if (!data.WriteUint64(timerId)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + int32_t result = Remote()->SendRequest(DESTORY_TIMER, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "failed, error code is: %{public}d",result); + return false; + } + + return true; +} + +int32_t TimeServiceProxy::SetTimeZone(std::string timezoneId) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + if (!data.WriteString(timezoneId)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(SET_TIME_ZONE, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "SetTimeZone failed, error code is: %{public}d",result); + return result; + } + return result; +} + +int32_t TimeServiceProxy::GetTimeZone(std::string &timezoneId) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_TIME_ZONE, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetTimeZone failed, error code is: %{public}d",result); + return result; + } + timezoneId = reply.ReadString(); + return result; +} + +int32_t TimeServiceProxy::GetWallTimeMs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_WALL_TIME_MILLI, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeMs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} + +int32_t TimeServiceProxy::GetWallTimeNs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_WALL_TIME_NANO, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeNs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} + +int32_t TimeServiceProxy::GetBootTimeMs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_BOOT_TIME_MILLI, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeMs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} + +int32_t TimeServiceProxy::GetBootTimeNs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_BOOT_TIME_MILLI, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeNs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} + +int32_t TimeServiceProxy::GetMonotonicTimeMs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_MONO_TIME_MILLI, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeMs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} + +int32_t TimeServiceProxy::GetMonotonicTimeNs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_MONO_TIME_NANO, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeNs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} + +int32_t TimeServiceProxy::GetThreadTimeMs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_THREAD_TIME_MILLI, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeMs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} + +int32_t TimeServiceProxy::GetThreadTimeNs(int64_t ×) +{ + MessageParcel data, reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + + int32_t result = Remote()->SendRequest(GET_THREAD_TIME_NANO, data, reply, option); + if (result != ERR_NONE){ + TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeNs failed, error code is: %{public}d",result); + return result; + } + times = reply.ReadInt64(); + return result; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/time_manager/src/time_service_stub.cpp b/services/time_manager/src/time_service_stub.cpp new file mode 100644 index 0000000..940cc3d --- /dev/null +++ b/services/time_manager/src/time_service_stub.cpp @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_service_stub.h" +#include + +#include "time_common.h" + +namespace OHOS { +namespace MiscServices { +using namespace OHOS::HiviewDFX; + +TimeServiceStub::TimeServiceStub(){ + memberFuncMap_[SET_TIME] = &TimeServiceStub::OnSetTime; + memberFuncMap_[SET_TIME_ZONE] = &TimeServiceStub::OnSetTimeZone; + memberFuncMap_[GET_TIME_ZONE] = &TimeServiceStub::OnGetTimeZone; + memberFuncMap_[GET_WALL_TIME_MILLI] = &TimeServiceStub::OnGetWallTimeMs; + memberFuncMap_[GET_WALL_TIME_NANO] = &TimeServiceStub::OnGetWallTimeNs; + + memberFuncMap_[GET_BOOT_TIME_MILLI] = &TimeServiceStub::OnGetBootTimeMs; + memberFuncMap_[GET_BOOT_TIME_NANO] = &TimeServiceStub::OnGetBootTimeNs; + memberFuncMap_[GET_MONO_TIME_MILLI] = &TimeServiceStub::OnGetMonotonicTimeMs; + memberFuncMap_[GET_MONO_TIME_NANO] = &TimeServiceStub::OnGetMonotonicTimeMs; + memberFuncMap_[GET_THREAD_TIME_MILLI] = &TimeServiceStub::OnGetThreadTimeMs; + memberFuncMap_[GET_THREAD_TIME_NANO] = &TimeServiceStub::OnGetThreadTimeNs; + memberFuncMap_[CREATE_TIMER] = &TimeServiceStub::OnCreateTimer; + memberFuncMap_[START_TIMER] = &TimeServiceStub::OnStartTimer; + memberFuncMap_[STOP_TIMER] = &TimeServiceStub::OnStopTimer; + memberFuncMap_[DESTORY_TIMER] = &TimeServiceStub::OnDestoryTimer; +} +TimeServiceStub::~TimeServiceStub(){ + memberFuncMap_.clear(); +} + +int32_t TimeServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start##code = %{public}u", code); + std::u16string myDescripter = TimeServiceStub::GetDescriptor(); + std::u16string remoteDescripter = data.ReadInterfaceToken(); + if (myDescripter != remoteDescripter) { + TIME_HILOGE(TIME_MODULE_SERVICE," end##descriptor checked fail"); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + pid_t p = IPCSkeleton::GetCallingPid(); + pid_t p1 = IPCSkeleton::GetCallingUid(); + TIME_HILOGI(TIME_MODULE_SERVICE,"CallingPid = %{public}d, CallingUid = %{public}d, code = %{public}u", p, p1, code); + auto itFunc = memberFuncMap_.find(code); + if (itFunc != memberFuncMap_.end()) { + auto memberFunc = itFunc->second; + if (memberFunc != nullptr) { + return (this->*memberFunc)(data, reply); + } + } + int ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); + TIME_HILOGI(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; +} + +int32_t TimeServiceStub::OnSetTime(MessageParcel& data, MessageParcel& reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t time = data.ReadInt64(); + + int32_t ret = SetTime(time); + TIME_HILOGI(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; +} + +int32_t TimeServiceStub::OnSetTimeZone(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + std::string timeZoneId = data.ReadString(); + + int32_t ret = SetTimeZone(timeZoneId); + TIME_HILOGI(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; +} + +int32_t TimeServiceStub::OnGetTimeZone(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + std::string timeZoneId; + + int32_t ret = GetTimeZone(timeZoneId); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteString(timeZoneId); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetWallTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + + int32_t ret = GetWallTimeMs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetWallTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + + int32_t ret = GetWallTimeNs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetBootTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + + int32_t ret = GetBootTimeMs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetBootTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + + int32_t ret = GetBootTimeNs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetMonotonicTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + + int32_t ret = GetMonotonicTimeMs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetMonotonicTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + + int32_t ret = GetMonotonicTimeNs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetThreadTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + + int32_t ret = GetThreadTimeMs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnGetThreadTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE," start."); + int64_t times; + int32_t ret = GetThreadTimeNs(times); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); + return ret; +} + +int32_t TimeServiceStub::OnCreateTimer(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"start."); + + auto type = data.ReadInt32(); + auto repeat = data.ReadBool(); + auto interval = data.ReadUint64(); + + sptr obj = data.ReadRemoteObject(); + if(obj == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Input nullptr"); + return E_TIME_PARAMETERS_INVALID; + } + auto timerId = CreateTimer(type, repeat, interval, obj); + if (timerId == 0 ){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Create timer failed"); + return E_TIME_DEAL_FAILED; + } + if (!reply.WriteUint64(timerId)){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to write parcelable"); + return E_TIME_WRITE_PARCEL_ERROR; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"end."); + return ERR_OK; +} + +int32_t TimeServiceStub::OnStartTimer(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"start."); + + auto timerId = data.ReadUint64(); + + auto triggerTime = data.ReadUint64(); + + if (!StartTimer(timerId, triggerTime)){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to start timer"); + return E_TIME_DEAL_FAILED; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"end."); + return ERR_OK; + +} +int32_t TimeServiceStub::OnStopTimer(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"start."); + + auto timerId = data.ReadUint64(); + + if (!StopTimer(timerId)){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to stop timer"); + return E_TIME_DEAL_FAILED; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"end."); + return ERR_OK; +} +int32_t TimeServiceStub::OnDestoryTimer(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"start."); + + auto timerId = data.ReadUint64(); + + if (!DestroyTimer(timerId)){ + TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to destory timer"); + return E_TIME_DEAL_FAILED; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"end."); + return ERR_OK; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/time_manager/src/time_zone_info.cpp b/services/time_manager/src/time_zone_info.cpp new file mode 100644 index 0000000..e3f5cf1 --- /dev/null +++ b/services/time_manager/src/time_zone_info.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_zone_info.h" +#include "time_common.h" + +#include + +namespace OHOS{ +namespace MiscServices{ + +std::mutex TimeZoneInfo::instanceLock_; +sptr TimeZoneInfo::instance_; + +TimeZoneInfo::TimeZoneInfo() +{ + std::vector timezoneList = { + {"Anadyr, Russia", "ANA", 12, "Anadyr Time"}, + {"Honiara, SolomonIslands", "SBT", 11, "Solomon Islands Time"}, + {"Melbourne, Australia", "AEST", 10, "Australian Eastern Standard Time"}, + {"Tokyo, Japan", "JST", 9, "Japan Standard Time"}, + {"Beijing, China", "CST", 8, "China Standard Time"}, + {"Jakarta, Indonesia", "WIB", 7, "Western Indonesian Time"}, + {"Dhaka, Bangladesh", "BST", 6, "Bangladesh Standard Time"}, + {"Tashkent, Uzbekistan", "UZT", 5, "Uzbekistan Time"}, + {"Dubai, U.A.E.", "GST", 4, "Gulf Standard Time"}, + {"Moscow, Russia", "MSK", 3, "Moscow Standard Time"}, + {"Brussels, Belgium", "CEST", 2, "Central European Summer Time"}, + {"London, England", "BST", 1, "British Summer Time"}, + {"Accra, Ghana", "GMT", 0, "Greenwich Mean Time"}, + {"Accra, Ghana", "UTC", 0, "Universal Time Coordinated"}, + {"Praia, CaboVerde", "CVT", -1, "Cabo Verde Time"}, + {"Nuuk, Greenland", "WGS", -2, "Western Greenland Summer Time"}, + {"Buenos Aires, Argentina", "ART", -3, "Argentina Time"}, + {"New York, U.S.A.", "EDT", -4, "Eastern Daylight Time"}, + {"Mexico City, Mexico", "CDT", -5, "Central Daylight Time"}, + {"Guatemala City, Guatemala", "CST", -6, "Central Standard Time"}, + {"Los Angeles, U.S.A.", "PDT", -7, "Pacific Daylight Time"}, + {"Anchorage, U.S.A.", "AKD", -8, "Alaska Daylight Time"}, + {"Adak, U.S.A.", "HDT", -9, "Hawaii-Aleutian Daylight Time"}, + {"Honolulu, U.S.A.", "HST", -10, "Hawaii Standard Time"}, + {"Alofi, Niue", "NUT", -11, "Niue Time"}, + {"Baker Island, U.S.A.", "AoE", -12, "Anywhere on Earth"}, + }; + + for (auto tz : timezoneList) { + timezoneInfoMap_[tz.ID] = tz; + } + +} + +TimeZoneInfo::~TimeZoneInfo(){ + timezoneInfoMap_.clear(); +} + +int32_t TimeZoneInfo::GetOffset(const std::string timezoneId, int &offset){ + auto itEntry = timezoneInfoMap_.find(timezoneId); + if (itEntry != timezoneInfoMap_.end()) { + auto zoneInfo = itEntry->second; + offset = zoneInfo.utcOffsetHours; + curTimezoneId_ = timezoneId; + return ERR_OK; + } + TIME_HILOGE(TIME_MODULE_SERVICE, "TimezoneId not found."); + return E_TIME_NOT_FOUND; +} + +int32_t TimeZoneInfo::GetTimezoneId( std::string &timezoneId ){ + timezoneId = curTimezoneId_; + return ERR_OK; +} + +sptr TimeZoneInfo::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new TimeZoneInfo; + } + } + return instance_; +} + +} +} \ No newline at end of file diff --git a/services/time_manager/src/timer_call_back.cpp b/services/time_manager/src/timer_call_back.cpp new file mode 100644 index 0000000..378daea --- /dev/null +++ b/services/time_manager/src/timer_call_back.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "timer_call_back.h" + +namespace OHOS { +namespace MiscServices { + +std::mutex TimerCallback::instanceLock_; +sptr TimerCallback::instance_; + +std::map> TimerCallback::TimerInfoMap_; +std::mutex TimerCallback::timerInfoMutex_; + +TimerCallback::TimerCallback() +{ +} + +TimerCallback::~TimerCallback() +{ + TimerInfoMap_.clear(); +} + +sptr TimerCallback::GetInstance() +{ + if (instance_ == nullptr) { + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new TimerCallback; + } + } + return instance_; +} + +bool TimerCallback::InsertTimerCallbackInfo(const uint64_t timerId, + const std::shared_ptr &timerInfo) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + if (timerInfo == nullptr){ + return false; + } + + std::lock_guard lock(timerInfoMutex_); + auto info = TimerInfoMap_.find(timerId); + if (info != TimerInfoMap_.end()) { + TIME_HILOGE(TIME_MODULE_CLIENT, "timer info already insert."); + return false; + } else { + TimerInfoMap_[timerId] = timerInfo; + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return true; +} + +bool TimerCallback::RemoveTimerCallbackInfo(const uint64_t timerId) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + std::lock_guard lock(timerInfoMutex_); + auto info = TimerInfoMap_.find(timerId); + if (info != TimerInfoMap_.end()) { + TimerInfoMap_.erase(info); + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return true; + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return false; +} + +void TimerCallback::NotifyTimer(const uint64_t timerId) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + std::lock_guard lock(timerInfoMutex_); + auto it = TimerInfoMap_.find(timerId); + if (it != TimerInfoMap_.end()) { + TIME_HILOGD(TIME_MODULE_SERVICE, "ontrigger."); + it->second->OnTrigger(); + + if (it->second->wantAgent != nullptr){ + TIME_HILOGD(TIME_MODULE_SERVICE, "trigger wantagent."); + std::shared_ptr context = std::make_shared(); + std::shared_ptr want = Notification::WantAgent::WantAgentHelper::GetWant(it->second->wantAgent); + + OHOS::Notification::WantAgent::TriggerInfo paramsInfo("", nullptr, want, 11); + Notification::WantAgent::WantAgentHelper::TriggerWantAgent(context, it->second->wantAgent, nullptr, paramsInfo); + } + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); +} + +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/time_manager/src/timer_call_back_proxy.cpp b/services/time_manager/src/timer_call_back_proxy.cpp new file mode 100644 index 0000000..794b6d4 --- /dev/null +++ b/services/time_manager/src/timer_call_back_proxy.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "timer_call_back_proxy.h" + +namespace OHOS { +namespace MiscServices { + +TimerCallbackProxy::TimerCallbackProxy(const sptr &object) : IRemoteProxy(object) +{ +} + + +TimerCallbackProxy::~TimerCallbackProxy() +{ + TIME_HILOGD(TIME_MODULE_CLIENT, "TimerCallbackProxy instance destoryed"); +} + +void TimerCallbackProxy::NotifyTimer(uint64_t timerId) +{ + TIME_HILOGD(TIME_MODULE_CLIENT, "start id: %{public}" PRId64 "", timerId); + sptr remote = Remote(); + if (remote == nullptr){ + return; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + TIME_HILOGE(TIME_MODULE_CLIENT, "write descriptor failed!"); + return; + } + + if (!data.WriteUint64(timerId)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "write timerId failed!"); + return; + } + int ret = remote->SendRequest(static_cast(ITimerCallback::Message::NOTIFY_TIMER), data, reply, option); + if (ret != ERR_OK) { + TIME_HILOGE(TIME_MODULE_CLIENT, "SendRequest is failed, error code: %{public}d", ret); + } + TIME_HILOGI(TIME_MODULE_CLIENT, "end."); +} + +} // namespace MiscServices +} // namespace OHOS diff --git a/services/time_manager/src/timer_call_back_stub.cpp b/services/time_manager/src/timer_call_back_stub.cpp new file mode 100644 index 0000000..2840536 --- /dev/null +++ b/services/time_manager/src/timer_call_back_stub.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "timer_call_back_stub.h" + +namespace OHOS { +namespace MiscServices { + +int TimerCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "cmd = %{public}d, flags= %{public}d", code, option.GetFlags()); + std::u16string descripter = GetDescriptor(); + std::u16string remoteDescripter = data.ReadInterfaceToken(); + if (descripter != remoteDescripter) { + TIME_HILOGE(TIME_MODULE_SERVICE, " failed, descriptor is not matched!"); + return E_TIME_READ_PARCEL_ERROR; + } + + switch (code) { + case static_cast(ITimerCallback::Message::NOTIFY_TIMER): { + return OnTriggerStub(data); + } + default: + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + return ERR_OK; +} + +int TimerCallbackStub::OnTriggerStub(MessageParcel& data) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + auto timerId = data.ReadUint64(); + TIME_HILOGD(TIME_MODULE_CLIENT, "id: %{public}" PRId64 "", timerId); + NotifyTimer(timerId); + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return ERR_OK; +} + +} // namespace MiscServices +} // namespace OHOS diff --git a/services/test/BUILD.gn b/services/time_manager/test/BUILD.gn old mode 100755 new mode 100644 similarity index 51% rename from services/test/BUILD.gn rename to services/time_manager/test/BUILD.gn index 3ce06ca..33927f5 --- a/services/test/BUILD.gn +++ b/services/time_manager/test/BUILD.gn @@ -9,26 +9,54 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and -# limitations under the License. +# limitations under the License. import("//build/test.gni") +config("module_private_config") { + visibility = [ ":*" ] + + include_dirs = [ + "//base/miscservices/time/interfaces/innerkits/include", + "unittest/include", + "//foundation/ace/napi/interfaces/kits/napi", + ] +} + module_output_path = "time_native/time_service" ohos_unittest("TimeServiceTest") { module_out_path = module_output_path - sources = [ "unittest/time_service_test.cpp" ] - external_deps = [ - "hiviewdfx_hilog_native:libhilog", - "ipc:ipc_core", + sources = [ "unittest/src/time_service_test.cpp" ] + + configs = [ + ":module_private_config", ] deps = [ "//base/miscservices/time/services:time_service", + "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", + "//foundation/ace/napi:ace_napi", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr:distributedschedsvr", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", "//third_party/googletest:gtest_main", "//utils/native/base:utils", ] + + external_deps = [ + "aafwk_standard:base", + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "appexecfwk_standard:libeventhandler", + "ces_standard:cesfwk_innerkits", + "hisysevent_native:libhisysevent", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr_L2:samgr_proxy", + ] } group("unittest") { diff --git a/services/time_manager/test/unittest/include/timer_test.h b/services/time_manager/test/unittest/include/timer_test.h new file mode 100644 index 0000000..92efe34 --- /dev/null +++ b/services/time_manager/test/unittest/include/timer_test.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "napi/native_api.h" +#include "napi/native_node_api.h" +#include +#include +#include +#include +#include + +#include +#include "time_common.h" +#include "time_service_client.h" +#include +#include + +namespace OHOS{ +namespace MiscServices{ +class TimerInfoTest : public ITimerInfo { +public: + TimerInfoTest(); + virtual ~TimerInfoTest(); + virtual void OnTrigger() override; + virtual void SetType(const int &type) override; + virtual void SetRepeat(bool repeat) override; + virtual void SetInterval(const uint64_t &interval) override; + virtual void SetWantAgent(std::shared_ptr wantAgent) override; + void SetCallbackInfo(const std::function &callBack); + + private: + std::function callBack_ = nullptr; +}; + +TimerInfoTest::TimerInfoTest() +{ +} + +TimerInfoTest::~TimerInfoTest() +{ +} + +void TimerInfoTest::OnTrigger() +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + if (callBack_ != nullptr){ + TIME_HILOGD(TIME_MODULE_SERVICE, "call back."); + callBack_(); + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); +} + +void TimerInfoTest::SetCallbackInfo(const std::function &callBack) +{ + callBack_ = callBack; +} + +void TimerInfoTest::SetType(const int &_type) +{ + type = _type; +} + +void TimerInfoTest::SetRepeat(bool _repeat) +{ + repeat = _repeat; +} +void TimerInfoTest::SetInterval(const uint64_t &_interval) +{ + interval = _interval; +} +void TimerInfoTest::SetWantAgent(std::shared_ptr _wantAgent) +{ + wantAgent = _wantAgent; +} + +} +} diff --git a/services/time_manager/test/unittest/src/time_service_test.cpp b/services/time_manager/test/unittest/src/time_service_test.cpp new file mode 100644 index 0000000..a1bc362 --- /dev/null +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -0,0 +1,362 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "timer_test.h" + +using namespace testing::ext; +using namespace OHOS; +using namespace OHOS::MiscServices; + +class TimeServiceTest : public testing::Test +{ +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void TimeServiceTest::SetUpTestCase(void) +{ +} + +void TimeServiceTest::TearDownTestCase(void) +{ +} + +void TimeServiceTest::SetUp(void) +{ +} + +void TimeServiceTest::TearDown(void) +{ +} + +/** +* @tc.name: SetTime001 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, SetTime001, TestSize.Level0) +{ + struct timeval getTime; + gettimeofday(&getTime, NULL); + int64_t time = (getTime.tv_sec + 1000) * 1000 + getTime.tv_usec / 1000; + TIME_HILOGI(TIME_MODULE_CLIENT, "Time now : %{public}" PRId64 "",time); + bool result = TimeServiceClient::GetInstance()->SetTime(time); + EXPECT_TRUE(result); +} + +#if 0 +/** +* @tc.name: SetTimeZone001 +* @tc.desc: set system time zone. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, SetTimeZone001, TestSize.Level0) +{ + std::string timeZoneSet("Beijing, China"); + + bool result = TimeServiceClient::GetInstance()->SetTimeZone(timeZoneSet); + EXPECT_TRUE(result); + auto timeZoneRes = TimeServiceClient::GetInstance()->GetTimeZone(); + EXPECT_EQ(timeZoneRes, timeZoneSet); +} + +/** +* @tc.name: SetTimeZone001 +* @tc.desc: set system time zone. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, SetTimeZone002, TestSize.Level0) +{ + std::string timeZoneSet("Beijing, China"); + + bool result = TimeServiceClient::GetInstance()->SetTimeZone(timeZoneSet); + EXPECT_TRUE(result); + auto timeZoneRes = TimeServiceClient::GetInstance()->GetTimeZone(); + EXPECT_EQ(timeZoneRes, timeZoneSet); +} + +/** +* @tc.name: GetTime001 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime001, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetWallTimeMs(); + EXPECT_TRUE(time1 > 0); + auto time2 = TimeServiceClient::GetInstance()->GetWallTimeMs(); + EXPECT_TRUE(time2 >= time1); +} + +/** +* @tc.name: GetTime002 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime002, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetWallTimeNs(); + auto time2 = TimeServiceClient::GetInstance()->GetWallTimeNs(); + EXPECT_TRUE(time2 >= time1); +} + +/** +* @tc.name: GetTime003 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime003, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetBootTimeMs(); + EXPECT_TRUE(time1 >= 0); + auto time2 = TimeServiceClient::GetInstance()->GetBootTimeMs(); + EXPECT_TRUE(time2 >= time1); +} + +/** +* @tc.name: GetTime004 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime004, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetMonotonicTimeMs(); + EXPECT_TRUE(time1 >= 0); + auto time2 = TimeServiceClient::GetInstance()->GetMonotonicTimeMs(); + EXPECT_TRUE(time2 >= time1); +} + +/** +* @tc.name: GetTime005 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime005, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetBootTimeNs(); + EXPECT_TRUE(time1 >= 0); + auto time2 = TimeServiceClient::GetInstance()->GetBootTimeNs(); + EXPECT_TRUE(time2 >= time1); +} + +/** +* @tc.name: GetTime006 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime006, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(); + EXPECT_TRUE(time1 >= 0); + auto time2 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(); + EXPECT_TRUE(time2 >= time1); +} + +/** +* @tc.name: GetTime007 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime007, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetThreadTimeMs(); + EXPECT_TRUE(time1 >= 0); + auto time2 = TimeServiceClient::GetInstance()->GetThreadTimeMs(); + EXPECT_TRUE(time2 >= time1); +} + +/** +* @tc.name: GetTime008 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime008, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetThreadTimeNs(); + EXPECT_TRUE(time1 >= 0); + auto time2 = TimeServiceClient::GetInstance()->GetThreadTimeNs(); + EXPECT_TRUE(time2 >= time1); +} + +std::atomic g_data1(0); + +void TimeOutCallback1() +{ + g_data1 += 1; +} + +std::atomic g_data2(0); +void TimeOutCallback2() +{ + g_data2 += 1; +} + +/** +* @tc.name: CreateTimer01 +* @tc.desc: Create system timer. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, CreateTimer01, TestSize.Level0) +{ + g_data1 = 0; + auto timerInfo = std::make_shared(); + timerInfo->SetType(1); + timerInfo->SetRepeat(false); + timerInfo->SetInterval(0); + timerInfo->SetWantAgent(nullptr); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo); + EXPECT_TRUE(timerId1 > 0); + + auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5); + std::this_thread::sleep_for(std::chrono::milliseconds(6000)); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data1 == 1); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_TRUE(ret); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); +} + +/** +* @tc.name: CreateTimer02 +* @tc.desc: Create system timer. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, CreateTimer02, TestSize.Level0) +{ + g_data1 = 0; + auto timerInfo = std::make_shared(); + timerInfo->SetType(1); + timerInfo->SetRepeat(false); + timerInfo->SetInterval(0); + timerInfo->SetWantAgent(nullptr); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo); + EXPECT_TRUE(timerId1 > 0); + + auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5000); + std::this_thread::sleep_for(std::chrono::milliseconds(5100)); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data1 == 1); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_TRUE(ret); + ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5000); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data1 == 1); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); +} + +/** +* @tc.name: CreateTimer03 +* @tc.desc: Create system timer. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, CreateTimer03, TestSize.Level0) +{ + uint64_t timerId = 0; + auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId, 5); + EXPECT_FALSE(ret); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId); + EXPECT_FALSE(ret); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId); + EXPECT_FALSE(ret); +} + +/** +* @tc.name: CreateTimer04 +* @tc.desc: Create system timer. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, CreateTimer04, TestSize.Level0) +{ + auto timerInfo = std::make_shared(); + timerInfo->SetType(1); + timerInfo->SetRepeat(false); + timerInfo->SetInterval(0); + timerInfo->SetWantAgent(nullptr); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo); + EXPECT_TRUE(timerId1 > 0); + auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 2000); + EXPECT_TRUE(ret); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_TRUE(ret); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); +} + +/** +* @tc.name: CreateTimer05 +* @tc.desc: Create system timer. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, CreateTimer05, TestSize.Level0) +{ + g_data1 = 0; + auto timerInfo = std::make_shared(); + timerInfo->SetType(1); + timerInfo->SetRepeat(false); + timerInfo->SetInterval(0); + timerInfo->SetWantAgent(nullptr); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo); + EXPECT_TRUE(timerId1 > 0); + + auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 2000); + EXPECT_TRUE(ret); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data1 == 0); + + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_FALSE(ret); +} + +/** +* @tc.name: CreateTimer06 +* @tc.desc: Create system timer. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0) +{ + g_data1 = 1; + auto timerInfo = std::make_shared(); + timerInfo->SetType(0); + timerInfo->SetRepeat(false); + timerInfo->SetInterval(0); + timerInfo->SetWantAgent(nullptr); + timerInfo->SetCallbackInfo(TimeOutCallback1); + + struct timeval getTime; + gettimeofday(&getTime, NULL); + int64_t current_time = (getTime.tv_sec + 100) * 1000 + getTime.tv_usec / 1000; + + auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo); + EXPECT_TRUE(timerId1 > 0); + + auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, static_cast(current_time)); + EXPECT_TRUE(ret); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data1 == 1); + + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_FALSE(ret); +} +#endif \ No newline at end of file diff --git a/services/timer/include/batch.h b/services/timer/include/batch.h new file mode 100644 index 0000000..3c2dd28 --- /dev/null +++ b/services/timer/include/batch.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIMER_BATCH_H +#define TIMER_BATCH_H + +#include +#include +#include +#include +#include "timer_info.h" +#include "time_common.h" +namespace OHOS { +namespace MiscServices { + +class Batch { + +public: + Batch (); + explicit Batch (const TimerInfo &seed); + + std::chrono::steady_clock::time_point GetStart () const; + std::chrono::steady_clock::time_point GetEnd () const; + uint32_t GetFlags () const; + + size_t Size () const; + std::shared_ptr Get (size_t index) const; + bool CanHold (std::chrono::steady_clock::time_point whenElapsed, + std::chrono::steady_clock::time_point maxWhen) const; + bool Add (const std::shared_ptr &alarm); + bool Remove (const TimerInfo &alarm); + bool Remove (std::function predicate); + bool HasPackage (const std::string &package_name); + bool HasWakeups () const; + +private: + std::chrono::steady_clock::time_point start_; + std::chrono::steady_clock::time_point end_; + uint32_t flags_; + std::vector> alarms_; +}; + +} +} +#endif \ No newline at end of file diff --git a/services/timer/include/timer_handler.h b/services/timer/include/timer_handler.h new file mode 100644 index 0000000..df87ac3 --- /dev/null +++ b/services/timer/include/timer_handler.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + + +#ifndef TIMER_HANDLER_H +#define TIMER_HANDLER_H + +#include "time_common.h" + +#include +#include +#include +#include +#include + + +namespace OHOS { +namespace MiscServices { + +static const size_t ALARM_TYPE_COUNT = 5; +static const size_t N_TIMER_FDS = ALARM_TYPE_COUNT + 1; + +typedef std::array TimerFds; + +class TimerHandler { +public: + static std::shared_ptr Create (); + + int Set (uint32_t type, std::chrono::nanoseconds when); + int WaitForAlarm (); + + ~TimerHandler (); + +private: + TimerHandler (const TimerFds &fds, int epollfd); + + const TimerFds fds_; + const int epollFd_; +}; + +}// MiscService +}// OHOS + +#endif \ No newline at end of file diff --git a/services/timer/include/timer_info.h b/services/timer/include/timer_info.h new file mode 100644 index 0000000..5e5026f --- /dev/null +++ b/services/timer/include/timer_info.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIMER_INFO_H +#define TIMER_INFO_H + +#include +#include +#include +#include +#include +#include "timer_manager_interface.h" + +namespace OHOS { +namespace MiscServices { + +class TimerInfo { + +public: + const uint64_t id; + const int type; + const std::chrono::milliseconds origWhen; + const bool wakeup; + const std::function callback; + const uint32_t flags; + const uint64_t uid; + + uint64_t count{}; + std::chrono::milliseconds when; + std::chrono::milliseconds windowLength; + std::chrono::steady_clock::time_point whenElapsed; + std::chrono::steady_clock::time_point maxWhenElapsed; + std::chrono::steady_clock::time_point expectedWhenElapsed; + std::chrono::steady_clock::time_point expectedMaxWhenElapsed; + std::chrono::milliseconds repeatInterval; + + TimerInfo (uint64_t id, int type, + std::chrono::milliseconds when, + std::chrono::steady_clock::time_point whenElapsed, + std::chrono::milliseconds windowLength, + std::chrono::steady_clock::time_point maxWhen, + std::chrono::milliseconds interval, + std::function callback, + uint32_t flags, + uint64_t uid); + + bool operator== (const TimerInfo &other) const; + bool Matches (const std::string &packageName) const; +}; + +}// MiscService +}// OHOSw + +#endif \ No newline at end of file diff --git a/services/timer/include/timer_manager.h b/services/timer/include/timer_manager.h new file mode 100644 index 0000000..d2b3da2 --- /dev/null +++ b/services/timer/include/timer_manager.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef TIMER_MANAGER_H +#define TIMER_MANAGER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "timer_handler.h" +#include "batch.h" +#include + +namespace OHOS{ +namespace MiscServices{ + +class TimerManager : public ITimerManager { +public: + static std::shared_ptr Create(); + + uint64_t CreateTimer(int type, uint64_t windowLength, uint64_t interval,int flag, + std::function callback,uint64_t uid) override; + bool StartTimer(uint64_t timerNumber, uint64_t triggerTime) override; + bool StopTimer(uint64_t timerNumber) override; + bool DestroyTimer(uint64_t timerNumber) override; + + ~TimerManager() override; + +private: + explicit TimerManager(std::shared_ptr impl); + void TimerLooper(); + + void SetHandler(uint64_t id, int type, uint64_t triggerAtTime, uint64_t windowLength, uint64_t interval, int flag, + std::function callback, + uint64_t uid); + + void SetHandlerLocked(uint64_t id, int type, + std::chrono::milliseconds when, + std::chrono::steady_clock::time_point whenElapsed, + std::chrono::milliseconds windowLength, + std::chrono::steady_clock::time_point maxWhen, + std::chrono::milliseconds interval, + std::function callback, + uint32_t flags, + bool doValidate, + uint64_t callingUid); + + void RemoveHandler(uint64_t id); + void RemoveLocked(uint64_t id); + void ReBatchAllTimers(); + void ReBatchAllTimersLocked(bool doValidate); + void ReAddTimerLocked(std::shared_ptr timer, + std::chrono::steady_clock::time_point nowElapsed, bool doValidate); + + void SetHandlerLocked(std::shared_ptr alarm, bool rebatching, bool doValidate); + void InsertAndBatchTimerLocked(std::shared_ptr alarm); + int64_t AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed, + std::chrono::steady_clock::time_point maxWhen); + + bool TriggerTimersLocked(std::vector> &triggerList, + std::chrono::steady_clock::time_point nowElapsed); + + void RescheduleKernelTimerLocked(); + + void DeliverTimersLocked(const std::vector> &triggerList, + std::chrono::steady_clock::time_point nowElapsed); + + std::shared_ptr FindFirstWakeupBatchLocked(); + void SetLocked(int type, std::chrono::nanoseconds when); + std::chrono::steady_clock::time_point ConvertToElapsed(std::chrono::milliseconds when, int type); + + std::map> timerEntryMap_; + std::default_random_engine random_; + std::atomic_bool runFlag_; + std::shared_ptr handler_; + std::unique_ptr alarmThread_; + std::vector> alarmBatches_; + std::mutex mutex_; + std::mutex entryMapMutex_; + + std::chrono::system_clock::time_point lastTimeChangeClockTime_; + std::chrono::steady_clock::time_point lastTimeChangeRealtime_; +}; // timer_manager + +} // MiscServices +} // OHOS + +#endif \ No newline at end of file diff --git a/services/timer/include/timer_manager_interface.h b/services/timer/include/timer_manager_interface.h new file mode 100644 index 0000000..0dcc691 --- /dev/null +++ b/services/timer/include/timer_manager_interface.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIMER_MANAGER_INTERFACE_H +#define TIMER_MANAGER_INTERFACE_H + +#include +#include "want_agent.h" + +namespace OHOS { +namespace MiscServices { + +struct TimerEntry { + uint64_t id; + int type; + uint64_t windowLength; + uint64_t interval; + int flag; + std::function callback; + uint64_t uid; +}; + +class ITimerManager { +public: + enum TimerFlag { + STANDALONE = 1 << 0, + WAKE_FROM_IDLE = 1 << 1, + ALLOW_WHILE_IDLE = 1 << 2, + ALLOW_WHILE_IDLE_UNRESTRICTED = 1 << 3, + IDLE_UNTIL = 1 << 4, + }; + + enum TimerType { + RTC_WAKEUP = 0, + RTC = 1, + ELAPSED_REALTIME_WAKEUP = 2, + ELAPSED_REALTIME = 3 + }; + + virtual uint64_t CreateTimer (int type, uint64_t windowLength, uint64_t interval, int flag, + std::function callback, + uint64_t uid) = 0; + + virtual bool StartTimer (uint64_t timerNumber, uint64_t triggerTime) = 0; + virtual bool StopTimer (uint64_t timerNumber) = 0; + virtual bool DestroyTimer (uint64_t timerNumber) = 0; + virtual ~ITimerManager () = default; +};// ITimerManager +}// MiscService +}// OHOS + +#endif \ No newline at end of file diff --git a/services/timer/src/batch.cpp b/services/timer/src/batch.cpp new file mode 100644 index 0000000..ef808df --- /dev/null +++ b/services/timer/src/batch.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "batch.h" +#include + +namespace OHOS { +namespace MiscServices { + +const auto TYPE_NONWAKEUP_MASK = 0x1; + +Batch::Batch () + : start_{std::chrono::steady_clock::time_point::min ()}, + end_{std::chrono::steady_clock::time_point::max ()}, + flags_{0} +{ +} + +Batch::Batch (const TimerInfo &seed) + : start_{seed.whenElapsed}, + end_{seed.maxWhenElapsed}, + flags_{seed.flags}, + alarms_{std::make_shared (seed)} +{ +} + +size_t Batch::Size () const +{ + return alarms_.size (); +} + +std::shared_ptr Batch::Get (size_t index) const +{ + return index >= alarms_.size () ? nullptr : alarms_.at (index); +} + +bool Batch::CanHold (std::chrono::steady_clock::time_point whenElapsed, + std::chrono::steady_clock::time_point maxWhen) const +{ + return (end_ > whenElapsed) && (start_ <= maxWhen); +} + +bool Batch::Add (const std::shared_ptr &alarm) +{ + bool new_start = false; + auto it = std::upper_bound (alarms_.begin (), alarms_.end (), alarm, + [] (const std::shared_ptr &first, const std::shared_ptr &second) + { + return first->whenElapsed < second->whenElapsed; + }); + alarms_.insert (it, alarm); //根据Alarm.when_elapsed从小到大排列 + + if (alarm->whenElapsed > start_) { + start_ = alarm->whenElapsed; + new_start = true; + } + + if (alarm->maxWhenElapsed < end_) { + end_ = alarm->maxWhenElapsed; + } + + flags_ |= alarm->flags; + return new_start; +} + +bool Batch::Remove (const TimerInfo &alarm) +{ + return Remove ([alarm] (const TimerInfo &a){ return a == alarm; }); +} + +bool Batch::Remove (std::function predicate) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start"); + bool didRemove = false; + auto newStart = std::chrono::steady_clock::time_point::min (); + auto newEnd = std::chrono::steady_clock::time_point::max (); + uint32_t newFlags = 0; + for (auto it = alarms_.begin (); it != alarms_.end ();) { + auto alarm = *it; + TIME_HILOGD(TIME_MODULE_SERVICE, "looper"); + if (predicate (*alarm)) { + TIME_HILOGD(TIME_MODULE_SERVICE, "erase"); + it = alarms_.erase(it); + didRemove = true; + } else { + if (alarm->whenElapsed > newStart) { + newStart = alarm->whenElapsed; + } + if (alarm->maxWhenElapsed < newEnd) { + newEnd = alarm->maxWhenElapsed; + } + newFlags |= alarm->flags; + ++it; + } + } + TIME_HILOGD(TIME_MODULE_SERVICE, "end"); + if (didRemove) { + start_ = newStart; + end_ = newEnd; + flags_ = newFlags; + } + return didRemove; +} + +bool Batch::HasPackage (const std::string &package_name) +{ + return std::find_if (alarms_.begin (), alarms_.end (), + [package_name] (const std::shared_ptr &alarm) + { return alarm->Matches (package_name); }) != alarms_.end (); +} + +bool Batch::HasWakeups () const +{ + return std::any_of (alarms_.begin (), alarms_.begin (), + [] (const std::shared_ptr &item) + { + return (static_cast(item->type) & TYPE_NONWAKEUP_MASK) == 0; + }); +} + +std::chrono::steady_clock::time_point Batch::GetStart () const +{ + return start_; +} + +std::chrono::steady_clock::time_point Batch::GetEnd () const +{ + return end_; +} + +uint32_t Batch::GetFlags () const +{ + return flags_; +} + +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/services/timer/src/timer_handler.cpp b/services/timer/src/timer_handler.cpp new file mode 100644 index 0000000..82c053a --- /dev/null +++ b/services/timer/src/timer_handler.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include "timer_handler.h" +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace MiscServices { + +static constexpr int ALARM_TIME_CHANGE_MASK = 1 << 16; +static const clockid_t alarm_to_clock_id[N_TIMER_FDS] = { + CLOCK_REALTIME_ALARM, + CLOCK_REALTIME, + CLOCK_BOOTTIME_ALARM, + CLOCK_BOOTTIME, + CLOCK_MONOTONIC, + CLOCK_REALTIME, +}; + + +std::shared_ptr TimerHandler::Create() +{ + int epollfd; + TimerFds fds; + + epollfd = epoll_create (fds.size ()); + if (epollfd < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE, "epoll_create %{public}d failed: %{public}s", static_cast(fds.size()), strerror (errno)); + return nullptr; + } + + for (size_t i = 0; i < fds.size (); i++) { + fds[i] = timerfd_create (alarm_to_clock_id[i], 0); + if (fds[i] < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE, "timerfd_create %{public}d failed: %{public}s", static_cast(i), strerror (errno)); + close (epollfd); + for (size_t j = 0; j < i; j++) { + close (fds[j]); + } + return nullptr; + } + } + + auto handler = std::shared_ptr (new TimerHandler (fds, epollfd)); + for (size_t i = 0; i < fds.size (); i++) { + epoll_event event{}; + event.events = EPOLLIN | EPOLLWAKEUP; + event.data.u32 = i; + + int err = epoll_ctl (epollfd, EPOLL_CTL_ADD, fds[i], &event); + if (err < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE, "epoll_ctl(EPOLL_CTL_ADD) failed: %{public}s", strerror (errno)); + return nullptr; + } + } + itimerspec spec{}; + + int err = timerfd_settime (fds[ALARM_TYPE_COUNT], TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, nullptr); + if (err < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE, "timerfd_settime() failed: %{public}s", strerror(errno)); + return nullptr; + } + + return handler; +} + +TimerHandler::TimerHandler (const TimerFds &fds, int epollfd) + : fds_{fds}, epollFd_{epollfd} +{ +} + +TimerHandler::~TimerHandler() +{ + for (auto fd : fds_) { + epoll_ctl (epollFd_, EPOLL_CTL_DEL, fd, nullptr); + close (fd); + } + close (epollFd_); +} + +int TimerHandler::Set (uint32_t type, std::chrono::nanoseconds when) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "type= %{public}d, when= %{public}lld", type, when.count()); + if (static_cast(type) > ALARM_TYPE_COUNT) { + errno = EINVAL; + return -1; + } + + auto second = std::chrono::duration_cast (when); + timespec ts { second.count (), (when - second).count()}; + itimerspec spec{timespec{}, ts}; + return timerfd_settime (fds_[type], TFD_TIMER_ABSTIME, &spec, nullptr); +} + +int TimerHandler::WaitForAlarm() +{ + epoll_event events[N_TIMER_FDS]; + + int nevents = epoll_wait (epollFd_, events, N_TIMER_FDS, -1); + if (nevents < 0){ + return nevents; + } + + int result = 0; + for (int i = 0; i < nevents; i++) { + uint32_t alarm_idx = events[i].data.u32; + uint64_t unused; + ssize_t err = read (fds_[alarm_idx], &unused, sizeof (unused)); + if (err < 0) { + if (alarm_idx == ALARM_TYPE_COUNT && errno == ECANCELED) { + result |= ALARM_TIME_CHANGE_MASK; + } else { + return err; + } + } else { + result |= (1 << alarm_idx); + } + } + return result; +} + +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/services/timer/src/timer_info.cpp b/services/timer/src/timer_info.cpp new file mode 100644 index 0000000..d320a00 --- /dev/null +++ b/services/timer/src/timer_info.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "timer_info.h" + +namespace OHOS { +namespace MiscServices { + +bool TimerInfo::operator== (const TimerInfo &other) const{ + return this->id == other.id; +} + +bool TimerInfo::Matches (const std::string &packageName) const{ + return false; +} + +TimerInfo::TimerInfo (uint64_t _id, int _type, + std::chrono::milliseconds _when, + std::chrono::steady_clock::time_point _whenElapsed, + std::chrono::milliseconds _windowLength, + std::chrono::steady_clock::time_point _maxWhen, + std::chrono::milliseconds _interval, + std::function _callback, + uint32_t _flags, + uint64_t _uid) + : id{_id}, + type{_type}, + origWhen{_when}, + wakeup{_type == ITimerManager::ELAPSED_REALTIME_WAKEUP || _type == ITimerManager::RTC_WAKEUP}, + callback{std::move (_callback)}, + flags{_flags}, + uid{_uid}, + when{_when}, + windowLength{_windowLength}, + whenElapsed{_whenElapsed}, + maxWhenElapsed{_maxWhen}, + expectedWhenElapsed{_whenElapsed}, + expectedMaxWhenElapsed{_maxWhen}, + repeatInterval{_interval} +{ +} + +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/services/timer/src/timer_manager.cpp b/services/timer/src/timer_manager.cpp new file mode 100644 index 0000000..58829a6 --- /dev/null +++ b/services/timer/src/timer_manager.cpp @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "timer_manager.h" +#include +#include +#include +#include +#include + +namespace OHOS{ +namespace MiscServices{ +using namespace std::chrono; + +static int TIME_CHANGED_MASK = 1 << 16; +const auto MIN_FUTURITY = seconds(5); +const auto MIN_INTERVAL = seconds(5); +const auto MAX_INTERVAL = hours(24 * 365); +const auto INTERVAL_HOUR = hours(1); +const auto INTERVAL_HALF_DAY = hours(12); +const auto MIN_FUZZABLE_INTERVAL = milliseconds(10000); + +extern bool AddBatchLocked(std::vector> &list, const std::shared_ptr &batch); +extern steady_clock::time_point MaxTriggerTime(steady_clock::time_point now, + steady_clock::time_point triggerAtTime, + milliseconds interval); + +std::shared_ptr TimerManager::Create() +{ + auto impl = TimerHandler::Create(); + if (impl == nullptr){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Create Timer handle failed."); + return nullptr; + } + return std::shared_ptr(new TimerManager(impl)); +} + +TimerManager::TimerManager(std::shared_ptr impl) + : random_{static_cast(time(nullptr))}, + runFlag_{false}, + handler_{std::move(impl)}, + lastTimeChangeClockTime_{system_clock::time_point::min()}, + lastTimeChangeRealtime_{steady_clock::time_point::min()} +{ + runFlag_ = true; + alarmThread_.reset(new std::thread(&TimerManager::TimerLooper, this)); +} + +uint64_t TimerManager::CreateTimer(int type, uint64_t windowLength, uint64_t interval, int flag, + std::function callback, uint64_t uid) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"Create timer: %{public}d windowLength:%{public}" PRId64 "interval:%{public}" PRId64 "flag:%{public}d", type, windowLength, interval, flag); + uint64_t timerNumber = 0; + while (timerNumber == 0){ + timerNumber = random_(); + } + auto timerInfo = std::make_shared(TimerEntry{timerNumber, type,windowLength, + interval, flag, std::move(callback), uid}); + std::lock_guard lock(entryMapMutex_); + timerEntryMap_.insert(std::make_pair(timerNumber, timerInfo)); + return timerNumber; +} + +bool TimerManager::StartTimer(uint64_t timerNumber, uint64_t triggerTime) +{ + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Timer id not found: %{public}" PRId64 "", timerNumber); + return false; + } + TIME_HILOGI(TIME_MODULE_SERVICE,"Start timer : %{public}" PRId64 "", timerNumber); + TIME_HILOGI(TIME_MODULE_SERVICE,"TriggerTime : %{public}" PRId64 "", triggerTime); + auto timerInfo = it->second; + SetHandler(timerInfo->id, + timerInfo->type, + triggerTime, + timerInfo->windowLength, + timerInfo->interval, + timerInfo->flag, + timerInfo->callback, + timerInfo->uid); + return true; +} + +bool TimerManager::StopTimer(uint64_t timerNumber) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start."); + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()){ + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return false; + } + RemoveHandler(timerNumber); + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return true; +} + +bool TimerManager::DestroyTimer(uint64_t timerNumber) +{ + TIME_HILOGD(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "", timerNumber); + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()){ + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return false; + } + RemoveHandler(timerNumber); + timerEntryMap_.erase(it); + TIME_HILOGD(TIME_MODULE_SERVICE, "end."); + return true; +} + +void TimerManager::SetHandler(uint64_t id, int type, uint64_t triggerAtTime, uint64_t windowLength, uint64_t interval, int flag, + std::function callback, uint64_t uid) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "",id); + TIME_HILOGI(TIME_MODULE_SERVICE, "start type : %{public}d windowLength:%{public}" PRId64 "interval:%{public}" PRId64 "flag:%{public}d", type, windowLength, interval, flag); + auto windowLengthDuration = milliseconds(windowLength); + if (windowLengthDuration > INTERVAL_HALF_DAY){ + windowLengthDuration = INTERVAL_HOUR; + } + + auto intervalDuration = milliseconds(interval); + if (intervalDuration > milliseconds::zero() && intervalDuration < MIN_INTERVAL){ + intervalDuration = MIN_INTERVAL; + }else if (intervalDuration > MAX_INTERVAL){ + intervalDuration = MAX_INTERVAL; + } + if (triggerAtTime < 0){ + triggerAtTime = 0; + } + + auto nowElapsed = steady_clock::now(); + auto nominalTrigger = ConvertToElapsed(milliseconds(triggerAtTime), type); + auto minTrigger = nowElapsed + MIN_FUTURITY; + auto triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger; + + steady_clock::time_point maxElapsed; + if (windowLengthDuration == milliseconds::zero()){ + maxElapsed = triggerElapsed; + } else if (windowLengthDuration < milliseconds::zero()){ + maxElapsed = MaxTriggerTime(nominalTrigger, triggerElapsed, intervalDuration); + windowLengthDuration = duration_cast(maxElapsed - triggerElapsed); + } else { + maxElapsed = triggerElapsed + windowLengthDuration; + } + TIME_HILOGI(TIME_MODULE_SERVICE, "Try get lock"); + std::lock_guard lockGuard(mutex_); + TIME_HILOGI(TIME_MODULE_SERVICE, "Lock guard"); + SetHandlerLocked(id,type, milliseconds(triggerAtTime),triggerElapsed, windowLengthDuration, maxElapsed, + intervalDuration, std::move(callback), static_cast(flag), true, uid); +} + +void TimerManager::SetHandlerLocked(uint64_t id, int type, + std::chrono::milliseconds when, + std::chrono::steady_clock::time_point whenElapsed, + std::chrono::milliseconds windowLength, + std::chrono::steady_clock::time_point maxWhen, + std::chrono::milliseconds interval, + std::function callback, + uint32_t flags, + bool doValidate, + uint64_t callingUid) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "", id); + auto alarm = std::make_shared(id, type, when, whenElapsed, windowLength, maxWhen, + interval, std::move(callback), flags, callingUid); + SetHandlerLocked(alarm, false, doValidate); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +void TimerManager::RemoveHandler(uint64_t id) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + std::lock_guard lock(mutex_); + RemoveLocked(id); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +void TimerManager::RemoveLocked(uint64_t id) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "",id); + auto whichAlarms = [id](const TimerInfo &timer) { + return timer.id == id; + }; + + bool didRemove = false; + for (auto it = alarmBatches_.begin(); it != alarmBatches_.end();) { + auto batch = *it; + didRemove |= batch->Remove(whichAlarms); + if (batch->Size() == 0) { + TIME_HILOGD(TIME_MODULE_SERVICE, "erase"); + it = alarmBatches_.erase(it); + }else{ + ++it; + } + } + + if (didRemove) { + ReBatchAllTimersLocked(true); + } + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +void TimerManager::SetHandlerLocked(std::shared_ptr alarm, bool rebatching, bool doValidate) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + TIME_HILOGI(TIME_MODULE_SERVICE, "rebatching= %{public}d, doValidate= %{public}d", rebatching, doValidate); + InsertAndBatchTimerLocked(std::move(alarm)); + if (!rebatching) { + RescheduleKernelTimerLocked(); + } + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +void TimerManager::ReBatchAllTimers() +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + ReBatchAllTimersLocked(true); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +void TimerManager::ReBatchAllTimersLocked(bool doValidate){ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + auto oldSet = alarmBatches_; + alarmBatches_.clear(); + auto nowElapsed = steady_clock::now(); + for (const auto &batch : oldSet){ + auto n = batch->Size(); + for (unsigned int i = 0; i < n; i++){ + ReAddTimerLocked(batch->Get(i), nowElapsed, doValidate); + } + } + RescheduleKernelTimerLocked(); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +void TimerManager::ReAddTimerLocked(std::shared_ptr timer, std::chrono::steady_clock::time_point nowElapsed, bool doValidate){ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + timer->when = timer->origWhen; + auto whenElapsed = ConvertToElapsed(timer->when, timer->type); + steady_clock::time_point maxElapsed; + if (timer->windowLength == milliseconds::zero()) { + maxElapsed = whenElapsed; + } else { + maxElapsed = (timer->windowLength > milliseconds::zero()) ? whenElapsed + timer->windowLength + : MaxTriggerTime(nowElapsed, whenElapsed, timer->repeatInterval); + } + timer->whenElapsed = whenElapsed; + timer->maxWhenElapsed = maxElapsed; + SetHandlerLocked(timer, true, doValidate); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +std::chrono::steady_clock::time_point TimerManager::ConvertToElapsed(std::chrono::milliseconds when, int type) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + if (type == RTC || type == RTC_WAKEUP){ + auto offset = when - system_clock::now().time_since_epoch(); + return steady_clock::now() + offset; + } + auto offset = when - steady_clock::now().time_since_epoch(); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); + return steady_clock::now() + offset; +} + +void TimerManager::TimerLooper() +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"Start timer wait loop"); + std::vector> triggerList; + while (runFlag_) { + int result = 0; + do { + result = handler_->WaitForAlarm(); + } while (result < 0 && errno == EINTR); + TIME_HILOGI(TIME_MODULE_SERVICE, "result= %{public}d", result); + + auto nowRtc = std::chrono::system_clock::now(); + auto nowElapsed = std::chrono::steady_clock::now(); + triggerList.clear(); + + if ((result & TIME_CHANGED_MASK) != 0) { + TIME_HILOGI(TIME_MODULE_SERVICE, "time changed"); + system_clock::time_point lastTimeChangeClockTime; + system_clock::time_point expectedClockTime; + TIME_HILOGI(TIME_MODULE_SERVICE, "lock"); + std::lock_guard lock(mutex_); + lastTimeChangeClockTime = lastTimeChangeClockTime_; + expectedClockTime = lastTimeChangeClockTime + (duration_cast(nowElapsed.time_since_epoch()) - + duration_cast(lastTimeChangeRealtime_.time_since_epoch())); + + + if (lastTimeChangeClockTime == system_clock::time_point::min() + || nowRtc < (expectedClockTime - milliseconds(1000)) + || nowRtc > (expectedClockTime + milliseconds(1000))) { + TIME_HILOGI(TIME_MODULE_SERVICE, "Time changed notification from kernel; rebatching"); + ReBatchAllTimers(); + lastTimeChangeClockTime_ = nowRtc; + lastTimeChangeRealtime_ = nowElapsed; + + } + } + + if (result != TIME_CHANGED_MASK) { + std::lock_guard lock(mutex_); + auto hasWakeup = TriggerTimersLocked(triggerList, nowElapsed); + TIME_HILOGI(TIME_MODULE_SERVICE, "hasWakeup= %{public}d", hasWakeup); + DeliverTimersLocked(triggerList, nowElapsed); + + RescheduleKernelTimerLocked(); + } else { + std::lock_guard lock(mutex_); + RescheduleKernelTimerLocked(); + } + } +} + +TimerManager::~TimerManager() +{ + if (alarmThread_ && alarmThread_->joinable()) { + alarmThread_->join(); + } +} + +bool TimerManager::TriggerTimersLocked(std::vector> &triggerList, + std::chrono::steady_clock::time_point nowElapsed) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", static_cast(alarmBatches_.size())); + bool hasWakeup = false; + while (!alarmBatches_.empty()) { + auto batch = alarmBatches_.at(0); + TIME_HILOGI(TIME_MODULE_SERVICE, "batch->GetStart()= %{public}lld", time_point_cast(batch->GetStart()).time_since_epoch().count()); + TIME_HILOGI(TIME_MODULE_SERVICE, "nowElapsed= %{public}lld", time_point_cast(nowElapsed).time_since_epoch().count()); + if (batch->GetStart() > nowElapsed) { + TIME_HILOGI(TIME_MODULE_SERVICE, "break alarmBatches_.size= %{public}d", static_cast(alarmBatches_.size())); + break; + } + alarmBatches_.erase(alarmBatches_.begin()); + TIME_HILOGI(TIME_MODULE_SERVICE, "after erase alarmBatches_.size= %{public}d", static_cast(alarmBatches_.size())); + + const auto n = batch->Size(); + for (unsigned int i = 0; i < n; ++i) { + auto alarm = batch->Get(i); + alarm->count = 1; + triggerList.push_back(alarm); + + if (alarm->repeatInterval > milliseconds::zero()) { + alarm->count += duration_cast(nowElapsed - alarm->expectedWhenElapsed) / alarm->repeatInterval; + auto delta = alarm->count * alarm->repeatInterval; + auto nextElapsed = alarm->whenElapsed + delta; + SetHandlerLocked(alarm->id, alarm->type, alarm->when + delta, nextElapsed, alarm->windowLength, + MaxTriggerTime(nowElapsed, nextElapsed, alarm->repeatInterval), alarm->repeatInterval, + nullptr, alarm->flags, true, alarm->uid); + } + if (alarm->wakeup) { + hasWakeup = true; + } + } + } + std::sort(triggerList.begin(), triggerList.end(), + [](const std::shared_ptr &l, + const std::shared_ptr &r){return l->whenElapsed < r->whenElapsed;}); + + return hasWakeup; +} + +void TimerManager::RescheduleKernelTimerLocked() +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", static_cast(alarmBatches_.size())); + auto nextNonWakeup = std::chrono::steady_clock::time_point::min(); + if (!alarmBatches_.empty()) { + auto firstWakeup = FindFirstWakeupBatchLocked(); + auto firstBatch = alarmBatches_.front(); + if (firstWakeup != nullptr) { + SetLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup->GetStart().time_since_epoch()); + } + if (firstBatch != firstWakeup) { + nextNonWakeup = firstBatch->GetStart(); + } + } + + if (nextNonWakeup != std::chrono::steady_clock::time_point::min()) { + SetLocked(ELAPSED_REALTIME, nextNonWakeup.time_since_epoch()); + } + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +std::shared_ptr TimerManager::FindFirstWakeupBatchLocked() +{ + auto it = std::find_if(alarmBatches_.begin(),alarmBatches_.end(), + [](const std::shared_ptr &batch) + { + return batch->HasWakeups(); + }); + return it != alarmBatches_.end() ? *it : nullptr; +} + +void TimerManager::SetLocked(int type, std::chrono::nanoseconds when) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + TIME_HILOGI(TIME_MODULE_SERVICE, "when.count= %{public}lld", when.count()); + handler_->Set(static_cast(type), when); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +void TimerManager::InsertAndBatchTimerLocked(std::shared_ptr alarm) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + int64_t whichBatch = (alarm->flags & static_cast(STANDALONE)) ? -1 + : AttemptCoalesceLocked(alarm->whenElapsed, alarm->maxWhenElapsed); + TIME_HILOGI(TIME_MODULE_SERVICE, "whichBatch= %{public}" PRId64 "", whichBatch); + if (whichBatch < 0) { + AddBatchLocked(alarmBatches_, std::make_shared(*alarm)); + } else { + auto batch = alarmBatches_.at(whichBatch); + if (batch->Add(alarm)) { + alarmBatches_.erase(alarmBatches_.begin() + whichBatch); + AddBatchLocked(alarmBatches_, batch); + } + } + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +int64_t TimerManager::AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed, + std::chrono::steady_clock::time_point maxWhen) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + int64_t i = 0; + for (const auto &item : alarmBatches_) { + if ((item->GetFlags() & static_cast(STANDALONE)) == 0 && item->CanHold(whenElapsed, maxWhen)) { + return i; + } + // ++i; + } + return -1; +} + +void TimerManager::DeliverTimersLocked(const std::vector> &triggerList, + std::chrono::steady_clock::time_point nowElapsed){ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + for (const auto &alarm : triggerList) { + if (alarm->callback) { + alarm->callback(alarm->id); + TIME_HILOGI(TIME_MODULE_SERVICE, "Trigger id: %{public}" PRId64 "", alarm->id); + } + } + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); +} + +bool AddBatchLocked(std::vector> &list, const std::shared_ptr &newBatch) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "start"); + auto it = std::upper_bound(list.begin(), list.end(), newBatch, + [](const std::shared_ptr &first, const std::shared_ptr &second) + { + return first->GetStart() < second->GetStart(); + }); + list.insert(it, newBatch); + TIME_HILOGI(TIME_MODULE_SERVICE, "end"); + return it == list.begin(); +} + +steady_clock::time_point MaxTriggerTime(steady_clock::time_point now, steady_clock::time_point triggerAtTime, milliseconds interval){ + milliseconds futurity = (interval == milliseconds::zero()) ? duration_cast(triggerAtTime - now) : interval; + if (futurity < MIN_FUZZABLE_INTERVAL) { + futurity = milliseconds::zero(); + } + return triggerAtTime + milliseconds(static_cast(0.75 * futurity.count())); +} + +} // MiscServices +} // OHOS \ No newline at end of file diff --git a/time.gni b/time.gni index 4c8394f..c20574f 100755 --- a/time.gni +++ b/time.gni @@ -10,11 +10,14 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import("//build/ohos.gni") -time_path = "//base/miscservices/time" +time_root_path = "//base/miscservices/time" -kits_path = "${time_path}/kits" +kits_path = "${time_root_path}/interface/kits" -innerkits_path = "${time_path}/interfaces/innerkits" +innerkits_path = "${time_root_path}/interfaces/innerkits" -adapter_path = "${time_path}/adapter" \ No newline at end of file +time_utils_path = "${time_root_path}/utils" + +adapter_path = "${time_root_path}/adapter" \ No newline at end of file diff --git a/utils/BUILD.gn b/utils/BUILD.gn new file mode 100644 index 0000000..6421ea4 --- /dev/null +++ b/utils/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//base/miscservices/time/time.gni") + +config("utils_config") { + include_dirs = [ + "mock/include", + "native/include", + "//utils/native/base/include", + "/foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk/include/", + ] +} + +ohos_source_set("time_utils") { + sources = [ + "mock/src/mock_permission.cpp", + "native/src/time_permission.cpp", + ] + + public_configs = [ ":utils_config" ] + + deps = [ + "//utils/native/base:utils", + "//foundation/aafwk/standard/interfaces/innerkits/base:base", + "//foundation/aafwk/standard/interfaces/innerkits/want:want", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk:native_appdatafwk", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_preferences:native_preferences", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] + + part_name = "time_native" +} diff --git a/services/include/time_service_stub.h b/utils/mock/include/mock_permission.h old mode 100755 new mode 100644 similarity index 52% rename from services/include/time_service_stub.h rename to utils/mock/include/mock_permission.h index ccef63e..a86b676 --- a/services/include/time_service_stub.h +++ b/utils/mock/include/mock_permission.h @@ -1,35 +1,30 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SERVICES_INCLUDE_TIME_SERVICE_STUB_H -#define SERVICES_INCLUDE_TIME_SERVICE_STUB_H - -#include "iremote_stub.h" -#include "time_service_interface.h" - -namespace OHOS { -namespace MiscServices { -class TimeServiceStub : public IRemoteStub { -public: - int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - virtual bool SetTime(const int64_t time) override; - -private: - int32_t OnSetTime(Parcel &data, Parcel &reply); -}; -} // namespace MiscServices -} // namespace OHOS - -#endif // SERVICES_INCLUDE_TIME_SERVICE_STUB_H \ No newline at end of file +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#ifndef MOCK_PERMISSION_H +#define MOCK_PERMISSION_H +namespace OHOS { +namespace MiscServices { +namespace MockPermission{ + + bool VerifyPermission(const std::string& bundleName, const std::string& permissionName, int userId); + +} +} +} + +#endif // MOCK_PERMISSION_H \ No newline at end of file diff --git a/utils/mock/src/mock_permission.cpp b/utils/mock/src/mock_permission.cpp new file mode 100644 index 0000000..373112f --- /dev/null +++ b/utils/mock/src/mock_permission.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mock_permission.h" + +namespace OHOS { +namespace MiscServices { +namespace MockPermission{ + +bool VerifyPermission(const std::string &bundleName, const std::string &permissionName, int userId) +{ + return true; +} + +} // OHOS +} // MiscServices +} // MockPermission \ No newline at end of file diff --git a/services/include/time_common.h b/utils/native/include/time_common.h old mode 100755 new mode 100644 similarity index 66% rename from services/include/time_common.h rename to utils/native/include/time_common.h index ad377ee..b16a0f8 --- a/services/include/time_common.h +++ b/utils/native/include/time_common.h @@ -1,39 +1,53 @@ -/* - * Copyright (C) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SERVICES_INCLUDE_TIME_COMMON_H -#define SERVICES_INCLUDE_TIME_COMMON_H - -#include "errors.h" - -namespace OHOS { -namespace MiscServices { -enum TimeModule { - TIME_MODULE_SERVICE = 0x04, -}; - -// time error offset, used only in this file. -constexpr ErrCode TIME_ERR_OFFSET = ErrCodeOffset(SUBSYS_SMALLSERVICES, TIME_MODULE_SERVICE); - -enum TimeError { - SUCCESS = ERR_OK, // Operation success - E_WRITE_PARCEL_ERROR = TIME_ERR_OFFSET, - E_READ_PARCEL_ERROR, - E_PUBLISH_FAIL, - E_TRANSACT_ERROR, -}; -} // namespace MiscServices -} // namespace OHOS +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SERVICES_INCLUDE_TIME_COMMON_H +#define SERVICES_INCLUDE_TIME_COMMON_H + +#include "errors.h" +#include "time_hilog_wreapper.h" + + +namespace OHOS { +namespace MiscServices { + +#define TIME_SERVICE_NAME "TimeService" + +enum TimeModule { + TIME_MODULE_SERVICE_ID = 0x04, +}; + + +// time error offset, used only in this file. +constexpr ErrCode TIME_ERR_OFFSET = ErrCodeOffset(SUBSYS_SMALLSERVICES, TIME_MODULE_SERVICE_ID); + + +enum TimeError { + E_TIME_OK = TIME_ERR_OFFSET, + E_TIME_SA_DIED, + E_TIME_READ_PARCEL_ERROR, + E_TIME_WRITE_PARCEL_ERROR, + E_TIME_PUBLISH_FAIL, + E_TIME_TRANSACT_ERROR, + E_TIME_DEAL_FAILED, + E_TIME_PARAMETERS_INVALID, + E_TIME_SET_RTC_FAILED, + E_TIME_NOT_FOUND, + E_TIME_NO_PERMISSION, +}; + +} // namespace MiscServices +} // namespace OHOS #endif // SERVICES_INCLUDE_TIME_COMMON_H \ No newline at end of file diff --git a/utils/native/include/time_hilog_wreapper.h b/utils/native/include/time_hilog_wreapper.h new file mode 100644 index 0000000..deb0c94 --- /dev/null +++ b/utils/native/include/time_hilog_wreapper.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TIME_HILOG_WRAPPER_H +#define TIME_HILOG_WRAPPER_H + +#include "hilog/log.h" + +namespace OHOS { +namespace MiscServices { + +// param of log interface, such as TIME_HILOGF. +enum TimeSubModule { + TIME_MODULE_INNERKIT = 0, + TIME_MODULE_CLIENT, + TIME_MODULE_SERVICE, + TIME_MODULE_JAVAKIT, // java kit, defined to avoid repeated use of domain. + TIME_MODULE_JNI, + TIME_MODULE_COMMON, + TIME_MODULE_JS_NAPI, + TIME_MODULE_BUTT, +}; + +// 0xD001C00: subsystem:TIME module:TimeManager, 8 bits reserved. +static constexpr unsigned int BASE_TIME_DOMAIN_ID = 0xD001C00; + +enum TimeDomainId { + TIME_INNERKIT_DOMAIN = BASE_TIME_DOMAIN_ID + TIME_MODULE_INNERKIT, + TIME_CLIENT_DOMAIN, + TIME_SERVICE_DOMAIN, + TIME_JAVAKIT_DOMAIN, + TIME_JNI_DOMAIN, + TIME_COMMON_DOMAIN, + TIME_JS_NAPI, + TIME_BUTT, +}; + +static constexpr OHOS::HiviewDFX::HiLogLabel TIME_MODULE_LABEL[TIME_MODULE_BUTT] = { + {LOG_CORE, TIME_INNERKIT_DOMAIN, "TimeInnerKit"}, + {LOG_CORE, TIME_CLIENT_DOMAIN, "TimeClient"}, + {LOG_CORE, TIME_SERVICE_DOMAIN, "TimeService"}, + {LOG_CORE, TIME_JAVAKIT_DOMAIN, "TimeJavaKit"}, + {LOG_CORE, TIME_JNI_DOMAIN, "TimeJni"}, + {LOG_CORE, TIME_COMMON_DOMAIN, "TimeCommon"}, + {LOG_CORE, TIME_JS_NAPI, "TimeJSNAPI"}, +}; + + +#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__) +#define __FORMATED(fmt, ...) "[%{public}s] %{public}s# " fmt, __FILENAME__, __FUNCTION__, ##__VA_ARGS__ + +// In order to improve performance, do not check the module range. +// Besides, make sure module is less than TIME_MODULE_BUTT. +#define TIME_HILOGF(module, ...) (void)OHOS::HiviewDFX::HiLog::Fatal(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__)) +#define TIME_HILOGE(module, ...) (void)OHOS::HiviewDFX::HiLog::Error(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__)) +#define TIME_HILOGW(module, ...) (void)OHOS::HiviewDFX::HiLog::Warn(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__)) +#define TIME_HILOGI(module, ...) (void)OHOS::HiviewDFX::HiLog::Info(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__)) +#define TIME_HILOGD(module, ...) (void)OHOS::HiviewDFX::HiLog::Debug(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__)) + +} // namespace MiscServices +} // namespace OHOS + + +#endif // TIME_HILOG_WRAPPER_H diff --git a/utils/native/include/time_permission.h b/utils/native/include/time_permission.h new file mode 100644 index 0000000..a37c0af --- /dev/null +++ b/utils/native/include/time_permission.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef TIME_PERMISSION_H +#define TIME_PERMISSION_H + +#include "bundle_mgr_interface.h" +#include "time_common.h" +#include "mock_permission.h" +#include "system_ability_definition.h" +#include "iservice_registry.h" +#include "refbase.h" + +#include +#include +namespace OHOS { +namespace MiscServices { +class TimePermission : public RefBase{ +public: + static sptr GetInstance(); + bool CheckSelfPermission(const std::string permName); + bool CheckCallingPermission(const int32_t uid, const std::string permName); + +private: + TimePermission(); + ~TimePermission(); + sptr GetBundleManager(); + + static std::mutex instanceLock_; + static sptr instance_; + static sptr bundleMgrProxy_; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // TIME_PERMISSION_H diff --git a/utils/native/include/time_rdb_handler.h b/utils/native/include/time_rdb_handler.h new file mode 100644 index 0000000..b67bc08 --- /dev/null +++ b/utils/native/include/time_rdb_handler.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rdb_errno.h" +#include "rdb_helper.h" +#include + +namespace OHOS { +namespace MiscServices { + using namespace OHOS::NativeRdb; + class TimeOpenCallback : public RdbOpenCallback { + public: + int OnCreate(RdbStore &rdbStore) override; + int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override; + static const std::string CREATE_TIMEZONE_DB; + }; + + std::string const TimeOpenCallback::CREATE_TIMEZONE_DB = std::string("CREATE TABLE IF NOT EXISTS timezone ") + + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, " + "timezoneId TEXT NOT NULL)"); + + int TimeOpenCallback::OnCreate(RdbStore &store) + { + return store.ExecuteSql(CREATE_TIMEZONE_DB); + } + + int TimeOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) + { + return E_OK; + } + + bool InsertTimeZoneIdToRdb(const std::string timeZoneId){ + const std::string dbPath_ = "/data/misc/zoneinfo/"; + const std::string dbName_ = "systime.db"; + + RdbStoreConfig config(dbPath_+ dbName_); + + TimeOpenCallback helper; + int errCode = E_OK; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + if (store == nullptr){ + return false; + } + int deletedRows; + store->Delete(deletedRows, "timezone", "id = 1"); + + int64_t id; + ValuesBucket values; + values.PutInt("id", 1); + values.PutString("timezoneId", timeZoneId); + auto ret = store->Insert(id, "timezone", values); + + TIME_HILOGD(TIME_MODULE_SERVICE,"end."); + return ret == E_OK; + } + + bool GetTimeZoneId(std::string &timeZoneId){ + const std::string dbPath_ = "/data/misc/zoneinfo/"; + const std::string dbName_ = "systime.db"; + + RdbStoreConfig config(dbPath_+ dbName_); + TimeOpenCallback helper; + int errCode = E_OK; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + if (store == nullptr){ + return false; + } + std::unique_ptr resultSet = store->QuerySql("SELECT * FROM timezone"); + if (resultSet == nullptr){ + TIME_HILOGD(TIME_MODULE_SERVICE,"not found"); + return false; + } + int columnIndex; + std::string strVal; + auto ret = resultSet->GoToFirstRow(); + if (ret != E_OK){ + return false; + } + ret = resultSet->GetColumnIndex("timezoneId", columnIndex); + if (ret != E_OK){ + return false; + } + ret = resultSet->GetString(columnIndex, strVal); + if (ret != E_OK){ + return false; + } + timeZoneId = strVal; + return E_OK; + } +} +} \ No newline at end of file diff --git a/utils/native/src/time_permission.cpp b/utils/native/src/time_permission.cpp new file mode 100644 index 0000000..c36e408 --- /dev/null +++ b/utils/native/src/time_permission.cpp @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_permission.h" + + +namespace OHOS { +namespace MiscServices { + +std::mutex TimePermission::instanceLock_; +sptr TimePermission::instance_; +sptr TimePermission::bundleMgrProxy_; + +TimePermission::TimePermission() +{ +} + +TimePermission::~TimePermission() +{ +} + +sptr TimePermission::GetInstance() +{ + if (instance_ == nullptr){ + std::lock_guard autoLock(instanceLock_); + if (instance_ == nullptr) { + instance_ = new TimePermission; + } + } + return instance_; +} + +bool TimePermission::CheckSelfPermission(std::string permName) +{ + return true; +} + +bool TimePermission::CheckCallingPermission(int32_t uid, std::string permName) +{ + if (bundleMgrProxy_ == nullptr){ + bundleMgrProxy_ = GetBundleManager(); + TIME_HILOGI(TIME_MODULE_COMMON,"get bundle mgr"); + } + + if (bundleMgrProxy_ == nullptr){ + TIME_HILOGE(TIME_MODULE_COMMON,"redo get bundle mgr failed"); + return false; + } + std::string bundleName; + auto ret = bundleMgrProxy_->GetBundleNameForUid(uid, bundleName); + if (!ret){ + TIME_HILOGE(TIME_MODULE_COMMON,"get bundle name failed"); + // always true + return true; + } + auto userId = uid / 100000; + TIME_HILOGI(TIME_MODULE_COMMON,"VerifyPermission bundleName %{public}s, permission %{public}s", bundleName.c_str(), permName.c_str()); + return MockPermission::VerifyPermission(bundleName, permName, userId); +} + +sptr TimePermission::GetBundleManager() +{ + if (bundleMgrProxy_ == nullptr) { + sptr systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemManager != nullptr) { + bundleMgrProxy_ = + iface_cast(systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID)); + } else { + TIME_HILOGE(TIME_MODULE_COMMON,"fail to get SAMGR"); + } + } + return bundleMgrProxy_; +} + +} // namespace MiscServices +} // namespace OHOS -- Gitee From de7556f50b984e8e2757f6ef14eb1ab69c1bac62 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Wed, 1 Sep 2021 19:11:48 +0800 Subject: [PATCH 2/5] xuyanjun27@163.com Signed-off-by: guduhanyan --- services/BUILD.gn | 2 +- .../test/unittest/src/time_service_test.cpp | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/services/BUILD.gn b/services/BUILD.gn index 48af5b6..b551356 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -57,9 +57,9 @@ ohos_shared_library("time_service") { "${time_utils_path}:time_utils", "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", - "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb", "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk:native_appdatafwk", "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_preferences:native_preferences", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb", "//utils/native/base:utils", ] external_deps = [ diff --git a/services/time_manager/test/unittest/src/time_service_test.cpp b/services/time_manager/test/unittest/src/time_service_test.cpp index a1bc362..9dafa7b 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -43,6 +43,21 @@ void TimeServiceTest::TearDown(void) { } +/** +* @tc.name: GetTime001 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime001, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetWallTimeMs(); + EXPECT_TRUE(time1 > 0); + auto time2 = TimeServiceClient::GetInstance()->GetWallTimeMs(); + EXPECT_TRUE(time2 >= time1); +} + + +#if 0 /** * @tc.name: SetTime001 * @tc.desc: get system time. @@ -58,7 +73,6 @@ HWTEST_F(TimeServiceTest, SetTime001, TestSize.Level0) EXPECT_TRUE(result); } -#if 0 /** * @tc.name: SetTimeZone001 * @tc.desc: set system time zone. -- Gitee From e9653dd7e1414473e5dd4679280f9dd5fa6451b9 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Thu, 2 Sep 2021 09:34:59 +0800 Subject: [PATCH 3/5] xuyanjun27@163.com Signed-off-by: guduhanyan --- .../test/unittest/src/time_service_test.cpp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/services/time_manager/test/unittest/src/time_service_test.cpp b/services/time_manager/test/unittest/src/time_service_test.cpp index 9dafa7b..14ea460 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -43,21 +43,6 @@ void TimeServiceTest::TearDown(void) { } -/** -* @tc.name: GetTime001 -* @tc.desc: get system time. -* @tc.type: FUNC -*/ -HWTEST_F(TimeServiceTest, GetTime001, TestSize.Level0) -{ - auto time1 = TimeServiceClient::GetInstance()->GetWallTimeMs(); - EXPECT_TRUE(time1 > 0); - auto time2 = TimeServiceClient::GetInstance()->GetWallTimeMs(); - EXPECT_TRUE(time2 >= time1); -} - - -#if 0 /** * @tc.name: SetTime001 * @tc.desc: get system time. @@ -72,7 +57,7 @@ HWTEST_F(TimeServiceTest, SetTime001, TestSize.Level0) bool result = TimeServiceClient::GetInstance()->SetTime(time); EXPECT_TRUE(result); } - +#if 0 /** * @tc.name: SetTimeZone001 * @tc.desc: set system time zone. -- Gitee From a337e8c7c12fe3695f0eaae02eae756655d971a4 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Thu, 2 Sep 2021 21:08:38 +0800 Subject: [PATCH 4/5] xuyanjun27@163.com Signed-off-by: guduhanyan --- services/time_manager/src/time_service.cpp | 4 +-- .../test/unittest/src/time_service_test.cpp | 29 +++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index 17dd653..f46136b 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -317,7 +317,7 @@ int32_t TimeService::SetTime(const int64_t time) return E_TIME_NO_PERMISSION; } TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}" PRId64 "", time); - if (time <= 0 || time / 1000LL >= INT_MAX) { + if (time < 0) { TIME_HILOGE(TIME_MODULE_SERVICE, "input param error"); return E_TIME_PARAMETERS_INVALID; } @@ -333,7 +333,7 @@ int32_t TimeService::SetTime(const int64_t time) auto ret = set_rtc_time(tv.tv_sec); if (ret < 0){ TIME_HILOGE(TIME_MODULE_SERVICE,"set rtc fail: %{public}d.", ret); - return ERR_OK; + return E_TIME_SET_RTC_FAILED; } int64_t currentTime = 0; diff --git a/services/time_manager/test/unittest/src/time_service_test.cpp b/services/time_manager/test/unittest/src/time_service_test.cpp index 14ea460..f557b4c 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -52,12 +52,15 @@ HWTEST_F(TimeServiceTest, SetTime001, TestSize.Level0) { struct timeval getTime; gettimeofday(&getTime, NULL); - int64_t time = (getTime.tv_sec + 1000) * 1000 + getTime.tv_usec / 1000; + int64_t time = (getTime.tv_sec + 1000) * 1000 + getTime.tv_usec / 1000; + if (time < 0){ + time = 1627307312000; + } TIME_HILOGI(TIME_MODULE_CLIENT, "Time now : %{public}" PRId64 "",time); bool result = TimeServiceClient::GetInstance()->SetTime(time); EXPECT_TRUE(result); } -#if 0 + /** * @tc.name: SetTimeZone001 * @tc.desc: set system time zone. @@ -74,7 +77,7 @@ HWTEST_F(TimeServiceTest, SetTimeZone001, TestSize.Level0) } /** -* @tc.name: SetTimeZone001 +* @tc.name: SetTimeZone002 * @tc.desc: set system time zone. * @tc.type: FUNC */ @@ -96,7 +99,7 @@ HWTEST_F(TimeServiceTest, SetTimeZone002, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime001, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetWallTimeMs(); - EXPECT_TRUE(time1 > 0); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetWallTimeMs(); EXPECT_TRUE(time2 >= time1); } @@ -109,6 +112,7 @@ HWTEST_F(TimeServiceTest, GetTime001, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime002, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetWallTimeNs(); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetWallTimeNs(); EXPECT_TRUE(time2 >= time1); } @@ -121,7 +125,7 @@ HWTEST_F(TimeServiceTest, GetTime002, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime003, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetBootTimeMs(); - EXPECT_TRUE(time1 >= 0); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetBootTimeMs(); EXPECT_TRUE(time2 >= time1); } @@ -134,7 +138,7 @@ HWTEST_F(TimeServiceTest, GetTime003, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime004, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetMonotonicTimeMs(); - EXPECT_TRUE(time1 >= 0); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetMonotonicTimeMs(); EXPECT_TRUE(time2 >= time1); } @@ -147,7 +151,7 @@ HWTEST_F(TimeServiceTest, GetTime004, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime005, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetBootTimeNs(); - EXPECT_TRUE(time1 >= 0); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetBootTimeNs(); EXPECT_TRUE(time2 >= time1); } @@ -160,7 +164,7 @@ HWTEST_F(TimeServiceTest, GetTime005, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime006, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(); - EXPECT_TRUE(time1 >= 0); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(); EXPECT_TRUE(time2 >= time1); } @@ -173,7 +177,7 @@ HWTEST_F(TimeServiceTest, GetTime006, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime007, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetThreadTimeMs(); - EXPECT_TRUE(time1 >= 0); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetThreadTimeMs(); EXPECT_TRUE(time2 >= time1); } @@ -186,7 +190,7 @@ HWTEST_F(TimeServiceTest, GetTime007, TestSize.Level0) HWTEST_F(TimeServiceTest, GetTime008, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetThreadTimeNs(); - EXPECT_TRUE(time1 >= 0); + EXPECT_TRUE(time1 != -1); auto time2 = TimeServiceClient::GetInstance()->GetThreadTimeNs(); EXPECT_TRUE(time2 >= time1); } @@ -345,7 +349,9 @@ HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0) struct timeval getTime; gettimeofday(&getTime, NULL); int64_t current_time = (getTime.tv_sec + 100) * 1000 + getTime.tv_usec / 1000; - + if (current_time < 0){ + current_time = 0; + } auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo); EXPECT_TRUE(timerId1 > 0); @@ -358,4 +364,3 @@ HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0) ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_FALSE(ret); } -#endif \ No newline at end of file -- Gitee From c030591769b454c6684b7d4dbe05be4265225549 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Thu, 2 Sep 2021 21:53:40 +0800 Subject: [PATCH 5/5] xuyanjun27@163.com Signed-off-by: guduhanyan --- services/time_manager/src/time_service.cpp | 2 +- time.gni | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index f46136b..86cb6ee 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -317,7 +317,7 @@ int32_t TimeService::SetTime(const int64_t time) return E_TIME_NO_PERMISSION; } TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}" PRId64 "", time); - if (time < 0) { + if (time < 0 || time / 1000LL >= LONG_MAX) { TIME_HILOGE(TIME_MODULE_SERVICE, "input param error"); return E_TIME_PARAMETERS_INVALID; } diff --git a/time.gni b/time.gni index c20574f..fa8f667 100755 --- a/time.gni +++ b/time.gni @@ -20,4 +20,4 @@ innerkits_path = "${time_root_path}/interfaces/innerkits" time_utils_path = "${time_root_path}/utils" -adapter_path = "${time_root_path}/adapter" \ No newline at end of file +adapter_path = "${time_root_path}/adapter" -- Gitee