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