From 912bf87c65894bc0496733809673fcb5f66e8b24 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Wed, 4 Aug 2021 23:08:22 +0800 Subject: [PATCH 01/14] time@timer func --- BUILD.gn | 3 +- .../innerkits/include/itimer_info.h | 76 +- .../innerkits/include/time_service_client.h | 160 ++++ .../js/declaration/api/@ohos.systemtime.d.ts | 23 +- .../js/declaration/api/@ohos.systemtimer.d.ts | 114 +++ .../kits/js/napi/{ => system_time}/BUILD.gn | 14 +- .../napi/system_time/include/js_systemtime.h | 119 +-- .../{ => system_time/src}/js_systemtime.cpp | 159 +++- 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 | 745 ++++++++++++++++++ .../js/napi/system_timer/src/timer_type.cpp | 45 ++ ohos.build | 2 +- services/BUILD.gn | 47 +- services/include/time_log.h | 76 -- services/src/time_service.cpp | 142 ---- services/src/time_service_manager.cpp | 103 --- .../{ => time_manager}/include/time_service.h | 158 ++-- .../include/time_service_interface.h | 171 ++++ .../include/time_service_notify.h | 51 ++ .../include/time_service_proxy.h | 86 +- .../include/time_service_stub.h} | 110 ++- .../include/time_zone_info.h} | 104 +-- .../src/itimer_info.cpp} | 67 +- services/time_manager/src/time_service.cpp | 567 +++++++++++++ .../time_manager/src/time_service_client.cpp | 364 +++++++++ .../time_manager/src/time_service_notify.cpp | 68 ++ .../time_manager/src/time_service_proxy.cpp | 224 ++++++ .../time_manager/src/time_service_stub.cpp | 224 ++++++ services/time_manager/src/time_zone_info.cpp | 104 +++ services/{ => time_manager}/test/BUILD.gn | 29 +- .../test/unittest/include/timer_test.h | 75 ++ .../test/unittest/src/time_service_test.cpp | 373 +++++++++ services/timer/include/batch.h | 56 ++ .../include/timer_handler.h} | 96 +-- services/timer/include/timer_info.h | 65 ++ services/timer/include/timer_manager.h | 121 +++ .../timer/include/timer_manager_interface.h | 67 ++ services/timer/src/batch.cpp | 165 ++++ services/timer/src/timer_handler.cpp | 286 +++++++ services/timer/src/timer_info.cpp | 64 ++ services/timer/src/timer_manager.cpp | 587 ++++++++++++++ time.gni | 11 +- utils/BUILD.gn | 33 + .../native}/include/time_common.h | 88 ++- utils/native/include/time_hilog_wreapper.h | 78 ++ utils/native/include/time_permission.h | 30 + utils/native/include/time_rdb_handler.h | 95 +++ utils/native/src/time_permission.cpp | 35 + 51 files changed, 5898 insertions(+), 797 deletions(-) rename services/include/time_service_stub.h => interfaces/innerkits/include/itimer_info.h (53%) mode change 100755 => 100644 create mode 100644 interfaces/innerkits/include/time_service_client.h create mode 100644 interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts rename interfaces/kits/js/napi/{ => system_time}/BUILD.gn (70%) mode change 100755 => 100644 rename services/test/unittest/time_service_test.cpp => interfaces/kits/js/napi/system_time/include/js_systemtime.h (39%) mode change 100755 => 100644 rename interfaces/kits/js/napi/{ => system_time/src}/js_systemtime.cpp (38%) mode change 100755 => 100644 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/src/time_service.cpp delete mode 100755 services/src/time_service_manager.cpp rename services/{ => time_manager}/include/time_service.h (47%) mode change 100755 => 100644 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 rename services/{src/time_service_stub.cpp => time_manager/include/time_service_stub.h} (32%) mode change 100755 => 100644 rename services/{include/time_service_manager.h => time_manager/include/time_zone_info.h} (42%) mode change 100755 => 100644 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 rename services/{ => time_manager}/test/BUILD.gn (67%) 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 rename services/{src/time_service_proxy.cpp => timer/include/timer_handler.h} (43%) mode change 100755 => 100644 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 => utils/native}/include/time_common.h (71%) 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 5664d616..06ad71cd 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/services/include/time_service_stub.h b/interfaces/innerkits/include/itimer_info.h old mode 100755 new mode 100644 similarity index 53% rename from services/include/time_service_stub.h rename to interfaces/innerkits/include/itimer_info.h index ccef63ef..d1d1dd08 --- a/services/include/time_service_stub.h +++ b/interfaces/innerkits/include/itimer_info.h @@ -1,35 +1,41 @@ -/* - * 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 +#include "want_agent.h" + +namespace OHOS { +namespace MiscServices { + +class ITimerInfo { +public: + ITimerInfo(); + ~ITimerInfo(); + + int type; + bool repeat; + uint64_t interval; + std::shared_ptr wantAgent; + + virtual void SetType(const int &type) = 0; + virtual void SetRepeat(bool repeat) = 0; + 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 00000000..d77338b3 --- /dev/null +++ b/interfaces/innerkits/include/time_service_client.h @@ -0,0 +1,160 @@ +/* + * 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 "itimer_info.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(); + + // timer callbackObject has func OnTrigger(); + uint64_t CreateTimer(std::shared_ptr TimerInfo); + bool StartTimer(uint64_t timerId, uint64_t triggerTime); + bool StopTimer(uint64_t timerId); + 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_; + + std::mutex mapMutex_; + +}; +} // 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 c6d1039d..d600cf46 100755 --- a/interfaces/kits/js/declaration/api/@ohos.systemtime.d.ts +++ b/interfaces/kits/js/declaration/api/@ohos.systemtime.d.ts @@ -21,9 +21,26 @@ import { AsyncCallback, ErrorCallback } from './basic'; * @since 6 */ declare namespace systemTime { - // Sets the system time. - function setTime(time : number, callback : AsyncCallback) : void; - function setTime(time : number) : Promise; + /** + * Set system time. + * @SystemApi + */ + function setTime(time: number, callback: AsyncCallback): void; + function setTime(time: number): Promise; + + /** + * Set system time. + * @SystemApi + */ + function setDate(date: Date, callback: AsyncCallback): void; + function setDate(date: Date): Promise; + /** + * Set system time zone. + * @SystemApi + */ + 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 00000000..293615f1 --- /dev/null +++ b/interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts @@ -0,0 +1,114 @@ +/* + * 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 + */ +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_REALTIME_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. + * @SystemApi + */ + function createTimer(options: TimerOptions, callback: AsyncCallback): void; + function createTimer(options: TimerOptions): Promise; + + /** + * Starts a timer. + * @SystemApi + */ + function startTimer(timer: number, callback: AsyncCallback): void; + function startTimer(timer: number): Promise; + + /** + * Stops a timer. + * @SystemApi + */ + function stopTimer(timer: number, callback: AsyncCallback): void; + function stopTimer(timer: number): Promise; + + /** + * Clears a timer. + * @SystemApi + */ + function destroyTimer(timer: number, callback: AsyncCallback): void; + function destroyTimer(timer: number): Promise; + + interface TimerOptions { + /** + * timer type. + */ + type: number; + + /** + * 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. + */ + triggerTime: 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 timer is not lost with shutdown or sleep, until all trigger actions have been completed. + * + */ + persistent: boolean; + + /** + * Indicates the intent to send when the timer goes off. + * @SystemApi + */ + 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/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 c7c07e50..878efdfc --- 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/services/test/unittest/time_service_test.cpp b/interfaces/kits/js/napi/system_time/include/js_systemtime.h old mode 100755 new mode 100644 similarity index 39% rename from services/test/unittest/time_service_test.cpp rename to interfaces/kits/js/napi/system_time/include/js_systemtime.h index 50ca1311..8b69322c --- a/services/test/unittest/time_service_test.cpp +++ b/interfaces/kits/js/napi/system_time/include/js_systemtime.h @@ -1,59 +1,60 @@ -/* - * 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); -} +/* + * 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; + +enum{ + TYPE_SET_TIME = 0, + TYPE_SET_DATE = 1, + TYPE_SET_TIMEZOME = 2 +}; + +#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; + int type; + int64_t time; + int64_t dateMs; + 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/js_systemtime.cpp b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp old mode 100755 new mode 100644 similarity index 38% rename from interfaces/kits/js/napi/js_systemtime.cpp rename to interfaces/kits/js/napi/system_time/src/js_systemtime.cpp index 0e76fcd6..f93ab2d4 --- a/interfaces/kits/js/napi/js_systemtime.cpp +++ b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp @@ -13,44 +13,48 @@ * limitations under the License. */ +#include "js_systemtime.h" + #include -#include "time_service_manager.h" +#include "time_service_client.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) +#include "js_native_api.h" -typedef struct _SetTimeAsyncContext { - napi_env env; - napi_async_work work; +#include "time_common.h" +#include - int64_t time; - napi_deferred deferred; - napi_ref callbackRef; - int status; -} SetTimeAsyncContext; +using namespace OHOS::MiscServices; static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) { - TIME_HILOGI("JSSystemTimeSetTime start"); + TIME_HILOGI(TIME_MODULE_JS_NAPI,"JSSystemTimeSetTime start"); GET_PARAMS(env, info, 2); - NAPI_ASSERT(env, argc >= 1, "requires 1 parameter"); + NAPI_ASSERT(env, argc == ONE_PARAMETER || argc == TWO_PARAMETER, "type mismatch"); - SetTimeAsyncContext* asyncContext = new SetTimeAsyncContext(); + 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_number) { - napi_get_value_int64(env, argv[i], &asyncContext->time); + if (napi_ok != napi_get_value_int64(env, argv[i], &asyncContext->time)){ + delete asyncContext; + NAPI_ASSERT(env, false, "input para invalid"); + } + asyncContext->type = TYPE_SET_TIME; + //double dateValue; + //napi_get_date_value(env, argv[i], &dateValue); + // } else if (i == 0 && valueType == napi_object){ + // double dateValue; + // if (napi_ok != napi_get_date_value(env, argv[i], &dateValue)){ + // delete asyncContext; + // NAPI_ASSERT(env, false, "input para invalid"); + // } + // asyncContext->dateMs = int64_t(dateValue); + // asyncContext->type = TYPE_SET_DATE; } else if (i == 1 && valueType == napi_function) { napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); } else { @@ -70,31 +74,34 @@ static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) 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); + napi_create_async_work(env, nullptr, resource,[](napi_env env, void* data) { + AsyncContext* asyncContext = (AsyncContext*)data; + bool setTimeResult; + if (asyncContext->type == TYPE_SET_DATE) { + setTimeResult = TimeServiceClient::GetInstance()->SetTime(asyncContext->dateMs); + }else{ + setTimeResult = TimeServiceClient::GetInstance()->SetTime(asyncContext->time); + } if (setTimeResult) { - asyncContext->status = 0; + asyncContext->status = RESOLVED; } else { - asyncContext->status = 1; + asyncContext->status = REJECT; } }, [](napi_env env, napi_status status, void* data) { - SetTimeAsyncContext* asyncContext = (SetTimeAsyncContext*)data; + AsyncContext* asyncContext = (AsyncContext*)data; napi_value result[2] = { 0 }; - if (!asyncContext->status) { + 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, "SetTime fail", NAPI_AUTO_LENGTH, &message); + 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) { + if (asyncContext->status == RESOLVED) { napi_resolve_deferred(env, asyncContext->deferred, result[1]); } else { napi_reject_deferred(env, asyncContext->deferred, result[0]); @@ -115,11 +122,97 @@ static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) 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; + asyncContext->type = TYPE_SET_TIMEZOME; + } 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("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; 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 00000000..b6c74315 --- /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 00000000..e6ec4465 --- /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 00000000..5147d323 --- /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 00000000..2bca0f22 --- /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 00000000..39e3005e --- /dev/null +++ b/interfaces/kits/js/napi/system_timer/src/system_timer.cpp @@ -0,0 +1,745 @@ +/* + * 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); + } + + asyncCallbackInfoCreateInfo.emplace_back(asynccallbackinfo); + + 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); + }, + [](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 00000000..53af1022 --- /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_REALTIME_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 759e4808..f96f7921 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 c245679c..abada9f0 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -12,14 +12,18 @@ # 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/", ] cflags_cc = [ "-fexceptions" ] @@ -27,25 +31,50 @@ config("time_service_config") { 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", + "timer/src/batch.cpp", + "timer/src/timer_handler.cpp", + "timer/src/timer_info.cpp", + "timer/src/timer_manager.cpp", + "time_manager/src/itimer_info.cpp", + "time_manager/src/time_service_client.cpp", + "time_manager/src/time_zone_info.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_service.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", + "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", + "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", "//utils/native/base:utils", + "${time_utils_path}:time_utils", + "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb", ] + 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 c7377976..00000000 --- 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/src/time_service.cpp b/services/src/time_service.cpp deleted file mode 100755 index 7b71f1fa..00000000 --- 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: %{public}lld", time); - 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 9f5d578d..00000000 --- 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/include/time_service.h b/services/time_manager/include/time_service.h old mode 100755 new mode 100644 similarity index 47% rename from services/include/time_service.h rename to services/time_manager/include/time_service.h index 32ac0d7b..9343ca14 --- a/services/include/time_service.h +++ b/services/time_manager/include/time_service.h @@ -1,60 +1,98 @@ -/* - * 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 +/* + * 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 "system_ability.h" +#include "event_handler.h" +#include "time.h" +#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* times) override; + int32_t GetWallTimeNs(int64_t* times) override; + int32_t GetBootTimeMs(int64_t* times) override; + int32_t GetBootTimeNs(int64_t* times) override; + int32_t GetMonotonicTimeMs(int64_t* times) override; + int32_t GetMonotonicTimeNs(int64_t* times) override; + int32_t GetThreadTimeMs(int64_t* times) override; + int32_t GetThreadTimeNs(int64_t* times) override; + uint64_t CreateTimer(int type, bool repeat, uint64_t interval, + std::shared_ptr wantAgent, std::function callback) override; + bool StartTimer(uint64_t timerId, uint64_t treggerTime) 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); + + template + std::string str_format(const std::string &format, Args ...); + bool check_rtc(); + int get_wall_clock_rtc_id(); + + ServiceRunningState state_; + static std::mutex instanceLock_; + static sptr instance_; + const int rtc_id; + const std::string rtc_path = "/sys/class/rtc"; + 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 00000000..44569879 --- /dev/null +++ b/services/time_manager/include/time_service_interface.h @@ -0,0 +1,171 @@ +/* + * 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 + }; + /** + * 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* times) = 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* times) = 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* times) = 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* times) = 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* times) = 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* times) = 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* times) = 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* times) = 0; + + /** + * CreateTimer + * + * @param times result of times ,unit: Nanosecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual uint64_t CreateTimer(int type, bool repeat, uint64_t interval, + std::shared_ptr wantAgent, std::function callback) = 0; + + /** + * GetThreadTimeNs + * + * @param times result of times ,unit: Nanosecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual bool StartTimer(uint64_t timerId, uint64_t treggerTime) = 0; + + /** + * GetThreadTimeNs + * + * @param times result of times ,unit: Nanosecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual bool StopTimer(uint64_t timerId) = 0; + + /** + * GetThreadTimeNs + * + * @param times result of times ,unit: Nanosecond + * @return int32_t ERR_OK on success, other on failure. + */ + virtual bool DestroyTimer(uint64_t timerId) = 0; + + +public: + 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 00000000..6fb3a36e --- /dev/null +++ b/services/time_manager/include/time_service_notify.h @@ -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. + */ + +#ifndef TIME_SERVICE_NOTIFY_H +#define TIME_SERVICE_NOTIFY_H + +#include +#include +#include "time_common.h" + + +namespace OHOS { +namespace MiscService { + +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_; + const std::string TIME_CHANGE_ACTION = "com.hos.action.TIME_CHANGE_ACTION"; + const std::string TIME_ZONE_CHANGE_ACTION = "com.hos.action.TIME_ZONE_CHANGE_ACTION"; + +}; +} // namespace MiscService +} // 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 b309a4e4..5011aa61 --- a/services/include/time_service_proxy.h +++ b/services/time_manager/include/time_service_proxy.h @@ -1,36 +1,52 @@ -/* - * 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* times) override; + int32_t GetWallTimeNs(int64_t* times) override; + int32_t GetBootTimeMs(int64_t* times) override; + int32_t GetBootTimeNs(int64_t* times) override; + int32_t GetMonotonicTimeMs(int64_t* times) override; + int32_t GetMonotonicTimeNs(int64_t* times) override; + int32_t GetThreadTimeMs(int64_t* times) override; + int32_t GetThreadTimeNs(int64_t* times) override; + uint64_t CreateTimer(int type, bool repeat, uint64_t interval, + std::shared_ptr wantAgent, std::function callback) 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/src/time_service_stub.cpp b/services/time_manager/include/time_service_stub.h old mode 100755 new mode 100644 similarity index 32% rename from services/src/time_service_stub.cpp rename to services/time_manager/include/time_service_stub.h index 167f06b3..9edbdd6a --- a/services/src/time_service_stub.cpp +++ b/services/time_manager/include/time_service_stub.h @@ -1,60 +1,50 @@ -/* - * 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 +/* + * 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 + +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); + + std::map memberFuncMap_; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // SERVICES_INCLUDE_TIME_SERVICE_STUB_H \ No newline at end of file diff --git a/services/include/time_service_manager.h b/services/time_manager/include/time_zone_info.h old mode 100755 new mode 100644 similarity index 42% rename from services/include/time_service_manager.h rename to services/time_manager/include/time_zone_info.h index dd5f1f6f..e455a33d --- a/services/include/time_service_manager.h +++ b/services/time_manager/include/time_zone_info.h @@ -1,51 +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_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 +/* + * 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(int offset, std::string *timezoneId); + +private: + 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/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 21041732..1cf2f26f --- a/services/include/time_service_interface.h +++ b/services/time_manager/src/itimer_info.cpp @@ -1,34 +1,33 @@ -/* - * 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 00000000..3932087a --- /dev/null +++ b/services/time_manager/src/time_service.cpp @@ -0,0 +1,567 @@ +/* + * 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 + + +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()) +{ +} + +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 Start."); + if (state_ == ServiceRunningState::STATE_RUNNING) { + TIME_HILOGE(TIME_MODULE_SERVICE," TimeService is already running."); + return; + } + + InitServiceHandler(); + InitTimeZone(); + InitTimerHandler(); + 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(){ + std::string timeZoneId; + auto hasTimeZone = GetTimeZoneId(timeZoneId); + if (!hasTimeZone){ + TIME_HILOGI(TIME_MODULE_SERVICE,"Time Zone Not Found."); + return; + } + SetTimeZone(timeZoneId); +} + +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(int type, bool repeat, uint64_t interval, + std::shared_ptr wantAgent, std::function callback) +{ + 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){ + if (interval < 5000){ + intervalOut = 5000; + } + intervalOut = interval; + }else{ + intervalOut = 0; + } + + auto timerId = timerManagerHandler_->CreateTimer(timerType, + windowLength, + intervalOut, + flag, + wantAgent, + callback, + 0); + return timerId; +} + +bool TimeService::StartTimer(uint64_t timerId, uint64_t triggerTimes) +{ + uint64_t triggerTimesIn; + triggerTimesIn = (triggerTimes < 5000) ? 5000 : triggerTimes; + auto ret = timerManagerHandler_->StartTimer(timerId, triggerTimesIn); + if (!ret){ + TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found."); + } + return ret; +} +bool TimeService::StopTimer(uint64_t timerId) +{ + auto ret = timerManagerHandler_->StopTimer(timerId); + if (!ret){ + TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found."); + } + return ret; +} +bool TimeService::DestroyTimer(uint64_t timerId) +{ + 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) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}lld.", 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; + } + if (set_rtc_time(tv.tv_sec) < 0){ + TIME_HILOGE(TIME_MODULE_SERVICE,"set rtc fail: %{public}d.",result); + return E_TIME_SET_RTC_FAILED; + } + + int64_t currentTime = 0; + GetWallTimeMs(¤tTime); + timeServiceNotify_->PublishTimeChanageEvents(currentTime); + return ERR_OK; +} + +int TimeService::set_rtc_time(time_t sec){ + + struct rtc_time rtc; + struct tm tm, *gmtime_res; + int fd; + int res; + if (rtc_id < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"invalid rtc id: %s:", strerror(ENODEV)); + return -1; + } + std::string rtc_dev = str_format("/dev/rtc%d", rtc_id); + fd = open(rtc_dev.data(), O_RDWR); + if (fd < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"open failed %s: %s", rtc_dev.data(), strerror(errno)); + return -1; + } + + gmtime_res = gmtime_r(&sec, &tm); + if (gmtime_res) { + memset(&rtc, 0, sizeof(rtc)); + 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: %s", strerror(errno)); + } + }else{ + TIME_HILOGE(TIME_MODULE_SERVICE,"convert rtc time failed: %s", strerror(errno)); + res = -1; + } + close(fd); + return res; +} + +int32_t TimeService::SetTimeZone(const std::string timeZoneId) +{ + + int gmtOffset; + struct timezone tz; + auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, &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(¤tTime); + timeServiceNotify_->PublishTimeZoneChangeEvents(currentTime); + + auto status = InsertTimeZoneIdToRdb(timeZoneId); + if (!status){ + TIME_HILOGE(TIME_MODULE_SERVICE,"Save TimeZone Failed."); + } + return ERR_OK;; +} + + +int32_t TimeService::GetTimeZone(std::string *timeZoneId) +{ + int gmtOffset; + struct timezone tz; + int result = gettimeofday(NULL, &tz); + if (result < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result); + return E_TIME_DEAL_FAILED; + } + gmtOffset = tz.tz_minuteswest *60; + auto ret = TimeZoneInfo::GetInstance()->GetTimezoneId(gmtOffset, timeZoneId); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret); + } + return ret; +} + +int32_t TimeService::GetWallTimeMs(int64_t* times) +{ + 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* times) +{ + 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* times) +{ + 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* times) +{ + 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* times) +{ + 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* times) +{ + 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* times) +{ + 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* times) +{ + 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; +} + +template +std::string TimeService::str_format(const std::string &format, Args ... args) +{ + auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; + std::unique_ptr buf(new(std::nothrow) char[size_buf]); + + if (!buf) + return std::string(""); + + std::snprintf(buf.get(), size_buf, format.c_str(), args...); + return std::string(buf.get(), buf.get() + size_buf - 1); +} + +bool TimeService::check_rtc() +{ + std::string hctosys_path = str_format("%s/rtc%u/hctosys", + rtc_path.c_str(), rtc_id); + FILE *file = fopen(hctosys_path.data(), "re"); + if (!file) { + TIME_HILOGE(TIME_MODULE_SERVICE,"failed to open %{public}s: %{public}s", hctosys_path.data(), strerror(errno)); + return false; + } + + unsigned int hctosys; + bool ret = false; + int err = fscanf(file, "%u", &hctosys); + if (err == EOF){ + TIME_HILOGE(TIME_MODULE_SERVICE,"read %{public}s failed: %{public}s", hctosys_path.data(),strerror(errno)); + + }else if (err == 0){ + TIME_HILOGE(TIME_MODULE_SERVICE,"%{public}s no contents", hctosys_path.data()); + } + else{ + ret = hctosys; + } + fclose(file); + return ret; +} + +int TimeService::get_wall_clock_rtc_id() +{ + 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; + int matched = sscanf(dirent->d_name, "rtc%u", &rtc_id); + + if (matched < 0) + break; + else if (matched != 1) + continue; + + if (check_rtc()) { + TIME_HILOGD(TIME_MODULE_SERVICE,"found wall clock rtc %{public}u", rtc_id); + return rtc_id; + } + } + + 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; +} + +} // 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 00000000..6f629ae5 --- /dev/null +++ b/services/time_manager/src/time_service_client.cpp @@ -0,0 +1,364 @@ +/* + * 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; + timeServiceProxy_ = ConnectService(); + } + } + 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 (timeServiceProxy_ == nullptr) { + TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService"); + timeServiceProxy_ = ConnectService(); + } + + if (timeServiceProxy_ == nullptr) { + TIME_HILOGE(TIME_MODULE_CLIENT, "CreateTimer quit because redoing ConnectService failed."); + return false; + } + std::function callBackFunc = std::bind(&ITimerInfo::OnTrigger, TimerOptions); + + auto timerId = timeServiceProxy_->CreateTimer(TimerOptions->type, TimerOptions->repeat, + TimerOptions->interval, TimerOptions->wantAgent, callBackFunc); + + 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; + } + return timeServiceProxy_->DestroyTimer(timerId); +} + + + +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){ + 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 ERROR_OPREATION_FAILED; + } + if(timeServiceProxy_->GetWallTimeMs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 ERROR_OPREATION_FAILED; + } + + if(timeServiceProxy_->GetWallTimeNs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 ERROR_OPREATION_FAILED; + } + + if(timeServiceProxy_->GetBootTimeMs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 ERROR_OPREATION_FAILED; + } + + if(timeServiceProxy_->GetBootTimeNs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 ERROR_OPREATION_FAILED; + } + + if(timeServiceProxy_->GetMonotonicTimeMs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 ERROR_OPREATION_FAILED; + } + + if(timeServiceProxy_->GetMonotonicTimeNs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 ERROR_OPREATION_FAILED; + } + + if(timeServiceProxy_->GetThreadTimeMs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 ERROR_OPREATION_FAILED; + } + if(timeServiceProxy_->GetThreadTimeNs(×) != ERR_OK){ + return ERROR_OPREATION_FAILED; + } + 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 00000000..2016f717 --- /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 MiscService{ + +void TimeServiceNotify::RegisterPublishEvents() +{ + if (publishInfo_ != nullptr) { + return; + } + publishInfo_ = new (std::nothrow)CommonEventPublishInfo(); + publishInfo_->SetOrdered(false); + timeChangeWant_ = new (std::nothrow)IntentWant(); + timeChangeWant_->SetAction(TIME_CHANGE_ACTION); + timeZoneChangeWant_ = new (std::nothrow)IntentWant(); + timeZoneChangeWant_->SetAction(TIME_ZONE_CHANGE_ACTION); +} + +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 00000000..86b0bbd5 --- /dev/null +++ b/services/time_manager/src/time_service_proxy.cpp @@ -0,0 +1,224 @@ +/* + * 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; + + data.WriteInterfaceToken(GetDescriptor()); + data.WriteInt64(time); + + 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(int type, bool repeat, uint64_t interval, + std::shared_ptr wantAgent, std::function callback) +{ + return 0; +} + +bool TimeServiceProxy::StartTimer(uint64_t timerId, uint64_t triggerTimes) +{ + return 0; +} +bool TimeServiceProxy::StopTimer(uint64_t timerId) +{ + return 0; +} +bool TimeServiceProxy::DestroyTimer(uint64_t timerId) +{ + + return 0; +} + +int32_t TimeServiceProxy::SetTimeZone(std::string timezoneId) +{ + MessageParcel data, reply; + MessageOption option; + data.WriteString(timezoneId); + data.WriteInterfaceToken(GetDescriptor()); + + 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; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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* times) +{ + MessageParcel data, reply; + MessageOption option; + + data.WriteInterfaceToken(GetDescriptor()); + + 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 00000000..9eef29d4 --- /dev/null +++ b/services/time_manager/src/time_service_stub.cpp @@ -0,0 +1,224 @@ +/* + * 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 "ipc_skeleton.h" + +#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; +} +TimeServiceStub::~TimeServiceStub(){ + memberFuncMap_.clear(); +} + +int32_t TimeServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnRemoteRequest start##code = %{public}u", code); + std::u16string myDescripter = TimeServiceStub::GetDescriptor(); + std::u16string remoteDescripter = data.ReadInterfaceToken(); + if (myDescripter != remoteDescripter) { + TIME_HILOGE(TIME_MODULE_SERVICE,"OnRemoteRequest 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,"OnRemoteRequest end##ret = %{public}d", ret); + return ret; +} + +int32_t TimeServiceStub::OnSetTime(MessageParcel& data, MessageParcel& reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnSetTime start."); + int64_t time = data.ReadInt64(); + + int32_t ret = SetTime(time); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnSetTime end##ret = %{public}d", ret); + return ret; +} + +int32_t TimeServiceStub::OnSetTimeZone(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnSetTimeZone start."); + std::string timeZoneId = data.ReadString(); + + int32_t ret = SetTimeZone(timeZoneId); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnSetTimeZone end##ret = %{public}d", ret); + return ret; +} + +int32_t TimeServiceStub::OnGetTimeZone(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetTimeZone start."); + std::string timeZoneId; + + int32_t ret = GetTimeZone(&timeZoneId); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetTimeZone end##ret = %{public}d", ret); + return ret; + } + reply.WriteString(timeZoneId); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetTimeZone end."); + return ret; +} + +int32_t TimeServiceStub::OnGetWallTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeMs start."); + int64_t times; + + int32_t ret = GetWallTimeMs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetWallTimeMs end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeMs end."); + return ret; +} + +int32_t TimeServiceStub::OnGetWallTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeNs start."); + int64_t times; + + int32_t ret = GetWallTimeNs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetWallTimeNs end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeNs end."); + return ret; +} + +int32_t TimeServiceStub::OnGetBootTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeMs start."); + int64_t times; + + int32_t ret = GetBootTimeMs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetBootTimeMs end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeMs end."); + return ret; +} + +int32_t TimeServiceStub::OnGetBootTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeNs start."); + int64_t times; + + int32_t ret = GetBootTimeNs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetBootTimeNs end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeNs end."); + return ret; +} + +int32_t TimeServiceStub::OnGetMonotonicTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetMonotonicTimeMs start."); + int64_t times; + + int32_t ret = GetMonotonicTimeMs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetMonotonicTimeMs end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetMonotonicTimeMs end."); + return ret; +} + +int32_t TimeServiceStub::OnGetMonotonicTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetMonotonicTimeNs start."); + int64_t times; + + int32_t ret = GetMonotonicTimeNs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetMonotonicTimeNs end."); + return ret; +} + +int32_t TimeServiceStub::OnGetThreadTimeMs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeMs start."); + int64_t times; + + int32_t ret = GetThreadTimeMs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetThreadTimeMs end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeMs end."); + return ret; +} + +int32_t TimeServiceStub::OnGetThreadTimeNs(MessageParcel &data, MessageParcel &reply) +{ + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeNs start."); + int64_t times; + int32_t ret = GetThreadTimeNs(×); + if (ret != ERR_OK){ + TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetThreadTimeNs end##ret = %{public}d", ret); + return ret; + } + reply.WriteInt64(times); + TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeNs end."); + return ret; +} + +} // 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 00000000..52b0daf0 --- /dev/null +++ b/services/time_manager/src/time_zone_info.cpp @@ -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. + */ + +#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; + return ERR_OK; + } + TIME_HILOGE(TIME_MODULE_SERVICE, "TimezoneId not found."); + return E_TIME_NOT_FOUND; +} + +int32_t TimeZoneInfo::GetTimezoneId(int offset, std::string *timezoneId ){ + auto itEntry = timezoneInfoMap_.find(*timezoneId); + if (itEntry != timezoneInfoMap_.end()) { + auto zoneInfo = itEntry->second; + offset = zoneInfo.utcOffsetHours; + return ERR_OK; + } + TIME_HILOGE(TIME_MODULE_SERVICE, "TimezoneId not found."); + return E_TIME_NOT_FOUND; +} + +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/test/BUILD.gn b/services/time_manager/test/BUILD.gn old mode 100755 new mode 100644 similarity index 67% rename from services/test/BUILD.gn rename to services/time_manager/test/BUILD.gn index 3ce06caf..1d3e599e --- a/services/test/BUILD.gn +++ b/services/time_manager/test/BUILD.gn @@ -9,26 +9,45 @@ # 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", "//third_party/googletest:gtest_main", "//utils/native/base:utils", ] + + external_deps = [ + "aafwk_standard:want", + "appexecfwk_standard:appexecfwk_base", + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] } 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 00000000..be40096b --- /dev/null +++ b/services/time_manager/test/unittest/include/timer_test.h @@ -0,0 +1,75 @@ +/* + * 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 "itimer_info.h" +#include + +namespace OHOS +{ + namespace MiscService + { + 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(std::function callBack); + + private: + std::function callBack_; + }; + + TimerInfoTest::TimerInfoTest() + { + } + + TimerInfoTest::~TimerInfoTest() + { + } + + void TimerInfoTest::OnTrigger() + { + callBack_(); + } + + void TimerInfoTest::SetCallbackInfo(std::function 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 00000000..852ceda5 --- /dev/null +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -0,0 +1,373 @@ +/* + * 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 "time_common.h" +#include "time_service_client.h" +#include +#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 + 100) * 1000 + getTime.tv_usec / 1000; + bool result = TimeServiceClient::GetInstance()->SetTime(time); + EXPECT_TRUE(result); +} + +/** +* @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, 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: 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(); + EXPECT_TRUE(time1 > 0); + 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: GetTime005 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime005, TestSize.Level0) +{ + auto time1 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(); + EXPECT_TRUE(time1 > 0); + auto time2 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(); + 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()->GetThreadTimeMs(); + EXPECT_TRUE(time1 > 0); + auto time2 = TimeServiceClient::GetInstance()->GetThreadTimeMs(); + EXPECT_TRUE(time2 > time1); +} + +/** +* @tc.name: GetTime007 +* @tc.desc: get system time. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, GetTime007, TestSize.Level0) +{ + Eauto 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) +{ + auto timerInfo = std::shared_ptr(); + timerInfo->SetType(2); + 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(10)); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data2 == 1); + auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_TRUE(ret); + auto 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::shared_ptr(); + timerInfo->SetType(3); + 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(10)); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data2 == 1); + auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_TRUE(ret); + auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data2 == 2); + auto 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); + auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId); + EXPECT_FALSE(ret); + auto 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) +{ + g_data1 = 0; + auto timerInfo = std::shared_ptr(); + timerInfo->SetType(3); + 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); + auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data2 == 0); + + auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_FALSE(ret); +} + +/** +* @tc.name: CreateTimer05 +* @tc.desc: Create system timer. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, CreateTimer05, TestSize.Level0) +{ + g_data1 = 0; + auto timerInfo = std::shared_ptr(); + timerInfo->SetType(0); + 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); + auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data2 == 0); + + auto 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 = 0; + auto timerInfo = std::shared_ptr(); + timerInfo->SetType(1); + 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); + auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + EXPECT_TRUE(ret); + EXPECT_TRUE(g_data2 == 0); + + auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + EXPECT_FALSE(ret); +} diff --git a/services/timer/include/batch.h b/services/timer/include/batch.h new file mode 100644 index 00000000..13f39b3b --- /dev/null +++ b/services/timer/include/batch.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. + */ + + +#include +#include +#include +#include +#include "timer_info.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_; + }; + + } +} \ No newline at end of file diff --git a/services/src/time_service_proxy.cpp b/services/timer/include/timer_handler.h old mode 100755 new mode 100644 similarity index 43% rename from services/src/time_service_proxy.cpp rename to services/timer/include/timer_handler.h index 23859929..ebf50b4f --- a/services/src/time_service_proxy.cpp +++ b/services/timer/include/timer_handler.h @@ -1,46 +1,50 @@ -/* - * 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 +/* + * 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 + +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 SetTime (struct timeval *tv); + int WaitForAlarm (); + + ~TimerHandler (); + + private: + TimerHandler (const TimerFds &fds, int epollfd, int rtc_id); + + const TimerFds fds_; + const int epollFd_; + const int rtcId_; + }; + } +} diff --git a/services/timer/include/timer_info.h b/services/timer/include/timer_info.h new file mode 100644 index 00000000..dd24c4f4 --- /dev/null +++ b/services/timer/include/timer_info.h @@ -0,0 +1,65 @@ +/* + * 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_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::shared_ptr operation; + 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::shared_ptr operation, + std::function callback, + uint32_t flags, + uint64_t uid); + + bool operator== (const TimerInfo &other) const; + bool Matches (const std::string &packageName) const; + }; + } +} \ 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 00000000..6739cd43 --- /dev/null +++ b/services/timer/include/timer_manager.h @@ -0,0 +1,121 @@ +/* + * 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 +#include +#include +#include "timer_handler.h" +#include "batch.h" +#include "ability_context.h" +#include "want_agent_helper.h" + +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::shared_ptr wantAgent, + 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::shared_ptr wantAgent, + 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::shared_ptr wantAgent, + 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_; + }; + + } +} \ 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 00000000..05553145 --- /dev/null +++ b/services/timer/include/timer_manager_interface.h @@ -0,0 +1,67 @@ +/* + * 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 + { + struct TimerEntry { + uint64_t id; + int type; + uint64_t windowLength; + uint64_t interval; + int flag; + std::shared_ptr wantAgent; + 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::shared_ptr wantAgent, + 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; + }; + } +} \ 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 00000000..534a3933 --- /dev/null +++ b/services/timer/src/batch.cpp @@ -0,0 +1,165 @@ +/* + * 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) + { + 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; + if (predicate (*alarm)) + { + alarms_.erase (it); + didRemove = true; + } + else + { + if (alarm->whenElapsed > newStart) + { + newStart = alarm->whenElapsed; + } + + if (alarm->maxWhenElapsed < newEnd) + { + newEnd = alarm->maxWhenElapsed; + } + newFlags |= alarm->flags; + ++it; + } + } + + 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 00000000..568f83f2 --- /dev/null +++ b/services/timer/src/timer_handler.cpp @@ -0,0 +1,286 @@ +/* + * 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 + +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, + }; + + static const char rtc_sysfs[] = "/sys/class/rtc"; + + static bool rtc_is_hctosys (unsigned int rtc_id) + { + + auto hctosys_path = rtc_sysfs + std::string ("/rtc") + std::to_string (rtc_id) + std::string ("/hctosys"); + FILE *file = fopen (hctosys_path.c_str (), "re"); + if (!file) + { + std::cerr << "failed to open " << hctosys_path << ": " << strerror (errno) << std::endl; + return false; + } + + unsigned int hctosys; + bool ret = false; + int err = fscanf (file, "%u", &hctosys); + if (err == EOF) + std::cerr << "failed to read from " << hctosys_path << ": " << strerror (errno) << std::endl; + else if (err == 0) + std::cerr << hctosys_path << " did not have expected contents" << std::endl; + else + ret = hctosys; + + fclose (file); + return ret; + } + + static int wall_clock_rtc () + { + std::unique_ptr dir (opendir (rtc_sysfs), closedir); + if (!dir) + { + std::cerr << "failed to open " << rtc_sysfs << ": " << strerror (errno) << std::endl; + return -1; + } + + struct dirent *dirent; + while (errno = 0, dirent = readdir (dir.get ())) + { + unsigned int rtc_id; + int matched = sscanf (dirent->d_name, "rtc%u", &rtc_id); + + if (matched < 0) + break; + else if (matched != 1) + continue; + + if (rtc_is_hctosys (rtc_id)) + { + std::cout << "found wall clock RTC " << rtc_id << std::endl; + return rtc_id; + } + } + + if (errno == 0) + std::cerr << "no wall clock RTC found" << std::endl; + else + std::cerr << "failed to enumerate RTCs: " << strerror (errno) << std::endl; + return -1; + } + + std::shared_ptr TimerHandler::Create () + { + int epollfd; + TimerFds fds; + + epollfd = epoll_create (fds.size ()); + if (epollfd < 0) + { + std::cerr << "epoll_create " << fds.size () << "failed: " << strerror (errno) << std::endl; + 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) + { + std::cerr << "timerfd_create " << i << " failed: " << strerror (errno) << std::endl; + close (epollfd); + for (size_t j = 0; j < i; j++) + { + close (fds[j]); + } + return nullptr; + } + } + + auto handler = std::shared_ptr (new TimerHandler (fds, epollfd, wall_clock_rtc ())); + 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) + { + std::cerr << "epoll_ctl(EPOLL_CTL_ADD) failed: " << strerror (errno) << std::endl; + 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) + { + std::cerr << "timerfd_settime() failed: " << strerror (errno) << std::endl; + return nullptr; + } + + return handler; + } + + TimerHandler::TimerHandler (const TimerFds &fds, int epollfd, int rtc_id) + : fds_{fds}, epollFd_{epollfd}, rtcId_{rtc_id} + { + } + + 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) + { + std::cout << __func__ << " type=" << type << " when=" << when.count () << std::endl; + 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::SetTime (struct timeval *tv) + { + struct rtc_time rtc + { + }; + struct tm tm + { + }, *gmtime_res; + int fd; + int res; + + res = settimeofday (tv, nullptr); + if (res < 0) + { + std::cerr << "settimeofday() failed: " << strerror (errno) << std::endl; + return -1; + } + + if (rtcId_ < 0) + { + std::cerr << "Not setting RTC because wall clock RTC was not found" << std::endl; + errno = ENODEV; + return -1; + } + + auto rtc_dev = std::string ("/dev/rtc") + std::to_string (rtcId_); + fd = open (rtc_dev.c_str (), O_RDWR); + if (fd < 0) + { + std::cerr << "Unable to open " << rtc_dev << ": " << strerror (errno) << std::endl; + return res; + } + + gmtime_res = gmtime_r (&tv->tv_sec, &tm); + if (!gmtime_res) + { + std::cerr << "gmtime_r() failed: " << strerror (errno) << std::endl; + res = -1; + goto done; + } + + memset (&rtc, 0, sizeof (rtc)); + 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) + std::cerr << "RTC_SET_TIME ioctl failed: " << strerror (errno) << std::endl; + done: + close (fd); + return res; + } + + 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 00000000..c4126d2f --- /dev/null +++ b/services/timer/src/timer_info.cpp @@ -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. + */ + +#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 + { + //TODO + 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::shared_ptr _operation, + 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}, + operation{std::move (_operation)}, + 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 00000000..777d6385 --- /dev/null +++ b/services/timer/src/timer_manager.cpp @@ -0,0 +1,587 @@ +/* + * 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; + + // const uint32_t TIMER_TYPE_REALTIME = 1; + // const uint32_t TIMER_TYPE_REALTIME_WAKEUP = 1 << 1; + // const uint32_t TIMER_TYPE_EXACT = 1 << 2; + // const uint32_t TIMER_TYPE_IDLE = 1 << 3; + + static int TIME_CHANGED_MASK = 1 << 16; + const auto MIN_FUTURITY = seconds(5); + //const auto MIN_INTERVAL = minutes(1); + 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 INTERVAL_DAY = hours(24); + 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) + { + 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::shared_ptr wantAgent, + std::function callback, + uint64_t uid) + { + + uint64_t timerNumber = random_(); + auto timerInfo = + std::make_shared(TimerEntry{timerNumber, + type, + windowLength, + interval, flag, + std::move(wantAgent), + 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()) + { + return false; + } + auto timerInfo = it->second; + SetHandler(timerInfo->id, + timerInfo->type, + triggerTime, + timerInfo->windowLength, + timerInfo->interval, + timerInfo->flag, + timerInfo->wantAgent, + timerInfo->callback, + timerInfo->uid); + return true; + } + + bool TimerManager::StopTimer(uint64_t timerNumber) + { + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()) + { + return false; + } + RemoveHandler(timerNumber); + return false; + } + + bool TimerManager::DestroyTimer(uint64_t timerNumber) + { + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()) + { + return false; + } + RemoveHandler(timerNumber); + timerEntryMap_.erase(it); + return false; + } + + void TimerManager::SetHandler(uint64_t id, + int type, + uint64_t triggerAtTime, + uint64_t windowLength, + uint64_t interval, + int flag, + std::shared_ptr wantAgent, + std::function callback, + uint64_t uid) + { + 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; + } + + std::lock_guard lockGuard(mutex_); + SetHandlerLocked(id, + type, + milliseconds(triggerAtTime), + triggerElapsed, + windowLengthDuration, + maxElapsed, + intervalDuration, + std::move(wantAgent), + 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::shared_ptr wantAgent, + std::function callback, + uint32_t flags, + bool doValidate, + uint64_t callingUid) + { + auto alarm = + std::make_shared(id, + type, + when, + whenElapsed, + windowLength, + maxWhen, + interval, + std::move(wantAgent), + std::move(callback), + flags, + callingUid); + SetHandlerLocked(alarm, false, doValidate); + } + + void TimerManager::RemoveHandler(uint64_t id) + { + std::lock_guard lock(mutex_); + RemoveLocked(id); + } + + void TimerManager::RemoveLocked(uint64_t id) + { + auto whichAlarms = [id](const TimerInfo &timer) + { + return timer.id == id; + }; + + bool didRemove = false; + for (auto it = alarmBatches_.begin(); it != alarmBatches_.end(); ++it) + { + auto batch = *it; + didRemove |= batch->Remove(whichAlarms); + if (batch->Size() == 0) + { + alarmBatches_.erase(it); + } + } + + if (didRemove) + { + ReBatchAllTimersLocked(true); + } + } + + void TimerManager::SetHandlerLocked(std::shared_ptr alarm, bool rebatching, bool doValidate) + { + std::cout << __func__ << " rebatching=" << rebatching << " doValidate=" << doValidate << std::endl; + InsertAndBatchTimerLocked(std::move(alarm)); + if (!rebatching) + { + RescheduleKernelTimerLocked(); + } + } + + void TimerManager::ReBatchAllTimers() + { + std::lock_guard lock(mutex_); + ReBatchAllTimersLocked(true); + } + + void TimerManager::ReBatchAllTimersLocked(bool doValidate) + { + 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(); + } + + void TimerManager::ReAddTimerLocked(std::shared_ptr timer, + std::chrono::steady_clock::time_point nowElapsed, + bool doValidate) + { + std::cout << __func__ << std::endl; + 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); + } + + std::chrono::steady_clock::time_point TimerManager::ConvertToElapsed(std::chrono::milliseconds when, int type) + { + 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(); + return steady_clock::now() + offset; + } + + void TimerManager::TimerLooper() + { + std::vector> triggerList; + while (runFlag_) + { + int result = 0; + do + { + result = handler_->WaitForAlarm(); + } while (result < 0 && errno == EINTR); + std::cout << "result=" << result << std::endl; + + auto nowRtc = std::chrono::system_clock::now(); + auto nowElapsed = std::chrono::steady_clock::now(); + triggerList.clear(); + + if ((result & TIME_CHANGED_MASK) != 0) + { + std::cout << "time changed" << std::endl; + system_clock::time_point lastTimeChangeClockTime; + system_clock::time_point expectedClockTime; + { + 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))) + { + std::cout << "Time changed notification from kernel; rebatching" << std::endl; + + ReBatchAllTimers(); + + { + std::lock_guard lock(mutex_); + lastTimeChangeClockTime_ = nowRtc; + lastTimeChangeRealtime_ = nowElapsed; + } + } + } + + if (result != TIME_CHANGED_MASK) + { + std::lock_guard lock(mutex_); + auto hasWakeup = TriggerTimersLocked(triggerList, nowElapsed); + std::cout << "hasWakeup=" << hasWakeup << std::endl; + + DeliverTimersLocked(triggerList, nowElapsed); + std::cout << "--------->2" << std::endl; + + 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) + { + std::cout << __func__ << " alarmBatches_.size=" << alarmBatches_.size() << std::endl; + bool hasWakeup = false; + while (!alarmBatches_.empty()) + { + auto batch = alarmBatches_.at(0); + std::cout << __func__ << " batch->GetStart()=" + << time_point_cast(batch->GetStart()).time_since_epoch().count() + << " nowElapsed=" << time_point_cast(nowElapsed).time_since_epoch().count() << std::endl; + if (batch->GetStart() > nowElapsed) + { + std::cout << __func__ << " break alarmBatches_.size=" << alarmBatches_.size() << std::endl; + break; + } + alarmBatches_.erase(alarmBatches_.begin()); + std::cout << __func__ << " after erase alarmBatches_.size=" << alarmBatches_.size() << std::endl; + + 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, + alarm->operation, + 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() + { + std::cout << __func__ << " alarmBatches_ size=" << alarmBatches_.size() << std::endl; + 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()); + } + } + + 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) + { + std::cout << __func__ << " " << when.count() << std::endl; + handler_->Set(static_cast(type), when); + } + + void TimerManager::InsertAndBatchTimerLocked(std::shared_ptr alarm) + { + int64_t whichBatch = (alarm->flags & static_cast(STANDALONE)) + ? -1 + : AttemptCoalesceLocked(alarm->whenElapsed, alarm->maxWhenElapsed); + std::cout << __func__ << " whichBatch=" << whichBatch << std::endl; + 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); + } + } + } + + int64_t TimerManager::AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed, + std::chrono::steady_clock::time_point maxWhen) + { + 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) + { + for (const auto &alarm : triggerList) + { + if (alarm->callback) + { + alarm->callback(); + } + + if (alarm->operation) + { + std::shared_ptr context = std::make_shared(); + std::shared_ptr want = Notification::WantAgent::WantAgentHelper::GetWant(alarm->operation); + + OHOS::Notification::WantAgent::TriggerInfo paramsInfo("", nullptr, want, 11); + Notification::WantAgent::WantAgentHelper::TriggerWantAgent(context, alarm->operation, nullptr, paramsInfo); + } + } + } + + bool AddBatchLocked(std::vector> &list, const std::shared_ptr &newBatch) + { + 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); + 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())); + } + + } // MiscService +} // OHOS \ No newline at end of file diff --git a/time.gni b/time.gni index 4c8394f4..c20574fc 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 00000000..215a1fae --- /dev/null +++ b/utils/BUILD.gn @@ -0,0 +1,33 @@ +# 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 = [ + "native/include", + "//utils/native/base/include", + ] +} + +ohos_source_set("time_utils") { + sources = [ + "native/src/time_permission.cpp", + ] + + public_configs = [ ":utils_config" ] + + deps = [ "//utils/native/base:utils" ] + + part_name = "time_native" +} diff --git a/services/include/time_common.h b/utils/native/include/time_common.h old mode 100755 new mode 100644 similarity index 71% rename from services/include/time_common.h rename to utils/native/include/time_common.h index ad377ee1..3ab6fc6a --- a/services/include/time_common.h +++ b/utils/native/include/time_common.h @@ -1,39 +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_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_WRITE_PARCEL_ERROR = TIME_ERR_OFFSET, + E_TIME_SA_DIED, + E_TIME_READ_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, +}; + +} // 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 00000000..ceb34e20 --- /dev/null +++ b/utils/native/include/time_hilog_wreapper.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. + */ + +#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 00000000..3d0a4faa --- /dev/null +++ b/utils/native/include/time_permission.h @@ -0,0 +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 TIME_PERMISSION_H +#define TIME_PERMISSION_H + +#include + +namespace OHOS { +namespace MiscService { +class TimePermission { +public: + static bool CheckSelfPermission(const std::string permName); + static bool CheckCallingPermission(const std::string bundle, const std::string permName, const int userId); +}; +} // namespace MiscService +} // 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 00000000..d3d32df9 --- /dev/null +++ b/utils/native/include/time_rdb_handler.h @@ -0,0 +1,95 @@ +/* + * 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 INSERT_TIME_ZONE; + }; + + std::string const TimeOpenCallback::INSERT_TIME_ZONE = "Insert Opreation"; + + int TimeOpenCallback::OnCreate(RdbStore &store) + { + return store.ExecuteSql(INSERT_TIME_ZONE); + } + + int TimeOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion) + { + return E_OK; + } + + bool InsertTimeZoneIdToRdb(const std::string timeZoneId){ + int deletedRows; + const std::string dbPath_ = "/data/time/"; + const std::string dbName_ = "time.db"; + + RdbStoreConfig config(dbPath_+ dbName_); + + config.SetJournalMode(JournalMode::MODE_TRUNCATE); + TimeOpenCallback helper; + int errCode = E_OK; + auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode); + if (store == nullptr){ + return false; + } + store->Delete(deletedRows, "time", "id = 1"); + + int64_t id; + ValuesBucket values; + values.PutInt("id", 1); + values.PutString("timezone", timeZoneId); + auto ret = store->Insert(id, "time", values); + return ret == E_OK; + } + + bool GetTimeZoneId(std::string &timeZoneId){ + const std::string dbPath_ = "/data/time/"; + const std::string dbName_ = "time.db"; + + RdbStoreConfig config(dbPath_+ dbName_); + + config.SetJournalMode(JournalMode::MODE_TRUNCATE); + 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 time"); + + int columnIndex; + std::string strVal; + auto ret = resultSet->GoToFirstRow(); + if (ret != E_OK){ + return false; + } + ret = resultSet->GetColumnIndexForName("timezone", columnIndex); + if (ret != E_OK){ + return false; + } + ret = resultSet->GetString(columnIndex, timeZoneId); + return ret == 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 00000000..2c147b14 --- /dev/null +++ b/utils/native/src/time_permission.cpp @@ -0,0 +1,35 @@ +/* + * 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" + +using namespace std; + +namespace OHOS { +namespace MiscService { + +bool TimePermission::CheckSelfPermission(std::string permName) +{ + return true; +} + +bool TimePermission::CheckCallingPermission(std::string bundle, std::string permName, int userId) +{ + return true; +} + + +} // namespace MiscService +} // namespace OHOS -- Gitee From 9035480fc9297b48c141f26611a38a8d78cf7ff9 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Sun, 8 Aug 2021 20:06:01 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- README_zh.md | 1 + .../innerkits/include/time_service_client.h | 35 +- .../js/napi/system_time/src/js_systemtime.cpp | 21 +- .../js/napi/system_timer/src/system_timer.cpp | 6 +- services/BUILD.gn | 3 + .../time_manager/include/itimer_call_back.h | 45 ++ services/time_manager/include/time_service.h | 32 +- .../include/time_service_interface.h | 57 +- .../include/time_service_notify.h | 6 +- .../time_manager/include/time_service_proxy.h | 21 +- .../time_manager/include/time_service_stub.h | 6 + .../time_manager/include/time_zone_info.h | 4 +- .../time_manager/include/timer_call_back.h | 61 ++ .../include/timer_call_back_proxy.h | 42 + .../include/timer_call_back_stub.h | 39 + services/time_manager/src/itimer_info.cpp | 13 +- services/time_manager/src/time_service.cpp | 261 +++---- .../time_manager/src/time_service_client.cpp | 90 ++- .../time_manager/src/time_service_notify.cpp | 10 +- .../time_manager/src/time_service_proxy.cpp | 208 ++++- .../time_manager/src/time_service_stub.cpp | 156 +++- services/time_manager/src/time_zone_info.cpp | 22 +- services/time_manager/src/timer_call_back.cpp | 95 +++ .../src/timer_call_back_proxy.cpp | 59 ++ .../time_manager/src/timer_call_back_stub.cpp | 50 ++ services/timer/include/batch.h | 59 +- services/timer/include/timer_handler.h | 51 +- services/timer/include/timer_info.h | 63 +- services/timer/include/timer_manager.h | 127 ++- .../timer/include/timer_manager_interface.h | 81 +- services/timer/src/batch.cpp | 205 +++-- services/timer/src/timer_handler.cpp | 306 ++------ services/timer/src/timer_info.cpp | 78 +- services/timer/src/timer_manager.cpp | 739 +++++++----------- utils/native/include/time_common.h | 3 +- utils/native/include/time_hilog_wreapper.h | 2 - utils/native/include/time_permission.h | 1 + utils/native/include/time_rdb_handler.h | 8 +- 39 files changed, 1702 insertions(+), 1367 deletions(-) create mode 100644 services/time_manager/include/itimer_call_back.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 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 diff --git a/README.md b/README.md index 5815c65b..fe91b38a 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 47a613d5..a48a65ea 100755 --- a/README_zh.md +++ b/README_zh.md @@ -22,6 +22,7 @@ ├── etc # 组件包含的进程的配置文件 ├── figures # 构架图 ├── interfaces # 组件对外提供的接口代码 +| └── innerkits # 服务间接口 │ └── kits # 对应用提供的接口 ├── profile # 组件包含的系统服务的配置文件 └── services # 时间服务实现 diff --git a/interfaces/innerkits/include/time_service_client.h b/interfaces/innerkits/include/time_service_client.h index d77338b3..c6fcb9be 100644 --- a/interfaces/innerkits/include/time_service_client.h +++ b/interfaces/innerkits/include/time_service_client.h @@ -19,7 +19,7 @@ #include "refbase.h" #include "time_service_interface.h" #include "iremote_object.h" -#include "itimer_info.h" +#include "timer_call_back.h" #include @@ -134,10 +134,37 @@ public: */ int64_t GetThreadTimeNs(); - // timer callbackObject has func OnTrigger(); + /** + * 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); @@ -145,14 +172,14 @@ public: private: TimeServiceClient(); ~TimeServiceClient(); + + static sptr ConnectService(); static std::mutex instanceLock_; static sptr instance_; static sptr timeServiceProxy_; static sptr deathRecipient_; - - std::mutex mapMutex_; }; } // MiscServices diff --git a/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp index f93ab2d4..8d360ab9 100644 --- a/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp +++ b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp @@ -45,16 +45,17 @@ static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) NAPI_ASSERT(env, false, "input para invalid"); } asyncContext->type = TYPE_SET_TIME; - //double dateValue; - //napi_get_date_value(env, argv[i], &dateValue); - // } else if (i == 0 && valueType == napi_object){ - // double dateValue; - // if (napi_ok != napi_get_date_value(env, argv[i], &dateValue)){ - // delete asyncContext; - // NAPI_ASSERT(env, false, "input para invalid"); - // } - // asyncContext->dateMs = int64_t(dateValue); - // asyncContext->type = TYPE_SET_DATE; + /*double dateValue; + * napi_get_date_value(env, argv[i], &dateValue); + * } else if (i == 0 && valueType == napi_object){ + * double dateValue; + * if (napi_ok != napi_get_date_value(env, argv[i], &dateValue)){ + * delete asyncContext; + * NAPI_ASSERT(env, false, "input para invalid"); + * } + * asyncContext->dateMs = int64_t(dateValue); + * asyncContext->type = TYPE_SET_DATE; + */ } else if (i == 1 && valueType == napi_function) { napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); } else { diff --git a/interfaces/kits/js/napi/system_timer/src/system_timer.cpp b/interfaces/kits/js/napi/system_timer/src/system_timer.cpp index 39e3005e..d357ef00 100644 --- a/interfaces/kits/js/napi/system_timer/src/system_timer.cpp +++ b/interfaces/kits/js/napi/system_timer/src/system_timer.cpp @@ -349,8 +349,6 @@ napi_value CreateTimer(napi_env env, napi_callback_info info) return JSParaError(env, callback); } - asyncCallbackInfoCreateInfo.emplace_back(asynccallbackinfo); - napi_value promise = 0; PaddingAsyncCallbackInfoIsByCreateTimer(env, asynccallbackinfo, callback, promise); @@ -364,6 +362,10 @@ napi_value CreateTimer(napi_env env, napi_callback_info info) 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; diff --git a/services/BUILD.gn b/services/BUILD.gn index abada9f0..8b1ec38b 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -36,6 +36,9 @@ ohos_shared_library("time_service") { "timer/src/timer_info.cpp", "timer/src/timer_manager.cpp", "time_manager/src/itimer_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", "time_manager/src/time_service_client.cpp", "time_manager/src/time_zone_info.cpp", "time_manager/src/time_service_notify.cpp", 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 00000000..da41b63d --- /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 index 9343ca14..fc185b4c 100644 --- a/services/time_manager/include/time_service.h +++ b/services/time_manager/include/time_service.h @@ -23,6 +23,7 @@ #include "system_ability.h" #include "event_handler.h" #include "time.h" +#include "securec.h" #include namespace OHOS { @@ -51,18 +52,18 @@ public: 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* times) override; - int32_t GetWallTimeNs(int64_t* times) override; - int32_t GetBootTimeMs(int64_t* times) override; - int32_t GetBootTimeNs(int64_t* times) override; - int32_t GetMonotonicTimeMs(int64_t* times) override; - int32_t GetMonotonicTimeNs(int64_t* times) override; - int32_t GetThreadTimeMs(int64_t* times) override; - int32_t GetThreadTimeNs(int64_t* times) override; - uint64_t CreateTimer(int type, bool repeat, uint64_t interval, - std::shared_ptr wantAgent, std::function callback) override; - bool StartTimer(uint64_t timerId, uint64_t treggerTime) 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; @@ -79,17 +80,14 @@ private: bool GetTimeByClockid(clockid_t clockID, struct timespec* tv); int set_rtc_time(time_t sec); - template - std::string str_format(const std::string &format, Args ...); - bool check_rtc(); + 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 int rtc_id; - const std::string rtc_path = "/sys/class/rtc"; - static std::shared_ptr timeServiceNotify_; + static std::shared_ptr timeServiceNotify_; static std::shared_ptr serviceHandler_; static std::shared_ptr timerManagerHandler_; }; diff --git a/services/time_manager/include/time_service_interface.h b/services/time_manager/include/time_service_interface.h index 44569879..be96b761 100644 --- a/services/time_manager/include/time_service_interface.h +++ b/services/time_manager/include/time_service_interface.h @@ -20,9 +20,8 @@ #include "want_agent.h" namespace OHOS { - - namespace MiscServices { + class ITimeService : public IRemoteBroker { public: @@ -38,7 +37,11 @@ public: GET_MONO_TIME_MILLI = 7, GET_MONO_TIME_NANO = 8, GET_THREAD_TIME_MILLI = 9, - GET_THREAD_TIME_NANO = 10 + GET_THREAD_TIME_NANO = 10, + CREATE_TIMER = 11, + START_TIMER = 12, + STOP_TIMER = 13, + DESTORY_TIMER = 14 }; /** * SetTime @@ -62,7 +65,7 @@ public: * @param timezoneId std::string &timezoneId string * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetTimeZone(std::string *timezoneId) = 0; + virtual int32_t GetTimeZone(std::string &timezoneId) = 0; /** * GetWallTimeMs @@ -70,7 +73,7 @@ public: * @param times result of times ,unit: millisecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetWallTimeMs(int64_t* times) = 0; + virtual int32_t GetWallTimeMs(int64_t ×) = 0; /** * GetWallTimeNs @@ -78,7 +81,7 @@ public: * @param times result of times ,unit: Nanosecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetWallTimeNs(int64_t* times) = 0; + virtual int32_t GetWallTimeNs(int64_t ×) = 0; /** * GetBootTimeMs @@ -86,7 +89,7 @@ public: * @param times result of times ,unit: millisecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetBootTimeMs(int64_t* times) = 0; + virtual int32_t GetBootTimeMs(int64_t ×) = 0; /** * GetBootTimeNs @@ -94,7 +97,7 @@ public: * @param times result of times ,unit: millisecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetBootTimeNs(int64_t* times) = 0; + virtual int32_t GetBootTimeNs(int64_t ×) = 0; /** * GetMonotonicTimeMs @@ -102,7 +105,7 @@ public: * @param times result of times ,unit: millisecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetMonotonicTimeMs(int64_t* times) = 0; + virtual int32_t GetMonotonicTimeMs(int64_t ×) = 0; /** * GetMonotonicTimeNs @@ -110,7 +113,7 @@ public: * @param times result of times ,unit: Nanosecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetMonotonicTimeNs(int64_t* times) = 0; + virtual int32_t GetMonotonicTimeNs(int64_t ×) = 0; /** * GetThreadTimeMs @@ -118,7 +121,7 @@ public: * @param times result of times ,unit: millisecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetThreadTimeMs(int64_t* times) = 0; + virtual int32_t GetThreadTimeMs(int64_t ×) = 0; /** * GetThreadTimeNs @@ -126,43 +129,43 @@ public: * @param times result of times ,unit: Nanosecond * @return int32_t ERR_OK on success, other on failure. */ - virtual int32_t GetThreadTimeNs(int64_t* times) = 0; + virtual int32_t GetThreadTimeNs(int64_t ×) = 0; /** * CreateTimer * - * @param times result of times ,unit: Nanosecond - * @return int32_t ERR_OK on success, other on failure. + * @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(int type, bool repeat, uint64_t interval, - std::shared_ptr wantAgent, std::function callback) = 0; + virtual uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr &timerCallback) = 0; /** - * GetThreadTimeNs + * StartTimer * - * @param times result of times ,unit: Nanosecond - * @return int32_t ERR_OK on success, other on failure. + * @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; /** - * GetThreadTimeNs + * StopTimer * - * @param times result of times ,unit: Nanosecond - * @return int32_t ERR_OK on success, other on failure. + * @param timerId indicate timerId + * @return bool true on success, false on failure. */ virtual bool StopTimer(uint64_t timerId) = 0; /** - * GetThreadTimeNs + * DestroyTimer * - * @param times result of times ,unit: Nanosecond - * @return int32_t ERR_OK on success, other on failure. + * @param timerId indicate timerId + * @return bool true on success, false on failure. */ virtual bool DestroyTimer(uint64_t timerId) = 0; - -public: DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimeService"); }; diff --git a/services/time_manager/include/time_service_notify.h b/services/time_manager/include/time_service_notify.h index 6fb3a36e..7830fb60 100644 --- a/services/time_manager/include/time_service_notify.h +++ b/services/time_manager/include/time_service_notify.h @@ -22,7 +22,7 @@ namespace OHOS { -namespace MiscService { +namespace MiscServices { class TimeServiceNotify { @@ -43,9 +43,9 @@ private: sptr publishInfo_; const std::string TIME_CHANGE_ACTION = "com.hos.action.TIME_CHANGE_ACTION"; const std::string TIME_ZONE_CHANGE_ACTION = "com.hos.action.TIME_ZONE_CHANGE_ACTION"; - }; -} // namespace MiscService + +} // namespace MiscServices } // namespace OHOS #endif // TIME_SERVICE_NOTIFY_H diff --git a/services/time_manager/include/time_service_proxy.h b/services/time_manager/include/time_service_proxy.h index 5011aa61..870a8a24 100644 --- a/services/time_manager/include/time_service_proxy.h +++ b/services/time_manager/include/time_service_proxy.h @@ -29,17 +29,16 @@ public: 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* times) override; - int32_t GetWallTimeNs(int64_t* times) override; - int32_t GetBootTimeMs(int64_t* times) override; - int32_t GetBootTimeNs(int64_t* times) override; - int32_t GetMonotonicTimeMs(int64_t* times) override; - int32_t GetMonotonicTimeNs(int64_t* times) override; - int32_t GetThreadTimeMs(int64_t* times) override; - int32_t GetThreadTimeNs(int64_t* times) override; - uint64_t CreateTimer(int type, bool repeat, uint64_t interval, - std::shared_ptr wantAgent, std::function callback) 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; diff --git a/services/time_manager/include/time_service_stub.h b/services/time_manager/include/time_service_stub.h index 9edbdd6a..31436e27 100644 --- a/services/time_manager/include/time_service_stub.h +++ b/services/time_manager/include/time_service_stub.h @@ -18,6 +18,7 @@ #include "iremote_stub.h" #include "time_service_interface.h" +#include "itimer_call_back.h" #include namespace OHOS { @@ -42,6 +43,11 @@ private: 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 diff --git a/services/time_manager/include/time_zone_info.h b/services/time_manager/include/time_zone_info.h index e455a33d..d131a25e 100644 --- a/services/time_manager/include/time_zone_info.h +++ b/services/time_manager/include/time_zone_info.h @@ -38,8 +38,8 @@ class TimeZoneInfo : public RefBase{ public: static sptr GetInstance(); void Init(); - int32_t GetOffset(const std::string timezoneId, int *offset); - int32_t GetTimezoneId(int offset, std::string *timezoneId); + int32_t GetOffset(const std::string timezoneId, int &offset); + int32_t GetTimezoneId(int offset, std::string &timezoneId); private: int32_t lastOffset_; 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 00000000..520b2bd0 --- /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 00000000..e9da3d39 --- /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" + +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 00000000..afb7edb3 --- /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" + +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/time_manager/src/itimer_info.cpp b/services/time_manager/src/itimer_info.cpp index 1cf2f26f..b2840233 100644 --- a/services/time_manager/src/itimer_info.cpp +++ b/services/time_manager/src/itimer_info.cpp @@ -18,14 +18,13 @@ namespace OHOS { namespace MiscServices { - ITimerInfo::ITimerInfo() - { - - } +ITimerInfo::ITimerInfo() +{ - ITimerInfo::~ITimerInfo(){ - - } +} +ITimerInfo::~ITimerInfo() +{ +} } // MiscServices diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index 3932087a..75e126e8 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -37,6 +37,8 @@ #include #include #include +#include +#include namespace OHOS { @@ -59,12 +61,13 @@ 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::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()) @@ -89,7 +92,7 @@ sptr TimeService::GetInstance() void TimeService::OnStart() { - TIME_HILOGI(TIME_MODULE_SERVICE," TimeService Start."); + TIME_HILOGI(TIME_MODULE_SERVICE," TimeService OnStart."); if (state_ == ServiceRunningState::STATE_RUNNING) { TIME_HILOGE(TIME_MODULE_SERVICE," TimeService is already running."); return; @@ -151,7 +154,7 @@ void TimeService::InitNotifyHandler(){ return; } - timeServiceNotify_ = std::make_shared(); + timeServiceNotify_ = std::make_shared(); timeServiceNotify_->RegisterPublishEvents(); } @@ -179,9 +182,13 @@ void TimeService::InitTimerHandler(){ } -uint64_t TimeService::CreateTimer(int type, bool repeat, uint64_t interval, - std::shared_ptr wantAgent, std::function callback) +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; @@ -218,15 +225,12 @@ uint64_t TimeService::CreateTimer(int type, bool repeat, uint64_t interval, }else{ intervalOut = 0; } + sptr timerCallback = iface_cast(obj); - auto timerId = timerManagerHandler_->CreateTimer(timerType, - windowLength, - intervalOut, - flag, - wantAgent, - callback, - 0); - return timerId; + auto callbackFunc = [timerCallback](uint64_t id){ + timerCallback->NotifyTimer(id); + }; + return timerManagerHandler_->CreateTimer(timerType, windowLength,intervalOut, flag, nullptr, callbackFunc, 0); } bool TimeService::StartTimer(uint64_t timerId, uint64_t triggerTimes) @@ -239,6 +243,7 @@ bool TimeService::StartTimer(uint64_t timerId, uint64_t triggerTimes) } return ret; } + bool TimeService::StopTimer(uint64_t timerId) { auto ret = timerManagerHandler_->StopTimer(timerId); @@ -247,6 +252,7 @@ bool TimeService::StopTimer(uint64_t timerId) } return ret; } + bool TimeService::DestroyTimer(uint64_t timerId) { auto ret = timerManagerHandler_->DestroyTimer(timerId); @@ -255,14 +261,16 @@ bool TimeService::DestroyTimer(uint64_t timerId) } return ret; } + int32_t TimeService::SetTime(const int64_t time) { + TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}lld.", time); if (time <= 0 || time / 1000LL >= INT_MAX) { TIME_HILOGE(TIME_MODULE_SERVICE, "input param error"); return E_TIME_PARAMETERS_INVALID; } - struct timeval tv; + struct timeval tv{}; tv.tv_sec = (time_t) (time / MILLI_TO_BASE); tv.tv_usec = (suseconds_t) ((time % MILLI_TO_BASE) * MILLI_TO_MICR); @@ -271,37 +279,41 @@ int32_t TimeService::SetTime(const int64_t time) TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result); return E_TIME_DEAL_FAILED; } - if (set_rtc_time(tv.tv_sec) < 0){ - TIME_HILOGE(TIME_MODULE_SERVICE,"set rtc fail: %{public}d.",result); - return E_TIME_SET_RTC_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(¤tTime); + GetWallTimeMs(currentTime); timeServiceNotify_->PublishTimeChanageEvents(currentTime); return ERR_OK; } int TimeService::set_rtc_time(time_t sec){ - struct rtc_time rtc; - struct tm tm, *gmtime_res; - int fd; + 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: %s:", strerror(ENODEV)); + TIME_HILOGE(TIME_MODULE_SERVICE,"invalid rtc id: %{public}s:", strerror(ENODEV)); return -1; } - std::string rtc_dev = str_format("/dev/rtc%d", rtc_id); + 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 %s: %s", rtc_dev.data(), strerror(errno)); + 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) { - memset(&rtc, 0, sizeof(rtc)); rtc.tm_sec = tm.tm_sec; rtc.tm_min = tm.tm_min; rtc.tm_hour = tm.tm_hour; @@ -313,22 +325,72 @@ int TimeService::set_rtc_time(time_t sec){ 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: %s", strerror(errno)); + TIME_HILOGE(TIME_MODULE_SERVICE,"ioctl RTC_SET_TIME failed: %{public}s", strerror(errno)); } }else{ - TIME_HILOGE(TIME_MODULE_SERVICE,"convert rtc time failed: %s", strerror(errno)); + 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) { int gmtOffset; struct timezone tz; - auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, &gmtOffset); + auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset); if (ret != ERR_OK){ TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret); return ret; @@ -342,100 +404,103 @@ int32_t TimeService::SetTimeZone(const std::string timeZoneId) return E_TIME_DEAL_FAILED; } int64_t currentTime = 0; - GetWallTimeMs(¤tTime); + GetWallTimeMs(currentTime); timeServiceNotify_->PublishTimeZoneChangeEvents(currentTime); auto status = InsertTimeZoneIdToRdb(timeZoneId); if (!status){ TIME_HILOGE(TIME_MODULE_SERVICE,"Save TimeZone Failed."); } - return ERR_OK;; + return ERR_OK; } -int32_t TimeService::GetTimeZone(std::string *timeZoneId) +int32_t TimeService::GetTimeZone(std::string &timeZoneId) { int gmtOffset; - struct timezone tz; + struct timezone tz{}; + std::string curTimezone; int result = gettimeofday(NULL, &tz); if (result < 0) { TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result); return E_TIME_DEAL_FAILED; } gmtOffset = tz.tz_minuteswest *60; - auto ret = TimeZoneInfo::GetInstance()->GetTimezoneId(gmtOffset, timeZoneId); - if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret); - } + auto ret = TimeZoneInfo::GetInstance()->GetTimezoneId(gmtOffset, curTimezone); + 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* times) +int32_t TimeService::GetWallTimeMs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; if(GetTimeByClockid(CLOCK_REALTIME, &tv)){ - *times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; + 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* times) +int32_t TimeService::GetWallTimeNs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; if(GetTimeByClockid(CLOCK_REALTIME, &tv)){ - *times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; return ERR_OK; } return E_TIME_DEAL_FAILED; } -int32_t TimeService::GetBootTimeMs(int64_t* times) +int32_t TimeService::GetBootTimeMs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; if(GetTimeByClockid(CLOCK_BOOTTIME, &tv)){ - *times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; + 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* times) +int32_t TimeService::GetBootTimeNs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; if(GetTimeByClockid(CLOCK_BOOTTIME, &tv)){ - *times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; return ERR_OK; } return E_TIME_DEAL_FAILED; } -int32_t TimeService::GetMonotonicTimeMs(int64_t* times) +int32_t TimeService::GetMonotonicTimeMs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; if(GetTimeByClockid(CLOCK_MONOTONIC, &tv)){ - *times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI; + 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* times) +int32_t TimeService::GetMonotonicTimeNs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; if(GetTimeByClockid(CLOCK_MONOTONIC, &tv)){ - *times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; return ERR_OK; } @@ -443,38 +508,36 @@ int32_t TimeService::GetMonotonicTimeNs(int64_t* times) } -int32_t TimeService::GetThreadTimeMs(int64_t* times) +int32_t TimeService::GetThreadTimeMs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; int ret; clockid_t cid; ret = pthread_getcpuclockid(pthread_self(), &cid); - if (ret != 0) - { + 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; + 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* times) +int32_t TimeService::GetThreadTimeNs(int64_t ×) { - struct timespec tv; + struct timespec tv{}; int ret; clockid_t cid; ret = pthread_getcpuclockid(pthread_self(), &cid); - if (ret != 0) - { + if (ret != 0){ return E_TIME_PARAMETERS_INVALID; } if(GetTimeByClockid(cid, &tv)){ - *times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; + times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec; return ERR_OK; } @@ -491,76 +554,6 @@ bool TimeService::GetTimeByClockid(clockid_t clk_id, struct timespec* tv){ return true; } -template -std::string TimeService::str_format(const std::string &format, Args ... args) -{ - auto size_buf = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; - std::unique_ptr buf(new(std::nothrow) char[size_buf]); - - if (!buf) - return std::string(""); - - std::snprintf(buf.get(), size_buf, format.c_str(), args...); - return std::string(buf.get(), buf.get() + size_buf - 1); -} - -bool TimeService::check_rtc() -{ - std::string hctosys_path = str_format("%s/rtc%u/hctosys", - rtc_path.c_str(), rtc_id); - FILE *file = fopen(hctosys_path.data(), "re"); - if (!file) { - TIME_HILOGE(TIME_MODULE_SERVICE,"failed to open %{public}s: %{public}s", hctosys_path.data(), strerror(errno)); - return false; - } - - unsigned int hctosys; - bool ret = false; - int err = fscanf(file, "%u", &hctosys); - if (err == EOF){ - TIME_HILOGE(TIME_MODULE_SERVICE,"read %{public}s failed: %{public}s", hctosys_path.data(),strerror(errno)); - - }else if (err == 0){ - TIME_HILOGE(TIME_MODULE_SERVICE,"%{public}s no contents", hctosys_path.data()); - } - else{ - ret = hctosys; - } - fclose(file); - return ret; -} - -int TimeService::get_wall_clock_rtc_id() -{ - 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; - int matched = sscanf(dirent->d_name, "rtc%u", &rtc_id); - - if (matched < 0) - break; - else if (matched != 1) - continue; - - if (check_rtc()) { - TIME_HILOGD(TIME_MODULE_SERVICE,"found wall clock rtc %{public}u", rtc_id); - return rtc_id; - } - } - - 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; -} } // namespace MiscServices } // namespace OHOS diff --git a/services/time_manager/src/time_service_client.cpp b/services/time_manager/src/time_service_client.cpp index 6f629ae5..613d88f2 100644 --- a/services/time_manager/src/time_service_client.cpp +++ b/services/time_manager/src/time_service_client.cpp @@ -21,7 +21,6 @@ #include namespace OHOS { - namespace MiscServices { std::mutex TimeServiceClient::instanceLock_; @@ -41,7 +40,6 @@ sptr TimeServiceClient::GetInstance() std::lock_guard autoLock(instanceLock_); if (instance_ == nullptr) { instance_ = new TimeServiceClient; - timeServiceProxy_ = ConnectService(); } } return instance_; @@ -112,20 +110,38 @@ bool TimeServiceClient::SetTimeZone(const std::string timezoneId) 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, "CreateTimer quit because redoing ConnectService failed."); - return false; + 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; } - std::function callBackFunc = std::bind(&ITimerInfo::OnTrigger, TimerOptions); - auto timerId = timeServiceProxy_->CreateTimer(TimerOptions->type, TimerOptions->repeat, - TimerOptions->interval, TimerOptions->wantAgent, callBackFunc); + auto timerId = timeServiceProxy_->CreateTimer(TimerOptions->type, TimerOptions->repeat, TimerOptions->interval, timerCallbackInfoObject); + + if (timerId == 0){ + TIME_HILOGE(TIME_MODULE_CLIENT, "Create timer failed"); + return 0; + } + + auto ret = TimerCallback::GetInstance()->InsertTimerCallbackInfo(timerId, TimerOptions); + if(!ret){ + return 0; + } return timerId; } @@ -170,11 +186,13 @@ bool TimeServiceClient::DestroyTimer(uint64_t timerId) TIME_HILOGE(TIME_MODULE_CLIENT, "DestroyTimer quit because redoing ConnectService failed."); return false; } - return timeServiceProxy_->DestroyTimer(timerId); + if (timeServiceProxy_->DestroyTimer(timerId)){ + TimerCallback::GetInstance()->RemoveTimerCallbackInfo(timerId); + return true; + } + return false; } - - std::string TimeServiceClient::GetTimeZone() { std::string timeZoneId; @@ -188,7 +206,7 @@ std::string TimeServiceClient::GetTimeZone() return std::string(""); } - if(timeServiceProxy_->GetTimeZone(&timeZoneId) != ERR_OK){ + if(timeServiceProxy_->GetTimeZone(timeZoneId) != ERR_OK){ return std::string(""); } return timeZoneId; @@ -204,10 +222,10 @@ int64_t TimeServiceClient::GetWallTimeMs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeMs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetWallTimeMs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetWallTimeMs(times) != ERR_OK){ + return -1; } return times; } @@ -222,11 +240,11 @@ int64_t TimeServiceClient::GetWallTimeNs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeNs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetWallTimeNs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetWallTimeNs(times) != ERR_OK){ + return -1; } return times; } @@ -241,11 +259,11 @@ int64_t TimeServiceClient::GetBootTimeMs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeMs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetBootTimeMs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetBootTimeMs(times) != ERR_OK){ + return -1; } return times; } @@ -260,11 +278,11 @@ int64_t TimeServiceClient::GetBootTimeNs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeNs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetBootTimeNs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetBootTimeNs(times) != ERR_OK){ + return -1; } return times; } @@ -279,11 +297,11 @@ int64_t TimeServiceClient::GetMonotonicTimeMs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeMs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetMonotonicTimeMs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetMonotonicTimeMs(times) != ERR_OK){ + return -1; } return times; } @@ -298,11 +316,11 @@ int64_t TimeServiceClient::GetMonotonicTimeNs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeNs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetMonotonicTimeNs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetMonotonicTimeNs(times) != ERR_OK){ + return -1; } return times; } @@ -317,11 +335,11 @@ int64_t TimeServiceClient::GetThreadTimeMs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeMs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetThreadTimeMs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetThreadTimeMs(times) != ERR_OK){ + return -1; } return times; } @@ -336,16 +354,15 @@ int64_t TimeServiceClient::GetThreadTimeNs() if (timeServiceProxy_ == nullptr) { TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeNs quit because redoing ConnectService failed."); - return ERROR_OPREATION_FAILED; + return -1; } - if(timeServiceProxy_->GetThreadTimeNs(×) != ERR_OK){ - return ERROR_OPREATION_FAILED; + if(timeServiceProxy_->GetThreadTimeNs(times) != ERR_OK){ + return -1; } return times; } - void TimeServiceClient::OnRemoteSaDied(const wptr &remote) { timeServiceProxy_ = ConnectService(); @@ -360,5 +377,6 @@ 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 index 2016f717..92dfb668 100644 --- a/services/time_manager/src/time_service_notify.cpp +++ b/services/time_manager/src/time_service_notify.cpp @@ -24,7 +24,7 @@ using namespace OHOS::AAFwk; using namespace OHOS::EventFwk; namespace OHOS{ -namespace MiscService{ +namespace MiscServices{ void TimeServiceNotify::RegisterPublishEvents() { @@ -42,15 +42,15 @@ void TimeServiceNotify::RegisterPublishEvents() void TimeServiceNotify::PublishEvents(int64_t eventTime, sptr want) { if ((want == nullptr) || (publishInfo_ == nullptr)) { - //TIME_HILOGE(TIME_MODULE_SERVICE, "Invalid parameter"); + 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)); + 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()); + TIME_HILOGI(TIME_MODULE_SERVICE, "Publish event %{public}s done", want->GetAction().c_str()); } void TimeServiceNotify::PublishTimeChanageEvents(int64_t eventTime) diff --git a/services/time_manager/src/time_service_proxy.cpp b/services/time_manager/src/time_service_proxy.cpp index 86b0bbd5..89640b88 100644 --- a/services/time_manager/src/time_service_proxy.cpp +++ b/services/time_manager/src/time_service_proxy.cpp @@ -31,9 +31,15 @@ int32_t TimeServiceProxy::SetTime(const int64_t time) MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); - data.WriteInt64(time); + 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); @@ -42,33 +48,131 @@ int32_t TimeServiceProxy::SetTime(const int64_t time) return result; } - -uint64_t TimeServiceProxy::CreateTimer(int type, bool repeat, uint64_t interval, - std::shared_ptr wantAgent, std::function callback) +uint64_t TimeServiceProxy::CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr &timerCallback) { - return 0; + 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) { - return 0; + 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) { - return 0; + 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; + } - return 0; + 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, "CreateTimer failed, error code is: %{public}d",result); + return false; + } + + return true; } int32_t TimeServiceProxy::SetTimeZone(std::string timezoneId) { MessageParcel data, reply; MessageOption option; - data.WriteString(timezoneId); - data.WriteInterfaceToken(GetDescriptor()); + + 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){ @@ -78,146 +182,174 @@ int32_t TimeServiceProxy::SetTimeZone(std::string timezoneId) return result; } -int32_t TimeServiceProxy::GetTimeZone(std::string* timezoneId) +int32_t TimeServiceProxy::GetTimeZone(std::string &timezoneId) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + timezoneId = reply.ReadString(); return result; } -int32_t TimeServiceProxy::GetWallTimeMs(int64_t* times) +int32_t TimeServiceProxy::GetWallTimeMs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } -int32_t TimeServiceProxy::GetWallTimeNs(int64_t* times) +int32_t TimeServiceProxy::GetWallTimeNs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } -int32_t TimeServiceProxy::GetBootTimeMs(int64_t* times) + +int32_t TimeServiceProxy::GetBootTimeMs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } -int32_t TimeServiceProxy::GetBootTimeNs(int64_t* times) +int32_t TimeServiceProxy::GetBootTimeNs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } -int32_t TimeServiceProxy::GetMonotonicTimeMs(int64_t* times) +int32_t TimeServiceProxy::GetMonotonicTimeMs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } -int32_t TimeServiceProxy::GetMonotonicTimeNs(int64_t* times) +int32_t TimeServiceProxy::GetMonotonicTimeNs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } -int32_t TimeServiceProxy::GetThreadTimeMs(int64_t* times) +int32_t TimeServiceProxy::GetThreadTimeMs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } -int32_t TimeServiceProxy::GetThreadTimeNs(int64_t* times) +int32_t TimeServiceProxy::GetThreadTimeNs(int64_t ×) { MessageParcel data, reply; MessageOption option; - data.WriteInterfaceToken(GetDescriptor()); + 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(); + times = reply.ReadInt64(); return result; } } // namespace MiscServices diff --git a/services/time_manager/src/time_service_stub.cpp b/services/time_manager/src/time_service_stub.cpp index 9eef29d4..046c790e 100644 --- a/services/time_manager/src/time_service_stub.cpp +++ b/services/time_manager/src/time_service_stub.cpp @@ -16,7 +16,6 @@ #include "time_service_stub.h" #include #include "ipc_skeleton.h" - #include "time_common.h" namespace OHOS { @@ -36,6 +35,10 @@ TimeServiceStub::TimeServiceStub(){ 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(); @@ -44,11 +47,11 @@ TimeServiceStub::~TimeServiceStub(){ int32_t TimeServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnRemoteRequest start##code = %{public}u", code); + 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,"OnRemoteRequest end##descriptor checked fail"); + TIME_HILOGE(TIME_MODULE_SERVICE," end##descriptor checked fail"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } pid_t p = IPCSkeleton::GetCallingPid(); @@ -62,163 +65,230 @@ int32_t TimeServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Mes } } int ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnRemoteRequest end##ret = %{public}d", ret); + 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,"OnSetTime start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t time = data.ReadInt64(); int32_t ret = SetTime(time); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnSetTime end##ret = %{public}d", ret); + 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,"OnSetTimeZone start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); std::string timeZoneId = data.ReadString(); int32_t ret = SetTimeZone(timeZoneId); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnSetTimeZone end##ret = %{public}d", ret); + 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,"OnGetTimeZone start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); std::string timeZoneId; - int32_t ret = GetTimeZone(&timeZoneId); + int32_t ret = GetTimeZone(timeZoneId); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetTimeZone end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteString(timeZoneId); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetTimeZone end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetWallTimeMs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeMs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetWallTimeMs(×); + int32_t ret = GetWallTimeMs(times); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetWallTimeMs end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteInt64(times); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeMs end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetWallTimeNs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeNs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetWallTimeNs(×); + int32_t ret = GetWallTimeNs(times); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetWallTimeNs end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteInt64(times); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetWallTimeNs end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetBootTimeMs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeMs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetBootTimeMs(×); + int32_t ret = GetBootTimeMs(times); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetBootTimeMs end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteInt64(times); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeMs end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetBootTimeNs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeNs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetBootTimeNs(×); + int32_t ret = GetBootTimeNs(times); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetBootTimeNs end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteInt64(times); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetBootTimeNs end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetMonotonicTimeMs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetMonotonicTimeMs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetMonotonicTimeMs(×); + int32_t ret = GetMonotonicTimeMs(times); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetMonotonicTimeMs end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteInt64(times); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetMonotonicTimeMs end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetMonotonicTimeNs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetMonotonicTimeNs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetMonotonicTimeNs(×); + 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,"OnGetMonotonicTimeNs end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetThreadTimeMs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeMs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetThreadTimeMs(×); + int32_t ret = GetThreadTimeMs(times); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetThreadTimeMs end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteInt64(times); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeMs end."); + TIME_HILOGI(TIME_MODULE_SERVICE," end."); return ret; } int32_t TimeServiceStub::OnGetThreadTimeNs(MessageParcel &data, MessageParcel &reply) { - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeNs start."); + TIME_HILOGI(TIME_MODULE_SERVICE," start."); int64_t times; - int32_t ret = GetThreadTimeNs(×); + int32_t ret = GetThreadTimeNs(times); if (ret != ERR_OK){ - TIME_HILOGE(TIME_MODULE_SERVICE,"OnGetThreadTimeNs end##ret = %{public}d", ret); + TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret); return ret; } reply.WriteInt64(times); - TIME_HILOGI(TIME_MODULE_SERVICE,"OnGetThreadTimeNs end."); + 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){ + 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 index 52b0daf0..21a6dbc2 100644 --- a/services/time_manager/src/time_zone_info.cpp +++ b/services/time_manager/src/time_zone_info.cpp @@ -55,35 +55,35 @@ TimeZoneInfo::TimeZoneInfo() {"Baker Island, U.S.A.", "AoE", -12, "Anywhere on Earth"}, }; - for (auto tz : timezoneList) - { + for (auto tz : timezoneList) { timezoneInfoMap_[tz.ID] = tz; } } - TimeZoneInfo::~TimeZoneInfo(){ timezoneInfoMap_.clear(); } -int32_t TimeZoneInfo::GetOffset(const std::string timezoneId, int* offset){ +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; + offset = zoneInfo.utcOffsetHours; return ERR_OK; } TIME_HILOGE(TIME_MODULE_SERVICE, "TimezoneId not found."); return E_TIME_NOT_FOUND; } -int32_t TimeZoneInfo::GetTimezoneId(int offset, std::string *timezoneId ){ - auto itEntry = timezoneInfoMap_.find(*timezoneId); - if (itEntry != timezoneInfoMap_.end()) { - auto zoneInfo = itEntry->second; - offset = zoneInfo.utcOffsetHours; - return ERR_OK; +int32_t TimeZoneInfo::GetTimezoneId(int offset, std::string &timezoneId ){ + auto iter = timezoneInfoMap_.begin(); + while(iter != timezoneInfoMap_.end()) { + if (offset == iter->second.utcOffsetHours) { + timezoneId = iter->first; + return ERR_OK; + } + iter++; } TIME_HILOGE(TIME_MODULE_SERVICE, "TimezoneId not found."); return E_TIME_NOT_FOUND; 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 00000000..7b22e058 --- /dev/null +++ b/services/time_manager/src/timer_call_back.cpp @@ -0,0 +1,95 @@ +/* + * 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) +{ + 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; + } + return true; +} + +bool TimerCallback::RemoveTimerCallbackInfo(const uint64_t timerId) +{ + std::lock_guard lock(timerInfoMutex_); + auto info = TimerInfoMap_.find(timerId); + if (info != TimerInfoMap_.end()) { + TimerInfoMap_.erase(info); + return true; + } + return false; +} + +void TimerCallback::NotifyTimer(const uint64_t timerId) +{ + + std::lock_guard lock(timerInfoMutex_); + auto it = TimerInfoMap_.find(timerId); + if (it != TimerInfoMap_.end()) { + it->second->OnTrigger(); + + if (it->second->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); + } + } +} + +} // 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 00000000..85c3421d --- /dev/null +++ b/services/time_manager/src/timer_call_back_proxy.cpp @@ -0,0 +1,59 @@ +/* + * 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) +{ + 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); + } +} + +} // 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 00000000..839401cb --- /dev/null +++ b/services/time_manager/src/timer_call_back_stub.cpp @@ -0,0 +1,50 @@ +/* + * 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) +{ + auto timerId = data.ReadUint64(); + NotifyTimer(timerId); + return ERR_OK; +} + +} // namespace MiscServices +} // namespace OHOS diff --git a/services/timer/include/batch.h b/services/timer/include/batch.h index 13f39b3b..41610fdd 100644 --- a/services/timer/include/batch.h +++ b/services/timer/include/batch.h @@ -13,6 +13,8 @@ * limitations under the License. */ +#ifndef TIMER_BATCH_H +#define TIMER_BATCH_H #include #include @@ -20,37 +22,36 @@ #include #include "timer_info.h" -namespace OHOS -{ - namespace MiscServices - { +namespace OHOS { +namespace MiscServices { - class Batch { +class Batch { - public: - Batch (); - explicit Batch (const TimerInfo &seed); +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; + 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, + 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_; - }; - - } -} \ No newline at end of file + 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 index ebf50b4f..df87ac37 100644 --- a/services/timer/include/timer_handler.h +++ b/services/timer/include/timer_handler.h @@ -14,37 +14,44 @@ */ + +#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; +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 (); - class TimerHandler { - public: - static std::shared_ptr Create (); + ~TimerHandler (); - int Set (uint32_t type, std::chrono::nanoseconds when); - int SetTime (struct timeval *tv); - int WaitForAlarm (); +private: + TimerHandler (const TimerFds &fds, int epollfd); - ~TimerHandler (); + const TimerFds fds_; + const int epollFd_; +}; - private: - TimerHandler (const TimerFds &fds, int epollfd, int rtc_id); +}// MiscService +}// OHOS - const TimerFds fds_; - const int epollFd_; - const int rtcId_; - }; - } -} +#endif \ No newline at end of file diff --git a/services/timer/include/timer_info.h b/services/timer/include/timer_info.h index dd24c4f4..5afbd873 100644 --- a/services/timer/include/timer_info.h +++ b/services/timer/include/timer_info.h @@ -13,6 +13,8 @@ * limitations under the License. */ +#ifndef TIMER_INFO_H +#define TIMER_INFO_H #include #include @@ -21,45 +23,46 @@ #include #include "timer_manager_interface.h" -namespace OHOS -{ - namespace MiscServices - { +namespace OHOS { +namespace MiscServices { - class TimerInfo { - public: - const uint64_t id; - const int type; - const std::chrono::milliseconds origWhen; - const bool wakeup; - const std::shared_ptr operation; - const std::function callback; - const uint32_t flags; - const uint64_t uid; +class TimerInfo { - 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; +public: + const uint64_t id; + const int type; + const std::chrono::milliseconds origWhen; + const bool wakeup; + const std::shared_ptr operation; + const std::function callback; + const uint32_t flags; + const uint64_t uid; - TimerInfo (uint64_t id, - int type, + 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::shared_ptr operation, - std::function callback, + std::function callback, uint32_t flags, uint64_t uid); - bool operator== (const TimerInfo &other) const; - bool Matches (const std::string &packageName) const; - }; - } -} \ No newline at end of file + 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 index 6739cd43..f7c5dabb 100644 --- a/services/timer/include/timer_manager.h +++ b/services/timer/include/timer_manager.h @@ -12,6 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef TIMER_MANAGER_H +#define TIMER_MANAGER_H #include #include @@ -23,99 +25,82 @@ #include #include "timer_handler.h" #include "batch.h" -#include "ability_context.h" -#include "want_agent_helper.h" - -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::shared_ptr wantAgent, - 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; +namespace OHOS{ +namespace MiscServices{ + +class TimerManager : public ITimerManager { +public: + static std::shared_ptr Create(); - ~TimerManager() override; + uint64_t CreateTimer(int type, uint64_t windowLength, uint64_t interval,int flag, + std::shared_ptr wantAgent, + 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; - private: - explicit TimerManager(std::shared_ptr impl); - void TimerLooper(); + ~TimerManager() override; - void SetHandler(uint64_t id, - int type, - uint64_t triggerAtTime, - uint64_t windowLength, - uint64_t interval, - int flag, +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::shared_ptr wantAgent, - std::function callback, + std::function callback, uint64_t uid); - void SetHandlerLocked(uint64_t id, - int type, + 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::shared_ptr wantAgent, - std::function callback, + std::function callback, uint32_t flags, bool doValidate, uint64_t callingUid); - void RemoveHandler(uint64_t id); - - void RemoveLocked(uint64_t id); + 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 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, + 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, + bool TriggerTimersLocked(std::vector> &triggerList, std::chrono::steady_clock::time_point nowElapsed); - void RescheduleKernelTimerLocked(); + void RescheduleKernelTimerLocked(); - void DeliverTimersLocked(const std::vector> &triggerList, + 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_; - }; - - } -} \ No newline at end of file + 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 index 05553145..2803cf91 100644 --- a/services/timer/include/timer_manager_interface.h +++ b/services/timer/include/timer_manager_interface.h @@ -13,55 +13,54 @@ * limitations under the License. */ +#ifndef TIMER_MANAGER_INTERFACE_H +#define TIMER_MANAGER_INTERFACE_H #include #include "want_agent.h" -namespace OHOS -{ +namespace OHOS { +namespace MiscServices { - namespace MiscServices - { - struct TimerEntry { - uint64_t id; - int type; - uint64_t windowLength; - uint64_t interval; - int flag; - std::shared_ptr wantAgent; - std::function callback; - uint64_t uid; - }; +struct TimerEntry { + uint64_t id; + int type; + uint64_t windowLength; + uint64_t interval; + int flag; + std::shared_ptr wantAgent; + 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, - }; +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 - }; + 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, + virtual uint64_t CreateTimer (int type, uint64_t windowLength, uint64_t interval, int flag, std::shared_ptr wantAgent, - std::function callback, + 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; - }; - } -} \ No newline at end of file + 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 index 534a3933..cae04634 100644 --- a/services/timer/src/batch.cpp +++ b/services/timer/src/batch.cpp @@ -16,150 +16,131 @@ #include "batch.h" #include -namespace OHOS -{ - namespace MiscServices - { +namespace OHOS { +namespace MiscServices { - const auto TYPE_NONWAKEUP_MASK = 0x1; +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 () + : 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)} - { - } +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 (); - } +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); - } +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, +bool Batch::CanHold (std::chrono::steady_clock::time_point whenElapsed, std::chrono::steady_clock::time_point maxWhen) const - { - return (end_ > whenElapsed) && (start_ <= maxWhen); - } +{ + 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, +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从小到大排列 + alarms_.insert (it, alarm); //根据Alarm.when_elapsed从小到大排列 - if (alarm->whenElapsed > start_) - { - start_ = alarm->whenElapsed; - new_start = true; - } + if (alarm->whenElapsed > start_) { + start_ = alarm->whenElapsed; + new_start = true; + } - if (alarm->maxWhenElapsed < end_) - { + 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; }); - } + flags_ |= alarm->flags; + return new_start; +} - bool Batch::Remove (std::function predicate) - { - 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; - if (predicate (*alarm)) - { - alarms_.erase (it); - didRemove = true; +bool Batch::Remove (const TimerInfo &alarm) +{ + return Remove ([alarm] (const TimerInfo &a){ return a == alarm; }); +} + +bool Batch::Remove (std::function predicate) +{ + 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; + if (predicate (*alarm)) { + alarms_.erase (it); + didRemove = true; + } else { + if (alarm->whenElapsed > newStart) { + newStart = alarm->whenElapsed; } - else - { - if (alarm->whenElapsed > newStart) - { - newStart = alarm->whenElapsed; - } - - if (alarm->maxWhenElapsed < newEnd) - { - newEnd = alarm->maxWhenElapsed; - } - newFlags |= alarm->flags; - ++it; + if (alarm->maxWhenElapsed < newEnd) { + newEnd = alarm->maxWhenElapsed; } + newFlags |= alarm->flags; + ++it; } + } - if (didRemove) - { - start_ = newStart; - end_ = newEnd; - flags_ = newFlags; - } - return didRemove; + 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 (), +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 (); - } + { return alarm->Matches (package_name); }) != alarms_.end (); +} - bool Batch::HasWakeups () const - { - return std::any_of (alarms_.begin (), - alarms_.begin (), +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_; - } +std::chrono::steady_clock::time_point Batch::GetStart () const +{ + return start_; +} - uint32_t Batch::GetFlags () const - { - return flags_; - } +std::chrono::steady_clock::time_point Batch::GetEnd () const +{ + return end_; +} - } // MiscServices +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 index 568f83f2..66c24c8a 100644 --- a/services/timer/src/timer_handler.cpp +++ b/services/timer/src/timer_handler.cpp @@ -24,263 +24,123 @@ #include #include #include +#include +#include -namespace OHOS -{ - namespace MiscServices - { - static constexpr int ALARM_TIME_CHANGE_MASK = 1 << 16; +namespace OHOS { +namespace MiscServices { - static const clockid_t alarm_to_clock_id[N_TIMER_FDS] = { +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, - }; - - static const char rtc_sysfs[] = "/sys/class/rtc"; - - static bool rtc_is_hctosys (unsigned int rtc_id) - { +}; - auto hctosys_path = rtc_sysfs + std::string ("/rtc") + std::to_string (rtc_id) + std::string ("/hctosys"); - FILE *file = fopen (hctosys_path.c_str (), "re"); - if (!file) - { - std::cerr << "failed to open " << hctosys_path << ": " << strerror (errno) << std::endl; - return false; - } - unsigned int hctosys; - bool ret = false; - int err = fscanf (file, "%u", &hctosys); - if (err == EOF) - std::cerr << "failed to read from " << hctosys_path << ": " << strerror (errno) << std::endl; - else if (err == 0) - std::cerr << hctosys_path << " did not have expected contents" << std::endl; - else - ret = hctosys; +std::shared_ptr TimerHandler::Create() +{ + int epollfd; + TimerFds fds; - fclose (file); - return ret; + epollfd = epoll_create (fds.size ()); + if (epollfd < 0) { + TIME_HILOGE(TIME_MODULE_SERVICE, "epoll_create %{public}d failed: %{public}s", fds.size() ,strerror (errno)); + return nullptr; } - static int wall_clock_rtc () - { - std::unique_ptr dir (opendir (rtc_sysfs), closedir); - if (!dir) - { - std::cerr << "failed to open " << rtc_sysfs << ": " << strerror (errno) << std::endl; - return -1; - } - - struct dirent *dirent; - while (errno = 0, dirent = readdir (dir.get ())) - { - unsigned int rtc_id; - int matched = sscanf (dirent->d_name, "rtc%u", &rtc_id); - - if (matched < 0) - break; - else if (matched != 1) - continue; - - if (rtc_is_hctosys (rtc_id)) - { - std::cout << "found wall clock RTC " << rtc_id << std::endl; - return rtc_id; + 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",i ,strerror (errno)); + close (epollfd); + for (size_t j = 0; j < i; j++) { + close (fds[j]); } + return nullptr; } - - if (errno == 0) - std::cerr << "no wall clock RTC found" << std::endl; - else - std::cerr << "failed to enumerate RTCs: " << strerror (errno) << std::endl; - return -1; } - std::shared_ptr TimerHandler::Create () - { - int epollfd; - TimerFds fds; + 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; - epollfd = epoll_create (fds.size ()); - if (epollfd < 0) - { - std::cerr << "epoll_create " << fds.size () << "failed: " << strerror (errno) << std::endl; - 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) - { - std::cerr << "timerfd_create " << i << " failed: " << strerror (errno) << std::endl; - close (epollfd); - for (size_t j = 0; j < i; j++) - { - close (fds[j]); - } - return nullptr; - } - } - - auto handler = std::shared_ptr (new TimerHandler (fds, epollfd, wall_clock_rtc ())); - 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) - { - std::cerr << "epoll_ctl(EPOLL_CTL_ADD) failed: " << strerror (errno) << std::endl; - return nullptr; - } + 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) - { - std::cerr << "timerfd_settime() failed: " << strerror (errno) << std::endl; - return nullptr; - } - - return handler; } + itimerspec spec{}; - TimerHandler::TimerHandler (const TimerFds &fds, int epollfd, int rtc_id) - : fds_{fds}, epollFd_{epollfd}, rtcId_{rtc_id} - { + 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; } - TimerHandler::~TimerHandler () - { - for (auto fd : fds_) - { - epoll_ctl (epollFd_, EPOLL_CTL_DEL, fd, nullptr); - close (fd); - } - close (epollFd_); - } + return handler; +} - int TimerHandler::Set (uint32_t type, std::chrono::nanoseconds when) - { - std::cout << __func__ << " type=" << type << " when=" << when.count () << std::endl; - if (static_cast(type) > ALARM_TYPE_COUNT) - { - errno = EINVAL; - return -1; - } +TimerHandler::TimerHandler (const TimerFds &fds, int epollfd) + : fds_{fds}, epollFd_{epollfd} +{ +} - 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); +TimerHandler::~TimerHandler() +{ + for (auto fd : fds_) { + epoll_ctl (epollFd_, EPOLL_CTL_DEL, fd, nullptr); + close (fd); } + close (epollFd_); +} - int TimerHandler::SetTime (struct timeval *tv) - { - struct rtc_time rtc - { - }; - struct tm tm - { - }, *gmtime_res; - int fd; - int res; - - res = settimeofday (tv, nullptr); - if (res < 0) - { - std::cerr << "settimeofday() failed: " << strerror (errno) << std::endl; - return -1; - } - - if (rtcId_ < 0) - { - std::cerr << "Not setting RTC because wall clock RTC was not found" << std::endl; - errno = ENODEV; - return -1; - } +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 rtc_dev = std::string ("/dev/rtc") + std::to_string (rtcId_); - fd = open (rtc_dev.c_str (), O_RDWR); - if (fd < 0) - { - std::cerr << "Unable to open " << rtc_dev << ": " << strerror (errno) << std::endl; - return res; - } + 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); +} - gmtime_res = gmtime_r (&tv->tv_sec, &tm); - if (!gmtime_res) - { - std::cerr << "gmtime_r() failed: " << strerror (errno) << std::endl; - res = -1; - goto done; - } +int TimerHandler::WaitForAlarm() +{ + epoll_event events[N_TIMER_FDS]; - memset (&rtc, 0, sizeof (rtc)); - 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) - std::cerr << "RTC_SET_TIME ioctl failed: " << strerror (errno) << std::endl; - done: - close (fd); - return res; + int nevents = epoll_wait (epollFd_, events, N_TIMER_FDS, -1); + if (nevents < 0){ + return nevents; } - 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); + 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; } + return result; +} - } // MiscServices +} // MiscServices } // OHOS \ No newline at end of file diff --git a/services/timer/src/timer_info.cpp b/services/timer/src/timer_info.cpp index c4126d2f..2cc62276 100644 --- a/services/timer/src/timer_info.cpp +++ b/services/timer/src/timer_info.cpp @@ -15,50 +15,44 @@ #include "timer_info.h" -namespace OHOS -{ - namespace MiscServices - { +namespace OHOS { +namespace MiscServices { - bool TimerInfo::operator== (const TimerInfo &other) const - { - return this->id == other.id; - } +bool TimerInfo::operator== (const TimerInfo &other) const{ + return this->id == other.id; +} - bool TimerInfo::Matches (const std::string &packageName) const - { - //TODO - return false; - } +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::shared_ptr _operation, - 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}, - operation{std::move (_operation)}, - callback{std::move (_callback)}, - flags{_flags}, - uid{_uid}, - when{_when}, - windowLength{_windowLength}, - whenElapsed{_whenElapsed}, - maxWhenElapsed{_maxWhen}, - expectedWhenElapsed{_whenElapsed}, - expectedMaxWhenElapsed{_maxWhen}, - repeatInterval{_interval} - { - } +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::shared_ptr _operation, + 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}, + operation{std::move (_operation)}, + callback{std::move (_callback)}, + flags{_flags}, + uid{_uid}, + when{_when}, + windowLength{_windowLength}, + whenElapsed{_whenElapsed}, + maxWhenElapsed{_maxWhen}, + expectedWhenElapsed{_whenElapsed}, + expectedMaxWhenElapsed{_maxWhen}, + repeatInterval{_interval} +{ +} - } // MiscServices +} // MiscServices } // OHOS \ No newline at end of file diff --git a/services/timer/src/timer_manager.cpp b/services/timer/src/timer_manager.cpp index 777d6385..09089217 100644 --- a/services/timer/src/timer_manager.cpp +++ b/services/timer/src/timer_manager.cpp @@ -20,568 +20,429 @@ #include #include -namespace OHOS -{ - namespace MiscServices - { - using namespace std::chrono; - - // const uint32_t TIMER_TYPE_REALTIME = 1; - // const uint32_t TIMER_TYPE_REALTIME_WAKEUP = 1 << 1; - // const uint32_t TIMER_TYPE_EXACT = 1 << 2; - // const uint32_t TIMER_TYPE_IDLE = 1 << 3; - - static int TIME_CHANGED_MASK = 1 << 16; - const auto MIN_FUTURITY = seconds(5); - //const auto MIN_INTERVAL = minutes(1); - 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 INTERVAL_DAY = hours(24); - 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, +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) - { +std::shared_ptr TimerManager::Create() +{ + auto impl = TimerHandler::Create(); + if (impl == nullptr){ 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)); } + 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, +uint64_t TimerManager::CreateTimer(int type, uint64_t windowLength, uint64_t interval, int flag, std::shared_ptr wantAgent, - std::function callback, - uint64_t uid) - { - - uint64_t timerNumber = random_(); - auto timerInfo = - std::make_shared(TimerEntry{timerNumber, - type, - windowLength, - interval, flag, - std::move(wantAgent), - std::move(callback), uid}); - std::lock_guard lock(entryMapMutex_); - timerEntryMap_.insert(std::make_pair(timerNumber, timerInfo)); - return timerNumber; + std::function callback, uint64_t uid) +{ + uint64_t timerNumber = 0; + while (timerNumber == 0){ + timerNumber = random_(); } + auto timerInfo = std::make_shared(TimerEntry{timerNumber, type,windowLength, + interval, flag, std::move(wantAgent), + 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()) - { +bool TimerManager::StartTimer(uint64_t timerNumber, uint64_t triggerTime) +{ + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()){ return false; - } - auto timerInfo = it->second; - SetHandler(timerInfo->id, - timerInfo->type, - triggerTime, - timerInfo->windowLength, - timerInfo->interval, - timerInfo->flag, - timerInfo->wantAgent, - timerInfo->callback, - timerInfo->uid); - return true; } - - bool TimerManager::StopTimer(uint64_t timerNumber) - { - std::lock_guard lock(entryMapMutex_); - auto it = timerEntryMap_.find(timerNumber); - if (it == timerEntryMap_.end()) - { + auto timerInfo = it->second; + SetHandler(timerInfo->id, + timerInfo->type, + triggerTime, + timerInfo->windowLength, + timerInfo->interval, + timerInfo->flag, + timerInfo->wantAgent, + timerInfo->callback, + timerInfo->uid); + return true; +} + +bool TimerManager::StopTimer(uint64_t timerNumber) +{ + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()){ return false; - } - RemoveHandler(timerNumber); - return false; } + RemoveHandler(timerNumber); + return false; +} - bool TimerManager::DestroyTimer(uint64_t timerNumber) - { - std::lock_guard lock(entryMapMutex_); - auto it = timerEntryMap_.find(timerNumber); - if (it == timerEntryMap_.end()) - { +bool TimerManager::DestroyTimer(uint64_t timerNumber) +{ + std::lock_guard lock(entryMapMutex_); + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()){ return false; - } - RemoveHandler(timerNumber); - timerEntryMap_.erase(it); - return false; } + RemoveHandler(timerNumber); + timerEntryMap_.erase(it); + return false; +} - void TimerManager::SetHandler(uint64_t id, - int type, - uint64_t triggerAtTime, - uint64_t windowLength, - uint64_t interval, - int flag, +void TimerManager::SetHandler(uint64_t id, int type, uint64_t triggerAtTime, uint64_t windowLength, uint64_t interval, int flag, std::shared_ptr wantAgent, - std::function callback, - uint64_t uid) - { - auto windowLengthDuration = milliseconds(windowLength); - if (windowLengthDuration > INTERVAL_HALF_DAY) - { + std::function callback, uint64_t uid) +{ + auto windowLengthDuration = milliseconds(windowLength); + if (windowLengthDuration > INTERVAL_HALF_DAY){ windowLengthDuration = INTERVAL_HOUR; } - auto intervalDuration = milliseconds(interval); - if (intervalDuration > milliseconds::zero() && intervalDuration < MIN_INTERVAL) - { + auto intervalDuration = milliseconds(interval); + if (intervalDuration > milliseconds::zero() && intervalDuration < MIN_INTERVAL){ intervalDuration = MIN_INTERVAL; - } - else if (intervalDuration > MAX_INTERVAL) - { + }else if (intervalDuration > MAX_INTERVAL){ intervalDuration = MAX_INTERVAL; - } - - if (triggerAtTime < 0) - { + } + 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; + 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()) - { + steady_clock::time_point maxElapsed; + if (windowLengthDuration == milliseconds::zero()){ maxElapsed = triggerElapsed; - } - else if (windowLengthDuration < milliseconds::zero()) - { + } else if (windowLengthDuration < milliseconds::zero()){ maxElapsed = MaxTriggerTime(nominalTrigger, triggerElapsed, intervalDuration); windowLengthDuration = duration_cast(maxElapsed - triggerElapsed); - } - else - { + } else { maxElapsed = triggerElapsed + windowLengthDuration; - } - - std::lock_guard lockGuard(mutex_); - SetHandlerLocked(id, - type, - milliseconds(triggerAtTime), - triggerElapsed, - windowLengthDuration, - maxElapsed, - intervalDuration, - std::move(wantAgent), - 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::shared_ptr wantAgent, - std::function callback, - uint32_t flags, - bool doValidate, - uint64_t callingUid) - { - auto alarm = - std::make_shared(id, - type, - when, - whenElapsed, - windowLength, - maxWhen, - interval, - std::move(wantAgent), - std::move(callback), - flags, - callingUid); - SetHandlerLocked(alarm, false, doValidate); + std::lock_guard lockGuard(mutex_); + SetHandlerLocked(id,type, milliseconds(triggerAtTime),triggerElapsed, windowLengthDuration, maxElapsed, + intervalDuration, std::move(wantAgent), 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::shared_ptr wantAgent, + std::function callback, + uint32_t flags, + bool doValidate, + uint64_t callingUid) +{ + auto alarm = std::make_shared(id, type, when, whenElapsed, windowLength, maxWhen, + interval, std::move(wantAgent), std::move(callback), flags, callingUid); + SetHandlerLocked(alarm, false, doValidate); } - void TimerManager::RemoveHandler(uint64_t id) - { - std::lock_guard lock(mutex_); - RemoveLocked(id); - } +void TimerManager::RemoveHandler(uint64_t id) +{ + std::lock_guard lock(mutex_); + RemoveLocked(id); +} - void TimerManager::RemoveLocked(uint64_t id) - { - auto whichAlarms = [id](const TimerInfo &timer) - { +void TimerManager::RemoveLocked(uint64_t id) +{ + auto whichAlarms = [id](const TimerInfo &timer) { return timer.id == id; - }; + }; - bool didRemove = false; - for (auto it = alarmBatches_.begin(); it != alarmBatches_.end(); ++it) - { + bool didRemove = false; + for (auto it = alarmBatches_.begin(); it != alarmBatches_.end(); ++it) { auto batch = *it; didRemove |= batch->Remove(whichAlarms); - if (batch->Size() == 0) - { - alarmBatches_.erase(it); + if (batch->Size() == 0) { + alarmBatches_.erase(it); } - } + } - if (didRemove) - { + if (didRemove) { ReBatchAllTimersLocked(true); - } } +} - void TimerManager::SetHandlerLocked(std::shared_ptr alarm, bool rebatching, bool doValidate) - { - std::cout << __func__ << " rebatching=" << rebatching << " doValidate=" << doValidate << std::endl; - InsertAndBatchTimerLocked(std::move(alarm)); - if (!rebatching) - { +void TimerManager::SetHandlerLocked(std::shared_ptr alarm, bool rebatching, bool doValidate) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "rebatching= %{public}d, doValidate= %{public}d", rebatching, doValidate); + InsertAndBatchTimerLocked(std::move(alarm)); + if (!rebatching) { RescheduleKernelTimerLocked(); - } - } - - void TimerManager::ReBatchAllTimers() - { - std::lock_guard lock(mutex_); - ReBatchAllTimersLocked(true); } +} - void TimerManager::ReBatchAllTimersLocked(bool doValidate) - { - auto oldSet = alarmBatches_; - alarmBatches_.clear(); - auto nowElapsed = steady_clock::now(); - for (const auto &batch : oldSet) - { +void TimerManager::ReBatchAllTimers() +{ + std::lock_guard lock(mutex_); + ReBatchAllTimersLocked(true); +} + +void TimerManager::ReBatchAllTimersLocked(bool doValidate){ + 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++) - { + for (unsigned int i = 0; i < n; i++){ ReAddTimerLocked(batch->Get(i), nowElapsed, doValidate); } - } - RescheduleKernelTimerLocked(); } - - void TimerManager::ReAddTimerLocked(std::shared_ptr timer, - std::chrono::steady_clock::time_point nowElapsed, - bool doValidate) - { - std::cout << __func__ << std::endl; - timer->when = timer->origWhen; - auto whenElapsed = ConvertToElapsed(timer->when, timer->type); - steady_clock::time_point maxElapsed; - if (timer->windowLength == milliseconds::zero()) - { + RescheduleKernelTimerLocked(); +} + +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 + } else { + maxElapsed = (timer->windowLength > milliseconds::zero()) ? whenElapsed + timer->windowLength : MaxTriggerTime(nowElapsed, whenElapsed, timer->repeatInterval); - } - timer->whenElapsed = whenElapsed; - timer->maxWhenElapsed = maxElapsed; - SetHandlerLocked(timer, true, doValidate); } + timer->whenElapsed = whenElapsed; + timer->maxWhenElapsed = maxElapsed; + SetHandlerLocked(timer, true, doValidate); +} - std::chrono::steady_clock::time_point TimerManager::ConvertToElapsed(std::chrono::milliseconds when, int type) - { - if (type == RTC || type == RTC_WAKEUP) - { +std::chrono::steady_clock::time_point TimerManager::ConvertToElapsed(std::chrono::milliseconds when, int type) +{ + 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(); - return steady_clock::now() + offset; } + auto offset = when - steady_clock::now().time_since_epoch(); + return steady_clock::now() + offset; +} - void TimerManager::TimerLooper() - { - std::vector> triggerList; - while (runFlag_) - { +void TimerManager::TimerLooper() +{ + std::vector> triggerList; + while (runFlag_) { int result = 0; - do - { + do { result = handler_->WaitForAlarm(); } while (result < 0 && errno == EINTR); - std::cout << "result=" << result << std::endl; + 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) - { - std::cout << "time changed" << std::endl; - system_clock::time_point lastTimeChangeClockTime; - system_clock::time_point expectedClockTime; - { + if ((result & TIME_CHANGED_MASK) != 0) { + TIME_HILOGI(TIME_MODULE_SERVICE, "time changed"); + system_clock::time_point lastTimeChangeClockTime; + system_clock::time_point expectedClockTime; 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))) - { - std::cout << "Time changed notification from kernel; rebatching" << std::endl; - - ReBatchAllTimers(); + expectedClockTime = lastTimeChangeClockTime + (duration_cast(nowElapsed.time_since_epoch()) - + duration_cast(lastTimeChangeRealtime_.time_since_epoch())); + - { - std::lock_guard lock(mutex_); - lastTimeChangeClockTime_ = nowRtc; - lastTimeChangeRealtime_ = nowElapsed; + 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(); + std::lock_guard lock(mutex_); + lastTimeChangeClockTime_ = nowRtc; + lastTimeChangeRealtime_ = nowElapsed; + } - } } - if (result != TIME_CHANGED_MASK) - { - std::lock_guard lock(mutex_); - auto hasWakeup = TriggerTimersLocked(triggerList, nowElapsed); - std::cout << "hasWakeup=" << hasWakeup << std::endl; - - DeliverTimersLocked(triggerList, nowElapsed); - std::cout << "--------->2" << std::endl; - - RescheduleKernelTimerLocked(); - } - else - { + 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); - std::lock_guard lock(mutex_); - RescheduleKernelTimerLocked(); + RescheduleKernelTimerLocked(); + } else { + std::lock_guard lock(mutex_); + RescheduleKernelTimerLocked(); } - } } +} - TimerManager::~TimerManager() - { - if (alarmThread_ && alarmThread_->joinable()) - { +TimerManager::~TimerManager() +{ + if (alarmThread_ && alarmThread_->joinable()) { alarmThread_->join(); - } } +} - bool TimerManager::TriggerTimersLocked(std::vector> &triggerList, +bool TimerManager::TriggerTimersLocked(std::vector> &triggerList, std::chrono::steady_clock::time_point nowElapsed) - { - std::cout << __func__ << " alarmBatches_.size=" << alarmBatches_.size() << std::endl; - bool hasWakeup = false; - while (!alarmBatches_.empty()) - { +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", alarmBatches_.size()); + bool hasWakeup = false; + while (!alarmBatches_.empty()) { auto batch = alarmBatches_.at(0); - std::cout << __func__ << " batch->GetStart()=" - << time_point_cast(batch->GetStart()).time_since_epoch().count() - << " nowElapsed=" << time_point_cast(nowElapsed).time_since_epoch().count() << std::endl; - if (batch->GetStart() > nowElapsed) - { - std::cout << __func__ << " break alarmBatches_.size=" << alarmBatches_.size() << std::endl; - break; + 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", alarmBatches_.size()); + break; } alarmBatches_.erase(alarmBatches_.begin()); - std::cout << __func__ << " after erase alarmBatches_.size=" << alarmBatches_.size() << std::endl; + TIME_HILOGI(TIME_MODULE_SERVICE, "after erase alarmBatches_.size= %{public}d", 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, - alarm->operation, - nullptr, - alarm->flags, - true, - alarm->uid); - } - - if (alarm->wakeup) - { - hasWakeup = true; - } + 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, alarm->operation, + 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; } + std::sort(triggerList.begin(), triggerList.end(), + [](const std::shared_ptr &l, + const std::shared_ptr &r){return l->whenElapsed < r->whenElapsed;}); - void TimerManager::RescheduleKernelTimerLocked() - { - std::cout << __func__ << " alarmBatches_ size=" << alarmBatches_.size() << std::endl; - auto nextNonWakeup = std::chrono::steady_clock::time_point::min(); - if (!alarmBatches_.empty()) - { + return hasWakeup; +} + +void TimerManager::RescheduleKernelTimerLocked() +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", alarmBatches_.size()); + auto nextNonWakeup = std::chrono::steady_clock::time_point::min(); + if (!alarmBatches_.empty()) { auto firstWakeup = FindFirstWakeupBatchLocked(); auto firstBatch = alarmBatches_.front(); - if (firstWakeup != nullptr) - { + if (firstWakeup != nullptr) { SetLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup->GetStart().time_since_epoch()); } - if (firstBatch != firstWakeup) - { + if (firstBatch != firstWakeup) { nextNonWakeup = firstBatch->GetStart(); } - } + } - if (nextNonWakeup != std::chrono::steady_clock::time_point::min()) - { + if (nextNonWakeup != std::chrono::steady_clock::time_point::min()) { SetLocked(ELAPSED_REALTIME, nextNonWakeup.time_since_epoch()); - } } +} - std::shared_ptr TimerManager::FindFirstWakeupBatchLocked() - { - auto it = std::find_if(alarmBatches_.begin(), - alarmBatches_.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; - } + return it != alarmBatches_.end() ? *it : nullptr; +} - void TimerManager::SetLocked(int type, std::chrono::nanoseconds when) - { - std::cout << __func__ << " " << when.count() << std::endl; - handler_->Set(static_cast(type), when); - } +void TimerManager::SetLocked(int type, std::chrono::nanoseconds when) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "when.count= %{public}lld", when.count()); + handler_->Set(static_cast(type), when); +} - void TimerManager::InsertAndBatchTimerLocked(std::shared_ptr alarm) - { - int64_t whichBatch = (alarm->flags & static_cast(STANDALONE)) - ? -1 - : AttemptCoalesceLocked(alarm->whenElapsed, alarm->maxWhenElapsed); - std::cout << __func__ << " whichBatch=" << whichBatch << std::endl; - if (whichBatch < 0) - { +void TimerManager::InsertAndBatchTimerLocked(std::shared_ptr alarm) +{ + int64_t whichBatch = (alarm->flags & static_cast(STANDALONE)) ? -1 + : AttemptCoalesceLocked(alarm->whenElapsed, alarm->maxWhenElapsed); + TIME_HILOGI(TIME_MODULE_SERVICE, "whichBatch= %{public}lld", whichBatch); + if (whichBatch < 0) { AddBatchLocked(alarmBatches_, std::make_shared(*alarm)); - } - else - { + } else { auto batch = alarmBatches_.at(whichBatch); - if (batch->Add(alarm)) - { - alarmBatches_.erase(alarmBatches_.begin() + whichBatch); - AddBatchLocked(alarmBatches_, batch); + if (batch->Add(alarm)) { + alarmBatches_.erase(alarmBatches_.begin() + whichBatch); + AddBatchLocked(alarmBatches_, batch); } - } } +} - int64_t TimerManager::AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed, +int64_t TimerManager::AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed, std::chrono::steady_clock::time_point maxWhen) - { - int64_t i = 0; - for (const auto &item : alarmBatches_) - { - if ((item->GetFlags() & static_cast(STANDALONE)) == 0 && item->CanHold(whenElapsed, maxWhen)) - { - return i; +{ + 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) - { - for (const auto &alarm : triggerList) - { - if (alarm->callback) - { - alarm->callback(); - } - - if (alarm->operation) - { - std::shared_ptr context = std::make_shared(); - std::shared_ptr want = Notification::WantAgent::WantAgentHelper::GetWant(alarm->operation); - - OHOS::Notification::WantAgent::TriggerInfo paramsInfo("", nullptr, want, 11); - Notification::WantAgent::WantAgentHelper::TriggerWantAgent(context, alarm->operation, nullptr, paramsInfo); + return -1; +} + +void TimerManager::DeliverTimersLocked(const std::vector> &triggerList, + std::chrono::steady_clock::time_point nowElapsed){ + for (const auto &alarm : triggerList) { + if (alarm->callback) { + alarm->callback(alarm->id); } - } } +} - bool AddBatchLocked(std::vector> &list, const std::shared_ptr &newBatch) - { - auto it = std::upper_bound(list.begin(), - list.end(), - newBatch, +bool AddBatchLocked(std::vector> &list, const std::shared_ptr &newBatch) +{ + 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); - return it == list.begin(); - } + list.insert(it, newBatch); + 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) - { +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())); } + return triggerAtTime + milliseconds(static_cast(0.75 * futurity.count())); +} - } // MiscService +} // MiscServices } // OHOS \ No newline at end of file diff --git a/utils/native/include/time_common.h b/utils/native/include/time_common.h index 3ab6fc6a..414ee0d8 100644 --- a/utils/native/include/time_common.h +++ b/utils/native/include/time_common.h @@ -35,9 +35,10 @@ constexpr ErrCode TIME_ERR_OFFSET = ErrCodeOffset(SUBSYS_SMALLSERVICES, TIME_MOD enum TimeError { - E_TIME_WRITE_PARCEL_ERROR = TIME_ERR_OFFSET, + 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, diff --git a/utils/native/include/time_hilog_wreapper.h b/utils/native/include/time_hilog_wreapper.h index ceb34e20..deb0c94c 100644 --- a/utils/native/include/time_hilog_wreapper.h +++ b/utils/native/include/time_hilog_wreapper.h @@ -18,11 +18,9 @@ #include "hilog/log.h" - namespace OHOS { namespace MiscServices { - // param of log interface, such as TIME_HILOGF. enum TimeSubModule { TIME_MODULE_INNERKIT = 0, diff --git a/utils/native/include/time_permission.h b/utils/native/include/time_permission.h index 3d0a4faa..b3df5949 100644 --- a/utils/native/include/time_permission.h +++ b/utils/native/include/time_permission.h @@ -13,6 +13,7 @@ * limitations under the License. */ + #ifndef TIME_PERMISSION_H #define TIME_PERMISSION_H diff --git a/utils/native/include/time_rdb_handler.h b/utils/native/include/time_rdb_handler.h index d3d32df9..e1182add 100644 --- a/utils/native/include/time_rdb_handler.h +++ b/utils/native/include/time_rdb_handler.h @@ -41,8 +41,8 @@ namespace MiscServices { bool InsertTimeZoneIdToRdb(const std::string timeZoneId){ int deletedRows; - const std::string dbPath_ = "/data/time/"; - const std::string dbName_ = "time.db"; + const std::string dbPath_ = "/data/misc/zoneinfo/"; + const std::string dbName_ = "timezone.db"; RdbStoreConfig config(dbPath_+ dbName_); @@ -64,8 +64,8 @@ namespace MiscServices { } bool GetTimeZoneId(std::string &timeZoneId){ - const std::string dbPath_ = "/data/time/"; - const std::string dbName_ = "time.db"; + const std::string dbPath_ = "/data/misc/zoneinfo/"; + const std::string dbName_ = "timezone.db"; RdbStoreConfig config(dbPath_+ dbName_); -- Gitee From 54fd94c4ad59b9c1b299add49e4c8100c3c19da5 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Sun, 8 Aug 2021 21:49:22 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E4=BF=AE=E6=94=B9c++=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/unittest/include/timer_test.h | 104 +++++++++--------- .../test/unittest/src/time_service_test.cpp | 62 +++++------ 2 files changed, 82 insertions(+), 84 deletions(-) diff --git a/services/time_manager/test/unittest/include/timer_test.h b/services/time_manager/test/unittest/include/timer_test.h index be40096b..382a0d71 100644 --- a/services/time_manager/test/unittest/include/timer_test.h +++ b/services/time_manager/test/unittest/include/timer_test.h @@ -14,62 +14,68 @@ */ #include "napi/native_api.h" #include "napi/native_node_api.h" -#include "itimer_info.h" #include +#include +#include +#include +#include -namespace OHOS -{ - namespace MiscService - { - 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(std::function callBack); +#include +#include "time_common.h" +#include "time_service_client.h" +#include +#include "timer_test.h" +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(std::function callBack); - private: - std::function callBack_; - }; + private: + std::function callBack_; +}; - TimerInfoTest::TimerInfoTest() - { - } +TimerInfoTest::TimerInfoTest() +{ +} - TimerInfoTest::~TimerInfoTest() - { - } +TimerInfoTest::~TimerInfoTest() +{ +} - void TimerInfoTest::OnTrigger() - { - callBack_(); - } +void TimerInfoTest::OnTrigger() +{ + callBack_(); +} - void TimerInfoTest::SetCallbackInfo(std::function callBack) - { - } +void TimerInfoTest::SetCallbackInfo(std::function callBack) +{ +} - void TimerInfoTest::SetType(const int &_type) - { - type = _type; - } +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; - } - } +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 index 852ceda5..0de18afd 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -13,16 +13,7 @@ * limitations under the License. */ -#include -#include -#include -#include -#include -#include "time_common.h" -#include "time_service_client.h" -#include -#include "timer_test.h" using namespace testing::ext; using namespace OHOS; @@ -87,7 +78,7 @@ HWTEST_F(TimeServiceTest, SetTimeZone001, TestSize.Level0) * @tc.desc: set system time zone. * @tc.type: FUNC */ -HWTEST_F(TimeServiceTest, SetTimeZone001, TestSize.Level0) +HWTEST_F(TimeServiceTest, SetTimeZone002, TestSize.Level0) { std::string timeZoneSet("Beijing, China"); @@ -163,11 +154,11 @@ HWTEST_F(TimeServiceTest, GetTime005, TestSize.Level0) } /** -* @tc.name: GetTime005 +* @tc.name: GetTime006 * @tc.desc: get system time. * @tc.type: FUNC */ -HWTEST_F(TimeServiceTest, GetTime005, TestSize.Level0) +HWTEST_F(TimeServiceTest, GetTime006, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs(); EXPECT_TRUE(time1 > 0); @@ -176,11 +167,11 @@ HWTEST_F(TimeServiceTest, GetTime005, TestSize.Level0) } /** -* @tc.name: GetTime006 +* @tc.name: GetTime007 * @tc.desc: get system time. * @tc.type: FUNC */ -HWTEST_F(TimeServiceTest, GetTime006, TestSize.Level0) +HWTEST_F(TimeServiceTest, GetTime007, TestSize.Level0) { auto time1 = TimeServiceClient::GetInstance()->GetThreadTimeMs(); EXPECT_TRUE(time1 > 0); @@ -189,17 +180,18 @@ HWTEST_F(TimeServiceTest, GetTime006, TestSize.Level0) } /** -* @tc.name: GetTime007 +* @tc.name: GetTime008 * @tc.desc: get system time. * @tc.type: FUNC */ -HWTEST_F(TimeServiceTest, GetTime007, TestSize.Level0) +HWTEST_F(TimeServiceTest, GetTime008, TestSize.Level0) { - Eauto time1 = TimeServiceClient::GetInstance()->GetThreadTimeNs(); + 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() @@ -220,7 +212,7 @@ void TimeOutCallback2() */ HWTEST_F(TimeServiceTest, CreateTimer01, TestSize.Level0) { - auto timerInfo = std::shared_ptr(); + auto timerInfo = std::make_shared(); timerInfo->SetType(2); timerInfo->SetRepeat(false); timerInfo->SetInterval(0); @@ -233,9 +225,9 @@ HWTEST_F(TimeServiceTest, CreateTimer01, TestSize.Level0) std::this_thread::sleep_for(std::chrono::milliseconds(10)); EXPECT_TRUE(ret); EXPECT_TRUE(g_data2 == 1); - auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_TRUE(ret); - auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); EXPECT_TRUE(ret); } @@ -247,7 +239,7 @@ HWTEST_F(TimeServiceTest, CreateTimer01, TestSize.Level0) HWTEST_F(TimeServiceTest, CreateTimer02, TestSize.Level0) { g_data1 = 0; - auto timerInfo = std::shared_ptr(); + auto timerInfo = std::make_shared(); timerInfo->SetType(3); timerInfo->SetRepeat(false); timerInfo->SetInterval(0); @@ -260,13 +252,13 @@ HWTEST_F(TimeServiceTest, CreateTimer02, TestSize.Level0) std::this_thread::sleep_for(std::chrono::milliseconds(10)); EXPECT_TRUE(ret); EXPECT_TRUE(g_data2 == 1); - auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_TRUE(ret); - auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5); + ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5); std::this_thread::sleep_for(std::chrono::milliseconds(10)); EXPECT_TRUE(ret); EXPECT_TRUE(g_data2 == 2); - auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); EXPECT_TRUE(ret); } @@ -280,9 +272,9 @@ HWTEST_F(TimeServiceTest, CreateTimer03, TestSize.Level0) uint64_t timerId = 0; auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId, 5); EXPECT_FALSE(ret); - auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId); EXPECT_FALSE(ret); - auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId); EXPECT_FALSE(ret); } @@ -294,7 +286,7 @@ HWTEST_F(TimeServiceTest, CreateTimer03, TestSize.Level0) HWTEST_F(TimeServiceTest, CreateTimer04, TestSize.Level0) { g_data1 = 0; - auto timerInfo = std::shared_ptr(); + auto timerInfo = std::make_shared(); timerInfo->SetType(3); timerInfo->SetRepeat(false); timerInfo->SetInterval(0); @@ -305,11 +297,11 @@ HWTEST_F(TimeServiceTest, CreateTimer04, TestSize.Level0) auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 2000); EXPECT_TRUE(ret); - auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); EXPECT_TRUE(ret); EXPECT_TRUE(g_data2 == 0); - auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_FALSE(ret); } @@ -321,7 +313,7 @@ HWTEST_F(TimeServiceTest, CreateTimer04, TestSize.Level0) HWTEST_F(TimeServiceTest, CreateTimer05, TestSize.Level0) { g_data1 = 0; - auto timerInfo = std::shared_ptr(); + auto timerInfo = std::make_shared(); timerInfo->SetType(0); timerInfo->SetRepeat(false); timerInfo->SetInterval(0); @@ -332,11 +324,11 @@ HWTEST_F(TimeServiceTest, CreateTimer05, TestSize.Level0) auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 2000); EXPECT_TRUE(ret); - auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); EXPECT_TRUE(ret); EXPECT_TRUE(g_data2 == 0); - auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_FALSE(ret); } @@ -348,7 +340,7 @@ HWTEST_F(TimeServiceTest, CreateTimer05, TestSize.Level0) HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0) { g_data1 = 0; - auto timerInfo = std::shared_ptr(); + auto timerInfo = std::make_shared(); timerInfo->SetType(1); timerInfo->SetRepeat(false); timerInfo->SetInterval(0); @@ -364,10 +356,10 @@ HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0) auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, static_cast(current_time)); EXPECT_TRUE(ret); - auto ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); + ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1); EXPECT_TRUE(ret); EXPECT_TRUE(g_data2 == 0); - auto ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); + ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_FALSE(ret); } -- Gitee From dc34c3a53b586953006a4a630946c7dfc57cc04a Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Mon, 9 Aug 2021 05:25:46 +0800 Subject: [PATCH 04/14] 20210809 --- services/time_manager/test/unittest/include/timer_test.h | 2 +- services/time_manager/test/unittest/src/time_service_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/time_manager/test/unittest/include/timer_test.h b/services/time_manager/test/unittest/include/timer_test.h index 382a0d71..a7199abc 100644 --- a/services/time_manager/test/unittest/include/timer_test.h +++ b/services/time_manager/test/unittest/include/timer_test.h @@ -24,7 +24,7 @@ #include "time_common.h" #include "time_service_client.h" #include -#include "timer_test.h" +//#include "timer_test.h" namespace OHOS{ namespace MiscServices{ class TimerInfoTest : public ITimerInfo { 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 0de18afd..49b4c675 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include "timer_test.h" using namespace testing::ext; -- Gitee From 7e12a47d2653aaf3781e12459935bd5b17109ba4 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Mon, 9 Aug 2021 12:49:37 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/time_manager/test/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/services/time_manager/test/BUILD.gn b/services/time_manager/test/BUILD.gn index 1d3e599e..a75d312e 100644 --- a/services/time_manager/test/BUILD.gn +++ b/services/time_manager/test/BUILD.gn @@ -38,6 +38,7 @@ ohos_unittest("TimeServiceTest") { "//base/miscservices/time/services:time_service", "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", "//foundation/ace/napi:ace_napi", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", "//third_party/googletest:gtest_main", "//utils/native/base:utils", ] -- Gitee From 0732aeeedbe13390604e54584e4c1c9e7bbaec23 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Mon, 9 Aug 2021 15:41:03 +0800 Subject: [PATCH 06/14] 20210809 --- services/time_manager/test/BUILD.gn | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/services/time_manager/test/BUILD.gn b/services/time_manager/test/BUILD.gn index a75d312e..33927f59 100644 --- a/services/time_manager/test/BUILD.gn +++ b/services/time_manager/test/BUILD.gn @@ -38,16 +38,24 @@ ohos_unittest("TimeServiceTest") { "//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", ] } -- Gitee From 3f3318543294fe25f3b5cf5962f847317c1cc78a Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Thu, 19 Aug 2021 02:06:59 +0800 Subject: [PATCH 07/14] 20210819 --- .../js/declaration/api/@ohos.systemtime.d.ts | 26 ++++---- .../js/declaration/api/@ohos.systemtimer.d.ts | 44 +++++++------- .../napi/system_time/include/js_systemtime.h | 7 --- .../js/napi/system_time/src/js_systemtime.cpp | 44 ++++++-------- .../js/napi/system_timer/src/timer_type.cpp | 2 +- services/time_manager/include/time_service.h | 3 + .../include/time_service_notify.h | 2 - services/time_manager/src/time_service.cpp | 15 ++++- .../time_manager/src/time_service_client.cpp | 4 +- .../time_manager/src/time_service_notify.cpp | 4 +- utils/BUILD.gn | 17 +++++- utils/mock/include/mock_permission.h | 30 ++++++++++ utils/mock/src/mock_permission.cpp | 29 +++++++++ utils/native/include/time_common.h | 1 + utils/native/include/time_permission.h | 27 +++++++-- utils/native/src/time_permission.cpp | 60 +++++++++++++++++-- 16 files changed, 232 insertions(+), 83 deletions(-) create mode 100644 utils/mock/include/mock_permission.h create mode 100644 utils/mock/src/mock_permission.cpp diff --git a/interfaces/kits/js/declaration/api/@ohos.systemtime.d.ts b/interfaces/kits/js/declaration/api/@ohos.systemtime.d.ts index d600cf46..2daeebb3 100755 --- a/interfaces/kits/js/declaration/api/@ohos.systemtime.d.ts +++ b/interfaces/kits/js/declaration/api/@ohos.systemtime.d.ts @@ -22,22 +22,26 @@ import { AsyncCallback, ErrorCallback } from './basic'; */ declare namespace systemTime { /** - * Set system time. - * @SystemApi - */ - function setTime(time: number, callback: AsyncCallback): void; - function setTime(time: number): Promise; + * Sets the system time. + * @permission ohos.permission.SET_TIME + * @since 6 + */ + function setTime(time : number, callback : AsyncCallback) : void; + function setTime(time : number) : Promise; /** - * Set system time. - * @SystemApi - */ + * Sets the system time. + * @permission ohos.permission.SET_TIME + * @since 7 + */ function setDate(date: Date, callback: AsyncCallback): void; function setDate(date: Date): Promise; + /** - * Set system time zone. - * @SystemApi - */ + * 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; diff --git a/interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts b/interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts index 293615f1..4a55a964 100644 --- a/interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts +++ b/interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts @@ -19,6 +19,8 @@ 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 { /** @@ -29,7 +31,7 @@ declare namespace systemTimer { /** * Describes whether a timer will wake the device up. */ - const TIMER_TYPE_REALTIME_WAKEUP: number; + const TIMER_TYPE_WAKEUP: number; /** * Describes whether a timer will be delivered precisely at a scheduled time. @@ -43,28 +45,41 @@ declare namespace systemTimer { /** * Creates a timer. - * @SystemApi + * @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. - * @SystemApi + *@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, callback: AsyncCallback): void; - function startTimer(timer: number): Promise; + function startTimer(timer: number, triggerTime: number, callback: AsyncCallback): void; + function startTimer(timer: number, triggerTime: number): Promise; /** * Stops a timer. - * @SystemApi + * @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. - * @SystemApi + * @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; @@ -74,13 +89,7 @@ declare namespace systemTimer { * timer type. */ type: number; - - /** - * 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. - */ - triggerTime: number; - + /** * Indicates a repeating timer */ @@ -92,15 +101,8 @@ declare namespace systemTimer { */ interval?: number; - /** - * Indicates the timer is not lost with shutdown or sleep, until all trigger actions have been completed. - * - */ - persistent: boolean; - /** * Indicates the intent to send when the timer goes off. - * @SystemApi */ wantAgent?: WantAgent; diff --git a/interfaces/kits/js/napi/system_time/include/js_systemtime.h b/interfaces/kits/js/napi/system_time/include/js_systemtime.h index 8b69322c..ffae8104 100644 --- a/interfaces/kits/js/napi/system_time/include/js_systemtime.h +++ b/interfaces/kits/js/napi/system_time/include/js_systemtime.h @@ -31,11 +31,6 @@ constexpr int THREE_PARAMETER = 3; constexpr int MAX_TIME_ZONE_ID = 1024; -enum{ - TYPE_SET_TIME = 0, - TYPE_SET_DATE = 1, - TYPE_SET_TIMEZOME = 2 -}; #define GET_PARAMS(env, info, num) \ size_t argc = num; \ @@ -47,9 +42,7 @@ enum{ typedef struct AsyncContext { napi_env env; napi_async_work work; - int type; int64_t time; - int64_t dateMs; std::string timeZone; napi_deferred deferred; napi_ref callbackRef; diff --git a/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp index 8d360ab9..92cd584a 100644 --- a/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp +++ b/interfaces/kits/js/napi/system_time/src/js_systemtime.cpp @@ -33,29 +33,28 @@ static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) GET_PARAMS(env, info, 2); NAPI_ASSERT(env, argc == ONE_PARAMETER || argc == TWO_PARAMETER, "type mismatch"); - AsyncContext* asyncContext = new AsyncContext(); + 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) { - if (napi_ok != napi_get_value_int64(env, argv[i], &asyncContext->time)){ - delete asyncContext; - NAPI_ASSERT(env, false, "input para invalid"); - } - asyncContext->type = TYPE_SET_TIME; - /*double dateValue; - * napi_get_date_value(env, argv[i], &dateValue); - * } else if (i == 0 && valueType == napi_object){ - * double dateValue; - * if (napi_ok != napi_get_date_value(env, argv[i], &dateValue)){ - * delete asyncContext; - * NAPI_ASSERT(env, false, "input para invalid"); - * } - * asyncContext->dateMs = int64_t(dateValue); - * asyncContext->type = TYPE_SET_DATE; - */ + 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 { @@ -78,11 +77,8 @@ static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info) napi_create_async_work(env, nullptr, resource,[](napi_env env, void* data) { AsyncContext* asyncContext = (AsyncContext*)data; bool setTimeResult; - if (asyncContext->type == TYPE_SET_DATE) { - setTimeResult = TimeServiceClient::GetInstance()->SetTime(asyncContext->dateMs); - }else{ - setTimeResult = TimeServiceClient::GetInstance()->SetTime(asyncContext->time); - } + setTimeResult = TimeServiceClient::GetInstance()->SetTime(asyncContext->time); + if (setTimeResult) { asyncContext->status = RESOLVED; } else { @@ -137,14 +133,12 @@ static napi_value JSSystemTimeSetTimeZone(napi_env env, napi_callback_info info) 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; - asyncContext->type = TYPE_SET_TIMEZOME; } else if (i == 1 && valueType == napi_function) { napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef); } else { @@ -212,7 +206,7 @@ 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("setDate", JSSystemTimeSetTime), DECLARE_NAPI_FUNCTION("setTimezone", JSSystemTimeSetTimeZone) }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); diff --git a/interfaces/kits/js/napi/system_timer/src/timer_type.cpp b/interfaces/kits/js/napi/system_timer/src/timer_type.cpp index 53af1022..283534aa 100644 --- a/interfaces/kits/js/napi/system_timer/src/timer_type.cpp +++ b/interfaces/kits/js/napi/system_timer/src/timer_type.cpp @@ -31,7 +31,7 @@ napi_value TimerTypeInit(napi_env env, napi_value exports) napi_create_object(env, &obj); SetNamedPropertyByInteger(env, obj, 1 << 0, "TIMER_TYPE_REALTIME"); - SetNamedPropertyByInteger(env, obj, 1 << 1, "TIMER_TYPE_REALTIME_WAKEUP"); + SetNamedPropertyByInteger(env, obj, 1 << 1, "TIMER_TYPE_WAKEUP"); SetNamedPropertyByInteger(env, obj, 1 << 2, "TIMER_TYPE_EXACT"); SetNamedPropertyByInteger(env, obj, 1 << 3, "TIMER_TYPE_IDLE"); diff --git a/services/time_manager/include/time_service.h b/services/time_manager/include/time_service.h index fc185b4c..fe8d35f6 100644 --- a/services/time_manager/include/time_service.h +++ b/services/time_manager/include/time_service.h @@ -20,6 +20,7 @@ #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" @@ -86,6 +87,8 @@ private: 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_; diff --git a/services/time_manager/include/time_service_notify.h b/services/time_manager/include/time_service_notify.h index 7830fb60..c2ecc784 100644 --- a/services/time_manager/include/time_service_notify.h +++ b/services/time_manager/include/time_service_notify.h @@ -41,8 +41,6 @@ private: sptr timeChangeWant_; sptr timeZoneChangeWant_; sptr publishInfo_; - const std::string TIME_CHANGE_ACTION = "com.hos.action.TIME_CHANGE_ACTION"; - const std::string TIME_ZONE_CHANGE_ACTION = "com.hos.action.TIME_ZONE_CHANGE_ACTION"; }; } // namespace MiscServices diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index 75e126e8..444199b6 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -153,7 +153,6 @@ void TimeService::InitNotifyHandler(){ TIME_HILOGE(TIME_MODULE_SERVICE," Already init."); return; } - timeServiceNotify_ = std::make_shared(); timeServiceNotify_->RegisterPublishEvents(); } @@ -264,7 +263,12 @@ bool TimeService::DestroyTimer(uint64_t timerId) 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}lld.", time); if (time <= 0 || time / 1000LL >= INT_MAX) { TIME_HILOGE(TIME_MODULE_SERVICE, "input param error"); @@ -387,7 +391,12 @@ int TimeService::get_wall_clock_rtc_id() 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; auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset); diff --git a/services/time_manager/src/time_service_client.cpp b/services/time_manager/src/time_service_client.cpp index 613d88f2..7ab30a28 100644 --- a/services/time_manager/src/time_service_client.cpp +++ b/services/time_manager/src/time_service_client.cpp @@ -32,7 +32,9 @@ TimeServiceClient::TimeServiceClient() { } -TimeServiceClient::~TimeServiceClient(){} +TimeServiceClient::~TimeServiceClient() +{ +} sptr TimeServiceClient::GetInstance() { diff --git a/services/time_manager/src/time_service_notify.cpp b/services/time_manager/src/time_service_notify.cpp index 92dfb668..641c7893 100644 --- a/services/time_manager/src/time_service_notify.cpp +++ b/services/time_manager/src/time_service_notify.cpp @@ -34,9 +34,9 @@ void TimeServiceNotify::RegisterPublishEvents() publishInfo_ = new (std::nothrow)CommonEventPublishInfo(); publishInfo_->SetOrdered(false); timeChangeWant_ = new (std::nothrow)IntentWant(); - timeChangeWant_->SetAction(TIME_CHANGE_ACTION); + timeChangeWant_->SetAction(CommonEventSupport::COMMON_EVENT_TIME_CHANGED); timeZoneChangeWant_ = new (std::nothrow)IntentWant(); - timeZoneChangeWant_->SetAction(TIME_ZONE_CHANGE_ACTION); + timeZoneChangeWant_->SetAction(CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED); } void TimeServiceNotify::PublishEvents(int64_t eventTime, sptr want) diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 215a1fae..707419c1 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -15,19 +15,34 @@ import("//base/miscservices/time/time.gni") config("utils_config") { include_dirs = [ + "mock/include", "native/include", "//utils/native/base/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core/include/bundlemgr/", ] } 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" ] + 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", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "ipc:ipc_core", + ] part_name = "time_native" } diff --git a/utils/mock/include/mock_permission.h b/utils/mock/include/mock_permission.h new file mode 100644 index 00000000..a86b676b --- /dev/null +++ b/utils/mock/include/mock_permission.h @@ -0,0 +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. + */ + +#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 00000000..373112f5 --- /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/utils/native/include/time_common.h b/utils/native/include/time_common.h index 414ee0d8..b16a0f89 100644 --- a/utils/native/include/time_common.h +++ b/utils/native/include/time_common.h @@ -45,6 +45,7 @@ enum TimeError { E_TIME_PARAMETERS_INVALID, E_TIME_SET_RTC_FAILED, E_TIME_NOT_FOUND, + E_TIME_NO_PERMISSION, }; } // namespace MiscServices diff --git a/utils/native/include/time_permission.h b/utils/native/include/time_permission.h index b3df5949..fd46730d 100644 --- a/utils/native/include/time_permission.h +++ b/utils/native/include/time_permission.h @@ -17,14 +17,31 @@ #ifndef TIME_PERMISSION_H #define TIME_PERMISSION_H -#include +#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 MiscService { -class TimePermission { +namespace MiscServices { +class TimePermission : public RefBase{ public: - static bool CheckSelfPermission(const std::string permName); - static bool CheckCallingPermission(const std::string bundle, const std::string permName, const int userId); + 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 MiscService } // namespace OHOS diff --git a/utils/native/src/time_permission.cpp b/utils/native/src/time_permission.cpp index 2c147b14..994611d5 100644 --- a/utils/native/src/time_permission.cpp +++ b/utils/native/src/time_permission.cpp @@ -15,21 +15,73 @@ #include "time_permission.h" -using namespace std; namespace OHOS { -namespace MiscService { +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(std::string bundle, std::string permName, int userId) +bool TimePermission::CheckCallingPermission(int32_t uid, std::string permName) { - return true; + 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"); + return false; + } + 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 MiscService } // namespace OHOS -- Gitee From 406ac77171f38b8190d182b861fdc943ecce83f4 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Thu, 19 Aug 2021 06:35:36 +0800 Subject: [PATCH 08/14] 2021081800 --- services/time_manager/src/time_service.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index 444199b6..de2e5c5a 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -263,12 +263,14 @@ bool TimeService::DestroyTimer(uint64_t timerId) int32_t TimeService::SetTime(const int64_t time) { +#if 0 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; } +#endif TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}lld.", time); if (time <= 0 || time / 1000LL >= INT_MAX) { TIME_HILOGE(TIME_MODULE_SERVICE, "input param error"); @@ -391,12 +393,14 @@ int TimeService::get_wall_clock_rtc_id() int32_t TimeService::SetTimeZone(const std::string timeZoneId) { +#if 0 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; } +#endif int gmtOffset; struct timezone tz; auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset); -- Gitee From e1d717156898c97fd5680e347230549a491d9612 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Tue, 24 Aug 2021 07:55:02 +0800 Subject: [PATCH 09/14] 20210824 --- README.md | 2 +- README_zh.md | 2 +- services/time_manager/include/time_service_stub.h | 1 + services/time_manager/src/time_service.cpp | 4 ---- services/time_manager/src/time_service_stub.cpp | 2 +- services/time_manager/test/unittest/src/time_service_test.cpp | 3 ++- utils/BUILD.gn | 1 - utils/native/include/time_permission.h | 2 +- utils/native/src/time_permission.cpp | 2 +- 9 files changed, 8 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index fe91b38a..56835148 100755 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ 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 -| └── innerkits # APIs between services +├ └── 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 a48a65ea..bdb45a95 100755 --- a/README_zh.md +++ b/README_zh.md @@ -22,7 +22,7 @@ ├── etc # 组件包含的进程的配置文件 ├── figures # 构架图 ├── interfaces # 组件对外提供的接口代码 -| └── innerkits # 服务间接口 +├ └── innerkits # 服务间接口 │ └── kits # 对应用提供的接口 ├── profile # 组件包含的系统服务的配置文件 └── services # 时间服务实现 diff --git a/services/time_manager/include/time_service_stub.h b/services/time_manager/include/time_service_stub.h index 31436e27..207c46cb 100644 --- a/services/time_manager/include/time_service_stub.h +++ b/services/time_manager/include/time_service_stub.h @@ -19,6 +19,7 @@ #include "iremote_stub.h" #include "time_service_interface.h" #include "itimer_call_back.h" +#include "ipc_skeleton.h" #include namespace OHOS { diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index de2e5c5a..444199b6 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -263,14 +263,12 @@ bool TimeService::DestroyTimer(uint64_t timerId) int32_t TimeService::SetTime(const int64_t time) { -#if 0 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; } -#endif TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}lld.", time); if (time <= 0 || time / 1000LL >= INT_MAX) { TIME_HILOGE(TIME_MODULE_SERVICE, "input param error"); @@ -393,14 +391,12 @@ int TimeService::get_wall_clock_rtc_id() int32_t TimeService::SetTimeZone(const std::string timeZoneId) { -#if 0 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; } -#endif int gmtOffset; struct timezone tz; auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset); diff --git a/services/time_manager/src/time_service_stub.cpp b/services/time_manager/src/time_service_stub.cpp index 046c790e..8e59101e 100644 --- a/services/time_manager/src/time_service_stub.cpp +++ b/services/time_manager/src/time_service_stub.cpp @@ -15,7 +15,7 @@ #include "time_service_stub.h" #include -#include "ipc_skeleton.h" + #include "time_common.h" namespace OHOS { 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 49b4c675..6705f5c6 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -14,7 +14,7 @@ */ #include "timer_test.h" - +#if 0 using namespace testing::ext; using namespace OHOS; using namespace OHOS::MiscServices; @@ -363,3 +363,4 @@ HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0) ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_FALSE(ret); } +#nedif \ No newline at end of file diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 707419c1..ed70a247 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -18,7 +18,6 @@ config("utils_config") { "mock/include", "native/include", "//utils/native/base/include", - "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core/include/bundlemgr/", ] } diff --git a/utils/native/include/time_permission.h b/utils/native/include/time_permission.h index fd46730d..a37c0afc 100644 --- a/utils/native/include/time_permission.h +++ b/utils/native/include/time_permission.h @@ -43,6 +43,6 @@ private: static sptr instance_; static sptr bundleMgrProxy_; }; -} // namespace MiscService +} // namespace MiscServices } // namespace OHOS #endif // TIME_PERMISSION_H diff --git a/utils/native/src/time_permission.cpp b/utils/native/src/time_permission.cpp index 994611d5..85871c3c 100644 --- a/utils/native/src/time_permission.cpp +++ b/utils/native/src/time_permission.cpp @@ -83,5 +83,5 @@ sptr TimePermission::GetBundleManager() return bundleMgrProxy_; } -} // namespace MiscService +} // namespace MiscServices } // namespace OHOS -- Gitee From 699c21a8d34fbfca4c3bfd3efe85a8e9551a81cc Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Tue, 24 Aug 2021 08:24:38 +0800 Subject: [PATCH 10/14] 2021082401 --- services/time_manager/test/unittest/src/time_service_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6705f5c6..619bc174 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -363,4 +363,4 @@ HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0) ret = TimeServiceClient::GetInstance()->StopTimer(timerId1); EXPECT_FALSE(ret); } -#nedif \ No newline at end of file +#endif \ No newline at end of file -- Gitee From b01d3baa62c80123366834317377918596d81154 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Tue, 24 Aug 2021 17:05:08 +0800 Subject: [PATCH 11/14] xuyanjun27@163.com Signed-off-by: guduhanyan --- services/time_manager/src/time_service.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index 444199b6..7770fb77 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -39,7 +39,7 @@ #include #include #include - +#include namespace OHOS { namespace MiscServices { @@ -269,7 +269,8 @@ int32_t TimeService::SetTime(const int64_t time) 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}lld.", time); + //TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}lld.", time); + 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; -- Gitee From 445907098b04fed21fd3a50f34fb0648db86f700 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Tue, 24 Aug 2021 11:44:26 +0000 Subject: [PATCH 12/14] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=20interfaces/?= =?UTF-8?q?kits/js/declaration/api/@ohos.systemtimer.d.ts=20=E4=B8=BA=20in?= =?UTF-8?q?terfaces/kits/js/declaration/api/@ohos.systemTimer.d.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/{@ohos.systemtimer.d.ts => @ohos.systemTimer.d.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename interfaces/kits/js/declaration/api/{@ohos.systemtimer.d.ts => @ohos.systemTimer.d.ts} (100%) diff --git a/interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts b/interfaces/kits/js/declaration/api/@ohos.systemTimer.d.ts similarity index 100% rename from interfaces/kits/js/declaration/api/@ohos.systemtimer.d.ts rename to interfaces/kits/js/declaration/api/@ohos.systemTimer.d.ts -- Gitee From b77ca70cadf90bb7a9b07b17539660ab5dddb7c0 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Wed, 25 Aug 2021 06:38:23 +0800 Subject: [PATCH 13/14] xuyanjun27@163.com Signed-off-by: guduhanyan --- services/BUILD.gn | 28 +++++++++---------- services/time_manager/include/time_service.h | 1 + services/time_manager/src/time_service.cpp | 5 ++-- .../test/unittest/include/timer_test.h | 2 +- services/timer/include/timer_manager.h | 1 + services/timer/src/timer_handler.cpp | 4 +-- services/timer/src/timer_manager.cpp | 12 ++++---- 7 files changed, 26 insertions(+), 27 deletions(-) diff --git a/services/BUILD.gn b/services/BUILD.gn index 8b1ec38b..24584833 100755 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -31,25 +31,23 @@ config("time_service_config") { ohos_shared_library("time_service") { sources = [ - "timer/src/batch.cpp", - "timer/src/timer_handler.cpp", - "timer/src/timer_info.cpp", - "timer/src/timer_manager.cpp", "time_manager/src/itimer_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", + "time_manager/src/time_service.cpp", "time_manager/src/time_service_client.cpp", - "time_manager/src/time_zone_info.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_service.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", - ] + configs = [ "${time_utils_path}:utils_config" ] public_configs = [ "//utils/native/base:utils_config", @@ -57,11 +55,11 @@ ohos_shared_library("time_service") { ] deps = [ + "${time_utils_path}:time_utils", "//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits", "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", - "//utils/native/base:utils", - "${time_utils_path}:time_utils", "//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb", + "//utils/native/base:utils", ] external_deps = [ @@ -78,6 +76,6 @@ ohos_shared_library("time_service") { ] subsystem_name = "miscservices" - + part_name = "time_native" } diff --git a/services/time_manager/include/time_service.h b/services/time_manager/include/time_service.h index fe8d35f6..1439b765 100644 --- a/services/time_manager/include/time_service.h +++ b/services/time_manager/include/time_service.h @@ -26,6 +26,7 @@ #include "time.h" #include "securec.h" #include +#include namespace OHOS { namespace MiscServices { diff --git a/services/time_manager/src/time_service.cpp b/services/time_manager/src/time_service.cpp index 7770fb77..bfa8e5b6 100644 --- a/services/time_manager/src/time_service.cpp +++ b/services/time_manager/src/time_service.cpp @@ -39,7 +39,7 @@ #include #include #include -#include + namespace OHOS { namespace MiscServices { @@ -269,8 +269,7 @@ int32_t TimeService::SetTime(const int64_t time) 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}lld.", time); - TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}" PRId64".", time); + 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; diff --git a/services/time_manager/test/unittest/include/timer_test.h b/services/time_manager/test/unittest/include/timer_test.h index a7199abc..d4a261b3 100644 --- a/services/time_manager/test/unittest/include/timer_test.h +++ b/services/time_manager/test/unittest/include/timer_test.h @@ -24,7 +24,7 @@ #include "time_common.h" #include "time_service_client.h" #include -//#include "timer_test.h" + namespace OHOS{ namespace MiscServices{ class TimerInfoTest : public ITimerInfo { diff --git a/services/timer/include/timer_manager.h b/services/timer/include/timer_manager.h index f7c5dabb..84fbaa8a 100644 --- a/services/timer/include/timer_manager.h +++ b/services/timer/include/timer_manager.h @@ -25,6 +25,7 @@ #include #include "timer_handler.h" #include "batch.h" +#include namespace OHOS{ namespace MiscServices{ diff --git a/services/timer/src/timer_handler.cpp b/services/timer/src/timer_handler.cpp index 66c24c8a..82c053a7 100644 --- a/services/timer/src/timer_handler.cpp +++ b/services/timer/src/timer_handler.cpp @@ -48,14 +48,14 @@ std::shared_ptr TimerHandler::Create() epollfd = epoll_create (fds.size ()); if (epollfd < 0) { - TIME_HILOGE(TIME_MODULE_SERVICE, "epoll_create %{public}d failed: %{public}s", fds.size() ,strerror (errno)); + 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",i ,strerror (errno)); + 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]); diff --git a/services/timer/src/timer_manager.cpp b/services/timer/src/timer_manager.cpp index 09089217..80494460 100644 --- a/services/timer/src/timer_manager.cpp +++ b/services/timer/src/timer_manager.cpp @@ -312,18 +312,18 @@ TimerManager::~TimerManager() bool TimerManager::TriggerTimersLocked(std::vector> &triggerList, std::chrono::steady_clock::time_point nowElapsed) { - TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", alarmBatches_.size()); + 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", alarmBatches_.size()); + 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", alarmBatches_.size()); + 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) { @@ -353,7 +353,7 @@ bool TimerManager::TriggerTimersLocked(std::vector> & void TimerManager::RescheduleKernelTimerLocked() { - TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", alarmBatches_.size()); + 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(); @@ -391,7 +391,7 @@ void TimerManager::InsertAndBatchTimerLocked(std::shared_ptr alarm) { int64_t whichBatch = (alarm->flags & static_cast(STANDALONE)) ? -1 : AttemptCoalesceLocked(alarm->whenElapsed, alarm->maxWhenElapsed); - TIME_HILOGI(TIME_MODULE_SERVICE, "whichBatch= %{public}lld", whichBatch); + TIME_HILOGI(TIME_MODULE_SERVICE, "whichBatch= %{public}" PRId64 "", whichBatch); if (whichBatch < 0) { AddBatchLocked(alarmBatches_, std::make_shared(*alarm)); } else { @@ -411,7 +411,7 @@ int64_t TimerManager::AttemptCoalesceLocked(std::chrono::steady_clock::time_poin if ((item->GetFlags() & static_cast(STANDALONE)) == 0 && item->CanHold(whenElapsed, maxWhen)) { return i; } - ++i; + // ++i; } return -1; } -- Gitee From 1a93ebfbeea4a0b4519d4da9a19ebd8862862434 Mon Sep 17 00:00:00 2001 From: guduhanyan Date: Thu, 26 Aug 2021 06:25:40 +0000 Subject: [PATCH 14/14] =?UTF-8?q?update=20services/time=5Fmanager/test/uni?= =?UTF-8?q?ttest/src/time=5Fservice=5Ftest.cpp.=20time=5Fservice=5Ftest.cp?= =?UTF-8?q?p=E6=96=87=E4=BB=B6=E6=94=BE=E5=BC=80=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/time_manager/test/unittest/src/time_service_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 619bc174..f7d91041 100644 --- a/services/time_manager/test/unittest/src/time_service_test.cpp +++ b/services/time_manager/test/unittest/src/time_service_test.cpp @@ -14,7 +14,6 @@ */ #include "timer_test.h" -#if 0 using namespace testing::ext; using namespace OHOS; using namespace OHOS::MiscServices; @@ -58,6 +57,7 @@ HWTEST_F(TimeServiceTest, SetTime001, TestSize.Level0) EXPECT_TRUE(result); } +#if 0 /** * @tc.name: SetTimeZone001 * @tc.desc: set system time zone. -- Gitee