diff --git a/framework/js/napi/system_timer/include/napi_system_timer.h b/framework/js/napi/system_timer/include/napi_system_timer.h index 5f06c31e485d42c9597cc89325c090432c81d9eb..5bfb13f65aeb1ab64062daeff23d56ddec1a24de 100644 --- a/framework/js/napi/system_timer/include/napi_system_timer.h +++ b/framework/js/napi/system_timer/include/napi_system_timer.h @@ -38,6 +38,7 @@ public: virtual void SetInterval(const uint64_t &interval) override; virtual void SetWantAgent(std::shared_ptr wantAgent) override; void SetCallbackInfo(const napi_env &env, const napi_ref &ref); + void SetName(const std::string &_name); private: struct CallbackInfo { diff --git a/framework/js/napi/system_timer/src/napi_system_timer.cpp b/framework/js/napi/system_timer/src/napi_system_timer.cpp index e8a0017f2d757ed49f9c78295a6ac7666af0f718..746b50f3a2a9f32069627b812872a8738f353bef 100644 --- a/framework/js/napi/system_timer/src/napi_system_timer.cpp +++ b/framework/js/napi/system_timer/src/napi_system_timer.cpp @@ -25,6 +25,9 @@ using namespace OHOS::MiscServices; namespace OHOS { namespace MiscServices { namespace Time { +static constexpr size_t STR_BUF_LENGTH = 4096; +static constexpr size_t STR_MAX_LENGTH = 64; + ITimerInfoInstance::ITimerInfoInstance() : callbackInfo_{} { } @@ -86,6 +89,11 @@ void ITimerInfoInstance::SetType(const int &_type) type = _type; } +void ITimerInfoInstance::SetName(const std::string &_name) +{ + name = _name; +} + void ITimerInfoInstance::SetRepeat(bool _repeat) { repeat = _repeat; @@ -122,6 +130,7 @@ napi_value NapiSystemTimer::SystemTimerInit(napi_env env, napi_value exports) } std::map PARA_NAPI_TYPE_MAP = { + { "name", napi_string }, { "type", napi_number }, { "repeat", napi_boolean }, { "interval", napi_number }, @@ -130,6 +139,7 @@ std::map PARA_NAPI_TYPE_MAP = { }; std::map NAPI_TYPE_STRING_MAP = { + { "name", "string" }, { "type", "number" }, { "repeat", "boolean" }, { "interval", "number" }, @@ -148,7 +158,16 @@ void ParseTimerOptions(napi_env env, ContextBase *context, std::string paraType, CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, context, valueType == PARA_NAPI_TYPE_MAP[paraType], paraType + ": incorrect parameter types, must be " + NAPI_TYPE_STRING_MAP[paraType], JsErrorCode::PARAMETER_ERROR); - if (paraType == "type") { + if (paraType == "name") { + std::string name = ""; + size_t nameLen = 0; + char buf[STR_BUF_LENGTH]{}; + napi_get_value_string_utf8(env, result, buf, STR_BUF_LENGTH, &nameLen); + name = std::string(buf); + CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, context, nameLen > STR_MAX_LENGTH, + "timer name must <= 64.", JsErrorCode::PARAMETER_ERROR); + iTimerInfoInstance->SetName(name); + } else if (paraType == "type") { int type = 0; napi_get_value_int32(env, result, &type); iTimerInfoInstance->SetType(type); @@ -180,7 +199,7 @@ void NapiSystemTimer::GetTimerOptions(const napi_env &env, ContextBase *context, const napi_value &value, std::shared_ptr &iTimerInfoInstance) { bool hasProperty = false; - + // type: number napi_has_named_property(env, value, "type", &hasProperty); CHECK_ARGS_RETURN_VOID(TIME_MODULE_JS_NAPI, context, hasProperty, @@ -195,6 +214,13 @@ void NapiSystemTimer::GetTimerOptions(const napi_env &env, ContextBase *context, ParseTimerOptions(env, context, "repeat", value, iTimerInfoInstance); CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, context, context->errMessage, JsErrorCode::PARAMETER_ERROR); + // name: string + napi_has_named_property(env, value, "name", &hasProperty); + if (hasProperty) { + ParseTimerOptions(env, context, "name", value, iTimerInfoInstance); + CHECK_STATUS_RETURN_VOID(TIME_MODULE_JS_NAPI, context, context->errMessage, JsErrorCode::PARAMETER_ERROR); + } + // interval?: number napi_has_named_property(env, value, "interval", &hasProperty); if (hasProperty) { diff --git a/interfaces/inner_api/include/itimer_info.h b/interfaces/inner_api/include/itimer_info.h index 8e2ae6007bc9f8862603953f404e16a3a8ac5e11..84598d6e29b91b6065a386d86f57a8261c25ae05 100644 --- a/interfaces/inner_api/include/itimer_info.h +++ b/interfaces/inner_api/include/itimer_info.h @@ -31,6 +31,7 @@ public: bool repeat; bool disposable = false; uint64_t interval; + std::string name = ""; std::shared_ptr wantAgent; /** @@ -89,6 +90,17 @@ public: { disposable = _disposable; } + + /** + * SetName set timer name + * @para: _name string + * If set a same timer with the same name as a previous one, + * the previous timer will be destroyed. + */ + void SetName(const std::string &_name) + { + name = _name; + } virtual void SetWantAgent(std::shared_ptr wantAgent) = 0; virtual void OnTrigger() = 0; }; diff --git a/interfaces/inner_api/include/time_service_client.h b/interfaces/inner_api/include/time_service_client.h index 6d3f4bc1259578e1ccf20535872e12e7a2b6caf5..4676da8d9216572eb3c16d020551942bc98556ff 100644 --- a/interfaces/inner_api/include/time_service_client.h +++ b/interfaces/inner_api/include/time_service_client.h @@ -478,12 +478,15 @@ private: void ClearProxy(); sptr GetProxy(); void SetProxy(sptr proxy); + void CheckName(std::string name); sptr listener_; static std::mutex instanceLock_; static sptr instance_; + TIME_API std::vector timerNameList_; TIME_API std::map> recoverTimerInfoMap_; TIME_API std::mutex recoverTimerInfoLock_; + std::mutex nameListLock_; std::mutex proxyLock_; std::mutex deathLock_; sptr timeServiceProxy_; diff --git a/interfaces/inner_api/src/time_service_client.cpp b/interfaces/inner_api/src/time_service_client.cpp index 8c44fb02c89925f412680b13b0a94219519e1de9..5f18c80f63b48a963e5048d3a2b525d2f5cd9ded 100644 --- a/interfaces/inner_api/src/time_service_client.cpp +++ b/interfaces/inner_api/src/time_service_client.cpp @@ -263,6 +263,30 @@ uint64_t TimeServiceClient::CreateTimer(std::shared_ptr timerOptions return timerId; } +void TimeServiceClient::CheckName(std::string name) +{ + { + std::lock_guard lock(nameListLock_); + auto it = std::find(timerNameList_.begin(), timerNameList_.end(), name); + if (it == timerNameList_.end()) { + timerNameList_.push_back(name); + return; + } + } + { + std::lock_guard lock(recoverTimerInfoLock_); + auto timerInfoMap = recoverTimerInfoMap_.begin(); + while (timerInfoMap != recoverTimerInfoMap_.end()) { + if (timerInfoMap->second->timerInfo->name == name) { + timerInfoMap = recoverTimerInfoMap_.erase(timerInfoMap); + return; + } else { + ++timerInfoMap; + } + } + } +} + int32_t TimeServiceClient::CreateTimerV9(std::shared_ptr timerOptions, uint64_t &timerId) { if (timerOptions == nullptr) { @@ -288,6 +312,9 @@ int32_t TimeServiceClient::CreateTimerV9(std::shared_ptr timerOption } if (timerOptions->wantAgent == nullptr) { + if (timerOptions->name != "") { + CheckName(timerOptions->name); + } std::lock_guard lock(recoverTimerInfoLock_); auto info = recoverTimerInfoMap_.find(timerId); if (info != recoverTimerInfoMap_.end()) { @@ -400,6 +427,13 @@ int32_t TimeServiceClient::DestroyTimerV9(uint64_t timerId) std::lock_guard lock(recoverTimerInfoLock_); auto info = recoverTimerInfoMap_.find(timerId); if (info != recoverTimerInfoMap_.end()) { + if (info->second->timerInfo->name != "") { + std::lock_guard lock(nameListLock_); + auto it = std::find(timerNameList_.begin(), timerNameList_.end(), info->second->timerInfo->name); + if (it != timerNameList_.end()) { + timerNameList_.erase(it); + } + } recoverTimerInfoMap_.erase(timerId); } return errCode; diff --git a/services/ipc/proxy/time_service_proxy.cpp b/services/ipc/proxy/time_service_proxy.cpp index dc7cb3359ad9eeec6961e3b839142bc444e12214..ee0cf41808592571db9249758c7e52cbbfec1b2b 100644 --- a/services/ipc/proxy/time_service_proxy.cpp +++ b/services/ipc/proxy/time_service_proxy.cpp @@ -62,6 +62,10 @@ int32_t TimeServiceProxy::CreateTimer(const std::shared_ptr &timerOp TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write descriptor"); return E_TIME_WRITE_PARCEL_ERROR; } + if (!data.WriteString(timerOptions->name)) { + TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write name"); + return E_TIME_WRITE_PARCEL_ERROR; + } if (!data.WriteInt32(timerOptions->type)) { TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write type"); return E_TIME_WRITE_PARCEL_ERROR; @@ -82,11 +86,9 @@ int32_t TimeServiceProxy::CreateTimer(const std::shared_ptr &timerOp TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write wantAgent status"); return E_TIME_WRITE_PARCEL_ERROR; } - if (timerOptions->wantAgent != nullptr) { - if (!data.WriteParcelable(&(*timerOptions->wantAgent))) { + if (timerOptions->wantAgent != nullptr && !data.WriteParcelable(&(*timerOptions->wantAgent))) { TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write wantAgent"); return E_TIME_WRITE_PARCEL_ERROR; - } } if (!data.WriteRemoteObject(timerCallback)) { TIME_HILOGE(TIME_MODULE_CLIENT, "Failed to write timerCallback"); @@ -100,7 +102,6 @@ int32_t TimeServiceProxy::CreateTimer(const std::shared_ptr &timerOp Remote()->SendRequest(static_cast(TimeServiceIpcInterfaceCode::CREATE_TIMER), data, reply, option); if (ret == E_TIME_OK) { timerId = reply.ReadUint64(); - return E_TIME_OK; } return ret; } diff --git a/services/ipc/stub/time_service_stub.cpp b/services/ipc/stub/time_service_stub.cpp index f645d897b91f8a4ce2e67fa7d6381d8c5064c98e..8aff20c314f94120b52601078c3d1122e1cae0f1 100644 --- a/services/ipc/stub/time_service_stub.cpp +++ b/services/ipc/stub/time_service_stub.cpp @@ -198,6 +198,7 @@ int32_t TimeServiceStub::OnCreateTimer(MessageParcel &data, MessageParcel &reply return E_TIME_NOT_SYSTEM_APP; } std::shared_ptr wantAgent{ nullptr }; + auto name = data.ReadString(); auto type = data.ReadInt32(); auto repeat = data.ReadBool(); auto disposable = data.ReadBool(); @@ -216,6 +217,7 @@ int32_t TimeServiceStub::OnCreateTimer(MessageParcel &data, MessageParcel &reply return E_TIME_NULLPTR; } auto timerOptions = std::make_shared(); + timerOptions->name = name; timerOptions->type = type; timerOptions->repeat = repeat; timerOptions->interval = interval; diff --git a/services/time_system_ability.cpp b/services/time_system_ability.cpp index a437422eb970cc375dd5af4355475ded1c4056ba..ca4433d8d384be4e3e77a7b2e5760200a335a6a7 100644 --- a/services/time_system_ability.cpp +++ b/services/time_system_ability.cpp @@ -65,13 +65,14 @@ static const uint32_t TIMER_TYPE_REALTIME_WAKEUP_MASK = 1 << 1; static const uint32_t TIMER_TYPE_EXACT_MASK = 1 << 2; static const uint32_t TIMER_TYPE_IDLE_MASK = 1 << 3; static const uint32_t TIMER_TYPE_INEXACT_REMINDER_MASK = 1 << 4; +static constexpr int32_t STR_MAX_LENGTH = 64; constexpr int32_t MILLI_TO_MICR = MICR_TO_BASE / MILLI_TO_BASE; constexpr int32_t NANO_TO_MILLI = NANO_TO_BASE / MILLI_TO_BASE; constexpr int32_t ONE_MILLI = 1000; constexpr uint64_t TWO_MINUTES_TO_MILLI = 120000; static const std::vector ALL_DATA = { "timerId", "type", "flag", "windowLength", "interval", \ "uid", "bundleName", "wantAgent", "state", "triggerTime", \ - "pid"}; + "pid", "name"}; const std::string BOOTEVENT_PARAMETER = "bootevent.boot.completed"; const std::string SUBSCRIBE_REMOVED = "UserRemoved"; } // namespace @@ -366,6 +367,9 @@ void TimeSystemAbility::ParseTimerPara(const std::shared_ptr &timerO if (disposable) { paras.flag += ITimerManager::TimerFlag::IS_DISPOSABLE; } + if (timerOptions->name != "") { + paras.name = timerOptions->name; + } paras.interval = timerOptions->repeat ? timerOptions->interval : 0; } @@ -387,6 +391,10 @@ int32_t TimeSystemAbility::CreateTimer(const std::shared_ptr &timerO if (timerManager == nullptr) { return E_TIME_NULLPTR; } + if (timerOptions->name.size() > STR_MAX_LENGTH) { + TIME_HILOGE(TIME_MODULE_SERVICE, "Timer name length beyond max length."); + return E_TIME_PARAMETERS_INVALID; + } auto callbackFunc = [timerCallback, timerOptions, timerManager](uint64_t id) -> int32_t { #ifdef POWER_MANAGER_ENABLE if (timerOptions->type == ITimerManager::TimerType::RTC_WAKEUP || @@ -1007,6 +1015,8 @@ void TimeSystemAbility::RecoverTimerInner(std::shared_ptr(GetLong(resultSet, 0)); auto timerInfo = std::make_shared(TimerEntry { + // line 11 is 'name' + GetString(resultSet, 11), // Line 0 is 'timerId' timerId, // Line 1 is 'type' diff --git a/services/timer/include/timer_database.h b/services/timer/include/timer_database.h index a5fe25ce4ba7a844c17556b00727c671839cf85e..28c56be7977ecf7dece6ed9355dc5746ca21bf0a 100644 --- a/services/timer/include/timer_database.h +++ b/services/timer/include/timer_database.h @@ -25,6 +25,7 @@ namespace MiscServices { constexpr const char *DB_NAME = "/data/service/el1/public/database/time/time.db"; constexpr int DATABASE_OPEN_VERSION = 1; constexpr int DATABASE_OPEN_VERSION_2 = 2; +constexpr int DATABASE_OPEN_VERSION_3 = 3; constexpr int CHECK_VERSION_FAILED = -1; constexpr int API12_5_0_RELEASE = 50; constexpr int INVALID_VERSION = -50; diff --git a/services/timer/include/timer_info.h b/services/timer/include/timer_info.h index f87cf6f8460673172f2879b6e7d878606207e584..f1b3862acc3e84d841a39f5bf3fe9e8987eb2883 100644 --- a/services/timer/include/timer_info.h +++ b/services/timer/include/timer_info.h @@ -27,6 +27,7 @@ static const uint32_t HALF_SECEND = 2; class TimerInfo { public: + const std::string name; const uint64_t id; const int type; const std::chrono::milliseconds origWhen; @@ -47,7 +48,7 @@ public: std::chrono::milliseconds offset; std::string bundleName; - TimerInfo(uint64_t id, int type, + TimerInfo(std::string name, uint64_t id, int type, std::chrono::milliseconds when, std::chrono::steady_clock::time_point whenElapsed, std::chrono::milliseconds windowLength, diff --git a/services/timer/include/timer_manager.h b/services/timer/include/timer_manager.h index 85a0fb15de2dd6366c026addec0a7b57a988a98b..7d3be37186f20377a15b62c92679ea146fdaeeaa 100644 --- a/services/timer/include/timer_manager.h +++ b/services/timer/include/timer_manager.h @@ -73,7 +73,8 @@ private: explicit TimerManager(std::shared_ptr impl); void TimerLooper(); - void SetHandler(uint64_t id, + void SetHandler(std::string name, + uint64_t id, int type, uint64_t triggerAtTime, int64_t windowLength, @@ -84,7 +85,8 @@ private: int uid, int pid, const std::string &bundleName); - void SetHandlerLocked(uint64_t id, + void SetHandlerLocked(std::string name, + uint64_t id, int type, std::chrono::milliseconds when, std::chrono::steady_clock::time_point whenElapsed, @@ -128,6 +130,7 @@ private: bool AdjustTimersBasedOnDeviceIdle(); void HandleRepeatTimer(const std::shared_ptr &timer, std::chrono::steady_clock::time_point nowElapsed); inline bool CheckNeedRecoverOnReboot(std::string bundleName, int type); + void CheckTimerName(int uid, std::string name, int64_t timerId); #ifdef POWER_MANAGER_ENABLE void HandleRunningLock(const std::shared_ptr &firstWakeup); void AddRunningLock(long long holdLockTime); @@ -140,10 +143,14 @@ private: void DecreaseTimerCount(int uid); void CheckTimerCount(); void ShowTimerCountByUid(); + int32_t DestroyTimerLocked(uint64_t timerNumber); + void DeleteTimerName(int uid, std::string name, int64_t timerId); std::map> timerEntryMap_; // vector std::vector> timerCount_; + // > + std::map> timerNameMap_; std::default_random_engine random_; std::atomic_bool runFlag_; std::shared_ptr handler_; diff --git a/services/timer/include/timer_manager_interface.h b/services/timer/include/timer_manager_interface.h index 6c3dd44cd13114215b9817796c97e69910e44f3b..ffcd5eb15cdab096835310f4d1734db852fff6c5 100644 --- a/services/timer/include/timer_manager_interface.h +++ b/services/timer/include/timer_manager_interface.h @@ -24,6 +24,7 @@ namespace OHOS { namespace MiscServices { struct TimerEntry { + std::string name; uint64_t id; int type; int64_t windowLength; diff --git a/services/timer/src/timer_database.cpp b/services/timer/src/timer_database.cpp index 411cd6dcae552735ea45320ffbfa9bf71e40c2e7..e6030bba276da7c2ab42d3fd578a9cb08419fe5f 100644 --- a/services/timer/src/timer_database.cpp +++ b/services/timer/src/timer_database.cpp @@ -29,7 +29,8 @@ constexpr const char *CREATE_TIME_TIMER_HOLD_ON_REBOOT = "CREATE TABLE IF NOT EX "wantAgent TEXT, " "state INTEGER, " "triggerTime INTEGER, " - "pid INTEGER)"; + "pid INTEGER, " + "name TEXT)"; constexpr const char *CREATE_TIME_TIMER_DROP_ON_REBOOT = "CREATE TABLE IF NOT EXISTS drop_on_reboot " "(timerId INTEGER PRIMARY KEY, " @@ -42,11 +43,14 @@ constexpr const char *CREATE_TIME_TIMER_DROP_ON_REBOOT = "CREATE TABLE IF NOT EX "wantAgent TEXT, " "state INTEGER, " "triggerTime INTEGER, " - "pid INTEGER)"; + "pid INTEGER, " + "name TEXT)"; -constexpr const char *HOLD_ON_REBOOT_ADD_COLUMN = "ALTER TABLE hold_on_reboot ADD COLUMN pid INTEGER"; +constexpr const char *HOLD_ON_REBOOT_ADD_PID_COLUMN = "ALTER TABLE hold_on_reboot ADD COLUMN pid INTEGER"; +constexpr const char *HOLD_ON_REBOOT_ADD_NAME_COLUMN = "ALTER TABLE hold_on_reboot ADD COLUMN name TEXT"; -constexpr const char *DROP_ON_REBOOT_ADD_COLUMN = "ALTER TABLE drop_on_reboot ADD COLUMN pid INTEGER"; +constexpr const char *DROP_ON_REBOOT_ADD_PID_COLUMN = "ALTER TABLE drop_on_reboot ADD COLUMN pid INTEGER"; +constexpr const char *DROP_ON_REBOOT_ADD_NAME_COLUMN = "ALTER TABLE hold_on_reboot ADD COLUMN name TEXT"; TimeDatabase::TimeDatabase() { @@ -56,7 +60,7 @@ TimeDatabase::TimeDatabase() config.SetEncryptStatus(false); config.SetReadConSize(1); TimeDBOpenCallback timeDBOpenCallback; - store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_2, timeDBOpenCallback, errCode); + store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDBOpenCallback, errCode); TIME_HILOGI(TIME_MODULE_SERVICE, "Gets time database, ret: %{public}d", errCode); if (errCode == OHOS::NativeRdb::E_SQLITE_CORRUPT) { auto ret = OHOS::NativeRdb::RdbHelper::DeleteRdbStore(config); @@ -64,7 +68,7 @@ TimeDatabase::TimeDatabase() TIME_HILOGE(TIME_MODULE_SERVICE, "delete corrupt database failed, ret: %{public}d", ret); return; } - store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_2, timeDBOpenCallback, errCode); + store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDBOpenCallback, errCode); } } @@ -87,7 +91,7 @@ bool TimeDatabase::RecoverDataBase() } TimeDBOpenCallback timeDbOpenCallback; int errCode; - store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_2, timeDbOpenCallback, errCode); + store_ = OHOS::NativeRdb::RdbHelper::GetRdbStore(config, DATABASE_OPEN_VERSION_3, timeDbOpenCallback, errCode); return true; } @@ -265,13 +269,25 @@ int TimeDBOpenCallback::OnOpen(OHOS::NativeRdb::RdbStore &store) int TimeDBOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &store, int oldVersion, int newVersion) { - if (oldVersion == DATABASE_OPEN_VERSION && newVersion == DATABASE_OPEN_VERSION_2) { - int ret = store.ExecuteSql(HOLD_ON_REBOOT_ADD_COLUMN); + if (oldVersion < DATABASE_OPEN_VERSION_2 && newVersion >= DATABASE_OPEN_VERSION_2) { + int ret = store.ExecuteSql(HOLD_ON_REBOOT_ADD_PID_COLUMN); if (ret != OHOS::NativeRdb::E_OK) { TIME_HILOGE(TIME_MODULE_SERVICE, "hold_on_reboot add column failed, ret: %{public}d", ret); return ret; } - ret = store.ExecuteSql(DROP_ON_REBOOT_ADD_COLUMN); + ret = store.ExecuteSql(DROP_ON_REBOOT_ADD_PID_COLUMN); + if (ret != OHOS::NativeRdb::E_OK) { + TIME_HILOGE(TIME_MODULE_SERVICE, "drop_on_reboot add column failed, ret: %{public}d", ret); + return ret; + } + } + if (oldVersion < DATABASE_OPEN_VERSION_3 && newVersion >= DATABASE_OPEN_VERSION_3) { + int ret = store.ExecuteSql(HOLD_ON_REBOOT_ADD_NAME_COLUMN); + if (ret != OHOS::NativeRdb::E_OK) { + TIME_HILOGE(TIME_MODULE_SERVICE, "hold_on_reboot add column failed, ret: %{public}d", ret); + return ret; + } + ret = store.ExecuteSql(DROP_ON_REBOOT_ADD_NAME_COLUMN); if (ret != OHOS::NativeRdb::E_OK) { TIME_HILOGE(TIME_MODULE_SERVICE, "drop_on_reboot add column failed, ret: %{public}d", ret); return ret; diff --git a/services/timer/src/timer_info.cpp b/services/timer/src/timer_info.cpp index 9ad408a5ea8034b0f892f72044c2590d0dd977ae..a0136b13a16ab66cc295a157d72f7af8db7d6c7c 100644 --- a/services/timer/src/timer_info.cpp +++ b/services/timer/src/timer_info.cpp @@ -31,7 +31,7 @@ bool TimerInfo::Matches(const std::string &packageName) const return false; } -TimerInfo::TimerInfo(uint64_t _id, int _type, +TimerInfo::TimerInfo(std::string _name, uint64_t _id, int _type, std::chrono::milliseconds _when, std::chrono::steady_clock::time_point _whenElapsed, std::chrono::milliseconds _windowLength, @@ -43,7 +43,8 @@ TimerInfo::TimerInfo(uint64_t _id, int _type, int _uid, int _pid, const std::string &_bundleName) - : id {_id}, + : name {_name}, + id {_id}, type {_type}, origWhen {_when}, wakeup {_type == ITimerManager::ELAPSED_REALTIME_WAKEUP || _type == ITimerManager::RTC_WAKEUP}, diff --git a/services/timer/src/timer_manager.cpp b/services/timer/src/timer_manager.cpp index 63b864360a0a7bc7690439ae9ec08554c10a307b..aa28c35ec3b3c1856b2222b8789c57369b45c4b8 100644 --- a/services/timer/src/timer_manager.cpp +++ b/services/timer/src/timer_manager.cpp @@ -146,9 +146,45 @@ OHOS::NativeRdb::ValuesBucket GetInsertValues(std::shared_ptr timerI insertValues.PutInt("state", 0); insertValues.PutLong("triggerTime", 0); insertValues.PutInt("pid", timerInfo->pid); + insertValues.PutString("name", timerInfo->name); return insertValues; } +void TimerManager::CheckTimerName(int uid, std::string name, int64_t timerId) +{ + if (timerNameMap_.find(uid) == timerNameMap_.end()) { + std::map nameMap {}; + timerNameMap_[uid][name] = timerId; + TIME_HILOGD(TIME_MODULE_SERVICE, "record name: %{public}s id %{public}" PRId64 "", name.c_str(), timerId); + return; + } + if (timerNameMap_[uid].find(name) == timerNameMap_[uid].end()) { + timerNameMap_[uid][name] = timerId; + TIME_HILOGD(TIME_MODULE_SERVICE, "record name: %{public}s id %{public}" PRId64 "", name.c_str(), timerId); + return; + } + auto oldTimerId = timerNameMap_[uid][name]; + timerNameMap_[uid][name] = timerId; + DestroyTimerLocked(oldTimerId); + TIME_HILOGI(TIME_MODULE_SERVICE, "name: %{public}s already exist, destory timer %{public}" PRId64 "", + name.c_str(), oldTimerId); + return; +} + +void TimerManager::DeleteTimerName(int uid, std::string name, int64_t timerId) +{ + if (timerNameMap_.find(uid) == timerNameMap_.end()) { + TIME_HILOGE(TIME_MODULE_SERVICE, "NameMap has no uid %{public}d", uid); + return; + } + auto it = timerNameMap_[uid].find(name); + if (it == timerNameMap_[uid].end()) { + TIME_HILOGE(TIME_MODULE_SERVICE, "NameMap has no name:%{public}s uid: %{public}d", name.c_str(), uid); + return; + } + timerNameMap_[uid].erase(it); +} + int32_t TimerManager::CreateTimer(TimerPara ¶s, std::function callback, std::shared_ptr wantAgent, @@ -172,7 +208,12 @@ int32_t TimerManager::CreateTimer(TimerPara ¶s, // random_() needs to be protected in a lock. timerId = random_(); } + auto timerName = paras.name; + if (timerName != "") { + CheckTimerName(uid, timerName, timerId); + } timerInfo = std::make_shared(TimerEntry { + timerName, timerId, paras.timerType, paras.windowLength, @@ -203,6 +244,9 @@ void TimerManager::ReCreateTimer(uint64_t timerId, std::shared_ptr t { std::lock_guard lock(entryMapMutex_); timerEntryMap_.insert(std::make_pair(timerId, timerInfo)); + if (timerInfo->name != "") { + CheckTimerName(timerInfo->uid, timerInfo->name, timerId); + } IncreaseTimerCount(timerInfo->uid); } @@ -228,9 +272,9 @@ int32_t TimerManager::StartTimer(uint64_t timerId, uint64_t triggerTime) std::lock_guard lock(mutex_); RemoveLocked(timerId, false); } - SetHandler(timerInfo->id, timerInfo->type, triggerTime, timerInfo->windowLength, timerInfo->interval, - timerInfo->flag, timerInfo->callback, timerInfo->wantAgent, timerInfo->uid, timerInfo->pid, - timerInfo->bundleName); + SetHandler(timerInfo->name, timerInfo->id, timerInfo->type, triggerTime, timerInfo->windowLength, + timerInfo->interval, timerInfo->flag, timerInfo->callback, timerInfo->wantAgent, timerInfo->uid, + timerInfo->pid, timerInfo->bundleName); } auto tableName = (CheckNeedRecoverOnReboot(timerInfo->bundleName, timerInfo->type) ? HOLD_ON_REBOOT @@ -318,6 +362,36 @@ int32_t TimerManager::DestroyTimer(uint64_t timerId) return StopTimerInner(timerId, true); } +// needs to acquire the lock `entryMapMutex_` before calling this method +int32_t TimerManager::DestroyTimerLocked(uint64_t timerNumber) +{ + auto it = timerEntryMap_.find(timerNumber); + if (it == timerEntryMap_.end()) { + TIME_HILOGW(TIME_MODULE_SERVICE, "timer not exist"); + return E_TIME_DEAL_FAILED; + } + RemoveHandler(timerNumber); + TimerProxy::GetInstance().RemoveProxy(timerNumber, it->second->uid); + TimerProxy::GetInstance().RemovePidProxy(timerNumber, it->second->pid); + TimerProxy::GetInstance().EraseTimerFromProxyUidMap(timerNumber, it->second->uid); + TimerProxy::GetInstance().EraseTimerFromProxyPidMap(timerNumber, it->second->pid); + auto needRecoverOnReboot = CheckNeedRecoverOnReboot(it->second->bundleName, it->second->type); + int uid = it->second->uid; + timerEntryMap_.erase(it); + DecreaseTimerCount(uid); + + if (needRecoverOnReboot) { + OHOS::NativeRdb::RdbPredicates rdbPredicatesDelete(HOLD_ON_REBOOT); + rdbPredicatesDelete.EqualTo("timerId", static_cast(timerNumber)); + TimeDatabase::GetInstance().Delete(rdbPredicatesDelete); + } else { + OHOS::NativeRdb::RdbPredicates rdbPredicatesDelete(DROP_ON_REBOOT); + rdbPredicatesDelete.EqualTo("timerId", static_cast(timerNumber)); + TimeDatabase::GetInstance().Delete(rdbPredicatesDelete); + } + return E_TIME_OK; +} + int32_t TimerManager::StopTimerInner(uint64_t timerNumber, bool needDestroy) { TIME_HILOGI(TIME_MODULE_SERVICE, "id: %{public}" PRId64 ", needDestroy: %{public}d", timerNumber, needDestroy); @@ -337,6 +411,9 @@ int32_t TimerManager::StopTimerInner(uint64_t timerNumber, bool needDestroy) needRecoverOnReboot = CheckNeedRecoverOnReboot(it->second->bundleName, it->second->type); if (needDestroy) { int uid = it->second->uid; + if (it->second->name != "") { + DeleteTimerName(uid, it->second->name, timerNumber); + } timerEntryMap_.erase(it); DecreaseTimerCount(uid); } @@ -367,7 +444,8 @@ int32_t TimerManager::StopTimerInner(uint64_t timerNumber, bool needDestroy) return E_TIME_OK; } -void TimerManager::SetHandler(uint64_t id, +void TimerManager::SetHandler(std::string name, + uint64_t id, int type, uint64_t triggerAtTime, int64_t windowLength, @@ -406,7 +484,8 @@ void TimerManager::SetHandler(uint64_t id, maxElapsed = triggerElapsed + windowLengthDuration; } std::lock_guard lockGuard(mutex_); - SetHandlerLocked(id, + SetHandlerLocked(name, + id, type, when, triggerElapsed, @@ -421,7 +500,8 @@ void TimerManager::SetHandler(uint64_t id, bundleName); } -void TimerManager::SetHandlerLocked(uint64_t id, int type, +void TimerManager::SetHandlerLocked(std::string name, + uint64_t id, int type, std::chrono::milliseconds when, std::chrono::steady_clock::time_point whenElapsed, std::chrono::milliseconds windowLength, @@ -435,7 +515,7 @@ void TimerManager::SetHandlerLocked(uint64_t id, int type, const std::string &bundleName) { TIME_HILOGD(TIME_MODULE_SERVICE, "start id: %{public}" PRId64 "", id); - auto alarm = std::make_shared(id, type, when, whenElapsed, windowLength, maxWhen, + auto alarm = std::make_shared(name, id, type, when, whenElapsed, windowLength, maxWhen, interval, std::move(callback), wantAgent, flags, callingUid, callingPid, bundleName); if (TimerProxy::GetInstance().IsUidProxy(alarm->uid)) { @@ -1221,6 +1301,7 @@ bool TimerManager::ShowTimerEntryMap(int fd) auto iter = timerEntryMap_.begin(); for (; iter != timerEntryMap_.end(); iter++) { dprintf(fd, " - dump timer number = %lu\n", iter->first); + dprintf(fd, " * timer name = %s\n", iter->second->name.c_str()); dprintf(fd, " * timer id = %lu\n", iter->second->id); dprintf(fd, " * timer type = %d\n", iter->second->type); dprintf(fd, " * timer flag = %lu\n", iter->second->flag); @@ -1358,7 +1439,7 @@ void TimerManager::HandleRepeatTimer( duration_cast(nowElapsed - timer->whenElapsed) / timer->repeatInterval); auto delta = count * timer->repeatInterval; auto nextElapsed = timer->whenElapsed + delta; - SetHandlerLocked(timer->id, timer->type, timer->when + delta, nextElapsed, timer->windowLength, + SetHandlerLocked(timer->name, timer->id, timer->type, timer->when + delta, nextElapsed, timer->windowLength, MaxTriggerTime(nowElapsed, nextElapsed, timer->repeatInterval), timer->repeatInterval, timer->callback, timer->wantAgent, timer->flags, timer->uid, timer->pid, timer->bundleName); } else { diff --git a/services/timer/src/timer_proxy.cpp b/services/timer/src/timer_proxy.cpp index 0ce59b2489148faa914b329952bea94d41d0cc07..47a764b68d7b6f371ce0b08f6876474ae2646bba 100644 --- a/services/timer/src/timer_proxy.cpp +++ b/services/timer/src/timer_proxy.cpp @@ -265,7 +265,10 @@ bool TimerProxy::SetTimerExemption(const std::unordered_set &nameAr bool TimerProxy::IsTimerExemption(std::shared_ptr timer) { - if (adjustExemptionList_.find(timer->bundleName) != adjustExemptionList_.end() + auto key = timer->bundleName + "|" + timer->name; + TIME_HILOGI(TIME_MODULE_SERVICE, "key is: %{public}s", key.c_str()); + if ((adjustExemptionList_.find(timer->bundleName) != adjustExemptionList_.end() + || adjustExemptionList_.find(key) != adjustExemptionList_.end()) && timer->windowLength == milliseconds::zero()) { return true; } diff --git a/test/unittest/service_test/include/timer_info_test.h b/test/unittest/service_test/include/timer_info_test.h index e3104c15599cfd6c5ce52509d0e55c95a1c41cb1..94f10b2e3fa859ff3848818e0e506a252e3c21de 100644 --- a/test/unittest/service_test/include/timer_info_test.h +++ b/test/unittest/service_test/include/timer_info_test.h @@ -43,6 +43,7 @@ public: virtual void SetRepeat(bool repeat) override; virtual void SetInterval(const uint64_t &interval) override; void SetDisposable(const bool &disposable); + void SetName(const std::string &name); virtual void SetWantAgent(std::shared_ptr wantAgent) override; void SetCallbackInfo(const std::function &callBack); @@ -98,6 +99,11 @@ void TimerInfoTest::SetDisposable(const bool &_disposable) disposable = _disposable; } +void TimerInfoTest::SetName(const std::string &_name) +{ + name = _name; +} + } // namespace MiscServices } // namespace OHOS #endif \ No newline at end of file diff --git a/test/unittest/service_test/src/time_client_test.cpp b/test/unittest/service_test/src/time_client_test.cpp index e701cc63be4d8df80642766724790e3cccaef7e3..cd7e3d8ae68b370a8675214b7aef30ae3fefcc8f 100644 --- a/test/unittest/service_test/src/time_client_test.cpp +++ b/test/unittest/service_test/src/time_client_test.cpp @@ -1,3 +1,4 @@ + /* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -579,6 +580,127 @@ HWTEST_F(TimeClientTest, CreateTimer007, TestSize.Level1) EXPECT_NE(codeDestroyTimer, TimeError::E_TIME_OK); } +/** +* @tc.name: CreateTimer008 +* @tc.desc: Create system timer with timer name. +* @tc.type: FUNC +*/ +HWTEST_F(TimeClientTest, CreateTimer008, TestSize.Level1) +{ + g_data1 = 0; + uint64_t timerId; + auto timerInfo = std::make_shared(); + timerInfo->SetName("C++timernametest"); + timerInfo->SetType(timerInfo->TIMER_TYPE_EXACT); + timerInfo->SetRepeat(false); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto wantAgent = std::shared_ptr(); + timerInfo->SetWantAgent(wantAgent); + auto errCode = TimeServiceClient::GetInstance()->CreateTimerV9(timerInfo, timerId); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); + EXPECT_NE(timerId, 0); + + TIME_HILOGI(TIME_MODULE_CLIENT, "test timer id: %{public}" PRId64 "", timerId); +} + +/** +* @tc.name: CreateTimer009 +* @tc.desc: Create system timer with a long name, expect false. +* @tc.type: FUNC +*/ +HWTEST_F(TimeClientTest, CreateTimer009, TestSize.Level1) +{ + g_data1 = 0; + uint64_t timerId; + auto timerInfo = std::make_shared(); + timerInfo->SetName("0123456789012345678901234567890123456789012345678901234567890123456789"); + timerInfo->SetType(timerInfo->TIMER_TYPE_EXACT); + timerInfo->SetRepeat(false); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto wantAgent = std::shared_ptr(); + timerInfo->SetWantAgent(wantAgent); + auto errCode = TimeServiceClient::GetInstance()->CreateTimerV9(timerInfo, timerId); + EXPECT_NE(errCode, TimeError::E_TIME_OK); + + TIME_HILOGI(TIME_MODULE_CLIENT, "test timer id: %{public}" PRId64 "", timerId); +} + +/** +* @tc.name: CreateTimer010 +* @tc.desc: Create two timers with same name, expect first is destroyed. +* @tc.type: FUNC +*/ +HWTEST_F(TimeClientTest, CreateTimer010, TestSize.Level1) +{ + g_data1 = 0; + uint64_t timerId1; + uint64_t timerId2; + auto timerInfo = std::make_shared(); + timerInfo->SetName("testname"); + timerInfo->SetType(timerInfo->TIMER_TYPE_EXACT); + timerInfo->SetRepeat(false); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto wantAgent = std::shared_ptr(); + timerInfo->SetWantAgent(wantAgent); + auto errCode = TimeServiceClient::GetInstance()->CreateTimerV9(timerInfo, timerId1); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); + EXPECT_NE(timerId1, 0); + auto nameList = TimeServiceClient::GetInstance()->timerNameList_; + auto name = std::find(nameList.begin(), nameList.end(), "testname"); + EXPECT_NE(name, nameList.end()); + + errCode = TimeServiceClient::GetInstance()->CreateTimerV9(timerInfo, timerId2); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); + EXPECT_NE(timerId2, 0); + + auto info = TimeServiceClient::GetInstance()->recoverTimerInfoMap_.find(timerId1); + EXPECT_EQ(info, TimeServiceClient::GetInstance()->recoverTimerInfoMap_.end()); + + errCode = TimeServiceClient::GetInstance()->DestroyTimerV9(timerId1); + EXPECT_NE(errCode, TimeError::E_TIME_OK); + + errCode = TimeServiceClient::GetInstance()->DestroyTimerV9(timerId2); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); + + nameList = TimeServiceClient::GetInstance()->timerNameList_; + name = std::find(nameList.begin(), nameList.end(), "testname"); + EXPECT_EQ(name, nameList.end()); +} + +/** +* @tc.name: CreateTimer011 +* @tc.desc: Create a timer with name and destroy it, create a new timer with same name, +* expect OK. +* @tc.type: FUNC +*/ +HWTEST_F(TimeClientTest, CreateTimer011, TestSize.Level1) +{ + g_data1 = 0; + uint64_t timerId1; + uint64_t timerId2; + auto timerInfo = std::make_shared(); + timerInfo->SetName("testname"); + timerInfo->SetType(timerInfo->TIMER_TYPE_EXACT); + timerInfo->SetRepeat(false); + timerInfo->SetCallbackInfo(TimeOutCallback1); + auto wantAgent = std::shared_ptr(); + timerInfo->SetWantAgent(wantAgent); + auto errCode = TimeServiceClient::GetInstance()->CreateTimerV9(timerInfo, timerId1); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); + EXPECT_NE(timerId1, 0); + + errCode = TimeServiceClient::GetInstance()->DestroyTimerV9(timerId1); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); + + errCode = TimeServiceClient::GetInstance()->CreateTimerV9(timerInfo, timerId2); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); + EXPECT_NE(timerId2, 0); + + errCode = TimeServiceClient::GetInstance()->DestroyTimerV9(timerId2); + EXPECT_EQ(errCode, TimeError::E_TIME_OK); +} + + /** * @tc.name: StartTimer001 * @tc.desc: Start system timer. diff --git a/test/unittest/service_test/src/time_proxy_test.cpp b/test/unittest/service_test/src/time_proxy_test.cpp index 32e0823396c0c62baf88ff0d5deeb74e6093f150..4c05d7ca7fe33e00699db76387f7906738214869 100644 --- a/test/unittest/service_test/src/time_proxy_test.cpp +++ b/test/unittest/service_test/src/time_proxy_test.cpp @@ -773,6 +773,25 @@ HWTEST_F(TimeProxyTest, AdjustTimerProxy001, TestSize.Level1) EXPECT_NE(TimerProxy::GetInstance().adjustTimers_.size(), (const unsigned int)0); } +/** +* @tc.name: AdjustTimerExemption001. +* @tc.desc: test. +* @tc.type: FUNC +*/ +HWTEST_F(TimeProxyTest, AdjustTimerExemption001, TestSize.Level0) +{ + TIME_HILOGI(TIME_MODULE_SERVICE, "AdjustTimerExemption001 start"); + std::unordered_set exemptionSet = {"bundleName|name"}; + TimerProxy::GetInstance().SetTimerExemption(exemptionSet, true); + auto duration = std::chrono::milliseconds::zero(); + auto timePoint = std::chrono::steady_clock::now(); + auto timerInfo = TimerInfo("name", 0, 0, duration, timePoint, duration, timePoint, duration, nullptr, + nullptr, 0, 0, 0, "bundleName"); + auto timerInfoPtr = std::make_shared(timerInfo); + auto ret = TimerProxy::GetInstance().IsTimerExemption(timerInfoPtr); + EXPECT_EQ(ret, true); +} + /** * @tc.name: ProxyTimerCover001 * @tc.desc: test CallbackAlarmIfNeed @@ -804,12 +823,12 @@ HWTEST_F(TimeProxyTest, ProxyTimerCover002, TestSize.Level1) auto duration = std::chrono::milliseconds::zero(); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo1 = std::make_shared(TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, + auto timerInfo1 = std::make_shared("", TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, UID, 0, ""); auto res = TimerProxy::GetInstance().CallbackAlarmIfNeed(timerInfo1); EXPECT_EQ(res, E_TIME_OK); - auto timerInfo2 = std::make_shared(TIMER_ID + 1, 0, duration, timePoint, duration, timePoint, duration, - nullptr, nullptr, 0, UID, 0, ""); + auto timerInfo2 = std::make_shared("", TIMER_ID + 1, 0, duration, timePoint, duration, timePoint, + duration, nullptr, nullptr, 0, UID, 0, ""); res = TimerProxy::GetInstance().CallbackAlarmIfNeed(timerInfo2); EXPECT_EQ(res, E_TIME_OK); @@ -860,12 +879,12 @@ HWTEST_F(TimeProxyTest, ProxyTimerCover003, TestSize.Level1) auto duration = std::chrono::milliseconds::zero(); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo1 = std::make_shared(TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, + auto timerInfo1 = std::make_shared("", TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, PID, ""); auto res = TimerProxy::GetInstance().CallbackAlarmIfNeed(timerInfo1); EXPECT_EQ(res, E_TIME_OK); - auto timerInfo2 = std::make_shared(TIMER_ID + 1, 0, duration, timePoint, duration, timePoint, duration, - nullptr, nullptr, 0, 0, PID, ""); + auto timerInfo2 = std::make_shared("", TIMER_ID + 1, 0, duration, timePoint, duration, timePoint, + duration, nullptr, nullptr, 0, 0, PID, ""); res = TimerProxy::GetInstance().CallbackAlarmIfNeed(timerInfo2); EXPECT_EQ(res, E_TIME_OK); @@ -906,7 +925,7 @@ HWTEST_F(TimeProxyTest, ProxyTimerCover004, TestSize.Level1) auto duration = std::chrono::milliseconds::zero(); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo = std::make_shared(TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, + auto timerInfo = std::make_shared("", TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, UID, PID, ""); TimerProxy::GetInstance().RecordUidTimerMap(timerInfo, false); { diff --git a/test/unittest/service_test/src/time_service_test.cpp b/test/unittest/service_test/src/time_service_test.cpp index ffdb25bf6874f636c2b075b99de31a2351534555..9e149b72000862ac036625102ba9aab2f8de0f75 100644 --- a/test/unittest/service_test/src/time_service_test.cpp +++ b/test/unittest/service_test/src/time_service_test.cpp @@ -64,6 +64,9 @@ constexpr int ONE_HUNDRED = 100; constexpr int FIVE_HUNDRED = 500; constexpr uint64_t MICRO_TO_MILLISECOND = 1000; constexpr int TIMER_ALARM_COUNT = 50; +static const std::vector ALL_DATA = { "timerId", "type", "flag", "windowLength", "interval", \ + "uid", "bundleName", "wantAgent", "state", "triggerTime", \ + "pid", "name"}; static HapPolicyParams g_policyA = { .apl = APL_SYSTEM_CORE, @@ -1105,7 +1108,7 @@ HWTEST_F(TimeServiceTest, TimerManager001, TestSize.Level0) { auto timerId1 = TIMER_ID; auto entry = std::make_shared( - TimerEntry{timerId1, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); + TimerEntry{"", timerId1, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); TimerManager::GetInstance()->ReCreateTimer(timerId1, entry); std::lock_guard lock(TimerManager::GetInstance()->entryMapMutex_); @@ -1125,7 +1128,8 @@ HWTEST_F(TimeServiceTest, TimerManager001, TestSize.Level0) HWTEST_F(TimeServiceTest, TimerManager002, TestSize.Level0) { uint64_t max = std::numeric_limits::max(); - TimerManager::GetInstance()->SetHandler(TIMER_ID, + TimerManager::GetInstance()->SetHandler("", + TIMER_ID, 0, max, 10, @@ -1167,7 +1171,7 @@ HWTEST_F(TimeServiceTest, TimerManager004, TestSize.Level0) { TimerManager::GetInstance()->DestroyTimer(TIMER_ID); auto entry = std::make_shared( - TimerEntry{TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, UID, PID, "bundleName"}); + TimerEntry{"", TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, UID, PID, "bundleName"}); TimerManager::GetInstance()->ReCreateTimer(TIMER_ID, entry); { @@ -1218,7 +1222,7 @@ HWTEST_F(TimeServiceTest, TimerManager005, TestSize.Level0) auto duration = std::chrono::milliseconds::zero(); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo = std::make_shared(TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, + auto timerInfo = std::make_shared("", TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, 0, ""); auto res = TimerManager::GetInstance()->NotifyWantAgent(timerInfo); EXPECT_FALSE(res); @@ -1286,7 +1290,7 @@ HWTEST_F(TimeServiceTest, TimerManager007, TestSize.Level0) { auto duration = std::chrono::milliseconds::zero(); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo1 = std::make_shared(TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, + auto timerInfo1 = std::make_shared("", TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, 0, ""); std::lock_guard lock(TimerManager::GetInstance()->mutex_); auto alarm = TimerManager::GetInstance()->mPendingIdleUntil_; @@ -1300,11 +1304,11 @@ HWTEST_F(TimeServiceTest, TimerManager007, TestSize.Level0) EXPECT_TRUE(res); auto duration1 = std::chrono::duration_cast( (timePoint + std::chrono::hours(1)).time_since_epoch()); - auto timerInfo2 = std::make_shared(TIMER_ID, 1, duration1, timePoint, duration, timePoint, duration, + auto timerInfo2 = std::make_shared("", TIMER_ID, 1, duration1, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, 0, ""); res = TimerManager::GetInstance()->AdjustDeliveryTimeBasedOnDeviceIdle(timerInfo2); EXPECT_TRUE(res); - auto timerInfo3 = std::make_shared(TIMER_ID, 2, duration, timePoint, duration, timePoint, duration, + auto timerInfo3 = std::make_shared("", TIMER_ID, 2, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, 0, ""); res = TimerManager::GetInstance()->AdjustDeliveryTimeBasedOnDeviceIdle(timerInfo3); EXPECT_TRUE(res); @@ -1333,7 +1337,7 @@ HWTEST_F(TimeServiceTest, TimerManager008, TestSize.Level0) HWTEST_F(TimeServiceTest, TimerManager009, TestSize.Level0) { auto entry = std::make_shared( - TimerEntry{TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); + TimerEntry{"", TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); TimerManager::GetInstance()->ReCreateTimer(TIMER_ID, entry); uint64_t triggerTime = std::numeric_limits::max(); TimerManager::GetInstance()->StartTimer(TIMER_ID, triggerTime); @@ -1359,14 +1363,14 @@ HWTEST_F(TimeServiceTest, TimerManager010, TestSize.Level0) auto duration = std::chrono::milliseconds::zero(); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo = std::make_shared(TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, + auto timerInfo = std::make_shared("", TIMER_ID, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, 0, ""); { std::lock_guard lock(TimerManager::GetInstance()->mutex_); TimerManager::GetInstance()->mPendingIdleUntil_ = timerInfo; } auto entry = std::make_shared( - TimerEntry{TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); + TimerEntry{"", TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); TimerManager::GetInstance()->ReCreateTimer(TIMER_ID, entry); TimerManager::GetInstance()->HandleRSSDeath(); auto res = TimerManager::GetInstance()->DestroyTimer(TIMER_ID); @@ -1406,7 +1410,7 @@ HWTEST_F(TimeServiceTest, TimerManager012, TestSize.Level0) } auto entry = std::make_shared( - TimerEntry{TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, UID, 0, "bundleName"}); + TimerEntry{"", TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, UID, 0, "bundleName"}); timerManager->ReCreateTimer(TIMER_ID, entry); timerManager->OnPackageRemoved(UID); @@ -1469,17 +1473,46 @@ HWTEST_F(TimeServiceTest, TimerManager014, TestSize.Level0) uint64_t i = 0; for (; i <= TIMER_ALARM_COUNT; ++i) { auto entry = std::make_shared( - TimerEntry{i, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); + TimerEntry{"", i, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); TimerManager::GetInstance()->ReCreateTimer(i, entry); } EXPECT_EQ(TimerManager::GetInstance()->timerOutOfRangeTimes_, 1); for (; i <= TIMER_ALARM_COUNT * 2; ++i) { auto entry = std::make_shared( - TimerEntry{i, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); + TimerEntry{"", i, 0, 0, 0, 0, nullptr, nullptr, 0, 0, "bundleName"}); TimerManager::GetInstance()->ReCreateTimer(i, entry); } EXPECT_EQ(TimerManager::GetInstance()->timerOutOfRangeTimes_, 2); } + +/** +* @tc.name: TimerManager015. +* @tc.desc: test create two timer with same name. +* @tc.type: FUNC +*/ +HWTEST_F(TimeServiceTest, TimerManager015, TestSize.Level0) +{ + TIME_HILOGI(TIME_MODULE_CLIENT, "TimerManager015 start"); + TimerManager::GetInstance()->timerNameMap_.clear(); + auto entry = std::make_shared( + TimerEntry{"name", TIMER_ID, 0, 0, 0, 0, nullptr, nullptr, UID, 0, "bundleName"}); + TimerManager::GetInstance()->ReCreateTimer(TIMER_ID, entry); + auto timerNameMap = TimerManager::GetInstance()->timerNameMap_; + EXPECT_NE(timerNameMap.find(UID), timerNameMap.end()); + EXPECT_NE(timerNameMap[UID].find("name"), timerNameMap[UID].end()); + EXPECT_EQ(timerNameMap[UID]["name"], TIMER_ID); + + entry = std::make_shared( + TimerEntry{"name", TIMER_ID + 1, 0, 0, 0, 0, nullptr, nullptr, UID, 0, "bundleName"}); + TimerManager::GetInstance()->ReCreateTimer(TIMER_ID + 1, entry); + timerNameMap = TimerManager::GetInstance()->timerNameMap_; + EXPECT_NE(timerNameMap.find(UID), timerNameMap.end()); + EXPECT_NE(timerNameMap[UID].find("name"), timerNameMap[UID].end()); + EXPECT_EQ(timerNameMap[UID]["name"], TIMER_ID + 1); + auto ret = TimerManager::GetInstance()->DestroyTimer(TIMER_ID); + EXPECT_NE(ret, E_TIME_OK); +} + /** * @tc.name: SystemAbility001. * @tc.desc: test OnStop. @@ -1668,7 +1701,7 @@ HWTEST_F(TimeServiceTest, TimerInfo001, TestSize.Level0) { auto duration = std::chrono::milliseconds::zero(); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo = TimerInfo(0, 0, duration, timePoint, duration, timePoint, duration, nullptr, + auto timerInfo = TimerInfo("", 0, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, 0, ""); auto res = timerInfo.UpdateWhenElapsedFromNow(timePoint, duration); EXPECT_FALSE(res); @@ -1683,7 +1716,7 @@ HWTEST_F(TimeServiceTest, TimerInfo002, TestSize.Level0) { auto duration = std::chrono::milliseconds(0); auto timePoint = std::chrono::steady_clock::now(); - auto timerInfo = TimerInfo(0, 0, duration, timePoint, duration, timePoint, duration, nullptr, + auto timerInfo = TimerInfo("", 0, 0, duration, timePoint, duration, timePoint, duration, nullptr, nullptr, 0, 0, 0, ""); auto res = timerInfo.AdjustTimer(timePoint, 1); EXPECT_TRUE(res); diff --git a/utils/native/include/time_common.h b/utils/native/include/time_common.h index 6ae9176e502c7db90e48b8a718875d88fb235eac..534cdbc64a5c13914ab88e41a7af85e6bd4a4171 100644 --- a/utils/native/include/time_common.h +++ b/utils/native/include/time_common.h @@ -26,6 +26,7 @@ namespace MiscServices { #define TIME_SERVICE_NAME "TimeService" struct TimerPara { + std::string name; int timerType; int64_t windowLength; uint64_t interval;