mirror of
https://github.com/openharmony/miscservices_time.git
synced 2026-07-19 20:03:38 -04:00
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:
@@ -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",
|
||||
]
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
├── etc # 组件包含的进程的配置文件
|
||||
├── figures # 构架图
|
||||
├── interfaces # 组件对外提供的接口代码
|
||||
├ └── innerkits # 服务间接口
|
||||
│ └── kits # 对应用提供的接口
|
||||
├── profile # 组件包含的系统服务的配置文件
|
||||
└── services # 时间服务实现
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
Executable → Regular
+12
-2
@@ -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
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 ×) override;
|
||||
int32_t GetWallTimeNs(int64_t ×) override;
|
||||
int32_t GetBootTimeMs(int64_t ×) override;
|
||||
int32_t GetBootTimeNs(int64_t ×) override;
|
||||
int32_t GetMonotonicTimeMs(int64_t ×) override;
|
||||
int32_t GetMonotonicTimeNs(int64_t ×) override;
|
||||
int32_t GetThreadTimeMs(int64_t ×) override;
|
||||
int32_t GetThreadTimeNs(int64_t ×) override;
|
||||
|
||||
uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr<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 ×) = 0;
|
||||
|
||||
/**
|
||||
* GetWallTimeNs
|
||||
*
|
||||
* @param times result of times ,unit: Nanosecond
|
||||
* @return int32_t ERR_OK on success, other on failure.
|
||||
*/
|
||||
virtual int32_t GetWallTimeNs(int64_t ×) = 0;
|
||||
|
||||
/**
|
||||
* GetBootTimeMs
|
||||
*
|
||||
* @param times result of times ,unit: millisecond
|
||||
* @return int32_t ERR_OK on success, other on failure.
|
||||
*/
|
||||
virtual int32_t GetBootTimeMs(int64_t ×) = 0;
|
||||
|
||||
/**
|
||||
* GetBootTimeNs
|
||||
*
|
||||
* @param times result of times ,unit: millisecond
|
||||
* @return int32_t ERR_OK on success, other on failure.
|
||||
*/
|
||||
virtual int32_t GetBootTimeNs(int64_t ×) = 0;
|
||||
|
||||
/**
|
||||
* GetMonotonicTimeMs
|
||||
*
|
||||
* @param times result of times ,unit: millisecond
|
||||
* @return int32_t ERR_OK on success, other on failure.
|
||||
*/
|
||||
virtual int32_t GetMonotonicTimeMs(int64_t ×) = 0;
|
||||
|
||||
/**
|
||||
* GetMonotonicTimeNs
|
||||
*
|
||||
* @param times result of times ,unit: Nanosecond
|
||||
* @return int32_t ERR_OK on success, other on failure.
|
||||
*/
|
||||
virtual int32_t GetMonotonicTimeNs(int64_t ×) = 0;
|
||||
|
||||
/**
|
||||
* GetThreadTimeMs
|
||||
*
|
||||
* @param times result of times ,unit: millisecond
|
||||
* @return int32_t ERR_OK on success, other on failure.
|
||||
*/
|
||||
virtual int32_t GetThreadTimeMs(int64_t ×) = 0;
|
||||
|
||||
/**
|
||||
* GetThreadTimeNs
|
||||
*
|
||||
* @param times result of times ,unit: Nanosecond
|
||||
* @return int32_t ERR_OK on success, other on failure.
|
||||
*/
|
||||
virtual int32_t GetThreadTimeNs(int64_t ×) = 0;
|
||||
|
||||
/**
|
||||
* CreateTimer
|
||||
*
|
||||
* @param type timer type
|
||||
* @param repeat is repeat or not
|
||||
* @param timerCallback remoteobject
|
||||
* @return uint64_t > 0 on success, == 0 failure.
|
||||
*/
|
||||
virtual uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr<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
|
||||
Executable → Regular
+50
-35
@@ -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 ×) override;
|
||||
int32_t GetWallTimeNs(int64_t ×) override;
|
||||
int32_t GetBootTimeMs(int64_t ×) override;
|
||||
int32_t GetBootTimeNs(int64_t ×) override;
|
||||
int32_t GetMonotonicTimeMs(int64_t ×) override;
|
||||
int32_t GetMonotonicTimeNs(int64_t ×) override;
|
||||
int32_t GetThreadTimeMs(int64_t ×) override;
|
||||
int32_t GetThreadTimeNs(int64_t ×) override;
|
||||
uint64_t CreateTimer(int32_t type, bool repeat, uint64_t interval, sptr<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
|
||||
Executable → Regular
+32
-34
@@ -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
|
||||
|
||||
@@ -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 ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
|
||||
if(GetTimeByClockid(CLOCK_REALTIME, &tv)){
|
||||
times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
int32_t TimeService::GetWallTimeNs(int64_t ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
|
||||
if(GetTimeByClockid(CLOCK_REALTIME, &tv)){
|
||||
times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
int32_t TimeService::GetBootTimeMs(int64_t ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
|
||||
if(GetTimeByClockid(CLOCK_BOOTTIME, &tv)){
|
||||
times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
int32_t TimeService::GetBootTimeNs(int64_t ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
|
||||
if(GetTimeByClockid(CLOCK_BOOTTIME, &tv)){
|
||||
times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
int32_t TimeService::GetMonotonicTimeMs(int64_t ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
|
||||
if(GetTimeByClockid(CLOCK_MONOTONIC, &tv)){
|
||||
times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
|
||||
return ERR_OK;
|
||||
}
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
|
||||
int32_t TimeService::GetMonotonicTimeNs(int64_t ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
|
||||
if(GetTimeByClockid(CLOCK_MONOTONIC, &tv)){
|
||||
times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
|
||||
int32_t TimeService::GetThreadTimeMs(int64_t ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
int ret;
|
||||
clockid_t cid;
|
||||
ret = pthread_getcpuclockid(pthread_self(), &cid);
|
||||
if (ret != 0){
|
||||
return E_TIME_PARAMETERS_INVALID;
|
||||
}
|
||||
|
||||
if(GetTimeByClockid(cid, &tv)){
|
||||
times = tv.tv_sec * MILLI_TO_BASE + tv.tv_nsec / NANO_TO_MILLI;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
int32_t TimeService::GetThreadTimeNs(int64_t ×)
|
||||
{
|
||||
struct timespec tv{};
|
||||
int ret;
|
||||
clockid_t cid;
|
||||
ret = pthread_getcpuclockid(pthread_self(), &cid);
|
||||
if (ret != 0){
|
||||
return E_TIME_PARAMETERS_INVALID;
|
||||
}
|
||||
|
||||
if(GetTimeByClockid(cid, &tv)){
|
||||
times = tv.tv_sec * NANO_TO_BASE + tv.tv_nsec;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
return E_TIME_DEAL_FAILED;
|
||||
}
|
||||
|
||||
|
||||
bool TimeService::GetTimeByClockid(clockid_t clk_id, struct timespec* tv){
|
||||
|
||||
if (clock_gettime(clk_id, tv) < 0){
|
||||
TIME_HILOGE(TIME_MODULE_SERVICE,"Failed clock_gettime.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -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 ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_WALL_TIME_MILLI, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeMs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t TimeServiceProxy::GetWallTimeNs(int64_t ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_WALL_TIME_NANO, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetWallTimeNs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t TimeServiceProxy::GetBootTimeMs(int64_t ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_BOOT_TIME_MILLI, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeMs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t TimeServiceProxy::GetBootTimeNs(int64_t ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_BOOT_TIME_MILLI, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetBootTimeNs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t TimeServiceProxy::GetMonotonicTimeMs(int64_t ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_MONO_TIME_MILLI, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeMs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t TimeServiceProxy::GetMonotonicTimeNs(int64_t ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_MONO_TIME_NANO, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetMonotonicTimeNs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t TimeServiceProxy::GetThreadTimeMs(int64_t ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_THREAD_TIME_MILLI, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeMs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t TimeServiceProxy::GetThreadTimeNs(int64_t ×)
|
||||
{
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write parcelable");
|
||||
return E_TIME_WRITE_PARCEL_ERROR;
|
||||
}
|
||||
|
||||
int32_t result = Remote()->SendRequest(GET_THREAD_TIME_NANO, data, reply, option);
|
||||
if (result != ERR_NONE){
|
||||
TIME_HILOGE(TIME_MODULE_CLIENT, "GetThreadTimeNs failed, error code is: %{public}d",result);
|
||||
return result;
|
||||
}
|
||||
times = reply.ReadInt64();
|
||||
return result;
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
@@ -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
|
||||
Executable → Regular
+33
-5
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
}
|
||||
Executable → Regular
+30
-35
@@ -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
|
||||
@@ -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
|
||||
Executable → Regular
+52
-38
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user