1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dm_log.h"
17 #include "dm_timer.h"
18 #include "dm_constants.h"
19 
20 namespace OHOS {
21 namespace DistributedHardware {
22 namespace {
23 const int32_t MIN_TIME_OUT = 0;
24 const int32_t MAX_TIME_OUT = 300;
25 const int64_t MICROSECOND_TO_SECOND = 1000000L;
26 constexpr const char* TIMER_TASK = "TimerTask";
27 }
28 
DmTimer()29 DmTimer::DmTimer()
30 {
31     LOGI("DmTimer constructor");
32     if (queue_ != nullptr) {
33         LOGI("Timer is already init.");
34         return;
35     }
36     queue_ = std::make_shared<ffrt::queue>(TIMER_TASK);
37 }
38 
~DmTimer()39 DmTimer::~DmTimer()
40 {
41     LOGI("DmTimer destructor");
42     DeleteAll();
43 }
44 
StartTimer(std::string name,int32_t timeOut,TimerCallback callback)45 int32_t DmTimer::StartTimer(std::string name, int32_t timeOut, TimerCallback callback)
46 {
47     if (name.empty() || timeOut <= MIN_TIME_OUT || timeOut > MAX_TIME_OUT || callback == nullptr) {
48         LOGE("DmTimer StartTimer input value invalid");
49         return ERR_DM_INPUT_PARA_INVALID;
50     }
51     CHECK_NULL_RETURN(queue_, ERR_DM_POINT_NULL);
52     LOGI("DmTimer StartTimer start name: %{public}s", name.c_str());
53     std::lock_guard<std::mutex> locker(timerMutex_);
54 
55     auto taskFunc = [callback, name] () { callback(name); };
56     ffrt::task_handle handle = queue_->submit_h(taskFunc, ffrt::task_attr().delay(timeOut * MICROSECOND_TO_SECOND));
57     if (handle == nullptr) {
58         LOGE("handle is nullptr.");
59         return ERR_DM_FAILED;
60     }
61     timerVec_[name] = std::move(handle);
62     return DM_OK;
63 }
64 
DeleteTimer(std::string timerName)65 int32_t DmTimer::DeleteTimer(std::string timerName)
66 {
67     if (timerName.empty()) {
68         LOGE("DmTimer DeleteTimer timer is null");
69         return ERR_DM_INPUT_PARA_INVALID;
70     }
71     LOGI("DmTimer DeleteTimer start name: %{public}s", timerName.c_str());
72     std::lock_guard<std::mutex> locker(timerMutex_);
73     auto item = timerVec_.find(timerName);
74     if (item == timerVec_.end()) {
75         LOGI("Invalid task.");
76         return ERR_DM_FAILED;
77     }
78     if (item->second != nullptr && queue_ != nullptr) {
79         int32_t ret = queue_->cancel(item->second);
80         if (ret != 0) {
81             LOGE("Cancel failed, errCode: %{public}d.", ret);
82         }
83     }
84     timerVec_.erase(timerName);
85     return DM_OK;
86 }
87 
DeleteAll()88 int32_t DmTimer::DeleteAll()
89 {
90     LOGI("DmTimer DeleteAll start");
91     std::lock_guard<std::mutex> locker(timerMutex_);
92     for (const auto &name : timerVec_) {
93         if (name.second != nullptr && queue_ != nullptr) {
94             int32_t ret = queue_->cancel(name.second);
95             if (ret != 0) {
96                 LOGE("Cancel failed, errCode: %{public}d.", ret);
97             }
98         }
99     }
100     timerVec_.clear();
101     return DM_OK;
102 }
103 }
104 }