IssueNo:#I39OPI

Description:定时器功能:L2定时服务能力补齐代码
Sig:SIG_BscSoftSrv
Feature or Bugfix: Feature
Binary Source: No

Signed-off-by: autumn330 <hw.liuwei@huawei.com>
This commit is contained in:
autumn330
2021-08-23 23:39:54 +08:00
committed by LiuWei
parent d88f9bdea2
commit 2d5d665c9f
70 changed files with 6656 additions and 908 deletions
+2 -1
View File
@@ -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",
]
+2 -1
View File
@@ -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
```
+1
View File
@@ -22,6 +22,7 @@
├── etc # 组件包含的进程的配置文件
├── figures # 构架图
├── interfaces # 组件对外提供的接口代码
├ └── innerkits # 服务间接口
│ └── kits # 对应用提供的接口
├── profile # 组件包含的系统服务的配置文件
└── services # 时间服务实现
+1 -1
View File
@@ -11,7 +11,7 @@
"path" : ["/system/bin/sa_main", "/system/profile/time_service.xml"],
"uid" : "system",
"gid" : ["system", "shell"],
"caps" : ["SYS_TIME"]
"caps" : ["SYS_TIME","WAKE_ALARM"]
}
]
}
+1 -1
View File
@@ -17,5 +17,5 @@ service time_service /system/bin/sa_main /system/profile/time_service.xml
class z_core
user system
group system shell
capabilities SYS_TIME
capabilities SYS_TIME WAKE_ALARM
seclabel u:r:time_service:s0
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <mutex>
#include "want_agent.h"
namespace OHOS {
namespace MiscServices {
class ITimerInfo {
public:
ITimerInfo();
~ITimerInfo();
int type;
bool repeat;
uint64_t interval;
std::shared_ptr<OHOS::Notification::WantAgent::WantAgent> wantAgent;
/**
* Indicates the timing policy the timer use, which can be REALTIME or UTC.
*/
const int TIMER_TYPE_REALTIME = 1 << 0;
/**
* Describes whether a timer will wake the device up.
*/
const int TIMER_TYPE_WAKEUP = 1 << 1;
/**
* Describes whether a timer will be delivered precisely at a scheduled time.
*/
const int TIMER_TYPE_EXACT = 1 << 2;
/**
* Indicates whether the timer waking up the system is supported in low-power mode.
*/
const int TIMER_TYPE_IDLE = 1 << 3;
/**
* SetType set timer type
* @para: type: TIMER_TYPE_REALTIME | TIMER_TYPE_WAKEUP
*
*/
virtual void SetType(const int &type) = 0;
/**
* SetRepeat set timer repeat or not
* @para: repeat: bool
*
*/
virtual void SetRepeat(bool repeat) = 0;
/**
* SetInterval set timer repeat interval
* @para: repeat: uint64_t >= 5000ms
*
*/
virtual void SetInterval(const uint64_t &interval) = 0;
virtual void SetWantAgent(std::shared_ptr<OHOS::Notification::WantAgent::WantAgent> wantAgent) = 0;
virtual void OnTrigger() = 0;
};
} // MiscServices
} // OHOS
@@ -0,0 +1,187 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H
#define SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H
#include "refbase.h"
#include "time_service_interface.h"
#include "iremote_object.h"
#include "timer_call_back.h"
#include <mutex>
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<IRemoteObject> &object) override;
private:
DISALLOW_COPY_AND_MOVE(TimeSaDeathRecipient);
};
class TimeServiceClient : public RefBase{
public:
DISALLOW_COPY_AND_MOVE(TimeServiceClient);
static sptr<TimeServiceClient> GetInstance();
/**
* SetTime
*
* @descrition
* @param milliseconds int64_t UTC time in milliseconds.
* @return bool true on success, false on failure.
*/
bool SetTime(const int64_t milliseconds);
/**
* SetTimeZone
*
* @descrition
* @param timeZoneId const std::string time zone. example: "Beijing, China".
* @return bool true on success, false on failure.
*/
bool SetTimeZone(const std::string timeZoneId);
/**
* GetTimeZone
*
* @descpriton
* @return std::string, time zone example: "Beijing, China", if result length == 0 on failed.
*/
std::string GetTimeZone();
/**
* GetWallTimeMs
*
* @descpriton get the wall time(the UTC time from 1970 0H:0M:0S) in milliseconds
* @return int64_t, milliseconds in wall time, ret < 0 on failed.
*/
int64_t GetWallTimeMs();
/**
* GetWallTimeNs
*
* @descpriton get the wall time(the UTC time from 1970 0H:0M:0S) in nanoseconds
* @return int64_t, nanoseconds in wall time, ret < 0 on failed.
*/
int64_t GetWallTimeNs();
/**
* GetBootTimeMs
*
* @descpriton get the time since boot(include time spent in sleep) in milliseconds.
* @return int64_t, milliseconds in boot time, ret < 0 on failed.
*/
int64_t GetBootTimeMs();
/**
* GetBootTimeNs
*
* @descpriton // get the time since boot(include time spent in sleep) in nanoseconds.
* @return int64_t, nanoseconds in boot time, ret < 0 on failed.
*/
int64_t GetBootTimeNs();
/**
* GetMonotonicTimeMs
*
* @descpriton get the time since boot(exclude time spent in sleep) in milliseconds.
* @return int64_t, milliseconds in Monotonic time, ret < 0 on failed.
*/
int64_t GetMonotonicTimeMs();
/**
* GetMonotonicTimeNs
*
* @descpriton get the time since boot(exclude time spent in sleep) in nanoseconds.
* @return int64_t, nanoseconds in Monotonic time, ret < 0 on failed.
*/
int64_t GetMonotonicTimeNs();
/**
* GetThreadTimeMs
*
* @descpriton get the Thread-specific CPU-time in milliseconds.
* @return int64_t, milliseconds in Thread-specific CPU-time, ret < 0 on failed.
*/
int64_t GetThreadTimeMs();
/**
* GetThreadTimeNs
*
* @descpriton get the Thread-specific CPU-time in nanoseconds.
* @return int64_t, nanoseconds in Thread-specific CPU-time, ret < 0 on failed.
*/
int64_t GetThreadTimeNs();
/**
* CreateTimer
*
* @param TimerInfo timer info
* @return uint64_t > 0 on success, == 0 failure.
*/
uint64_t CreateTimer(std::shared_ptr<ITimerInfo> 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<IRemoteObject> &object);
private:
TimeServiceClient();
~TimeServiceClient();
static sptr<ITimeService> ConnectService();
static std::mutex instanceLock_;
static sptr<TimeServiceClient> instance_;
static sptr<ITimeService> timeServiceProxy_;
static sptr<TimeSaDeathRecipient> deathRecipient_;
};
} // MiscServices
} // OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H
+22 -1
View File
@@ -21,9 +21,30 @@ import { AsyncCallback, ErrorCallback } from './basic';
* @since 6
*/
declare namespace systemTime {
// Sets the system time.
/**
* Sets the system time.
* @permission ohos.permission.SET_TIME
* @since 6
*/
function setTime(time : number, callback : AsyncCallback<boolean>) : void;
function setTime(time : number) : Promise<boolean>;
/**
* Sets the system time.
* @permission ohos.permission.SET_TIME
* @since 7
*/
function setDate(date: Date, callback: AsyncCallback<boolean>): void;
function setDate(date: Date): Promise<boolean>;
/**
* Sets the system time zone.
* @permission ohos.permission.SET_TIME_ZONE
* @since 7
*/
function setTimezone(timezone: string, callback: AsyncCallback<boolean>): void;
function setTimezone(timezone: string): Promise<boolean>;
}
export default systemTime;
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AsyncCallback, ErrorCallback } from './basic';
import { WantAgent } from './@ohos.wantAgent';
/**
* Provides js api for systemTimer
*
* @since 7
* @devices phone, tablet, tv, wearable
* @systemapi Hide this for inner system use.
*/
declare namespace systemTimer {
/**
* Indicates the timing policy the timer use, which can be REALTIME or UTC.
*/
const TIMER_TYPE_REALTIME: number;
/**
* Describes whether a timer will wake the device up.
*/
const TIMER_TYPE_WAKEUP: number;
/**
* Describes whether a timer will be delivered precisely at a scheduled time.
*/
const TIMER_TYPE_EXACT: number;
/**
* Indicates whether the timer waking up the system is supported in low-power mode.
*/
const TIMER_TYPE_IDLE: number;
/**
* Creates a timer.
* @since 7
* @Param options Indicates the timer options.
* @Return timer ID.
*
* @systemapi Hide this for inner system use.
*/
function createTimer(options: TimerOptions, callback: AsyncCallback<number>): void;
function createTimer(options: TimerOptions): Promise<number>;
/**
* Starts a timer.
*@since 7
* @Param timer The timer ID.
* @Param triggerTime Indicates the time at which the timer is triggered for the first time, in milliseconds.
* The time will be automatically set to 5000 milliseconds after the current time if the passed
* value is smaller than the current time plus 5000 milliseconds.
* @systemapi Hide this for inner system use.
*/
function startTimer(timer: number, triggerTime: number, callback: AsyncCallback<boolean>): void;
function startTimer(timer: number, triggerTime: number): Promise<boolean>;
/**
* Stops a timer.
* @since 7
* @Param timer The timer ID.
* @systemapi Hide this for inner system use.
*/
function stopTimer(timer: number, callback: AsyncCallback<boolean>): void;
function stopTimer(timer: number): Promise<boolean>;
/**
* Clears a timer.
* @since 7
* @Param timer The timer ID.
* @systemapi Hide this for inner system use.
*/
function destroyTimer(timer: number, callback: AsyncCallback<boolean>): void;
function destroyTimer(timer: number): Promise<boolean>;
interface TimerOptions {
/**
* timer type.
*/
type: number;
/**
* Indicates a repeating timer
*/
repeat: boolean;
/**
* Indicates the interval between two consecutive triggers, in milliseconds.
* The interval will be set to 5000 milliseconds automatically if the passed value is smaller than 5000.
*/
interval?: number;
/**
* Indicates the intent to send when the timer goes off.
*/
wantAgent?: WantAgent;
/**
* Called back when the timer goes off.
*/
callback?: () => void;
}
}
export default systemTimer;
-142
View File
@@ -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 <string>
#include "time_service_manager.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "time_log.h"
#define GET_PARAMS(env, info, num) \
size_t argc = num; \
napi_value argv[num]; \
napi_value thisVar; \
void* data; \
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)
typedef struct _SetTimeAsyncContext {
napi_env env;
napi_async_work work;
int64_t time;
napi_deferred deferred;
napi_ref callbackRef;
int status;
} SetTimeAsyncContext;
static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info)
{
TIME_HILOGI("JSSystemTimeSetTime start");
GET_PARAMS(env, info, 2);
NAPI_ASSERT(env, argc >= 1, "requires 1 parameter");
SetTimeAsyncContext* asyncContext = new SetTimeAsyncContext();
asyncContext->env = env;
for (size_t i = 0; i < argc; i++) {
napi_valuetype valueType;
napi_typeof(env, argv[i], &valueType);
if (i == 0 && valueType == napi_number) {
napi_get_value_int64(env, argv[i], &asyncContext->time);
} else if (i == 1 && valueType == napi_function) {
napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
} else {
delete asyncContext;
NAPI_ASSERT(env, false, "type mismatch");
}
}
napi_value result = nullptr;
if (asyncContext->callbackRef == nullptr) {
napi_create_promise(env, &asyncContext->deferred, &result);
} else {
napi_get_undefined(env, &result);
}
napi_value resource = nullptr;
napi_create_string_utf8(env, "JSSystemTimeSetTime", NAPI_AUTO_LENGTH, &resource);
napi_create_async_work(
env, nullptr, resource,
[](napi_env env, void* data) {
SetTimeAsyncContext* asyncContext = (SetTimeAsyncContext*)data;
bool setTimeResult = OHOS::MiscServices::TimeServiceManager::GetInstance()->SetTime(asyncContext->time);
if (setTimeResult) {
asyncContext->status = 0;
} else {
asyncContext->status = 1;
}
},
[](napi_env env, napi_status status, void* data) {
SetTimeAsyncContext* asyncContext = (SetTimeAsyncContext*)data;
napi_value result[2] = { 0 };
if (!asyncContext->status) {
napi_get_undefined(env, &result[0]);
napi_get_boolean(env, true, &result[1]);
} else {
napi_value message = nullptr;
napi_create_string_utf8(env, "SetTime fail", NAPI_AUTO_LENGTH, &message);
napi_create_error(env, nullptr, message, &result[0]);
napi_get_undefined(env, &result[1]);
}
if (asyncContext->deferred) {
if (!asyncContext->status) {
napi_resolve_deferred(env, asyncContext->deferred, result[1]);
} else {
napi_reject_deferred(env, asyncContext->deferred, result[0]);
}
} else {
napi_value callback = nullptr;
napi_get_reference_value(env, asyncContext->callbackRef, &callback);
// 2 -> result size
napi_call_function(env, nullptr, callback, 2, result, nullptr);
napi_delete_reference(env, asyncContext->callbackRef);
}
napi_delete_async_work(env, asyncContext->work);
delete asyncContext;
},
(void*)asyncContext, &asyncContext->work);
napi_queue_async_work(env, asyncContext->work);
return result;
}
EXTERN_C_START
napi_value SystemTimeExport(napi_env env, napi_value exports)
{
static napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("setTime", JSSystemTimeSetTime)
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;
}
EXTERN_C_END
static napi_module system_time_module = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = SystemTimeExport,
.nm_modname = "systemTime",
.nm_priv = ((void*)0),
.reserved = {0}
};
extern "C" __attribute__((constructor)) void SystemTimeRegister()
{
napi_module_register(&system_time_module);
}
@@ -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",
]
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef N_JS_SYSTEMTIME_H
#define N_JS_SYSTEMTIME_H
#include <string>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "js_native_api.h"
constexpr int RESOLVED = 1;
constexpr int REJECT = 0;
constexpr int NONE_PARAMETER = 0;
constexpr int ONE_PARAMETER = 1;
constexpr int TWO_PARAMETER = 2;
constexpr int THREE_PARAMETER = 3;
constexpr int MAX_TIME_ZONE_ID = 1024;
#define GET_PARAMS(env, info, num) \
size_t argc = num; \
napi_value argv[num]; \
napi_value thisVar; \
void* data; \
napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)
typedef struct AsyncContext {
napi_env env;
napi_async_work work;
int64_t time;
std::string timeZone;
napi_deferred deferred;
napi_ref callbackRef;
int status;
} AsyncContext;
#endif
@@ -0,0 +1,230 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "js_systemtime.h"
#include <string>
#include "time_service_client.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "js_native_api.h"
#include "time_common.h"
#include <initializer_list>
using namespace OHOS::MiscServices;
static napi_value JSSystemTimeSetTime(napi_env env, napi_callback_info info)
{
TIME_HILOGI(TIME_MODULE_JS_NAPI,"JSSystemTimeSetTime start");
GET_PARAMS(env, info, 2);
NAPI_ASSERT(env, argc == ONE_PARAMETER || argc == TWO_PARAMETER, "type mismatch");
AsyncContext* asyncContext = new (std::nothrow)AsyncContext();
asyncContext->env = env;
for (size_t i = 0; i < argc; i++) {
napi_valuetype valueType;
napi_typeof(env, argv[i], &valueType);
if (i == 0 && valueType == napi_number) {
napi_get_value_int64(env, argv[i], &asyncContext->time);
} else if (i == 0 && valueType == napi_object){
bool hasProperty = false;
napi_valuetype resValueType;
NAPI_CALL(env, napi_has_named_property(env, argv[i], "getTime", &hasProperty));
NAPI_ASSERT(env, hasProperty, "type expected.");
napi_value getTimeFunc = nullptr;
napi_get_named_property(env, argv[i], "getTime", &getTimeFunc);
napi_value getTimeResult = nullptr;
napi_call_function(env, argv[i], getTimeFunc, 0, nullptr, &getTimeResult);
NAPI_CALL(env, napi_typeof(env, getTimeResult, &resValueType));
NAPI_ASSERT(env, resValueType == napi_number, "type mismatch");
int64_t dateValue = 0;
napi_get_value_int64(env, getTimeResult, &dateValue);
asyncContext->time = dateValue;
} else if (i == 1 && valueType == napi_function) {
napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
} else {
delete asyncContext;
NAPI_ASSERT(env, false, "type mismatch");
}
}
napi_value result = nullptr;
if (asyncContext->callbackRef == nullptr) {
napi_create_promise(env, &asyncContext->deferred, &result);
} else {
napi_get_undefined(env, &result);
}
napi_value resource = nullptr;
napi_create_string_utf8(env, "JSSystemTimeSetTime", NAPI_AUTO_LENGTH, &resource);
napi_create_async_work(env, nullptr, resource,[](napi_env env, void* data) {
AsyncContext* asyncContext = (AsyncContext*)data;
bool setTimeResult;
setTimeResult = TimeServiceClient::GetInstance()->SetTime(asyncContext->time);
if (setTimeResult) {
asyncContext->status = RESOLVED;
} else {
asyncContext->status = REJECT;
}
},
[](napi_env env, napi_status status, void* data) {
AsyncContext* asyncContext = (AsyncContext*)data;
napi_value result[2] = { 0 };
if (asyncContext->status == RESOLVED) {
napi_get_undefined(env, &result[0]);
napi_get_boolean(env, true, &result[1]);
} else {
napi_value message = nullptr;
napi_create_string_utf8(env, "Set fail", NAPI_AUTO_LENGTH, &message);
napi_create_error(env, nullptr, message, &result[0]);
napi_get_undefined(env, &result[1]);
}
if (asyncContext->deferred) {
if (asyncContext->status == RESOLVED) {
napi_resolve_deferred(env, asyncContext->deferred, result[1]);
} else {
napi_reject_deferred(env, asyncContext->deferred, result[0]);
}
} else {
napi_value callback = nullptr;
napi_get_reference_value(env, asyncContext->callbackRef, &callback);
// 2 -> result size
napi_call_function(env, nullptr, callback, 2, result, nullptr);
napi_delete_reference(env, asyncContext->callbackRef);
}
napi_delete_async_work(env, asyncContext->work);
delete asyncContext;
},
(void*)asyncContext, &asyncContext->work);
napi_queue_async_work(env, asyncContext->work);
return result;
}
static napi_value JSSystemTimeSetTimeZone(napi_env env, napi_callback_info info){
TIME_HILOGI(TIME_MODULE_JS_NAPI,"JSSystemTimeSetTimeZone start");
GET_PARAMS(env, info, 2);
NAPI_ASSERT(env, argc == ONE_PARAMETER || argc == TWO_PARAMETER, "type mismatch");
AsyncContext* asyncContext = new AsyncContext();
asyncContext->env = env;
for (size_t i = 0; i < argc; i++) {
napi_valuetype valueType;
napi_typeof(env, argv[i], &valueType);
if (i == 0 && valueType == napi_string) {
char timeZoneChars[MAX_TIME_ZONE_ID];
size_t timeZoneCharsSize;
if (napi_ok != napi_get_value_string_utf8(env, argv[i], timeZoneChars, MAX_TIME_ZONE_ID-1, &timeZoneCharsSize)){
delete asyncContext;
NAPI_ASSERT(env, false, "input para invalid");
}
std::string timeZoneStr(timeZoneChars, timeZoneCharsSize);
asyncContext->timeZone = timeZoneStr;
} else if (i == 1 && valueType == napi_function) {
napi_create_reference(env, argv[i], 1, &asyncContext->callbackRef);
} else {
delete asyncContext;
NAPI_ASSERT(env, false, "type mismatch");
}
}
napi_value result = nullptr;
if (asyncContext->callbackRef == nullptr) {
napi_create_promise(env, &asyncContext->deferred, &result);
} else {
napi_get_undefined(env, &result);
}
napi_value resource = nullptr;
napi_create_string_utf8(env, "JSSystemTimeSetTimeZone", NAPI_AUTO_LENGTH, &resource);
napi_create_async_work(env, nullptr, resource,
[](napi_env env, void* data) {
AsyncContext* asyncContext = (AsyncContext*)data;
auto setTimeResult = TimeServiceClient::GetInstance()->SetTimeZone(asyncContext->timeZone);
if (setTimeResult) {
asyncContext->status = RESOLVED;
} else {
asyncContext->status = REJECT;
}
},
[](napi_env env, napi_status status, void* data) {
AsyncContext* asyncContext = (AsyncContext*)data;
napi_value result[2] = { 0 };
if (asyncContext->status == RESOLVED) {
napi_get_undefined(env, &result[0]);
napi_get_boolean(env, true, &result[1]);
} else {
napi_value message = nullptr;
napi_create_string_utf8(env, "Set fail", NAPI_AUTO_LENGTH, &message);
napi_create_error(env, nullptr, message, &result[0]);
napi_get_undefined(env, &result[1]);
}
if (asyncContext->deferred) {
if (asyncContext->status == RESOLVED) {
napi_resolve_deferred(env, asyncContext->deferred, result[1]);
} else {
napi_reject_deferred(env, asyncContext->deferred, result[0]);
}
} else {
napi_value callback = nullptr;
napi_get_reference_value(env, asyncContext->callbackRef, &callback);
// 2 -> result size
napi_call_function(env, nullptr, callback, 2, result, nullptr);
napi_delete_reference(env, asyncContext->callbackRef);
}
napi_delete_async_work(env, asyncContext->work);
delete asyncContext;
},
(void*)asyncContext,
&asyncContext->work);
napi_queue_async_work(env, asyncContext->work);
return result;
}
EXTERN_C_START
napi_value SystemTimeExport(napi_env env, napi_value exports)
{
static napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("setTime", JSSystemTimeSetTime),
DECLARE_NAPI_FUNCTION("setDate", JSSystemTimeSetTime),
DECLARE_NAPI_FUNCTION("setTimezone", JSSystemTimeSetTimeZone)
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;
}
EXTERN_C_END
static napi_module system_time_module = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = SystemTimeExport,
.nm_modname = "systemTime",
.nm_priv = ((void*)0),
.reserved = {0}
};
extern "C" __attribute__((constructor)) void SystemTimeRegister()
{
napi_module_register(&system_time_module);
}
@@ -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"
}
@@ -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<OHOS::Notification::WantAgent::WantAgent> 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
@@ -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 <string>
#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
@@ -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
@@ -0,0 +1,747 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <uv.h>
#include <memory>
#include <string>
#include <vector>
#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> 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<AsyncCallbackInfoCreate *> 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<OHOS::Notification::WantAgent::WantAgent> _wantAgent)
{
wantAgent = _wantAgent;
}
napi_value GetTimerOptions(const napi_env &env, const napi_value &value,
std::shared_ptr<ITimerInfoInstance> &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<OHOS::Notification::WantAgent::WantAgent> sWantAgent = std::make_shared<OHOS::Notification::WantAgent::WantAgent>(*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> &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> iTimerInfoInstance = std::make_shared<ITimerInfoInstance>();
napi_ref callback = nullptr;
if (ParseParametersByCreateTimer(env, argv, argc, iTimerInfoInstance, callback) == nullptr) {
return JSParaError(env, callback);
}
AsyncCallbackInfoCreate *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoCreate{.env = env,
.asyncWork = nullptr,
.iTimerInfoInstance = iTimerInfoInstance};
if (!asynccallbackinfo) {
return JSParaError(env, callback);
}
napi_value promise = 0;
PaddingAsyncCallbackInfoIsByCreateTimer(env, asynccallbackinfo, callback, promise);
napi_value resourceName;
napi_create_string_latin1(env, "createTimer", NAPI_AUTO_LENGTH, &resourceName);
// Asynchronous function call
napi_create_async_work(env,
nullptr,
resourceName,
[](napi_env env, void *data) {
AsyncCallbackInfoCreate *asynccallbackinfo = (AsyncCallbackInfoCreate *)data;
asynccallbackinfo->timerId =
TimeServiceClient::GetInstance()->CreateTimer(asynccallbackinfo->iTimerInfoInstance);
if (asynccallbackinfo->timerId > 0){
asyncCallbackInfoCreateInfo.emplace_back(asynccallbackinfo);
}
},
[](napi_env env, napi_status status, void *data) {
AsyncCallbackInfoCreate *asynccallbackinfo = (AsyncCallbackInfoCreate *)data;
CallbackPromiseInfo info;
info.isCallback = asynccallbackinfo->isCallback;
info.callback = asynccallbackinfo->callback;
info.deferred = asynccallbackinfo->deferred;
info.errorCode = asynccallbackinfo->errorCode;
// timerId: number
napi_value result;
napi_create_int64(env, asynccallbackinfo->timerId, &result);
ReturnCallbackPromise(env, info, result);
napi_delete_async_work(env, asynccallbackinfo->asyncWork);
},
(void *)asynccallbackinfo,
&asynccallbackinfo->asyncWork);
NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
if (asynccallbackinfo->isCallback) {
return NapiGetNull(env);
} else {
return promise;
}
}
napi_value ParseParametersByStartTimer(const napi_env &env, const napi_value (&argv)[START_MAX_PARA],
const size_t &argc, uint64_t &uintTimerId, uint64_t &uintTriggerTime, napi_ref &callback)
{
NAPI_ASSERT(env, argc >= START_MAX_PARA - 1, "Wrong number of arguments");
napi_valuetype valuetype;
// argv[0]: timer
NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
int64_t timerId = 0;
napi_get_value_int64(env, argv[0], &timerId);
NAPI_ASSERT(env, timerId >= 0, "Wrong argument timer. Positive number expected.");
uintTimerId = (uint64_t)timerId;
// argv[1]: triggerTime
NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
int64_t triggerTime = 0;
napi_get_value_int64(env, argv[1], &triggerTime);
NAPI_ASSERT(env, triggerTime >= 0, "Wrong argument triggerTime. Positive number expected.");
uintTriggerTime = (uint64_t)triggerTime;
// argv[2]:callback
if (argc >= START_MAX_PARA) {
NAPI_CALL(env, napi_typeof(env, argv[2], &valuetype));
NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected.");
napi_create_reference(env, argv[2], 1, &callback);
}
return NapiGetNull(env);
}
void PaddingAsyncCallbackInfoIsByStartTimer(
const napi_env &env, AsyncCallbackInfoStart *&asynccallbackinfo, const napi_ref &callback, napi_value &promise)
{
if (callback) {
asynccallbackinfo->callback = callback;
asynccallbackinfo->isCallback = true;
} else {
napi_deferred deferred = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
asynccallbackinfo->deferred = deferred;
asynccallbackinfo->isCallback = false;
}
}
napi_value StartTimer(napi_env env, napi_callback_info info)
{
size_t argc = START_MAX_PARA;
napi_value argv[START_MAX_PARA];
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
uint64_t timerId;
uint64_t triggerTime;
napi_ref callback = nullptr;
if (ParseParametersByStartTimer(env, argv, argc, timerId, triggerTime, callback) == nullptr) {
return JSParaError(env, callback);
}
AsyncCallbackInfoStart *asynccallbackinfo = new (std::nothrow)
AsyncCallbackInfoStart{.env = env, .asyncWork = nullptr, .timerId = timerId, .triggerTime = triggerTime};
if (!asynccallbackinfo) {
return JSParaError(env, callback);
}
napi_value promise = 0;
PaddingAsyncCallbackInfoIsByStartTimer(env, asynccallbackinfo, callback, promise);
napi_value resourceName;
napi_create_string_latin1(env, "startTimer", NAPI_AUTO_LENGTH, &resourceName);
// Asynchronous function call
napi_create_async_work(env,
nullptr,
resourceName,
[](napi_env env, void *data) {
AsyncCallbackInfoStart *asynccallbackinfo = (AsyncCallbackInfoStart *)data;
asynccallbackinfo->isOK = TimeServiceClient::GetInstance()->StartTimer(
asynccallbackinfo->timerId, asynccallbackinfo->triggerTime);
},
[](napi_env env, napi_status status, void *data) {
AsyncCallbackInfoStart *asynccallbackinfo = (AsyncCallbackInfoStart *)data;
if (!asynccallbackinfo->isOK) {
asynccallbackinfo->errorCode = ERROR;
}
CallbackPromiseInfo info;
info.isCallback = asynccallbackinfo->isCallback;
info.callback = asynccallbackinfo->callback;
info.deferred = asynccallbackinfo->deferred;
info.errorCode = asynccallbackinfo->errorCode;
// result: bool
napi_value result;
napi_get_boolean(env, asynccallbackinfo->isOK, &result);
ReturnCallbackPromise(env, info, result);
napi_delete_async_work(env, asynccallbackinfo->asyncWork);
if (asynccallbackinfo) {
delete asynccallbackinfo;
asynccallbackinfo = nullptr;
}
},
(void *)asynccallbackinfo,
&asynccallbackinfo->asyncWork);
NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
if (asynccallbackinfo->isCallback) {
return NapiGetNull(env);
} else {
return promise;
}
}
napi_value ParseParametersByStopTimer(const napi_env &env, const napi_value (&argv)[STOP_MAX_PARA], const size_t &argc,
uint64_t &uintTimerId, napi_ref &callback)
{
NAPI_ASSERT(env, argc >= STOP_MAX_PARA - 1, "Wrong number of arguments");
napi_valuetype valuetype;
// argv[0]: timer
NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
int64_t timerId = 0;
napi_get_value_int64(env, argv[0], &timerId);
NAPI_ASSERT(env, timerId >= 0, "Wrong argument timer. Positive number expected.");
uintTimerId = (uint64_t)timerId;
// argv[1]:callback
if (argc >= STOP_MAX_PARA) {
NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype));
NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected.");
napi_create_reference(env, argv[1], 1, &callback);
}
return NapiGetNull(env);
}
void PaddingAsyncCallbackInfoIsByStopTimer(
const napi_env &env, AsyncCallbackInfoStop *&asynccallbackinfo, const napi_ref &callback, napi_value &promise)
{
if (callback) {
asynccallbackinfo->callback = callback;
asynccallbackinfo->isCallback = true;
} else {
napi_deferred deferred = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
asynccallbackinfo->deferred = deferred;
asynccallbackinfo->isCallback = false;
}
}
napi_value StopTimer(napi_env env, napi_callback_info info)
{
size_t argc = STOP_MAX_PARA;
napi_value argv[STOP_MAX_PARA];
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
uint64_t timerId;
napi_ref callback = nullptr;
if (ParseParametersByStopTimer(env, argv, argc, timerId, callback) == nullptr) {
return JSParaError(env, callback);
}
AsyncCallbackInfoStop *asynccallbackinfo =
new (std::nothrow) AsyncCallbackInfoStop{.env = env, .asyncWork = nullptr, .timerId = timerId};
if (!asynccallbackinfo) {
return JSParaError(env, callback);
}
napi_value promise = 0;
PaddingAsyncCallbackInfoIsByStopTimer(env, asynccallbackinfo, callback, promise);
napi_value resourceName;
napi_create_string_latin1(env, "stopTimer", NAPI_AUTO_LENGTH, &resourceName);
// Asynchronous function call
napi_create_async_work(env,
nullptr,
resourceName,
[](napi_env env, void *data) {
AsyncCallbackInfoStop *asynccallbackinfo = (AsyncCallbackInfoStop *)data;
asynccallbackinfo->isOK = TimeServiceClient::GetInstance()->StopTimer(asynccallbackinfo->timerId);
},
[](napi_env env, napi_status status, void *data) {
AsyncCallbackInfoStop *asynccallbackinfo = (AsyncCallbackInfoStop *)data;
if (!asynccallbackinfo->isOK) {
asynccallbackinfo->errorCode = ERROR;
}
CallbackPromiseInfo info;
info.isCallback = asynccallbackinfo->isCallback;
info.callback = asynccallbackinfo->callback;
info.deferred = asynccallbackinfo->deferred;
info.errorCode = asynccallbackinfo->errorCode;
// result: bool
napi_value result;
napi_get_boolean(env, asynccallbackinfo->isOK, &result);
ReturnCallbackPromise(env, info, result);
napi_delete_async_work(env, asynccallbackinfo->asyncWork);
if (asynccallbackinfo) {
delete asynccallbackinfo;
asynccallbackinfo = nullptr;
}
},
(void *)asynccallbackinfo,
&asynccallbackinfo->asyncWork);
NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
if (asynccallbackinfo->isCallback) {
return NapiGetNull(env);
} else {
return promise;
}
}
napi_value ParseParametersByDestroyTimer(const napi_env &env, const napi_value (&argv)[DESTROY_MAX_PARA],
const size_t &argc, uint64_t &uintTimerId, napi_ref &callback)
{
NAPI_ASSERT(env, argc >= DESTROY_MAX_PARA - 1, "Wrong number of arguments");
napi_valuetype valuetype;
// argv[0]: timer
NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
NAPI_ASSERT(env, valuetype == napi_number, "Wrong argument type. Number expected.");
int64_t timerId = 0;
napi_get_value_int64(env, argv[0], &timerId);
NAPI_ASSERT(env, timerId >= 0, "Wrong argument timer. Positive number expected.");
uintTimerId = (uint64_t)timerId;
// argv[1]:callback
if (argc >= DESTROY_MAX_PARA) {
NAPI_CALL(env, napi_typeof(env, argv[1], &valuetype));
NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected.");
napi_create_reference(env, argv[1], 1, &callback);
}
return NapiGetNull(env);
}
void PaddingAsyncCallbackInfoIsByDestroyTimer(
const napi_env &env, AsyncCallbackInfoDestroy *&asynccallbackinfo, const napi_ref &callback, napi_value &promise)
{
if (callback) {
asynccallbackinfo->callback = callback;
asynccallbackinfo->isCallback = true;
} else {
napi_deferred deferred = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
asynccallbackinfo->deferred = deferred;
asynccallbackinfo->isCallback = false;
}
}
napi_value DestroyTimer(napi_env env, napi_callback_info info)
{
size_t argc = DESTROY_MAX_PARA;
napi_value argv[DESTROY_MAX_PARA];
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
uint64_t timerId;
napi_ref callback = nullptr;
if (ParseParametersByDestroyTimer(env, argv, argc, timerId, callback) == nullptr) {
return JSParaError(env, callback);
}
AsyncCallbackInfoDestroy *asynccallbackinfo =
new (std::nothrow) AsyncCallbackInfoDestroy{.env = env, .asyncWork = nullptr, .timerId = timerId};
if (!asynccallbackinfo) {
return JSParaError(env, callback);
}
napi_value promise = 0;
PaddingAsyncCallbackInfoIsByDestroyTimer(env, asynccallbackinfo, callback, promise);
napi_value resourceName;
napi_create_string_latin1(env, "destroyTimer", NAPI_AUTO_LENGTH, &resourceName);
// Asynchronous function call
napi_create_async_work(env,
nullptr,
resourceName,
[](napi_env env, void *data) {
AsyncCallbackInfoDestroy *asynccallbackinfo = (AsyncCallbackInfoDestroy *)data;
asynccallbackinfo->isOK = TimeServiceClient::GetInstance()->DestroyTimer(asynccallbackinfo->timerId);
},
[](napi_env env, napi_status status, void *data) {
AsyncCallbackInfoDestroy *asynccallbackinfo = (AsyncCallbackInfoDestroy *)data;
if (asynccallbackinfo->isOK) {
for (auto it = asyncCallbackInfoCreateInfo.begin(); it != asyncCallbackInfoCreateInfo.end(); it++) {
if ((*it)->timerId == asynccallbackinfo->timerId) {
it = asyncCallbackInfoCreateInfo.erase(it);
delete (*it);
*it = nullptr;
}
}
} else {
asynccallbackinfo->errorCode = ERROR;
}
CallbackPromiseInfo info;
info.isCallback = asynccallbackinfo->isCallback;
info.callback = asynccallbackinfo->callback;
info.deferred = asynccallbackinfo->deferred;
info.errorCode = asynccallbackinfo->errorCode;
// result: bool
napi_value result;
napi_get_boolean(env, asynccallbackinfo->isOK, &result);
ReturnCallbackPromise(env, info, result);
napi_delete_async_work(env, asynccallbackinfo->asyncWork);
if (asynccallbackinfo) {
delete asynccallbackinfo;
asynccallbackinfo = nullptr;
}
},
(void *)asynccallbackinfo,
&asynccallbackinfo->asyncWork);
NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
if (asynccallbackinfo->isCallback) {
return NapiGetNull(env);
} else {
return promise;
}
}
napi_value SystemtimerInit(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("createTimer", CreateTimer),
DECLARE_NAPI_FUNCTION("startTimer", StartTimer),
DECLARE_NAPI_FUNCTION("stopTimer", StopTimer),
DECLARE_NAPI_FUNCTION("destroyTimer", DestroyTimer),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
OHOS::MiscServicesNapi::TimerTypeInit(env, exports);
return exports;
}
} // namespace MiscServicesNapi
} // namespace OHOS
@@ -0,0 +1,45 @@
/*
* Copyright (c); 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer_type.h"
namespace OHOS {
namespace MiscServicesNapi {
void SetNamedPropertyByInteger(napi_env env, napi_value dstObj, int32_t objName, const char *propName)
{
napi_value prop = nullptr;
if (napi_create_int32(env, objName, &prop) == napi_ok) {
napi_set_named_property(env, dstObj, propName, prop);
}
}
napi_value TimerTypeInit(napi_env env, napi_value exports)
{
napi_value obj = nullptr;
napi_create_object(env, &obj);
SetNamedPropertyByInteger(env, obj, 1 << 0, "TIMER_TYPE_REALTIME");
SetNamedPropertyByInteger(env, obj, 1 << 1, "TIMER_TYPE_WAKEUP");
SetNamedPropertyByInteger(env, obj, 1 << 2, "TIMER_TYPE_EXACT");
SetNamedPropertyByInteger(env, obj, 1 << 3, "TIMER_TYPE_IDLE");
napi_property_descriptor exportFuncs[] = {DECLARE_NAPI_PROPERTY("systemTimer", obj)};
napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
return exports;
}
} // namespace MiscServicesNapi
} // namespace OHOS
+1 -1
View File
@@ -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"
]
}
}
+38 -10
View File
@@ -12,39 +12,67 @@
# limitations under the License.
import("//base/miscservices/time/time.gni")
import("//build/ohos.gni")
config("time_service_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//base/miscservices/time/interfaces/innerkits/include",
"../utils/native/include",
"time_manager/include",
"timer/include",
"//utils/system/safwk/native/include",
"//third_party/json/include",
"//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb/include/",
"/foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk/include/",
]
cflags_cc = [ "-fexceptions" ]
}
ohos_shared_library("time_service") {
sources = [
"src/time_service.cpp",
"src/time_service_manager.cpp",
"src/time_service_proxy.cpp",
"src/time_service_stub.cpp",
"time_manager/src/itimer_info.cpp",
"time_manager/src/time_service.cpp",
"time_manager/src/time_service_client.cpp",
"time_manager/src/time_service_notify.cpp",
"time_manager/src/time_service_proxy.cpp",
"time_manager/src/time_service_stub.cpp",
"time_manager/src/time_zone_info.cpp",
"time_manager/src/timer_call_back.cpp",
"time_manager/src/timer_call_back_proxy.cpp",
"time_manager/src/timer_call_back_stub.cpp",
"timer/src/batch.cpp",
"timer/src/timer_handler.cpp",
"timer/src/timer_info.cpp",
"timer/src/timer_manager.cpp",
]
configs = [ "${time_utils_path}:utils_config" ]
public_configs = [
"//utils/native/base:utils_config",
":time_service_config",
]
deps = [
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"${time_utils_path}:time_utils",
"//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits",
"//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk:native_appdatafwk",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_preferences:native_preferences",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb",
"//utils/native/base:utils",
]
external_deps = [
"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"
-76
View File
@@ -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 <cstdint>
#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
-60
View File
@@ -1,60 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICES_H
#define SERVICES_INCLUDE_TIME_SERVICES_H
#include <mutex>
#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<TimeService> 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<TimeService> instance_;
static std::shared_ptr<AppExecFwk::EventHandler> serviceHandler_;
};
} // MiscServices
} // OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICES_H
-51
View File
@@ -1,51 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H
#define SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H
#include "refbase.h"
#include "time_service_stub.h"
#include "iremote_object.h"
namespace OHOS {
namespace MiscServices {
class TimeSaDeathRecipient : public IRemoteObject::DeathRecipient {
public:
explicit TimeSaDeathRecipient();
~TimeSaDeathRecipient() = default;
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
class TimeServiceManager : public RefBase {
public:
TimeServiceManager();
~TimeServiceManager();
static sptr<TimeServiceManager> GetInstance();
bool SetTime(const int64_t time);
void OnRemoteSaDied(const wptr<IRemoteObject> &object);
private:
static sptr<ITimeService> GetTimeServiceProxy();
static std::mutex instanceLock_;
static sptr<TimeServiceManager> instance_;
static sptr<ITimeService> timeServiceProxy_;
static sptr<TimeSaDeathRecipient> deathRecipient_;
};
} // MiscServices
} // OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICES_MANAGER_H
-142
View File
@@ -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 <string>
#include <unistd.h>
#include <sys/time.h>
#include <cerrno>
#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> TimeService::instance_;
std::shared_ptr<AppExecFwk::EventHandler> 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> TimeService::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> 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<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("TimeService");
serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
TIME_HILOGI("InitServiceHandler succeeded.");
}
bool TimeService::SetTime(const int64_t time)
{
TIME_HILOGI("Setting time of day to milliseconds");
if (time <= 0 || time / 1000LL >= INT_MAX) {
TIME_HILOGE("SetTime input param error");
return false;
}
struct timeval tv;
tv.tv_sec = (time_t) (time / 1000LL);
tv.tv_usec = (suseconds_t) ((time % 1000LL) * 1000LL);
int result = settimeofday(&tv, NULL);
if (result < 0) {
TIME_HILOGE("settimeofday fail: %{public}s", strerror(errno));
return false;
}
return true;
}
} // namespace MiscServices
} // namespace OHOS
-103
View File
@@ -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 <cinttypes>
#include "system_ability_definition.h"
#include "iservice_registry.h"
#include "time_log.h"
namespace OHOS {
namespace MiscServices {
std::mutex TimeServiceManager::instanceLock_;
sptr<TimeServiceManager> TimeServiceManager::instance_;
sptr<ITimeService> TimeServiceManager::timeServiceProxy_;
sptr<TimeSaDeathRecipient> TimeServiceManager::deathRecipient_;
TimeServiceManager::TimeServiceManager()
{
}
TimeServiceManager::~TimeServiceManager(){}
sptr<TimeServiceManager> TimeServiceManager::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> 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<ITimeService> TimeServiceManager::GetTimeServiceProxy()
{
sptr<ISystemAbilityManager> 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<ITimeService> timeServiceProxy = iface_cast<ITimeService>(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<IRemoteObject> &remote)
{
timeServiceProxy_ = GetTimeServiceProxy();
}
TimeSaDeathRecipient::TimeSaDeathRecipient()
{
}
void TimeSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
TIME_HILOGE("TimeSaDeathRecipient on remote systemAbility died.");
TimeServiceManager::GetInstance()->OnRemoteSaDied(object);
}
} // namespace MiscServices
} // namespace OHOS
-46
View File
@@ -1,46 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_service_proxy.h"
#include "iremote_broker.h"
#include "time_log.h"
#include "time_common.h"
namespace OHOS {
namespace MiscServices {
using namespace OHOS::HiviewDFX;
TimeServiceProxy::TimeServiceProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<ITimeService>(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
-60
View File
@@ -1,60 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_service_stub.h"
#include <cinttypes>
#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
@@ -1,59 +0,0 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
#include <sys/time.h>
#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);
}
@@ -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
@@ -0,0 +1,100 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICES_H
#define SERVICES_INCLUDE_TIME_SERVICES_H
#include "time_service_stub.h"
#include "time_service_notify.h"
#include "time_rdb_handler.h"
#include "timer_manager.h"
#include "time_permission.h"
#include "system_ability.h"
#include "event_handler.h"
#include "time.h"
#include "securec.h"
#include <mutex>
#include <inttypes.h>
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<TimeService> 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(int32_t type, bool repeat, uint64_t interval, sptr<IRemoteObject> &timerCallback) override;
bool StartTimer(uint64_t timerId, uint64_t triggerTime) override;
bool StopTimer(uint64_t timerId) override;
bool DestroyTimer(uint64_t timerId) override;
protected:
void OnStart() override;
void OnStop() override;
private:
int32_t Init();
void InitServiceHandler();
void InitNotifyHandler();
void InitTimeZone();
void InitTimerHandler();
bool GetTimeByClockid(clockid_t clockID, struct timespec* tv);
int set_rtc_time(time_t sec);
bool check_rtc(std::string rtc_path, uint32_t rtc_id);
int get_wall_clock_rtc_id();
ServiceRunningState state_;
static std::mutex instanceLock_;
static sptr<TimeService> 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<MiscServices::TimeServiceNotify> timeServiceNotify_;
static std::shared_ptr<AppExecFwk::EventHandler> serviceHandler_;
static std::shared_ptr<TimerManager> timerManagerHandler_;
};
} // MiscServices
} // OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICES_H
@@ -0,0 +1,174 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H
#define SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H
#include "iremote_broker.h"
#include "want_agent.h"
namespace OHOS {
namespace MiscServices {
class ITimeService : public IRemoteBroker {
public:
// remote method code
enum {
SET_TIME = 0,
SET_TIME_ZONE = 1,
GET_TIME_ZONE = 2,
GET_WALL_TIME_MILLI = 3,
GET_WALL_TIME_NANO = 4,
GET_BOOT_TIME_MILLI = 5,
GET_BOOT_TIME_NANO = 6,
GET_MONO_TIME_MILLI = 7,
GET_MONO_TIME_NANO = 8,
GET_THREAD_TIME_MILLI = 9,
GET_THREAD_TIME_NANO = 10,
CREATE_TIMER = 11,
START_TIMER = 12,
STOP_TIMER = 13,
DESTORY_TIMER = 14
};
/**
* SetTime
*
* @param time int64_t set milliseconds
* @return int32_t ERR_OK on success, other on failure.
*/
virtual int32_t SetTime(const int64_t time) = 0;
/**
* SetTimeZone
*
* @param timezoneId std::string &timezoneId string
* @return int32_t ERR_OK on success, other on failure.
*/
virtual int32_t SetTimeZone(const std::string timezoneId) = 0;
/**
* GetTimeZone
*
* @param timezoneId std::string &timezoneId string
* @return int32_t ERR_OK on success, other on failure.
*/
virtual int32_t GetTimeZone(std::string &timezoneId) = 0;
/**
* GetWallTimeMs
*
* @param times result of times ,unit: millisecond
* @return int32_t ERR_OK on success, other on failure.
*/
virtual int32_t GetWallTimeMs(int64_t &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 type timer type
* @param repeat is repeat or not
* @param timerCallback remoteobject
* @return uint64_t > 0 on success, == 0 failure.
*/
virtual uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr<IRemoteObject> &timerCallback) = 0;
/**
* StartTimer
*
* @param timerId indicate timerId
* @param treggerTime trigger times
* @return bool true on success, false on failure.
*/
virtual bool StartTimer(uint64_t timerId, uint64_t treggerTime) = 0;
/**
* StopTimer
*
* @param timerId indicate timerId
* @return bool true on success, false on failure.
*/
virtual bool StopTimer(uint64_t timerId) = 0;
/**
* DestroyTimer
*
* @param timerId indicate timerId
* @return bool true on success, false on failure.
*/
virtual bool DestroyTimer(uint64_t timerId) = 0;
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimeService");
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIME_SERVICE_NOTIFY_H
#define TIME_SERVICE_NOTIFY_H
#include <common_event_publish_info.h>
#include <ohos/aafwk/content/want.h>
#include "time_common.h"
namespace OHOS {
namespace MiscServices {
class TimeServiceNotify {
public:
TimeServiceNotify() = default;
~TimeServiceNotify() = default;
void RegisterPublishEvents();
void PublishTimeChanageEvents(int64_t eventTime);
void PublishTimeZoneChangeEvents(int64_t eventTime);
private:
using IntentWant = OHOS::AAFwk::Want;
void PublishEvents(int64_t eventTime, sptr<IntentWant> intent);
sptr<IntentWant> timeChangeWant_;
sptr<IntentWant> timeZoneChangeWant_;
sptr<OHOS::EventFwk::CommonEventPublishInfo> publishInfo_;
};
} // namespace MiscServices
} // namespace OHOS
#endif // TIME_SERVICE_NOTIFY_H
@@ -1,36 +1,51 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICE_PROXY_H
#define SERVICES_INCLUDE_TIME_SERVICE_PROXY_H
#include "iremote_proxy.h"
#include "time_service_interface.h"
namespace OHOS {
namespace MiscServices {
class TimeServiceProxy : public IRemoteProxy<ITimeService> {
public:
explicit TimeServiceProxy(const sptr<IRemoteObject> &object);
~TimeServiceProxy() = default;
DISALLOW_COPY_AND_MOVE(TimeServiceProxy);
bool SetTime(const int64_t time) override;
private:
static inline BrokerDelegator<TimeServiceProxy> 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<ITimeService> {
public:
explicit TimeServiceProxy(const sptr<IRemoteObject> &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(int32_t type, bool repeat, uint64_t interval, sptr<IRemoteObject> &timerCallback) override;
bool StartTimer(uint64_t timerId, uint64_t treggerTime) override;
bool StopTimer(uint64_t timerId) override;
bool DestroyTimer(uint64_t timerId) override;
private:
static inline BrokerDelegator<TimeServiceProxy> delegator_;
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICE_PROXY_H
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICE_STUB_H
#define SERVICES_INCLUDE_TIME_SERVICE_STUB_H
#include "iremote_stub.h"
#include "time_service_interface.h"
#include "itimer_call_back.h"
#include "ipc_skeleton.h"
#include <map>
namespace OHOS {
namespace MiscServices {
class TimeServiceStub : public IRemoteStub<ITimeService> {
public:
TimeServiceStub();
~TimeServiceStub();
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
private:
using TimeServiceFunc = int32_t (TimeServiceStub::*)(MessageParcel &data, MessageParcel &reply);
int32_t OnSetTime(MessageParcel &data, MessageParcel &reply);
int32_t OnSetTimeZone(MessageParcel &data, MessageParcel &reply);
int32_t OnGetTimeZone(MessageParcel &data, MessageParcel &reply);
int32_t OnGetWallTimeMs(MessageParcel &data, MessageParcel &reply);
int32_t OnGetWallTimeNs(MessageParcel &data, MessageParcel &reply);
int32_t OnGetBootTimeMs(MessageParcel &data, MessageParcel &reply);
int32_t OnGetBootTimeNs(MessageParcel &data, MessageParcel &reply);
int32_t OnGetMonotonicTimeMs(MessageParcel &data, MessageParcel &reply);
int32_t OnGetMonotonicTimeNs(MessageParcel &data, MessageParcel &reply);
int32_t OnGetThreadTimeMs(MessageParcel &data, MessageParcel &reply);
int32_t OnGetThreadTimeNs(MessageParcel &data, MessageParcel &reply);
int32_t OnCreateTimer(MessageParcel &data, MessageParcel &reply);
int32_t OnStartTimer(MessageParcel &data, MessageParcel &reply);
int32_t OnStopTimer(MessageParcel &data, MessageParcel &reply);
int32_t OnDestoryTimer(MessageParcel &data, MessageParcel &reply);
std::map<uint32_t, TimeServiceFunc> memberFuncMap_;
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICE_STUB_H
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_ZONE_INFO_H
#define SERVICES_INCLUDE_TIME_ZONE_INFO_H
#include <map>
#include <mutex>
#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<TimeZoneInfo> GetInstance();
void Init();
int32_t GetOffset(const std::string timezoneId, int &offset);
int32_t GetTimezoneId(std::string &timezoneId);
private:
std::string curTimezoneId_;
int32_t lastOffset_;
static std::mutex instanceLock_;
static sptr<TimeZoneInfo> instance_;
std::map<std::string, struct zoneInfoEntry> timezoneInfoMap_;
};
} // MiscServices
} // OHOS
#endif // SERVICES_INCLUDE_TIME_ZONE_INFO_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 <mutex>
#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<TimerCallback> 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<ITimerInfo> &timerInfo);
bool RemoveTimerCallbackInfo(const uint64_t timerId);
private:
TimerCallback();
~TimerCallback();
static std::mutex instanceLock_;
static sptr<TimerCallback> instance_;
static std::map<uint64_t, std::shared_ptr<ITimerInfo>> TimerInfoMap_;
static std::mutex timerInfoMutex_;
};
} // namespace MiscServices
} // namespace OHOS
#endif // TIMER_CALL_BACK_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 <iremote_proxy.h>
#include <nocopyable.h>
#include "itimer_call_back.h"
#include "time_common.h"
#include <inttypes.h>
namespace OHOS {
namespace MiscServices {
class TimerCallbackProxy : public IRemoteProxy<ITimerCallback> {
public:
explicit TimerCallbackProxy(const sptr<IRemoteObject>& impl);
~TimerCallbackProxy();
DISALLOW_COPY_AND_MOVE(TimerCallbackProxy);
virtual void NotifyTimer(uint64_t timerId) override;
private:
static inline BrokerDelegator<TimerCallbackProxy> delegator_;
};
} // namespace PowerMgr
} // namespace OHOS
#endif // TIMER_CALL_BACK_PROXY_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 <iremote_stub.h>
#include <nocopyable.h>
#include "time_common.h"
#include "itimer_call_back.h"
#include <inttypes.h>
namespace OHOS {
namespace MiscServices {
class TimerCallbackStub : public IRemoteStub<ITimerCallback> {
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
@@ -1,34 +1,32 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H
#define SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H
#include "iremote_broker.h"
namespace OHOS {
namespace MiscServices {
class ITimeService : public IRemoteBroker {
public:
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.time.ITimeService");
virtual bool SetTime(const int64_t time) = 0;
};
enum {
SET_TIME = 0
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_TIME_SERVICE_INTERFACE_H
/*
* 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
+611
View File
@@ -0,0 +1,611 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_service.h"
#include "time_zone_info.h"
#include "time_common.h"
#include "system_ability.h"
#include "system_ability_definition.h"
#include "iservice_registry.h"
#include <time.h>
#include <stdio.h>
#include <string>
#include <unistd.h>
#include <sys/time.h>
#include <cerrno>
#include "pthread.h"
#include <mutex>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include <dirent.h>
#include <string.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fstream>
#include <sstream>
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> TimeService::instance_;
std::shared_ptr<AppExecFwk::EventHandler> TimeService::serviceHandler_ = nullptr;
std::shared_ptr<MiscServices::TimeServiceNotify> TimeService::timeServiceNotify_ = nullptr;
std::shared_ptr<TimerManager> TimeService::timerManagerHandler_ = nullptr;
TimeService::TimeService(int32_t systemAbilityId, bool runOnCreate)
: SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START), rtc_id(get_wall_clock_rtc_id())
{
TIME_HILOGI(TIME_MODULE_SERVICE," TimeService Start.");
}
TimeService::TimeService() : state_(ServiceRunningState::STATE_NOT_START), rtc_id(get_wall_clock_rtc_id())
{
//TODO : Read time zone information from the global and set to kernel;
}
TimeService::~TimeService()
{
}
sptr<TimeService> TimeService::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
instance_ = new TimeService;
}
}
return instance_;
}
void TimeService::OnStart()
{
TIME_HILOGI(TIME_MODULE_SERVICE," TimeService OnStart.");
if (state_ == ServiceRunningState::STATE_RUNNING) {
TIME_HILOGE(TIME_MODULE_SERVICE," TimeService is already running.");
return;
}
InitServiceHandler();
InitTimerHandler();
InitNotifyHandler();
if (Init() != ERR_OK) {
auto callback = [=]() { Init(); };
serviceHandler_->PostTask(callback, INIT_INTERVAL);
TIME_HILOGE(TIME_MODULE_SERVICE,"Init failed. Try again 10s later.");
return;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Start TimeService success.");
return;
}
int32_t TimeService::Init()
{
bool ret = Publish(TimeService::GetInstance());
if (!ret) {
TIME_HILOGE(TIME_MODULE_SERVICE,"Init Failed.");
return E_TIME_PUBLISH_FAIL;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Init Success.");
state_ = ServiceRunningState::STATE_RUNNING;
return ERR_OK;
}
void TimeService::OnStop()
{
TIME_HILOGI(TIME_MODULE_SERVICE,"OnStop Started.");
if (state_ != ServiceRunningState::STATE_RUNNING) {
return;
}
serviceHandler_ = nullptr;
timeServiceNotify_ = nullptr;
state_ = ServiceRunningState::STATE_NOT_START;
TIME_HILOGI(TIME_MODULE_SERVICE,"OnStop End.");
}
void TimeService::InitTimeZone(){
TIME_HILOGD(TIME_MODULE_SERVICE,"start");
std::string timeZoneId;
auto hasTimeZone = GetTimeZoneId(timeZoneId);
if (!hasTimeZone){
TIME_HILOGE(TIME_MODULE_SERVICE,"Time Zone Not Found.");
return;
}
int gmtOffset;
struct timezone tz;
TIME_HILOGD(TIME_MODULE_SERVICE,"timezone id: %{public}s.", timeZoneId.c_str());
auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset);
TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone offset: %{public}d.", gmtOffset);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret);
}
tz.tz_minuteswest = gmtOffset * 60;
tz.tz_dsttime = 0;
int result = settimeofday(NULL, &tz);
if (result < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result);
}
}
void TimeService::InitNotifyHandler(){
TIME_HILOGI(TIME_MODULE_SERVICE,"InitNotify started.");
if (timeServiceNotify_ != nullptr) {
TIME_HILOGE(TIME_MODULE_SERVICE," Already init.");
return;
}
timeServiceNotify_ = std::make_shared<MiscServices::TimeServiceNotify>();
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<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(TIME_SERVICE_NAME);
serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
TIME_HILOGI(TIME_MODULE_SERVICE,"InitServiceHandler Succeeded.");
}
void TimeService::InitTimerHandler(){
TIME_HILOGI(TIME_MODULE_SERVICE,"Init Timer started.");
if (timerManagerHandler_ != nullptr) {
TIME_HILOGE(TIME_MODULE_SERVICE," Already init.");
return;
}
timerManagerHandler_ = TimerManager::Create();
}
uint64_t TimeService::CreateTimer(int32_t type, bool repeat, uint64_t interval,
sptr<IRemoteObject> &obj)
{
if (obj == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Input nullptr.");
return 0;
}
auto isRealtime = false;
auto isWakeup = false;
int timerType;
int64_t windowLength;
uint64_t intervalOut;
int flag = 0;
if ((type & TIMER_TYPE_REALTIME_MASK) > 0 ){
isRealtime = true;
}
if ((type & TIMER_TYPE_REALTIME_WAKEUP_MASK) > 0 ){
isWakeup = true;
}
if ((type & TIMER_TYPE_EXACT_MASK) > 0){
windowLength = 0;
}else{
windowLength = -1;
}
if (isRealtime && isWakeup){
timerType = 2; // ELAPSED_REALTIME_WAKEUP = 2
}else if (isRealtime){
timerType = 3; // ELAPSED_REALTIME = 3
}else if (isWakeup){
timerType = 0; // RTC_WAKEUP = 0
}else{
timerType = 1; // RTC = 1
}
if (repeat){
intervalOut = (interval < 5000) ? 5000 : interval;
}else{
intervalOut = 0;
}
sptr<ITimerCallback> timerCallback = iface_cast<ITimerCallback>(obj);
if (timerCallback == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"ITimerCallback nullptr.");
return 0;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Start create timer.");
auto callbackFunc = [timerCallback](uint64_t id){
timerCallback->NotifyTimer(id);
};
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr.");
timerManagerHandler_ = TimerManager::Create();
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed.");
return 0;
}
}
return timerManagerHandler_->CreateTimer(timerType, windowLength, intervalOut, flag, callbackFunc, 0);
}
bool TimeService::StartTimer(uint64_t timerId, uint64_t triggerTimes)
{
uint64_t triggerTimesIn;
triggerTimesIn = (triggerTimes < 5000) ? 5000 : triggerTimes;
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr.");
timerManagerHandler_ = TimerManager::Create();
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed.");
return 0;
}
}
auto ret = timerManagerHandler_->StartTimer(timerId, triggerTimesIn);
if (!ret){
TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found.");
}
return ret;
}
bool TimeService::StopTimer(uint64_t timerId)
{
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr.");
timerManagerHandler_ = TimerManager::Create();
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed.");
return 0;
}
}
auto ret = timerManagerHandler_->StopTimer(timerId);
if (!ret){
TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found.");
}
return ret;
}
bool TimeService::DestroyTimer(uint64_t timerId)
{
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Timer manager nullptr.");
timerManagerHandler_ = TimerManager::Create();
if (timerManagerHandler_ == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Redo Timer manager Init Failed.");
return 0;
}
}
auto ret = timerManagerHandler_->DestroyTimer(timerId);
if (!ret){
TIME_HILOGE(TIME_MODULE_SERVICE,"TimerId Not found.");
}
return ret;
}
int32_t TimeService::SetTime(const int64_t time)
{
pid_t uid = IPCSkeleton::GetCallingUid();
auto hasPerm = TimePermission::GetInstance()->CheckCallingPermission(uid, setTimePermName_);
if (!hasPerm){
TIME_HILOGE(TIME_MODULE_SERVICE, "Permission check failed, uid : %{public}d", uid);
return E_TIME_NO_PERMISSION;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Setting time of day to milliseconds: %{public}" PRId64 "", time);
if (time < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE, "input param error");
return E_TIME_PARAMETERS_INVALID;
}
struct timeval tv{};
tv.tv_sec = (time_t) (time / MILLI_TO_BASE);
tv.tv_usec = (suseconds_t) ((time % MILLI_TO_BASE) * MILLI_TO_MICR);
int result = settimeofday(&tv, NULL);
if (result < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result);
return E_TIME_DEAL_FAILED;
}
auto ret = set_rtc_time(tv.tv_sec);
if (ret < 0){
TIME_HILOGE(TIME_MODULE_SERVICE,"set rtc fail: %{public}d.", ret);
return E_TIME_SET_RTC_FAILED;
}
int64_t currentTime = 0;
GetWallTimeMs(currentTime);
if (timeServiceNotify_ != nullptr){
timeServiceNotify_->PublishTimeChanageEvents(currentTime);
}
return ERR_OK;
}
int TimeService::set_rtc_time(time_t sec){
struct rtc_time rtc{};
struct tm tm{};
struct tm *gmtime_res = nullptr;
int fd = 0;
int res;
if (rtc_id < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE,"invalid rtc id: %{public}s:", strerror(ENODEV));
return -1;
}
std::stringstream strs;
strs << "/dev/rtc" << rtc_id;
auto rtc_dev = strs.str();
TIME_HILOGI(TIME_MODULE_SERVICE,"rtc_dev : %{public}s:", rtc_dev.data());
fd = open(rtc_dev.data(), O_RDWR);
if (fd < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE,"open failed %{public}s: %{public}s", rtc_dev.data(), strerror(errno));
return -1;
}
gmtime_res = gmtime_r(&sec, &tm);
if (gmtime_res) {
rtc.tm_sec = tm.tm_sec;
rtc.tm_min = tm.tm_min;
rtc.tm_hour = tm.tm_hour;
rtc.tm_mday = tm.tm_mday;
rtc.tm_mon = tm.tm_mon;
rtc.tm_year = tm.tm_year;
rtc.tm_wday = tm.tm_wday;
rtc.tm_yday = tm.tm_yday;
rtc.tm_isdst = tm.tm_isdst;
res = ioctl(fd, RTC_SET_TIME, &rtc);
if (res < 0){
TIME_HILOGE(TIME_MODULE_SERVICE,"ioctl RTC_SET_TIME failed: %{public}s", strerror(errno));
}
}else{
TIME_HILOGE(TIME_MODULE_SERVICE,"convert rtc time failed: %{public}s", strerror(errno));
res = -1;
}
close(fd);
return res;
}
bool TimeService::check_rtc(std::string rtc_path, uint32_t rtc_id_t)
{
std::stringstream strs;
strs << rtc_path << "/rtc" << rtc_id_t << "/hctosys";
auto hctosys_path = strs.str();
uint32_t hctosys;
std::fstream file(hctosys_path.data(), std::ios_base::in);
if (file.is_open()) {
file >> hctosys;
} else {
TIME_HILOGE(TIME_MODULE_SERVICE,"failed to open %{public}s", hctosys_path.data());
return false;
}
return true;
}
int TimeService::get_wall_clock_rtc_id()
{
std::string rtc_path = "/sys/class/rtc";
std::unique_ptr<DIR, int(*)(DIR*)> dir(opendir(rtc_path.c_str()), closedir);
if (!dir.get()) {
TIME_HILOGE(TIME_MODULE_SERVICE,"failed to open %{public}s: %{public}s", rtc_path.c_str(), strerror(errno));
return -1;
}
struct dirent *dirent;
while (errno = 0, dirent = readdir(dir.get())) {
unsigned int rtc_id_t;
int matched = sscanf_s(dirent->d_name, "rtc%u", &rtc_id_t, sizeof(int));
if (matched < 0) {
break;
} else if (matched != 1) {
continue;
}
if (check_rtc(rtc_path, rtc_id_t)) {
TIME_HILOGD(TIME_MODULE_SERVICE,"found wall clock rtc %{public}u", rtc_id_t);
return rtc_id_t;
}
}
if (errno == 0){
TIME_HILOGE(TIME_MODULE_SERVICE,"no wall clock rtc found");
}else{
TIME_HILOGE(TIME_MODULE_SERVICE,"failed to check rtc: %{public}s", strerror(errno));
}
return -1;
}
int32_t TimeService::SetTimeZone(const std::string timeZoneId)
{
pid_t uid = IPCSkeleton::GetCallingUid();
auto hasPerm = TimePermission::GetInstance()->CheckCallingPermission(uid, setTimezonePermName_);
if (!hasPerm){
TIME_HILOGE(TIME_MODULE_SERVICE, "Permission check failed, uid : %{public}d", uid);
return E_TIME_NO_PERMISSION;
}
int gmtOffset;
struct timezone tz;
TIME_HILOGE(TIME_MODULE_SERVICE,"timezone id: %{public}s.", timeZoneId.c_str());
auto ret = TimeZoneInfo::GetInstance()->GetOffset(timeZoneId, gmtOffset);
TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone offset: %{public}d.", gmtOffset);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret);
return ret;
}
tz.tz_minuteswest = gmtOffset * 60;
tz.tz_dsttime = 0;
int result = settimeofday(NULL, &tz);
if (result < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE,"settimeofday fail: %{public}d.",result);
return E_TIME_DEAL_FAILED;
}
int64_t currentTime = 0;
GetWallTimeMs(currentTime);
if (timeServiceNotify_ != nullptr){
timeServiceNotify_->PublishTimeZoneChangeEvents(currentTime);
}
return ERR_OK;
}
int32_t TimeService::GetTimeZone(std::string &timeZoneId)
{
std::string curTimezone;
auto ret = TimeZoneInfo::GetInstance()->GetTimezoneId(curTimezone);
TIME_HILOGI(TIME_MODULE_SERVICE,"get timezone : %{public}s.", curTimezone.c_str());
if (ret == ERR_OK){
timeZoneId = curTimezone;
return ERR_OK;
}
TIME_HILOGE(TIME_MODULE_SERVICE,"get timezone info fail: %{public}d.", ret);
return ret;
}
int32_t TimeService::GetWallTimeMs(int64_t &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;
}
} // namespace MiscServices
} // namespace OHOS
@@ -0,0 +1,401 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_service_client.h"
#include "time_common.h"
#include <cinttypes>
#include "system_ability_definition.h"
#include "iservice_registry.h"
#include <mutex>
namespace OHOS {
namespace MiscServices {
std::mutex TimeServiceClient::instanceLock_;
sptr<TimeServiceClient> TimeServiceClient::instance_;
sptr<ITimeService> TimeServiceClient::timeServiceProxy_;
sptr<TimeSaDeathRecipient> TimeServiceClient::deathRecipient_;
TimeServiceClient::TimeServiceClient()
{
}
TimeServiceClient::~TimeServiceClient()
{
}
sptr<TimeServiceClient> TimeServiceClient::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
instance_ = new TimeServiceClient;
}
}
return instance_;
}
sptr<ITimeService> TimeServiceClient::ConnectService()
{
sptr<ISystemAbilityManager> 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<ITimeService> timeServiceProxy = iface_cast<ITimeService>(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<ITimerInfo> TimerOptions)
{
if (TimerOptions == nullptr){
TIME_HILOGW(TIME_MODULE_CLIENT, "Input nullptr");
return 0;
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, " quit because redoing ConnectService failed.");
return 0;
}
auto timerCallbackInfoObject = TimerCallback::GetInstance()->AsObject();
if (!timerCallbackInfoObject) {
TIME_HILOGE(TIME_MODULE_CLIENT, "New TimerCallback failed");
return 0;
}
auto timerId = timeServiceProxy_->CreateTimer(TimerOptions->type, TimerOptions->repeat, TimerOptions->interval, timerCallbackInfoObject);
if (timerId == 0){
TIME_HILOGE(TIME_MODULE_CLIENT, "Create timer failed");
return 0;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"CreateTimer id: %{public}" PRId64 "", timerId);
auto ret = TimerCallback::GetInstance()->InsertTimerCallbackInfo(timerId, TimerOptions);
if(!ret){
return 0;
}
return timerId;
}
bool TimeServiceClient::StartTimer(uint64_t timerId, uint64_t triggerTime)
{
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "StartTimer quit because redoing ConnectService failed.");
return false;
}
return timeServiceProxy_->StartTimer(timerId, triggerTime);
}
bool TimeServiceClient::StopTimer(uint64_t timerId)
{
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "StopTimer quit because redoing ConnectService failed.");
return false;
}
return timeServiceProxy_->StopTimer(timerId);
}
bool TimeServiceClient::DestroyTimer(uint64_t timerId)
{
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "DestroyTimer quit because redoing ConnectService failed.");
return false;
}
if (timeServiceProxy_->DestroyTimer(timerId)){
TimerCallback::GetInstance()->RemoveTimerCallbackInfo(timerId);
return true;
}
return false;
}
std::string TimeServiceClient::GetTimeZone()
{
std::string timeZoneId;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetTimeZone quit because redoing ConnectService failed.");
return std::string("");
}
if(timeServiceProxy_->GetTimeZone(timeZoneId) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return std::string("");
}
return timeZoneId;
}
int64_t TimeServiceClient::GetWallTimeMs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeMs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetWallTimeMs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
int64_t TimeServiceClient::GetWallTimeNs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeNs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetWallTimeNs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
int64_t TimeServiceClient::GetBootTimeMs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeMs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetBootTimeMs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
int64_t TimeServiceClient::GetBootTimeNs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeNs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetBootTimeNs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
int64_t TimeServiceClient::GetMonotonicTimeMs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeMs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetMonotonicTimeMs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
int64_t TimeServiceClient::GetMonotonicTimeNs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeNs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetMonotonicTimeNs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
int64_t TimeServiceClient::GetThreadTimeMs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeMs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetThreadTimeMs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
int64_t TimeServiceClient::GetThreadTimeNs()
{
int64_t times;
if (timeServiceProxy_ == nullptr) {
TIME_HILOGW(TIME_MODULE_CLIENT, "Redo ConnectService");
timeServiceProxy_ = ConnectService();
}
if (timeServiceProxy_ == nullptr) {
TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeNs quit because redoing ConnectService failed.");
return -1;
}
if(timeServiceProxy_->GetThreadTimeNs(times) != ERR_OK){
TIME_HILOGE(TIME_MODULE_CLIENT, "get failed.");
return -1;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Result: %{public}" PRId64 "", times);
return times;
}
void TimeServiceClient::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
{
timeServiceProxy_ = ConnectService();
}
TimeSaDeathRecipient::TimeSaDeathRecipient()
{
}
void TimeSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
TIME_HILOGE(TIME_MODULE_CLIENT, "TimeSaDeathRecipient on remote systemAbility died.");
TimeServiceClient::GetInstance()->OnRemoteSaDied(object);
}
} // namespace MiscServices
} // namespace OHOS
@@ -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 <unistd.h>
using namespace OHOS::AAFwk;
using namespace OHOS::EventFwk;
namespace OHOS{
namespace MiscServices{
void TimeServiceNotify::RegisterPublishEvents()
{
if (publishInfo_ != nullptr) {
return;
}
publishInfo_ = new (std::nothrow)CommonEventPublishInfo();
publishInfo_->SetOrdered(false);
timeChangeWant_ = new (std::nothrow)IntentWant();
timeChangeWant_->SetAction(CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
timeZoneChangeWant_ = new (std::nothrow)IntentWant();
timeZoneChangeWant_->SetAction(CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
}
void TimeServiceNotify::PublishEvents(int64_t eventTime, sptr<IntentWant> 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<long long>(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
@@ -0,0 +1,356 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is: distributed on an "AS is:"BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_service_proxy.h"
#include "iremote_broker.h"
#include "time_common.h"
#include "time_service_interface.h"
namespace OHOS {
namespace MiscServices {
using namespace OHOS::HiviewDFX;
TimeServiceProxy::TimeServiceProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<ITimeService>(object)
{
}
int32_t TimeServiceProxy::SetTime(const int64_t time)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
if (!data.WriteInt64(time)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(SET_TIME, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "SetTime failed, error code is: %{public}d",result);
return result;
}
return result;
}
uint64_t TimeServiceProxy::CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr<IRemoteObject> &timerCallback)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return 0;
}
if (!data.WriteInt32(type)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return 0;
}
if (!data.WriteBool(repeat)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return 0;
}
if (!data.WriteUint64(interval)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return 0;
}
if (!data.WriteRemoteObject(timerCallback)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return 0;
}
int32_t result = Remote()->SendRequest(CREATE_TIMER, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "CreateTimer failed, error code is: %{public}d",result);
return 0;
}
auto TimerId = reply.ReadUint64();
return TimerId;
}
bool TimeServiceProxy::StartTimer(uint64_t timerId, uint64_t triggerTimes)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
if (!data.WriteUint64(timerId)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
if (!data.WriteUint64(triggerTimes)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(START_TIMER, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "Start failed, error code is: %{public}d",result);
return false;
}
return true;
}
bool TimeServiceProxy::StopTimer(uint64_t timerId)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
if (!data.WriteUint64(timerId)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(STOP_TIMER, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "Stop failed, error code is: %{public}d",result);
return false;
}
return true;
}
bool TimeServiceProxy::DestroyTimer(uint64_t timerId)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
if (!data.WriteUint64(timerId)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(DESTORY_TIMER, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "failed, error code is: %{public}d",result);
return false;
}
return true;
}
int32_t TimeServiceProxy::SetTimeZone(std::string timezoneId)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
if (!data.WriteString(timezoneId)) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(SET_TIME_ZONE, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "SetTimeZone failed, error code is: %{public}d",result);
return result;
}
return result;
}
int32_t TimeServiceProxy::GetTimeZone(std::string &timezoneId)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_TIME_ZONE, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetTimeZone failed, error code is: %{public}d",result);
return result;
}
timezoneId = reply.ReadString();
return result;
}
int32_t TimeServiceProxy::GetWallTimeMs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_WALL_TIME_MILLI, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeMs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
int32_t TimeServiceProxy::GetWallTimeNs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_WALL_TIME_NANO, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeNs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
int32_t TimeServiceProxy::GetBootTimeMs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_BOOT_TIME_MILLI, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeMs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
int32_t TimeServiceProxy::GetBootTimeNs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_BOOT_TIME_MILLI, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeNs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
int32_t TimeServiceProxy::GetMonotonicTimeMs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_MONO_TIME_MILLI, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeMs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
int32_t TimeServiceProxy::GetMonotonicTimeNs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_MONO_TIME_NANO, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeNs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
int32_t TimeServiceProxy::GetThreadTimeMs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_THREAD_TIME_MILLI, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeMs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
int32_t TimeServiceProxy::GetThreadTimeNs(int64_t &times)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
int32_t result = Remote()->SendRequest(GET_THREAD_TIME_NANO, data, reply, option);
if (result != ERR_NONE){
TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeNs failed, error code is: %{public}d",result);
return result;
}
times = reply.ReadInt64();
return result;
}
} // namespace MiscServices
} // namespace OHOS
@@ -0,0 +1,295 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_service_stub.h"
#include <cinttypes>
#include "time_common.h"
namespace OHOS {
namespace MiscServices {
using namespace OHOS::HiviewDFX;
TimeServiceStub::TimeServiceStub(){
memberFuncMap_[SET_TIME] = &TimeServiceStub::OnSetTime;
memberFuncMap_[SET_TIME_ZONE] = &TimeServiceStub::OnSetTimeZone;
memberFuncMap_[GET_TIME_ZONE] = &TimeServiceStub::OnGetTimeZone;
memberFuncMap_[GET_WALL_TIME_MILLI] = &TimeServiceStub::OnGetWallTimeMs;
memberFuncMap_[GET_WALL_TIME_NANO] = &TimeServiceStub::OnGetWallTimeNs;
memberFuncMap_[GET_BOOT_TIME_MILLI] = &TimeServiceStub::OnGetBootTimeMs;
memberFuncMap_[GET_BOOT_TIME_NANO] = &TimeServiceStub::OnGetBootTimeNs;
memberFuncMap_[GET_MONO_TIME_MILLI] = &TimeServiceStub::OnGetMonotonicTimeMs;
memberFuncMap_[GET_MONO_TIME_NANO] = &TimeServiceStub::OnGetMonotonicTimeMs;
memberFuncMap_[GET_THREAD_TIME_MILLI] = &TimeServiceStub::OnGetThreadTimeMs;
memberFuncMap_[GET_THREAD_TIME_NANO] = &TimeServiceStub::OnGetThreadTimeNs;
memberFuncMap_[CREATE_TIMER] = &TimeServiceStub::OnCreateTimer;
memberFuncMap_[START_TIMER] = &TimeServiceStub::OnStartTimer;
memberFuncMap_[STOP_TIMER] = &TimeServiceStub::OnStopTimer;
memberFuncMap_[DESTORY_TIMER] = &TimeServiceStub::OnDestoryTimer;
}
TimeServiceStub::~TimeServiceStub(){
memberFuncMap_.clear();
}
int32_t TimeServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start##code = %{public}u", code);
std::u16string myDescripter = TimeServiceStub::GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken();
if (myDescripter != remoteDescripter) {
TIME_HILOGE(TIME_MODULE_SERVICE," end##descriptor checked fail");
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
pid_t p = IPCSkeleton::GetCallingPid();
pid_t p1 = IPCSkeleton::GetCallingUid();
TIME_HILOGI(TIME_MODULE_SERVICE,"CallingPid = %{public}d, CallingUid = %{public}d, code = %{public}u", p, p1, code);
auto itFunc = memberFuncMap_.find(code);
if (itFunc != memberFuncMap_.end()) {
auto memberFunc = itFunc->second;
if (memberFunc != nullptr) {
return (this->*memberFunc)(data, reply);
}
}
int ret = IPCObjectStub::OnRemoteRequest(code, data, reply, option);
TIME_HILOGI(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
int32_t TimeServiceStub::OnSetTime(MessageParcel& data, MessageParcel& reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t time = data.ReadInt64();
int32_t ret = SetTime(time);
TIME_HILOGI(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
int32_t TimeServiceStub::OnSetTimeZone(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
std::string timeZoneId = data.ReadString();
int32_t ret = SetTimeZone(timeZoneId);
TIME_HILOGI(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
int32_t TimeServiceStub::OnGetTimeZone(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
std::string timeZoneId;
int32_t ret = GetTimeZone(timeZoneId);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteString(timeZoneId);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetWallTimeMs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetWallTimeMs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetWallTimeNs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetWallTimeNs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetBootTimeMs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetBootTimeMs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetBootTimeNs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetBootTimeNs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetMonotonicTimeMs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetMonotonicTimeMs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetMonotonicTimeNs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetMonotonicTimeNs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetThreadTimeMs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetThreadTimeMs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnGetThreadTimeNs(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE," start.");
int64_t times;
int32_t ret = GetThreadTimeNs(times);
if (ret != ERR_OK){
TIME_HILOGE(TIME_MODULE_SERVICE," end##ret = %{public}d", ret);
return ret;
}
reply.WriteInt64(times);
TIME_HILOGI(TIME_MODULE_SERVICE," end.");
return ret;
}
int32_t TimeServiceStub::OnCreateTimer(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE,"start.");
auto type = data.ReadInt32();
auto repeat = data.ReadBool();
auto interval = data.ReadUint64();
sptr<IRemoteObject> obj = data.ReadRemoteObject();
if(obj == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE, "Input nullptr");
return E_TIME_PARAMETERS_INVALID;
}
auto timerId = CreateTimer(type, repeat, interval, obj);
if (timerId == 0 ){
TIME_HILOGE(TIME_MODULE_SERVICE, "Create timer failed");
return E_TIME_DEAL_FAILED;
}
if (!reply.WriteUint64(timerId)){
TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to write parcelable");
return E_TIME_WRITE_PARCEL_ERROR;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"end.");
return ERR_OK;
}
int32_t TimeServiceStub::OnStartTimer(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE,"start.");
auto timerId = data.ReadUint64();
auto triggerTime = data.ReadUint64();
if (!StartTimer(timerId, triggerTime)){
TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to start timer");
return E_TIME_DEAL_FAILED;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"end.");
return ERR_OK;
}
int32_t TimeServiceStub::OnStopTimer(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE,"start.");
auto timerId = data.ReadUint64();
if (!StopTimer(timerId)){
TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to stop timer");
return E_TIME_DEAL_FAILED;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"end.");
return ERR_OK;
}
int32_t TimeServiceStub::OnDestoryTimer(MessageParcel &data, MessageParcel &reply)
{
TIME_HILOGI(TIME_MODULE_SERVICE,"start.");
auto timerId = data.ReadUint64();
if (!DestroyTimer(timerId)){
TIME_HILOGE(TIME_MODULE_SERVICE, "Failed to destory timer");
return E_TIME_DEAL_FAILED;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"end.");
return ERR_OK;
}
} // namespace MiscServices
} // namespace OHOS
@@ -0,0 +1,97 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_zone_info.h"
#include "time_common.h"
#include <vector>
namespace OHOS{
namespace MiscServices{
std::mutex TimeZoneInfo::instanceLock_;
sptr<TimeZoneInfo> TimeZoneInfo::instance_;
TimeZoneInfo::TimeZoneInfo()
{
std::vector<struct zoneInfoEntry> timezoneList = {
{"Anadyr, Russia", "ANA", 12, "Anadyr Time"},
{"Honiara, SolomonIslands", "SBT", 11, "Solomon Islands Time"},
{"Melbourne, Australia", "AEST", 10, "Australian Eastern Standard Time"},
{"Tokyo, Japan", "JST", 9, "Japan Standard Time"},
{"Beijing, China", "CST", 8, "China Standard Time"},
{"Jakarta, Indonesia", "WIB", 7, "Western Indonesian Time"},
{"Dhaka, Bangladesh", "BST", 6, "Bangladesh Standard Time"},
{"Tashkent, Uzbekistan", "UZT", 5, "Uzbekistan Time"},
{"Dubai, U.A.E.", "GST", 4, "Gulf Standard Time"},
{"Moscow, Russia", "MSK", 3, "Moscow Standard Time"},
{"Brussels, Belgium", "CEST", 2, "Central European Summer Time"},
{"London, England", "BST", 1, "British Summer Time"},
{"Accra, Ghana", "GMT", 0, "Greenwich Mean Time"},
{"Accra, Ghana", "UTC", 0, "Universal Time Coordinated"},
{"Praia, CaboVerde", "CVT", -1, "Cabo Verde Time"},
{"Nuuk, Greenland", "WGS", -2, "Western Greenland Summer Time"},
{"Buenos Aires, Argentina", "ART", -3, "Argentina Time"},
{"New York, U.S.A.", "EDT", -4, "Eastern Daylight Time"},
{"Mexico City, Mexico", "CDT", -5, "Central Daylight Time"},
{"Guatemala City, Guatemala", "CST", -6, "Central Standard Time"},
{"Los Angeles, U.S.A.", "PDT", -7, "Pacific Daylight Time"},
{"Anchorage, U.S.A.", "AKD", -8, "Alaska Daylight Time"},
{"Adak, U.S.A.", "HDT", -9, "Hawaii-Aleutian Daylight Time"},
{"Honolulu, U.S.A.", "HST", -10, "Hawaii Standard Time"},
{"Alofi, Niue", "NUT", -11, "Niue Time"},
{"Baker Island, U.S.A.", "AoE", -12, "Anywhere on Earth"},
};
for (auto tz : timezoneList) {
timezoneInfoMap_[tz.ID] = tz;
}
}
TimeZoneInfo::~TimeZoneInfo(){
timezoneInfoMap_.clear();
}
int32_t TimeZoneInfo::GetOffset(const std::string timezoneId, int &offset){
auto itEntry = timezoneInfoMap_.find(timezoneId);
if (itEntry != timezoneInfoMap_.end()) {
auto zoneInfo = itEntry->second;
offset = zoneInfo.utcOffsetHours;
curTimezoneId_ = timezoneId;
return ERR_OK;
}
TIME_HILOGE(TIME_MODULE_SERVICE, "TimezoneId not found.");
return E_TIME_NOT_FOUND;
}
int32_t TimeZoneInfo::GetTimezoneId( std::string &timezoneId ){
timezoneId = curTimezoneId_;
return ERR_OK;
}
sptr<TimeZoneInfo> TimeZoneInfo::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
instance_ = new TimeZoneInfo;
}
}
return instance_;
}
}
}
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer_call_back.h"
namespace OHOS {
namespace MiscServices {
std::mutex TimerCallback::instanceLock_;
sptr<TimerCallback> TimerCallback::instance_;
std::map<uint64_t, std::shared_ptr<ITimerInfo>> TimerCallback::TimerInfoMap_;
std::mutex TimerCallback::timerInfoMutex_;
TimerCallback::TimerCallback()
{
}
TimerCallback::~TimerCallback()
{
TimerInfoMap_.clear();
}
sptr<TimerCallback> TimerCallback::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
instance_ = new TimerCallback;
}
}
return instance_;
}
bool TimerCallback::InsertTimerCallbackInfo(const uint64_t timerId,
const std::shared_ptr<ITimerInfo> &timerInfo)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
if (timerInfo == nullptr){
return false;
}
std::lock_guard<std::mutex> lock(timerInfoMutex_);
auto info = TimerInfoMap_.find(timerId);
if (info != TimerInfoMap_.end()) {
TIME_HILOGE(TIME_MODULE_CLIENT, "timer info already insert.");
return false;
} else {
TimerInfoMap_[timerId] = timerInfo;
}
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return true;
}
bool TimerCallback::RemoveTimerCallbackInfo(const uint64_t timerId)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
std::lock_guard<std::mutex> lock(timerInfoMutex_);
auto info = TimerInfoMap_.find(timerId);
if (info != TimerInfoMap_.end()) {
TimerInfoMap_.erase(info);
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return true;
}
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return false;
}
void TimerCallback::NotifyTimer(const uint64_t timerId)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
std::lock_guard<std::mutex> lock(timerInfoMutex_);
auto it = TimerInfoMap_.find(timerId);
if (it != TimerInfoMap_.end()) {
TIME_HILOGD(TIME_MODULE_SERVICE, "ontrigger.");
it->second->OnTrigger();
if (it->second->wantAgent != nullptr){
TIME_HILOGD(TIME_MODULE_SERVICE, "trigger wantagent.");
std::shared_ptr<AppExecFwk::Context> context = std::make_shared<OHOS::AppExecFwk::AbilityContext>();
std::shared_ptr<AAFwk::Want> want = Notification::WantAgent::WantAgentHelper::GetWant(it->second->wantAgent);
OHOS::Notification::WantAgent::TriggerInfo paramsInfo("", nullptr, want, 11);
Notification::WantAgent::WantAgentHelper::TriggerWantAgent(context, it->second->wantAgent, nullptr, paramsInfo);
}
}
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
}
} // namespace MiscServices
} // namespace OHOS
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer_call_back_proxy.h"
namespace OHOS {
namespace MiscServices {
TimerCallbackProxy::TimerCallbackProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<ITimerCallback>(object)
{
}
TimerCallbackProxy::~TimerCallbackProxy()
{
TIME_HILOGD(TIME_MODULE_CLIENT, "TimerCallbackProxy instance destoryed");
}
void TimerCallbackProxy::NotifyTimer(uint64_t timerId)
{
TIME_HILOGD(TIME_MODULE_CLIENT, "start id: %{public}" PRId64 "", timerId);
sptr<IRemoteObject> 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<int>(ITimerCallback::Message::NOTIFY_TIMER), data, reply, option);
if (ret != ERR_OK) {
TIME_HILOGE(TIME_MODULE_CLIENT, "SendRequest is failed, error code: %{public}d", ret);
}
TIME_HILOGI(TIME_MODULE_CLIENT, "end.");
}
} // namespace MiscServices
} // namespace OHOS
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer_call_back_stub.h"
namespace OHOS {
namespace MiscServices {
int TimerCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "cmd = %{public}d, flags= %{public}d", code, option.GetFlags());
std::u16string descripter = GetDescriptor();
std::u16string remoteDescripter = data.ReadInterfaceToken();
if (descripter != remoteDescripter) {
TIME_HILOGE(TIME_MODULE_SERVICE, " failed, descriptor is not matched!");
return E_TIME_READ_PARCEL_ERROR;
}
switch (code) {
case static_cast<int>(ITimerCallback::Message::NOTIFY_TIMER): {
return OnTriggerStub(data);
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return ERR_OK;
}
int TimerCallbackStub::OnTriggerStub(MessageParcel& data)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
auto timerId = data.ReadUint64();
TIME_HILOGD(TIME_MODULE_CLIENT, "id: %{public}" PRId64 "", timerId);
NotifyTimer(timerId);
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return ERR_OK;
}
} // namespace MiscServices
} // namespace OHOS
+33 -5
View File
@@ -9,26 +9,54 @@
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# limitations under the License.
import("//build/test.gni")
config("module_private_config") {
visibility = [ ":*" ]
include_dirs = [
"//base/miscservices/time/interfaces/innerkits/include",
"unittest/include",
"//foundation/ace/napi/interfaces/kits/napi",
]
}
module_output_path = "time_native/time_service"
ohos_unittest("TimeServiceTest") {
module_out_path = module_output_path
sources = [ "unittest/time_service_test.cpp" ]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
sources = [ "unittest/src/time_service_test.cpp" ]
configs = [
":module_private_config",
]
deps = [
"//base/miscservices/time/services:time_service",
"//base/notification/ans_standard/frameworks/wantagent:wantagent_innerkits",
"//foundation/ace/napi:ace_napi",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/distributedschedule/dmsfwk/services/dtbschedmgr:distributedschedsvr",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
]
external_deps = [
"aafwk_standard:base",
"aafwk_standard:want",
"appexecfwk_standard:appexecfwk_base",
"appexecfwk_standard:libeventhandler",
"ces_standard:cesfwk_innerkits",
"hisysevent_native:libhisysevent",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr_L2:samgr_proxy",
]
}
group("unittest") {
@@ -0,0 +1,88 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include <functional>
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
#include <sys/time.h>
#include <thread>
#include "time_common.h"
#include "time_service_client.h"
#include <string>
#include <inttypes.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<OHOS::Notification::WantAgent::WantAgent> wantAgent) override;
void SetCallbackInfo(const std::function<void()> &callBack);
private:
std::function<void()> callBack_ = nullptr;
};
TimerInfoTest::TimerInfoTest()
{
}
TimerInfoTest::~TimerInfoTest()
{
}
void TimerInfoTest::OnTrigger()
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
if (callBack_ != nullptr){
TIME_HILOGD(TIME_MODULE_SERVICE, "call back.");
callBack_();
}
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
}
void TimerInfoTest::SetCallbackInfo(const std::function<void()> &callBack)
{
callBack_ = callBack;
}
void TimerInfoTest::SetType(const int &_type)
{
type = _type;
}
void TimerInfoTest::SetRepeat(bool _repeat)
{
repeat = _repeat;
}
void TimerInfoTest::SetInterval(const uint64_t &_interval)
{
interval = _interval;
}
void TimerInfoTest::SetWantAgent(std::shared_ptr<OHOS::Notification::WantAgent::WantAgent> _wantAgent)
{
wantAgent = _wantAgent;
}
}
}
@@ -0,0 +1,366 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer_test.h"
using namespace testing::ext;
using namespace OHOS;
using namespace OHOS::MiscServices;
class TimeServiceTest : public testing::Test
{
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
};
void TimeServiceTest::SetUpTestCase(void)
{
}
void TimeServiceTest::TearDownTestCase(void)
{
}
void TimeServiceTest::SetUp(void)
{
}
void TimeServiceTest::TearDown(void)
{
}
/**
* @tc.name: SetTime001
* @tc.desc: get system time.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, SetTime001, TestSize.Level0)
{
struct timeval getTime;
gettimeofday(&getTime, NULL);
int64_t time = (getTime.tv_sec + 1000) * 1000 + getTime.tv_usec / 1000;
if (time < 0){
time = 1627307312000;
}
TIME_HILOGI(TIME_MODULE_CLIENT, "Time now : %{public}" PRId64 "",time);
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: SetTimeZone002
* @tc.desc: set system time zone.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, SetTimeZone002, TestSize.Level0)
{
std::string timeZoneSet("Beijing, China");
bool result = TimeServiceClient::GetInstance()->SetTimeZone(timeZoneSet);
EXPECT_TRUE(result);
auto timeZoneRes = TimeServiceClient::GetInstance()->GetTimeZone();
EXPECT_EQ(timeZoneRes, timeZoneSet);
}
/**
* @tc.name: GetTime001
* @tc.desc: get system time.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, GetTime001, TestSize.Level0)
{
auto time1 = TimeServiceClient::GetInstance()->GetWallTimeMs();
EXPECT_TRUE(time1 != -1);
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 != -1);
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 != -1);
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 != -1);
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 != -1);
auto time2 = TimeServiceClient::GetInstance()->GetBootTimeNs();
EXPECT_TRUE(time2 >= time1);
}
/**
* @tc.name: GetTime006
* @tc.desc: get system time.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, GetTime006, TestSize.Level0)
{
auto time1 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs();
EXPECT_TRUE(time1 != -1);
auto time2 = TimeServiceClient::GetInstance()->GetMonotonicTimeNs();
EXPECT_TRUE(time2 >= time1);
}
/**
* @tc.name: GetTime007
* @tc.desc: get system time.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, GetTime007, TestSize.Level0)
{
auto time1 = TimeServiceClient::GetInstance()->GetThreadTimeMs();
EXPECT_TRUE(time1 != -1);
auto time2 = TimeServiceClient::GetInstance()->GetThreadTimeMs();
EXPECT_TRUE(time2 >= time1);
}
/**
* @tc.name: GetTime008
* @tc.desc: get system time.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, GetTime008, TestSize.Level0)
{
auto time1 = TimeServiceClient::GetInstance()->GetThreadTimeNs();
EXPECT_TRUE(time1 != -1);
auto time2 = TimeServiceClient::GetInstance()->GetThreadTimeNs();
EXPECT_TRUE(time2 >= time1);
}
std::atomic<int> g_data1(0);
void TimeOutCallback1()
{
g_data1 += 1;
}
std::atomic<int> g_data2(0);
void TimeOutCallback2()
{
g_data2 += 1;
}
/**
* @tc.name: CreateTimer01
* @tc.desc: Create system timer.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, CreateTimer01, TestSize.Level0)
{
g_data1 = 0;
auto timerInfo = std::make_shared<TimerInfoTest>();
timerInfo->SetType(1);
timerInfo->SetRepeat(false);
timerInfo->SetInterval(0);
timerInfo->SetWantAgent(nullptr);
timerInfo->SetCallbackInfo(TimeOutCallback1);
auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo);
EXPECT_TRUE(timerId1 > 0);
auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5);
std::this_thread::sleep_for(std::chrono::milliseconds(6000));
EXPECT_TRUE(ret);
EXPECT_TRUE(g_data1 == 1);
ret = TimeServiceClient::GetInstance()->StopTimer(timerId1);
EXPECT_TRUE(ret);
ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1);
EXPECT_TRUE(ret);
}
/**
* @tc.name: CreateTimer02
* @tc.desc: Create system timer.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, CreateTimer02, TestSize.Level0)
{
g_data1 = 0;
auto timerInfo = std::make_shared<TimerInfoTest>();
timerInfo->SetType(1);
timerInfo->SetRepeat(false);
timerInfo->SetInterval(0);
timerInfo->SetWantAgent(nullptr);
timerInfo->SetCallbackInfo(TimeOutCallback1);
auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo);
EXPECT_TRUE(timerId1 > 0);
auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5000);
std::this_thread::sleep_for(std::chrono::milliseconds(5100));
EXPECT_TRUE(ret);
EXPECT_TRUE(g_data1 == 1);
ret = TimeServiceClient::GetInstance()->StopTimer(timerId1);
EXPECT_TRUE(ret);
ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 5000);
EXPECT_TRUE(ret);
EXPECT_TRUE(g_data1 == 1);
ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1);
EXPECT_TRUE(ret);
}
/**
* @tc.name: CreateTimer03
* @tc.desc: Create system timer.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, CreateTimer03, TestSize.Level0)
{
uint64_t timerId = 0;
auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId, 5);
EXPECT_FALSE(ret);
ret = TimeServiceClient::GetInstance()->StopTimer(timerId);
EXPECT_FALSE(ret);
ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId);
EXPECT_FALSE(ret);
}
/**
* @tc.name: CreateTimer04
* @tc.desc: Create system timer.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, CreateTimer04, TestSize.Level0)
{
auto timerInfo = std::make_shared<TimerInfoTest>();
timerInfo->SetType(1);
timerInfo->SetRepeat(false);
timerInfo->SetInterval(0);
timerInfo->SetWantAgent(nullptr);
timerInfo->SetCallbackInfo(TimeOutCallback1);
auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo);
EXPECT_TRUE(timerId1 > 0);
auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 2000);
EXPECT_TRUE(ret);
ret = TimeServiceClient::GetInstance()->StopTimer(timerId1);
EXPECT_TRUE(ret);
ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1);
EXPECT_TRUE(ret);
}
/**
* @tc.name: CreateTimer05
* @tc.desc: Create system timer.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, CreateTimer05, TestSize.Level0)
{
g_data1 = 0;
auto timerInfo = std::make_shared<TimerInfoTest>();
timerInfo->SetType(1);
timerInfo->SetRepeat(false);
timerInfo->SetInterval(0);
timerInfo->SetWantAgent(nullptr);
timerInfo->SetCallbackInfo(TimeOutCallback1);
auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo);
EXPECT_TRUE(timerId1 > 0);
auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, 2000);
EXPECT_TRUE(ret);
ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1);
EXPECT_TRUE(ret);
EXPECT_TRUE(g_data1 == 0);
ret = TimeServiceClient::GetInstance()->StopTimer(timerId1);
EXPECT_FALSE(ret);
}
/**
* @tc.name: CreateTimer06
* @tc.desc: Create system timer.
* @tc.type: FUNC
*/
HWTEST_F(TimeServiceTest, CreateTimer06, TestSize.Level0)
{
g_data1 = 1;
auto timerInfo = std::make_shared<TimerInfoTest>();
timerInfo->SetType(0);
timerInfo->SetRepeat(false);
timerInfo->SetInterval(0);
timerInfo->SetWantAgent(nullptr);
timerInfo->SetCallbackInfo(TimeOutCallback1);
struct timeval getTime;
gettimeofday(&getTime, NULL);
int64_t current_time = (getTime.tv_sec + 100) * 1000 + getTime.tv_usec / 1000;
if (current_time < 0){
current_time = 0;
}
auto timerId1 = TimeServiceClient::GetInstance()->CreateTimer(timerInfo);
EXPECT_TRUE(timerId1 > 0);
auto ret = TimeServiceClient::GetInstance()->StartTimer(timerId1, static_cast<uint64_t>(current_time));
EXPECT_TRUE(ret);
ret = TimeServiceClient::GetInstance()->DestroyTimer(timerId1);
EXPECT_TRUE(ret);
EXPECT_TRUE(g_data1 == 1);
ret = TimeServiceClient::GetInstance()->StopTimer(timerId1);
EXPECT_FALSE(ret);
}
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIMER_BATCH_H
#define TIMER_BATCH_H
#include <cstdint>
#include <vector>
#include <chrono>
#include <functional>
#include "timer_info.h"
#include "time_common.h"
namespace OHOS {
namespace MiscServices {
class Batch {
public:
Batch ();
explicit Batch (const TimerInfo &seed);
std::chrono::steady_clock::time_point GetStart () const;
std::chrono::steady_clock::time_point GetEnd () const;
uint32_t GetFlags () const;
size_t Size () const;
std::shared_ptr<TimerInfo> 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<TimerInfo> &alarm);
bool Remove (const TimerInfo &alarm);
bool Remove (std::function<bool (const TimerInfo &)> 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<std::shared_ptr<TimerInfo>> alarms_;
};
}
}
#endif
+57
View File
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIMER_HANDLER_H
#define TIMER_HANDLER_H
#include "time_common.h"
#include <array>
#include <cstdint>
#include <string>
#include <chrono>
#include <memory>
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<int, N_TIMER_FDS> TimerFds;
class TimerHandler {
public:
static std::shared_ptr<TimerHandler> Create ();
int Set (uint32_t type, std::chrono::nanoseconds when);
int WaitForAlarm ();
~TimerHandler ();
private:
TimerHandler (const TimerFds &fds, int epollfd);
const TimerFds fds_;
const int epollFd_;
};
}// MiscService
}// OHOS
#endif
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIMER_INFO_H
#define TIMER_INFO_H
#include <cstdint>
#include <string>
#include <chrono>
#include <utility>
#include <functional>
#include "timer_manager_interface.h"
namespace OHOS {
namespace MiscServices {
class TimerInfo {
public:
const uint64_t id;
const int type;
const std::chrono::milliseconds origWhen;
const bool wakeup;
const std::function<void (const uint64_t)> callback;
const uint32_t flags;
const uint64_t uid;
uint64_t count{};
std::chrono::milliseconds when;
std::chrono::milliseconds windowLength;
std::chrono::steady_clock::time_point whenElapsed;
std::chrono::steady_clock::time_point maxWhenElapsed;
std::chrono::steady_clock::time_point expectedWhenElapsed;
std::chrono::steady_clock::time_point expectedMaxWhenElapsed;
std::chrono::milliseconds repeatInterval;
TimerInfo (uint64_t id, int type,
std::chrono::milliseconds when,
std::chrono::steady_clock::time_point whenElapsed,
std::chrono::milliseconds windowLength,
std::chrono::steady_clock::time_point maxWhen,
std::chrono::milliseconds interval,
std::function<void (const uint64_t)> callback,
uint32_t flags,
uint64_t uid);
bool operator== (const TimerInfo &other) const;
bool Matches (const std::string &packageName) const;
};
}// MiscService
}// OHOSw
#endif
+104
View File
@@ -0,0 +1,104 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIMER_MANAGER_H
#define TIMER_MANAGER_H
#include <mutex>
#include <thread>
#include <atomic>
#include <vector>
#include <chrono>
#include <functional>
#include <map>
#include <random>
#include "timer_handler.h"
#include "batch.h"
#include <inttypes.h>
namespace OHOS{
namespace MiscServices{
class TimerManager : public ITimerManager {
public:
static std::shared_ptr<TimerManager> Create();
uint64_t CreateTimer(int type, uint64_t windowLength, uint64_t interval,int flag,
std::function<void (const uint64_t)> 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<TimerHandler> impl);
void TimerLooper();
void SetHandler(uint64_t id, int type, uint64_t triggerAtTime, uint64_t windowLength, uint64_t interval, int flag,
std::function<void (const uint64_t)> callback,
uint64_t uid);
void SetHandlerLocked(uint64_t id, int type,
std::chrono::milliseconds when,
std::chrono::steady_clock::time_point whenElapsed,
std::chrono::milliseconds windowLength,
std::chrono::steady_clock::time_point maxWhen,
std::chrono::milliseconds interval,
std::function<void (const uint64_t)> 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<TimerInfo> timer,
std::chrono::steady_clock::time_point nowElapsed, bool doValidate);
void SetHandlerLocked(std::shared_ptr<TimerInfo> alarm, bool rebatching, bool doValidate);
void InsertAndBatchTimerLocked(std::shared_ptr<TimerInfo> alarm);
int64_t AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed,
std::chrono::steady_clock::time_point maxWhen);
bool TriggerTimersLocked(std::vector<std::shared_ptr<TimerInfo>> &triggerList,
std::chrono::steady_clock::time_point nowElapsed);
void RescheduleKernelTimerLocked();
void DeliverTimersLocked(const std::vector<std::shared_ptr<TimerInfo>> &triggerList,
std::chrono::steady_clock::time_point nowElapsed);
std::shared_ptr<Batch> FindFirstWakeupBatchLocked();
void SetLocked(int type, std::chrono::nanoseconds when);
std::chrono::steady_clock::time_point ConvertToElapsed(std::chrono::milliseconds when, int type);
std::map<uint64_t, std::shared_ptr<TimerEntry>> timerEntryMap_;
std::default_random_engine random_;
std::atomic_bool runFlag_;
std::shared_ptr<TimerHandler> handler_;
std::unique_ptr<std::thread> alarmThread_;
std::vector<std::shared_ptr<Batch>> 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
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIMER_MANAGER_INTERFACE_H
#define TIMER_MANAGER_INTERFACE_H
#include <memory>
#include "want_agent.h"
namespace OHOS {
namespace MiscServices {
struct TimerEntry {
uint64_t id;
int type;
uint64_t windowLength;
uint64_t interval;
int flag;
std::function<void (const uint64_t)> callback;
uint64_t uid;
};
class ITimerManager {
public:
enum TimerFlag {
STANDALONE = 1 << 0,
WAKE_FROM_IDLE = 1 << 1,
ALLOW_WHILE_IDLE = 1 << 2,
ALLOW_WHILE_IDLE_UNRESTRICTED = 1 << 3,
IDLE_UNTIL = 1 << 4,
};
enum TimerType {
RTC_WAKEUP = 0,
RTC = 1,
ELAPSED_REALTIME_WAKEUP = 2,
ELAPSED_REALTIME = 3
};
virtual uint64_t CreateTimer (int type, uint64_t windowLength, uint64_t interval, int flag,
std::function<void (const uint64_t)> callback,
uint64_t uid) = 0;
virtual bool StartTimer (uint64_t timerNumber, uint64_t triggerTime) = 0;
virtual bool StopTimer (uint64_t timerNumber) = 0;
virtual bool DestroyTimer (uint64_t timerNumber) = 0;
virtual ~ITimerManager () = default;
};// ITimerManager
}// MiscService
}// OHOS
#endif
+149
View File
@@ -0,0 +1,149 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "batch.h"
#include <algorithm>
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<TimerInfo> (seed)}
{
}
size_t Batch::Size () const
{
return alarms_.size ();
}
std::shared_ptr<TimerInfo> 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<TimerInfo> &alarm)
{
bool new_start = false;
auto it = std::upper_bound (alarms_.begin (), alarms_.end (), alarm,
[] (const std::shared_ptr<TimerInfo> &first, const std::shared_ptr<TimerInfo> &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<bool (const TimerInfo &)> predicate)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start");
bool didRemove = false;
auto newStart = std::chrono::steady_clock::time_point::min ();
auto newEnd = std::chrono::steady_clock::time_point::max ();
uint32_t newFlags = 0;
for (auto it = alarms_.begin (); it != alarms_.end ();) {
auto alarm = *it;
TIME_HILOGD(TIME_MODULE_SERVICE, "looper");
if (predicate (*alarm)) {
TIME_HILOGD(TIME_MODULE_SERVICE, "erase");
it = alarms_.erase(it);
didRemove = true;
} else {
if (alarm->whenElapsed > newStart) {
newStart = alarm->whenElapsed;
}
if (alarm->maxWhenElapsed < newEnd) {
newEnd = alarm->maxWhenElapsed;
}
newFlags |= alarm->flags;
++it;
}
}
TIME_HILOGD(TIME_MODULE_SERVICE, "end");
if (didRemove) {
start_ = newStart;
end_ = newEnd;
flags_ = newFlags;
}
return didRemove;
}
bool Batch::HasPackage (const std::string &package_name)
{
return std::find_if (alarms_.begin (), alarms_.end (),
[package_name] (const std::shared_ptr<TimerInfo> &alarm)
{ return alarm->Matches (package_name); }) != alarms_.end ();
}
bool Batch::HasWakeups () const
{
return std::any_of (alarms_.begin (), alarms_.begin (),
[] (const std::shared_ptr<TimerInfo> &item)
{
return (static_cast<uint32_t>(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
+146
View File
@@ -0,0 +1,146 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/epoll.h>
#include <iostream>
#include <cstring>
#include <sys/timerfd.h>
#include <unistd.h>
#include "timer_handler.h"
#include <linux/rtc.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <sys/time.h>
#include <sstream>
#include <fstream>
namespace OHOS {
namespace MiscServices {
static constexpr int ALARM_TIME_CHANGE_MASK = 1 << 16;
static const clockid_t alarm_to_clock_id[N_TIMER_FDS] = {
CLOCK_REALTIME_ALARM,
CLOCK_REALTIME,
CLOCK_BOOTTIME_ALARM,
CLOCK_BOOTTIME,
CLOCK_MONOTONIC,
CLOCK_REALTIME,
};
std::shared_ptr<TimerHandler> TimerHandler::Create()
{
int epollfd;
TimerFds fds;
epollfd = epoll_create (fds.size ());
if (epollfd < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE, "epoll_create %{public}d failed: %{public}s", static_cast<int>(fds.size()), strerror (errno));
return nullptr;
}
for (size_t i = 0; i < fds.size (); i++) {
fds[i] = timerfd_create (alarm_to_clock_id[i], 0);
if (fds[i] < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE, "timerfd_create %{public}d failed: %{public}s", static_cast<int>(i), strerror (errno));
close (epollfd);
for (size_t j = 0; j < i; j++) {
close (fds[j]);
}
return nullptr;
}
}
auto handler = std::shared_ptr<TimerHandler> (new TimerHandler (fds, epollfd));
for (size_t i = 0; i < fds.size (); i++) {
epoll_event event{};
event.events = EPOLLIN | EPOLLWAKEUP;
event.data.u32 = i;
int err = epoll_ctl (epollfd, EPOLL_CTL_ADD, fds[i], &event);
if (err < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE, "epoll_ctl(EPOLL_CTL_ADD) failed: %{public}s", strerror (errno));
return nullptr;
}
}
itimerspec spec{};
int err = timerfd_settime (fds[ALARM_TYPE_COUNT], TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &spec, nullptr);
if (err < 0) {
TIME_HILOGE(TIME_MODULE_SERVICE, "timerfd_settime() failed: %{public}s", strerror(errno));
return nullptr;
}
return handler;
}
TimerHandler::TimerHandler (const TimerFds &fds, int epollfd)
: fds_{fds}, epollFd_{epollfd}
{
}
TimerHandler::~TimerHandler()
{
for (auto fd : fds_) {
epoll_ctl (epollFd_, EPOLL_CTL_DEL, fd, nullptr);
close (fd);
}
close (epollFd_);
}
int TimerHandler::Set (uint32_t type, std::chrono::nanoseconds when)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "type= %{public}d, when= %{public}lld", type, when.count());
if (static_cast<size_t>(type) > ALARM_TYPE_COUNT) {
errno = EINVAL;
return -1;
}
auto second = std::chrono::duration_cast<std::chrono::seconds> (when);
timespec ts { second.count (), (when - second).count()};
itimerspec spec{timespec{}, ts};
return timerfd_settime (fds_[type], TFD_TIMER_ABSTIME, &spec, nullptr);
}
int TimerHandler::WaitForAlarm()
{
epoll_event events[N_TIMER_FDS];
int nevents = epoll_wait (epollFd_, events, N_TIMER_FDS, -1);
if (nevents < 0){
return nevents;
}
int result = 0;
for (int i = 0; i < nevents; i++) {
uint32_t alarm_idx = events[i].data.u32;
uint64_t unused;
ssize_t err = read (fds_[alarm_idx], &unused, sizeof (unused));
if (err < 0) {
if (alarm_idx == ALARM_TYPE_COUNT && errno == ECANCELED) {
result |= ALARM_TIME_CHANGE_MASK;
} else {
return err;
}
} else {
result |= (1 << alarm_idx);
}
}
return result;
}
} // MiscServices
} // OHOS
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer_info.h"
namespace OHOS {
namespace MiscServices {
bool TimerInfo::operator== (const TimerInfo &other) const{
return this->id == other.id;
}
bool TimerInfo::Matches (const std::string &packageName) const{
return false;
}
TimerInfo::TimerInfo (uint64_t _id, int _type,
std::chrono::milliseconds _when,
std::chrono::steady_clock::time_point _whenElapsed,
std::chrono::milliseconds _windowLength,
std::chrono::steady_clock::time_point _maxWhen,
std::chrono::milliseconds _interval,
std::function<void (const uint64_t)> _callback,
uint32_t _flags,
uint64_t _uid)
: id{_id},
type{_type},
origWhen{_when},
wakeup{_type == ITimerManager::ELAPSED_REALTIME_WAKEUP || _type == ITimerManager::RTC_WAKEUP},
callback{std::move (_callback)},
flags{_flags},
uid{_uid},
when{_when},
windowLength{_windowLength},
whenElapsed{_whenElapsed},
maxWhenElapsed{_maxWhen},
expectedWhenElapsed{_whenElapsed},
expectedMaxWhenElapsed{_maxWhen},
repeatInterval{_interval}
{
}
} // MiscServices
} // OHOS
+487
View File
@@ -0,0 +1,487 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "timer_manager.h"
#include <utility>
#include <vector>
#include <algorithm>
#include <time.h>
#include <iostream>
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<std::shared_ptr<Batch>> &list, const std::shared_ptr<Batch> &batch);
extern steady_clock::time_point MaxTriggerTime(steady_clock::time_point now,
steady_clock::time_point triggerAtTime,
milliseconds interval);
std::shared_ptr<TimerManager> TimerManager::Create()
{
auto impl = TimerHandler::Create();
if (impl == nullptr){
TIME_HILOGE(TIME_MODULE_SERVICE,"Create Timer handle failed.");
return nullptr;
}
return std::shared_ptr<TimerManager>(new TimerManager(impl));
}
TimerManager::TimerManager(std::shared_ptr<TimerHandler> impl)
: random_{static_cast<uint64_t>(time(nullptr))},
runFlag_{false},
handler_{std::move(impl)},
lastTimeChangeClockTime_{system_clock::time_point::min()},
lastTimeChangeRealtime_{steady_clock::time_point::min()}
{
runFlag_ = true;
alarmThread_.reset(new std::thread(&TimerManager::TimerLooper, this));
}
uint64_t TimerManager::CreateTimer(int type, uint64_t windowLength, uint64_t interval, int flag,
std::function<void (const uint64_t)> callback, uint64_t uid)
{
TIME_HILOGI(TIME_MODULE_SERVICE,"Create timer: %{public}d windowLength:%{public}" PRId64 "interval:%{public}" PRId64 "flag:%{public}d", type, windowLength, interval, flag);
uint64_t timerNumber = 0;
while (timerNumber == 0){
timerNumber = random_();
}
auto timerInfo = std::make_shared<TimerEntry>(TimerEntry{timerNumber, type,windowLength,
interval, flag, std::move(callback), uid});
std::lock_guard<std::mutex> lock(entryMapMutex_);
timerEntryMap_.insert(std::make_pair(timerNumber, timerInfo));
return timerNumber;
}
bool TimerManager::StartTimer(uint64_t timerNumber, uint64_t triggerTime)
{
std::lock_guard<std::mutex> lock(entryMapMutex_);
auto it = timerEntryMap_.find(timerNumber);
if (it == timerEntryMap_.end()){
TIME_HILOGE(TIME_MODULE_SERVICE,"Timer id not found: %{public}" PRId64 "", timerNumber);
return false;
}
TIME_HILOGI(TIME_MODULE_SERVICE,"Start timer : %{public}" PRId64 "", timerNumber);
TIME_HILOGI(TIME_MODULE_SERVICE,"TriggerTime : %{public}" PRId64 "", triggerTime);
auto timerInfo = it->second;
SetHandler(timerInfo->id,
timerInfo->type,
triggerTime,
timerInfo->windowLength,
timerInfo->interval,
timerInfo->flag,
timerInfo->callback,
timerInfo->uid);
return true;
}
bool TimerManager::StopTimer(uint64_t timerNumber)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start.");
std::lock_guard<std::mutex> lock(entryMapMutex_);
auto it = timerEntryMap_.find(timerNumber);
if (it == timerEntryMap_.end()){
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return false;
}
RemoveHandler(timerNumber);
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return true;
}
bool TimerManager::DestroyTimer(uint64_t timerNumber)
{
TIME_HILOGD(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "", timerNumber);
std::lock_guard<std::mutex> lock(entryMapMutex_);
auto it = timerEntryMap_.find(timerNumber);
if (it == timerEntryMap_.end()){
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return false;
}
RemoveHandler(timerNumber);
timerEntryMap_.erase(it);
TIME_HILOGD(TIME_MODULE_SERVICE, "end.");
return true;
}
void TimerManager::SetHandler(uint64_t id, int type, uint64_t triggerAtTime, uint64_t windowLength, uint64_t interval, int flag,
std::function<void (const uint64_t)> callback, uint64_t uid)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "",id);
TIME_HILOGI(TIME_MODULE_SERVICE, "start type : %{public}d windowLength:%{public}" PRId64 "interval:%{public}" PRId64 "flag:%{public}d", type, windowLength, interval, flag);
auto windowLengthDuration = milliseconds(windowLength);
if (windowLengthDuration > INTERVAL_HALF_DAY){
windowLengthDuration = INTERVAL_HOUR;
}
auto intervalDuration = milliseconds(interval);
if (intervalDuration > milliseconds::zero() && intervalDuration < MIN_INTERVAL){
intervalDuration = MIN_INTERVAL;
}else if (intervalDuration > MAX_INTERVAL){
intervalDuration = MAX_INTERVAL;
}
if (triggerAtTime < 0){
triggerAtTime = 0;
}
auto nowElapsed = steady_clock::now();
auto nominalTrigger = ConvertToElapsed(milliseconds(triggerAtTime), type);
auto minTrigger = nowElapsed + MIN_FUTURITY;
auto triggerElapsed = (nominalTrigger > minTrigger) ? nominalTrigger : minTrigger;
steady_clock::time_point maxElapsed;
if (windowLengthDuration == milliseconds::zero()){
maxElapsed = triggerElapsed;
} else if (windowLengthDuration < milliseconds::zero()){
maxElapsed = MaxTriggerTime(nominalTrigger, triggerElapsed, intervalDuration);
windowLengthDuration = duration_cast<milliseconds>(maxElapsed - triggerElapsed);
} else {
maxElapsed = triggerElapsed + windowLengthDuration;
}
TIME_HILOGI(TIME_MODULE_SERVICE, "Try get lock");
std::lock_guard<std::mutex> lockGuard(mutex_);
TIME_HILOGI(TIME_MODULE_SERVICE, "Lock guard");
SetHandlerLocked(id,type, milliseconds(triggerAtTime),triggerElapsed, windowLengthDuration, maxElapsed,
intervalDuration, std::move(callback), static_cast<uint32_t>(flag), true, uid);
}
void TimerManager::SetHandlerLocked(uint64_t id, int type,
std::chrono::milliseconds when,
std::chrono::steady_clock::time_point whenElapsed,
std::chrono::milliseconds windowLength,
std::chrono::steady_clock::time_point maxWhen,
std::chrono::milliseconds interval,
std::function<void (const uint64_t)> callback,
uint32_t flags,
bool doValidate,
uint64_t callingUid)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "", id);
auto alarm = std::make_shared<TimerInfo>(id, type, when, whenElapsed, windowLength, maxWhen,
interval, std::move(callback), flags, callingUid);
SetHandlerLocked(alarm, false, doValidate);
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
void TimerManager::RemoveHandler(uint64_t id)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
std::lock_guard<std::mutex> lock(mutex_);
RemoveLocked(id);
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
void TimerManager::RemoveLocked(uint64_t id)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "",id);
auto whichAlarms = [id](const TimerInfo &timer) {
return timer.id == id;
};
bool didRemove = false;
for (auto it = alarmBatches_.begin(); it != alarmBatches_.end();) {
auto batch = *it;
didRemove |= batch->Remove(whichAlarms);
if (batch->Size() == 0) {
TIME_HILOGD(TIME_MODULE_SERVICE, "erase");
it = alarmBatches_.erase(it);
}else{
++it;
}
}
if (didRemove) {
ReBatchAllTimersLocked(true);
}
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
void TimerManager::SetHandlerLocked(std::shared_ptr<TimerInfo> alarm, bool rebatching, bool doValidate)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
TIME_HILOGI(TIME_MODULE_SERVICE, "rebatching= %{public}d, doValidate= %{public}d", rebatching, doValidate);
InsertAndBatchTimerLocked(std::move(alarm));
if (!rebatching) {
RescheduleKernelTimerLocked();
}
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
void TimerManager::ReBatchAllTimers()
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
ReBatchAllTimersLocked(true);
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
void TimerManager::ReBatchAllTimersLocked(bool doValidate){
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
auto oldSet = alarmBatches_;
alarmBatches_.clear();
auto nowElapsed = steady_clock::now();
for (const auto &batch : oldSet){
auto n = batch->Size();
for (unsigned int i = 0; i < n; i++){
ReAddTimerLocked(batch->Get(i), nowElapsed, doValidate);
}
}
RescheduleKernelTimerLocked();
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
void TimerManager::ReAddTimerLocked(std::shared_ptr<TimerInfo> timer, std::chrono::steady_clock::time_point nowElapsed, bool doValidate){
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
timer->when = timer->origWhen;
auto whenElapsed = ConvertToElapsed(timer->when, timer->type);
steady_clock::time_point maxElapsed;
if (timer->windowLength == milliseconds::zero()) {
maxElapsed = whenElapsed;
} else {
maxElapsed = (timer->windowLength > milliseconds::zero()) ? whenElapsed + timer->windowLength
: MaxTriggerTime(nowElapsed, whenElapsed, timer->repeatInterval);
}
timer->whenElapsed = whenElapsed;
timer->maxWhenElapsed = maxElapsed;
SetHandlerLocked(timer, true, doValidate);
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
std::chrono::steady_clock::time_point TimerManager::ConvertToElapsed(std::chrono::milliseconds when, int type)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
if (type == RTC || type == RTC_WAKEUP){
auto offset = when - system_clock::now().time_since_epoch();
return steady_clock::now() + offset;
}
auto offset = when - steady_clock::now().time_since_epoch();
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
return steady_clock::now() + offset;
}
void TimerManager::TimerLooper()
{
TIME_HILOGI(TIME_MODULE_SERVICE,"Start timer wait loop");
std::vector<std::shared_ptr<TimerInfo>> triggerList;
while (runFlag_) {
int result = 0;
do {
result = handler_->WaitForAlarm();
} while (result < 0 && errno == EINTR);
TIME_HILOGI(TIME_MODULE_SERVICE, "result= %{public}d", result);
auto nowRtc = std::chrono::system_clock::now();
auto nowElapsed = std::chrono::steady_clock::now();
triggerList.clear();
if ((result & TIME_CHANGED_MASK) != 0) {
TIME_HILOGI(TIME_MODULE_SERVICE, "time changed");
system_clock::time_point lastTimeChangeClockTime;
system_clock::time_point expectedClockTime;
TIME_HILOGI(TIME_MODULE_SERVICE, "lock");
std::lock_guard<std::mutex> lock(mutex_);
lastTimeChangeClockTime = lastTimeChangeClockTime_;
expectedClockTime = lastTimeChangeClockTime + (duration_cast<milliseconds>(nowElapsed.time_since_epoch()) -
duration_cast<milliseconds>(lastTimeChangeRealtime_.time_since_epoch()));
if (lastTimeChangeClockTime == system_clock::time_point::min()
|| nowRtc < (expectedClockTime - milliseconds(1000))
|| nowRtc > (expectedClockTime + milliseconds(1000))) {
TIME_HILOGI(TIME_MODULE_SERVICE, "Time changed notification from kernel; rebatching");
ReBatchAllTimers();
lastTimeChangeClockTime_ = nowRtc;
lastTimeChangeRealtime_ = nowElapsed;
}
}
if (result != TIME_CHANGED_MASK) {
std::lock_guard<std::mutex> lock(mutex_);
auto hasWakeup = TriggerTimersLocked(triggerList, nowElapsed);
TIME_HILOGI(TIME_MODULE_SERVICE, "hasWakeup= %{public}d", hasWakeup);
DeliverTimersLocked(triggerList, nowElapsed);
RescheduleKernelTimerLocked();
} else {
std::lock_guard<std::mutex> lock(mutex_);
RescheduleKernelTimerLocked();
}
}
}
TimerManager::~TimerManager()
{
if (alarmThread_ && alarmThread_->joinable()) {
alarmThread_->join();
}
}
bool TimerManager::TriggerTimersLocked(std::vector<std::shared_ptr<TimerInfo>> &triggerList,
std::chrono::steady_clock::time_point nowElapsed)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", static_cast<int>(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<nanoseconds>(batch->GetStart()).time_since_epoch().count());
TIME_HILOGI(TIME_MODULE_SERVICE, "nowElapsed= %{public}lld", time_point_cast<nanoseconds>(nowElapsed).time_since_epoch().count());
if (batch->GetStart() > nowElapsed) {
TIME_HILOGI(TIME_MODULE_SERVICE, "break alarmBatches_.size= %{public}d", static_cast<int>(alarmBatches_.size()));
break;
}
alarmBatches_.erase(alarmBatches_.begin());
TIME_HILOGI(TIME_MODULE_SERVICE, "after erase alarmBatches_.size= %{public}d", static_cast<int>(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<milliseconds>(nowElapsed - alarm->expectedWhenElapsed) / alarm->repeatInterval;
auto delta = alarm->count * alarm->repeatInterval;
auto nextElapsed = alarm->whenElapsed + delta;
SetHandlerLocked(alarm->id, alarm->type, alarm->when + delta, nextElapsed, alarm->windowLength,
MaxTriggerTime(nowElapsed, nextElapsed, alarm->repeatInterval), alarm->repeatInterval,
nullptr, alarm->flags, true, alarm->uid);
}
if (alarm->wakeup) {
hasWakeup = true;
}
}
}
std::sort(triggerList.begin(), triggerList.end(),
[](const std::shared_ptr<TimerInfo> &l,
const std::shared_ptr<TimerInfo> &r){return l->whenElapsed < r->whenElapsed;});
return hasWakeup;
}
void TimerManager::RescheduleKernelTimerLocked()
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
TIME_HILOGI(TIME_MODULE_SERVICE, "alarmBatches_.size= %{public}d", static_cast<int>(alarmBatches_.size()));
auto nextNonWakeup = std::chrono::steady_clock::time_point::min();
if (!alarmBatches_.empty()) {
auto firstWakeup = FindFirstWakeupBatchLocked();
auto firstBatch = alarmBatches_.front();
if (firstWakeup != nullptr) {
SetLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup->GetStart().time_since_epoch());
}
if (firstBatch != firstWakeup) {
nextNonWakeup = firstBatch->GetStart();
}
}
if (nextNonWakeup != std::chrono::steady_clock::time_point::min()) {
SetLocked(ELAPSED_REALTIME, nextNonWakeup.time_since_epoch());
}
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
std::shared_ptr<Batch> TimerManager::FindFirstWakeupBatchLocked()
{
auto it = std::find_if(alarmBatches_.begin(),alarmBatches_.end(),
[](const std::shared_ptr<Batch> &batch)
{
return batch->HasWakeups();
});
return it != alarmBatches_.end() ? *it : nullptr;
}
void TimerManager::SetLocked(int type, std::chrono::nanoseconds when)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
TIME_HILOGI(TIME_MODULE_SERVICE, "when.count= %{public}lld", when.count());
handler_->Set(static_cast<uint32_t>(type), when);
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
void TimerManager::InsertAndBatchTimerLocked(std::shared_ptr<TimerInfo> alarm)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
int64_t whichBatch = (alarm->flags & static_cast<uint32_t>(STANDALONE)) ? -1
: AttemptCoalesceLocked(alarm->whenElapsed, alarm->maxWhenElapsed);
TIME_HILOGI(TIME_MODULE_SERVICE, "whichBatch= %{public}" PRId64 "", whichBatch);
if (whichBatch < 0) {
AddBatchLocked(alarmBatches_, std::make_shared<Batch>(*alarm));
} else {
auto batch = alarmBatches_.at(whichBatch);
if (batch->Add(alarm)) {
alarmBatches_.erase(alarmBatches_.begin() + whichBatch);
AddBatchLocked(alarmBatches_, batch);
}
}
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
int64_t TimerManager::AttemptCoalesceLocked(std::chrono::steady_clock::time_point whenElapsed,
std::chrono::steady_clock::time_point maxWhen)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
int64_t i = 0;
for (const auto &item : alarmBatches_) {
if ((item->GetFlags() & static_cast<uint32_t>(STANDALONE)) == 0 && item->CanHold(whenElapsed, maxWhen)) {
return i;
}
// ++i;
}
return -1;
}
void TimerManager::DeliverTimersLocked(const std::vector<std::shared_ptr<TimerInfo>> &triggerList,
std::chrono::steady_clock::time_point nowElapsed){
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
for (const auto &alarm : triggerList) {
if (alarm->callback) {
alarm->callback(alarm->id);
TIME_HILOGI(TIME_MODULE_SERVICE, "Trigger id: %{public}" PRId64 "", alarm->id);
}
}
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
}
bool AddBatchLocked(std::vector<std::shared_ptr<Batch>> &list, const std::shared_ptr<Batch> &newBatch)
{
TIME_HILOGI(TIME_MODULE_SERVICE, "start");
auto it = std::upper_bound(list.begin(), list.end(), newBatch,
[](const std::shared_ptr<Batch> &first, const std::shared_ptr<Batch> &second)
{
return first->GetStart() < second->GetStart();
});
list.insert(it, newBatch);
TIME_HILOGI(TIME_MODULE_SERVICE, "end");
return it == list.begin();
}
steady_clock::time_point MaxTriggerTime(steady_clock::time_point now, steady_clock::time_point triggerAtTime, milliseconds interval){
milliseconds futurity = (interval == milliseconds::zero()) ? duration_cast<milliseconds>(triggerAtTime - now) : interval;
if (futurity < MIN_FUZZABLE_INTERVAL) {
futurity = milliseconds::zero();
}
return triggerAtTime + milliseconds(static_cast<long>(0.75 * futurity.count()));
}
} // MiscServices
} // OHOS
+7 -4
View File
@@ -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"
time_utils_path = "${time_root_path}/utils"
adapter_path = "${time_root_path}/adapter"
+51
View File
@@ -0,0 +1,51 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/miscservices/time/time.gni")
config("utils_config") {
include_dirs = [
"mock/include",
"native/include",
"//utils/native/base/include",
"/foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk/include/",
]
}
ohos_source_set("time_utils") {
sources = [
"mock/src/mock_permission.cpp",
"native/src/time_permission.cpp",
]
public_configs = [ ":utils_config" ]
deps = [
"//utils/native/base:utils",
"//foundation/aafwk/standard/interfaces/innerkits/base:base",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_rdb:native_rdb",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_appdatafwk:native_appdatafwk",
"//foundation/distributeddatamgr/appdatamgr/interfaces/innerkits/native_preferences:native_preferences",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
part_name = "time_native"
}
+30 -35
View File
@@ -1,35 +1,30 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_SERVICE_STUB_H
#define SERVICES_INCLUDE_TIME_SERVICE_STUB_H
#include "iremote_stub.h"
#include "time_service_interface.h"
namespace OHOS {
namespace MiscServices {
class TimeServiceStub : public IRemoteStub<ITimeService> {
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
/*
* 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 <string>
#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
+29
View File
@@ -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
+52 -38
View File
@@ -1,39 +1,53 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_COMMON_H
#define SERVICES_INCLUDE_TIME_COMMON_H
#include "errors.h"
namespace OHOS {
namespace MiscServices {
enum TimeModule {
TIME_MODULE_SERVICE = 0x04,
};
// time error offset, used only in this file.
constexpr ErrCode TIME_ERR_OFFSET = ErrCodeOffset(SUBSYS_SMALLSERVICES, TIME_MODULE_SERVICE);
enum TimeError {
SUCCESS = ERR_OK, // Operation success
E_WRITE_PARCEL_ERROR = TIME_ERR_OFFSET,
E_READ_PARCEL_ERROR,
E_PUBLISH_FAIL,
E_TRANSACT_ERROR,
};
} // namespace MiscServices
} // namespace OHOS
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INCLUDE_TIME_COMMON_H
#define SERVICES_INCLUDE_TIME_COMMON_H
#include "errors.h"
#include "time_hilog_wreapper.h"
namespace OHOS {
namespace MiscServices {
#define TIME_SERVICE_NAME "TimeService"
enum TimeModule {
TIME_MODULE_SERVICE_ID = 0x04,
};
// time error offset, used only in this file.
constexpr ErrCode TIME_ERR_OFFSET = ErrCodeOffset(SUBSYS_SMALLSERVICES, TIME_MODULE_SERVICE_ID);
enum TimeError {
E_TIME_OK = TIME_ERR_OFFSET,
E_TIME_SA_DIED,
E_TIME_READ_PARCEL_ERROR,
E_TIME_WRITE_PARCEL_ERROR,
E_TIME_PUBLISH_FAIL,
E_TIME_TRANSACT_ERROR,
E_TIME_DEAL_FAILED,
E_TIME_PARAMETERS_INVALID,
E_TIME_SET_RTC_FAILED,
E_TIME_NOT_FOUND,
E_TIME_NO_PERMISSION,
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_TIME_COMMON_H
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIME_HILOG_WRAPPER_H
#define TIME_HILOG_WRAPPER_H
#include "hilog/log.h"
namespace OHOS {
namespace MiscServices {
// param of log interface, such as TIME_HILOGF.
enum TimeSubModule {
TIME_MODULE_INNERKIT = 0,
TIME_MODULE_CLIENT,
TIME_MODULE_SERVICE,
TIME_MODULE_JAVAKIT, // java kit, defined to avoid repeated use of domain.
TIME_MODULE_JNI,
TIME_MODULE_COMMON,
TIME_MODULE_JS_NAPI,
TIME_MODULE_BUTT,
};
// 0xD001C00: subsystem:TIME module:TimeManager, 8 bits reserved.
static constexpr unsigned int BASE_TIME_DOMAIN_ID = 0xD001C00;
enum TimeDomainId {
TIME_INNERKIT_DOMAIN = BASE_TIME_DOMAIN_ID + TIME_MODULE_INNERKIT,
TIME_CLIENT_DOMAIN,
TIME_SERVICE_DOMAIN,
TIME_JAVAKIT_DOMAIN,
TIME_JNI_DOMAIN,
TIME_COMMON_DOMAIN,
TIME_JS_NAPI,
TIME_BUTT,
};
static constexpr OHOS::HiviewDFX::HiLogLabel TIME_MODULE_LABEL[TIME_MODULE_BUTT] = {
{LOG_CORE, TIME_INNERKIT_DOMAIN, "TimeInnerKit"},
{LOG_CORE, TIME_CLIENT_DOMAIN, "TimeClient"},
{LOG_CORE, TIME_SERVICE_DOMAIN, "TimeService"},
{LOG_CORE, TIME_JAVAKIT_DOMAIN, "TimeJavaKit"},
{LOG_CORE, TIME_JNI_DOMAIN, "TimeJni"},
{LOG_CORE, TIME_COMMON_DOMAIN, "TimeCommon"},
{LOG_CORE, TIME_JS_NAPI, "TimeJSNAPI"},
};
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
#define __FORMATED(fmt, ...) "[%{public}s] %{public}s# " fmt, __FILENAME__, __FUNCTION__, ##__VA_ARGS__
// In order to improve performance, do not check the module range.
// Besides, make sure module is less than TIME_MODULE_BUTT.
#define TIME_HILOGF(module, ...) (void)OHOS::HiviewDFX::HiLog::Fatal(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__))
#define TIME_HILOGE(module, ...) (void)OHOS::HiviewDFX::HiLog::Error(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__))
#define TIME_HILOGW(module, ...) (void)OHOS::HiviewDFX::HiLog::Warn(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__))
#define TIME_HILOGI(module, ...) (void)OHOS::HiviewDFX::HiLog::Info(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__))
#define TIME_HILOGD(module, ...) (void)OHOS::HiviewDFX::HiLog::Debug(TIME_MODULE_LABEL[module], __FORMATED(__VA_ARGS__))
} // namespace MiscServices
} // namespace OHOS
#endif // TIME_HILOG_WRAPPER_H
+48
View File
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TIME_PERMISSION_H
#define TIME_PERMISSION_H
#include "bundle_mgr_interface.h"
#include "time_common.h"
#include "mock_permission.h"
#include "system_ability_definition.h"
#include "iservice_registry.h"
#include "refbase.h"
#include <mutex>
#include <string>
namespace OHOS {
namespace MiscServices {
class TimePermission : public RefBase{
public:
static sptr<TimePermission> GetInstance();
bool CheckSelfPermission(const std::string permName);
bool CheckCallingPermission(const int32_t uid, const std::string permName);
private:
TimePermission();
~TimePermission();
sptr<AppExecFwk::IBundleMgr> GetBundleManager();
static std::mutex instanceLock_;
static sptr<TimePermission> instance_;
static sptr<AppExecFwk::IBundleMgr> bundleMgrProxy_;
};
} // namespace MiscServices
} // namespace OHOS
#endif // TIME_PERMISSION_H
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "rdb_errno.h"
#include "rdb_helper.h"
#include <mutex>
namespace OHOS {
namespace MiscServices {
using namespace OHOS::NativeRdb;
class TimeOpenCallback : public RdbOpenCallback {
public:
int OnCreate(RdbStore &rdbStore) override;
int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override;
static const std::string CREATE_TIMEZONE_DB;
};
std::string const TimeOpenCallback::CREATE_TIMEZONE_DB = std::string("CREATE TABLE IF NOT EXISTS timezone ")
+ std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"timezoneId TEXT NOT NULL)");
int TimeOpenCallback::OnCreate(RdbStore &store)
{
return store.ExecuteSql(CREATE_TIMEZONE_DB);
}
int TimeOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
{
return E_OK;
}
bool InsertTimeZoneIdToRdb(const std::string timeZoneId){
const std::string dbPath_ = "/data/misc/zoneinfo/";
const std::string dbName_ = "systime.db";
RdbStoreConfig config(dbPath_+ dbName_);
TimeOpenCallback helper;
int errCode = E_OK;
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
if (store == nullptr){
return false;
}
int deletedRows;
store->Delete(deletedRows, "timezone", "id = 1");
int64_t id;
ValuesBucket values;
values.PutInt("id", 1);
values.PutString("timezoneId", timeZoneId);
auto ret = store->Insert(id, "timezone", values);
TIME_HILOGD(TIME_MODULE_SERVICE,"end.");
return ret == E_OK;
}
bool GetTimeZoneId(std::string &timeZoneId){
const std::string dbPath_ = "/data/misc/zoneinfo/";
const std::string dbName_ = "systime.db";
RdbStoreConfig config(dbPath_+ dbName_);
TimeOpenCallback helper;
int errCode = E_OK;
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
if (store == nullptr){
return false;
}
std::unique_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM timezone");
if (resultSet == nullptr){
TIME_HILOGD(TIME_MODULE_SERVICE,"not found");
return false;
}
int columnIndex;
std::string strVal;
auto ret = resultSet->GoToFirstRow();
if (ret != E_OK){
return false;
}
ret = resultSet->GetColumnIndex("timezoneId", columnIndex);
if (ret != E_OK){
return false;
}
ret = resultSet->GetString(columnIndex, strVal);
if (ret != E_OK){
return false;
}
timeZoneId = strVal;
return E_OK;
}
}
}
+88
View File
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "time_permission.h"
namespace OHOS {
namespace MiscServices {
std::mutex TimePermission::instanceLock_;
sptr<TimePermission> TimePermission::instance_;
sptr<AppExecFwk::IBundleMgr> TimePermission::bundleMgrProxy_;
TimePermission::TimePermission()
{
}
TimePermission::~TimePermission()
{
}
sptr<TimePermission> TimePermission::GetInstance()
{
if (instance_ == nullptr){
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
instance_ = new TimePermission;
}
}
return instance_;
}
bool TimePermission::CheckSelfPermission(std::string permName)
{
return true;
}
bool TimePermission::CheckCallingPermission(int32_t uid, std::string permName)
{
if (bundleMgrProxy_ == nullptr){
bundleMgrProxy_ = GetBundleManager();
TIME_HILOGI(TIME_MODULE_COMMON,"get bundle mgr");
}
if (bundleMgrProxy_ == nullptr){
TIME_HILOGE(TIME_MODULE_COMMON,"redo get bundle mgr failed");
return false;
}
std::string bundleName;
auto ret = bundleMgrProxy_->GetBundleNameForUid(uid, bundleName);
if (!ret){
TIME_HILOGE(TIME_MODULE_COMMON,"get bundle name failed");
// always true
return true;
}
auto userId = uid / 100000;
TIME_HILOGI(TIME_MODULE_COMMON,"VerifyPermission bundleName %{public}s, permission %{public}s", bundleName.c_str(), permName.c_str());
return MockPermission::VerifyPermission(bundleName, permName, userId);
}
sptr<AppExecFwk::IBundleMgr> TimePermission::GetBundleManager()
{
if (bundleMgrProxy_ == nullptr) {
sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemManager != nullptr) {
bundleMgrProxy_ =
iface_cast<AppExecFwk::IBundleMgr>(systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID));
} else {
TIME_HILOGE(TIME_MODULE_COMMON,"fail to get SAMGR");
}
}
return bundleMgrProxy_;
}
} // namespace MiscServices
} // namespace OHOS