179a732c7Sopenharmony_ci/*
279a732c7Sopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
379a732c7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
479a732c7Sopenharmony_ci * you may not use this file except in compliance with the License.
579a732c7Sopenharmony_ci * You may obtain a copy of the License at
679a732c7Sopenharmony_ci *
779a732c7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
879a732c7Sopenharmony_ci *
979a732c7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1079a732c7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1179a732c7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1279a732c7Sopenharmony_ci * See the License for the specific language governing permissions and
1379a732c7Sopenharmony_ci * limitations under the License.
1479a732c7Sopenharmony_ci */
1579a732c7Sopenharmony_ci
1679a732c7Sopenharmony_ci#include "dm_log.h"
1779a732c7Sopenharmony_ci#include "dm_timer.h"
1879a732c7Sopenharmony_ci#include "dm_constants.h"
1979a732c7Sopenharmony_ci
2079a732c7Sopenharmony_cinamespace OHOS {
2179a732c7Sopenharmony_cinamespace DistributedHardware {
2279a732c7Sopenharmony_cinamespace {
2379a732c7Sopenharmony_ciconst int32_t MIN_TIME_OUT = 0;
2479a732c7Sopenharmony_ciconst int32_t MAX_TIME_OUT = 300;
2579a732c7Sopenharmony_ciconst int64_t MICROSECOND_TO_SECOND = 1000000L;
2679a732c7Sopenharmony_ciconstexpr const char* TIMER_TASK = "TimerTask";
2779a732c7Sopenharmony_ci}
2879a732c7Sopenharmony_ci
2979a732c7Sopenharmony_ciDmTimer::DmTimer()
3079a732c7Sopenharmony_ci{
3179a732c7Sopenharmony_ci    LOGI("DmTimer constructor");
3279a732c7Sopenharmony_ci    if (queue_ != nullptr) {
3379a732c7Sopenharmony_ci        LOGI("Timer is already init.");
3479a732c7Sopenharmony_ci        return;
3579a732c7Sopenharmony_ci    }
3679a732c7Sopenharmony_ci    queue_ = std::make_shared<ffrt::queue>(TIMER_TASK);
3779a732c7Sopenharmony_ci}
3879a732c7Sopenharmony_ci
3979a732c7Sopenharmony_ciDmTimer::~DmTimer()
4079a732c7Sopenharmony_ci{
4179a732c7Sopenharmony_ci    LOGI("DmTimer destructor");
4279a732c7Sopenharmony_ci    DeleteAll();
4379a732c7Sopenharmony_ci}
4479a732c7Sopenharmony_ci
4579a732c7Sopenharmony_ciint32_t DmTimer::StartTimer(std::string name, int32_t timeOut, TimerCallback callback)
4679a732c7Sopenharmony_ci{
4779a732c7Sopenharmony_ci    if (name.empty() || timeOut <= MIN_TIME_OUT || timeOut > MAX_TIME_OUT || callback == nullptr) {
4879a732c7Sopenharmony_ci        LOGE("DmTimer StartTimer input value invalid");
4979a732c7Sopenharmony_ci        return ERR_DM_INPUT_PARA_INVALID;
5079a732c7Sopenharmony_ci    }
5179a732c7Sopenharmony_ci    CHECK_NULL_RETURN(queue_, ERR_DM_POINT_NULL);
5279a732c7Sopenharmony_ci    LOGI("DmTimer StartTimer start name: %{public}s", name.c_str());
5379a732c7Sopenharmony_ci    std::lock_guard<std::mutex> locker(timerMutex_);
5479a732c7Sopenharmony_ci
5579a732c7Sopenharmony_ci    auto taskFunc = [callback, name] () { callback(name); };
5679a732c7Sopenharmony_ci    ffrt::task_handle handle = queue_->submit_h(taskFunc, ffrt::task_attr().delay(timeOut * MICROSECOND_TO_SECOND));
5779a732c7Sopenharmony_ci    if (handle == nullptr) {
5879a732c7Sopenharmony_ci        LOGE("handle is nullptr.");
5979a732c7Sopenharmony_ci        return ERR_DM_FAILED;
6079a732c7Sopenharmony_ci    }
6179a732c7Sopenharmony_ci    timerVec_[name] = std::move(handle);
6279a732c7Sopenharmony_ci    return DM_OK;
6379a732c7Sopenharmony_ci}
6479a732c7Sopenharmony_ci
6579a732c7Sopenharmony_ciint32_t DmTimer::DeleteTimer(std::string timerName)
6679a732c7Sopenharmony_ci{
6779a732c7Sopenharmony_ci    if (timerName.empty()) {
6879a732c7Sopenharmony_ci        LOGE("DmTimer DeleteTimer timer is null");
6979a732c7Sopenharmony_ci        return ERR_DM_INPUT_PARA_INVALID;
7079a732c7Sopenharmony_ci    }
7179a732c7Sopenharmony_ci    LOGI("DmTimer DeleteTimer start name: %{public}s", timerName.c_str());
7279a732c7Sopenharmony_ci    std::lock_guard<std::mutex> locker(timerMutex_);
7379a732c7Sopenharmony_ci    auto item = timerVec_.find(timerName);
7479a732c7Sopenharmony_ci    if (item == timerVec_.end()) {
7579a732c7Sopenharmony_ci        LOGI("Invalid task.");
7679a732c7Sopenharmony_ci        return ERR_DM_FAILED;
7779a732c7Sopenharmony_ci    }
7879a732c7Sopenharmony_ci    if (item->second != nullptr && queue_ != nullptr) {
7979a732c7Sopenharmony_ci        int32_t ret = queue_->cancel(item->second);
8079a732c7Sopenharmony_ci        if (ret != 0) {
8179a732c7Sopenharmony_ci            LOGE("Cancel failed, errCode: %{public}d.", ret);
8279a732c7Sopenharmony_ci        }
8379a732c7Sopenharmony_ci    }
8479a732c7Sopenharmony_ci    timerVec_.erase(timerName);
8579a732c7Sopenharmony_ci    return DM_OK;
8679a732c7Sopenharmony_ci}
8779a732c7Sopenharmony_ci
8879a732c7Sopenharmony_ciint32_t DmTimer::DeleteAll()
8979a732c7Sopenharmony_ci{
9079a732c7Sopenharmony_ci    LOGI("DmTimer DeleteAll start");
9179a732c7Sopenharmony_ci    std::lock_guard<std::mutex> locker(timerMutex_);
9279a732c7Sopenharmony_ci    for (const auto &name : timerVec_) {
9379a732c7Sopenharmony_ci        if (name.second != nullptr && queue_ != nullptr) {
9479a732c7Sopenharmony_ci            int32_t ret = queue_->cancel(name.second);
9579a732c7Sopenharmony_ci            if (ret != 0) {
9679a732c7Sopenharmony_ci                LOGE("Cancel failed, errCode: %{public}d.", ret);
9779a732c7Sopenharmony_ci            }
9879a732c7Sopenharmony_ci        }
9979a732c7Sopenharmony_ci    }
10079a732c7Sopenharmony_ci    timerVec_.clear();
10179a732c7Sopenharmony_ci    return DM_OK;
10279a732c7Sopenharmony_ci}
10379a732c7Sopenharmony_ci}
10479a732c7Sopenharmony_ci}