1 /*
2 * Copyright (C) 2024-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 "tasks/task.h"
17
18 #include "global.h"
19
20 namespace OHOS {
21 namespace MiscServices {
22 // LCOV_EXCL_START
Task(TaskType type)23 Task::Task(TaskType type) : type_(type), seqId_(GetNextSeqId()) { }
24
Task(TaskType type,uint64_t seqId)25 Task::Task(TaskType type, uint64_t seqId) : type_(type), seqId_(seqId) { }
26
Execute()27 RunningState Task::Execute()
28 {
29 if (state_ != RUNNING_STATE_IDLE) {
30 IMSA_HILOGE("Task not runnable, state=%{public}u", state_);
31 return RUNNING_STATE_ERROR;
32 }
33 return ExecuteInner();
34 }
35
Resume(uint64_t seqId)36 RunningState Task::Resume(uint64_t seqId)
37 {
38 if (!curAction_) {
39 IMSA_HILOGE("curAction_ is NULL, error!");
40 return RUNNING_STATE_ERROR;
41 }
42
43 if (state_ != RUNNING_STATE_PAUSED) {
44 IMSA_HILOGE("state_ is %{public}u, do not need to resume", state_);
45 return RUNNING_STATE_ERROR;
46 }
47
48 auto ret = curAction_->Resume(seqId);
49 if (ret == RUNNING_STATE_PAUSED) { // resume failed, return
50 return state_;
51 }
52 if (ret == RUNNING_STATE_COMPLETED) { // resume success, continue to execute
53 curAction_.reset();
54 return ExecuteInner();
55 }
56
57 // unreachable
58 IMSA_HILOGE("curAction_ resume return %{public}u, error!", ret);
59 return RUNNING_STATE_ERROR;
60 }
61
OnTask(std::shared_ptr<Task> task)62 RunningState Task::OnTask(std::shared_ptr<Task> task)
63 {
64 if (task == nullptr) {
65 IMSA_HILOGE("task is NULL, error!");
66 return state_;
67 }
68 auto src = task->GetSourceType();
69 if (src == SOURCE_TYPE_INNER) {
70 return Resume(task->GetSeqId());
71 }
72 if (src == SOURCE_TYPE_IMA) {
73 Pend(task);
74 return state_;
75 }
76 return state_;
77 }
78
GetType() const79 TaskType Task::GetType() const
80 {
81 return type_;
82 }
83
GetSourceType() const84 SourceType Task::GetSourceType() const
85 {
86 if (type_ >= TASK_TYPE_AMS_BEGIN && type_ <= TASK_TYPE_AMS_END) {
87 return SOURCE_TYPE_AMS;
88 }
89 if (type_ >= TASK_TYPE_IMA_BEGIN && type_ <= TASK_TYPE_IMA_END) {
90 return SOURCE_TYPE_IMA;
91 }
92 if (type_ >= TASK_TYPE_IMSA_BEGIN && type_ <= TASK_TYPE_IMSA_END) {
93 return SOURCE_TYPE_IMSA;
94 }
95 return SOURCE_TYPE_INNER;
96 }
97
GetSeqId() const98 uint64_t Task::GetSeqId() const
99 {
100 return seqId_;
101 }
102
GetState() const103 RunningState Task::GetState() const
104 {
105 return state_;
106 }
107
IsRunning() const108 bool Task::IsRunning() const
109 {
110 return state_ == RUNNING_STATE_RUNNING;
111 }
112
GetActions() const113 const std::list<std::unique_ptr<Action>> &Task::GetActions() const
114 {
115 return actions_;
116 }
117
GetNextSeqId()118 uint64_t Task::GetNextSeqId()
119 {
120 static std::atomic<uint64_t> maxSeqId(1);
121 return maxSeqId.fetch_add(1);
122 }
123
ExecuteInner()124 RunningState Task::ExecuteInner()
125 {
126 state_ = RUNNING_STATE_RUNNING;
127 if (!pendingActions_.empty()) {
128 pendingActions_.splice(pendingActions_.end(), actions_);
129 actions_.swap(pendingActions_);
130 }
131
132 while (!actions_.empty()) {
133 curAction_ = std::move(actions_.front());
134 actions_.pop_front();
135
136 auto ret = curAction_->Execute();
137
138 // check pending tasks
139 if (!pendingActions_.empty()) {
140 pendingActions_.splice(pendingActions_.end(), actions_);
141 actions_.swap(pendingActions_);
142 }
143
144 if (ret == RUNNING_STATE_COMPLETED) {
145 curAction_.reset();
146 continue;
147 }
148
149 state_ = RUNNING_STATE_PAUSED;
150 return state_;
151 }
152 state_ = RUNNING_STATE_COMPLETED;
153 return state_;
154 }
155
Pend(std::shared_ptr<Task> task)156 int32_t Task::Pend(std::shared_ptr<Task> task)
157 {
158 pendingActions_.splice(pendingActions_.end(), task->actions_);
159 actions_.swap(pendingActions_);
160 return ErrorCode::NO_ERROR;
161 }
162
Pend(std::unique_ptr<Action> action)163 int32_t Task::Pend(std::unique_ptr<Action> action)
164 {
165 pendingActions_.push_back(std::move(action));
166 return ErrorCode::NO_ERROR;
167 }
168 // LCOV_EXCL_STOP
169 } // namespace MiscServices
170 } // namespace OHOS