1 /*
2  * Copyright (c) 2023-2023 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 "timer.h"
17 #include "steady_clock.h"
18 #include "core/timer_core.h"
19 #include "dp_log.h"
20 
21 namespace OHOS {
22 namespace CameraStandard {
23 namespace DeferredProcessing {
24 
Create(const std::string & name,TimerType timerType,uint32_t intervalMs,TimerCallback callback)25 std::shared_ptr<Timer> Timer::Create(const std::string& name, TimerType timerType,
26     uint32_t intervalMs, TimerCallback callback)
27 {
28     DP_DEBUG_LOG("name: %s, timer type: %{public}d(0: once, 1: periodic), intervalMs: %u",
29         name.c_str(), timerType, intervalMs);
30     struct MakeSharedHelper : public Timer {
31         MakeSharedHelper(const std::string& name, TimerType timerType, uint32_t intervalMs, TimerCallback callback)
32             : Timer(name, timerType, intervalMs, std::move(callback))
33         {
34         }
35     };
36     auto timer = std::make_shared<MakeSharedHelper>(name, timerType, intervalMs, std::move(callback));
37     if (!timer->Initialize()) {
38         timer.reset();
39     }
40     return timer;
41 }
42 
Timer(const std::string & name,TimerType timerType,uint32_t intervalMs,TimerCallback callback)43 Timer::Timer(const std::string& name, TimerType timerType, uint32_t intervalMs, TimerCallback callback)
44     : name_(name), timerType_(timerType), intervalMs_(intervalMs), callback_(std::move(callback)), expiredTimeMs_(0)
45 {
46     DP_DEBUG_LOG("name: %s, timer type: %{public}d(0: once, 1: periodic), intervalMs: %u",
47         name_.c_str(), timerType, intervalMs);
48 }
49 
~Timer()50 Timer::~Timer()
51 {
52     DP_DEBUG_LOG("name: %s, timer type: %{public}d(0: once, 1: periodic), intervalMs: %u",
53         name_.c_str(), timerType_, intervalMs_);
54     std::lock_guard<std::mutex> lock(mutex_);
55     active_ = false;
56 }
57 
Initialize()58 bool Timer::Initialize()
59 {
60     return TimerCore::GetInstance().Initialize();
61 }
62 
GetName()63 const std::string& Timer::GetName()
64 {
65     return name_;
66 }
67 
Start(uint32_t delayTimeMs)68 bool Timer::Start(uint32_t delayTimeMs)
69 {
70     std::lock_guard<std::mutex> lock(mutex_);
71     return StartUnlocked(delayTimeMs);
72 }
73 
StartAt(uint64_t timestampMs)74 bool Timer::StartAt(uint64_t timestampMs)
75 {
76     std::lock_guard<std::mutex> lock(mutex_);
77     return StartAtUnlocked(timestampMs);
78 }
79 
Stop()80 bool Timer::Stop()
81 {
82     std::lock_guard<std::mutex> lock(mutex_);
83     DP_DEBUG_LOG("stop timer (%s), timer type: %{public}d(0: once, 1: periodic), intervalMs: %u",
84         name_.c_str(), timerType_, intervalMs_);
85     if (!active_) {
86         return true;
87     }
88     active_ = false;
89     return TimerCore::GetInstance().DeregisterTimer(expiredTimeMs_, shared_from_this());
90 }
91 
StartUnlocked(uint32_t delayTimeMs)92 bool Timer::StartUnlocked(uint32_t delayTimeMs)
93 {
94     auto curTimeMs = SteadyClock::GetTimestampMilli();
95     auto timestampMs = curTimeMs + (delayTimeMs == 0 ? intervalMs_ : delayTimeMs);
96     DP_DEBUG_LOG("timer (%s), type: %{public}d(0: once, 1: periodic), curTime: %{public}d, expiredTime: %{public}d",
97         name_.c_str(), timerType_, static_cast<int>(curTimeMs), static_cast<int>(timestampMs));
98     return StartAtUnlocked(timestampMs);
99 }
100 
StartAtUnlocked(uint64_t timestampMs)101 bool Timer::StartAtUnlocked(uint64_t timestampMs)
102 {
103     if (active_) {
104         TimerCore::GetInstance().DeregisterTimer(expiredTimeMs_, shared_from_this());
105     }
106     active_ = true;
107     expiredTimeMs_ = timestampMs;
108     return TimerCore::GetInstance().RegisterTimer(expiredTimeMs_, shared_from_this());
109 }
110 
IsActive()111 bool Timer::IsActive()
112 {
113     std::lock_guard<std::mutex> lock(mutex_);
114     return active_;
115 }
116 
TimerExpired()117 void Timer::TimerExpired()
118 {
119     {
120         std::lock_guard<std::mutex> lock(mutex_);
121         if (!active_) {
122             DP_DEBUG_LOG("inactive timer (%s) expired, type: %{public}d(0: once, 1: periodic), intervalMs: %u",
123                 name_.c_str(), timerType_, intervalMs_);
124             return;
125         }
126         if (timerType_ == TimerType::PERIODIC) {
127             StartUnlocked();
128         } else {
129             active_ = false;
130         }
131     }
132     DP_DEBUG_LOG("timer (%s) expired, type: %{public}d(0: once, 1: periodic), expiredTimeMs at %{public}d",
133         name_.c_str(), timerType_, static_cast<int>(expiredTimeMs_));
134     if (callback_) {
135         callback_();
136     }
137 }
138 } //namespace DeferredProcessing
139 } // namespace CameraStandard
140 } // namespace OHOS
141