1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 #include <stdlib.h>
17 #include <algorithm>
18 #include "Log.h"
19 #include "StringUtil.h"
20 #include "task/TaskSequential.h"
21 #include "task/TaskCase.h"
22 #include "task/TaskAsync.h"
23 
TaskSequential()24 TaskSequential::TaskSequential()
25     : TaskGeneric(TaskGeneric::ETaskSequential),
26       mRepeatCount(1),
27       mRepeatIndex(-1)
28 {
29 
30 }
31 
~TaskSequential()32 TaskSequential::~TaskSequential()
33 {
34 
35 }
36 
37 
run()38 TaskGeneric::ExecutionResult TaskSequential::run()
39 {
40     mRepeatIndex = -1;
41     bool storeIndex = (mIndexName.length() == 0 ? false: true);
42     if (storeIndex && !getTestCase()->registerIndex(mIndexName, mRepeatIndex)) {
43         if (!getTestCase()->updateIndex(mIndexName, mRepeatIndex)) {
44             LOGE("register/update of index %s failed", mIndexName.string());
45             return TaskGeneric::EResultError;
46         }
47     }
48 
49     TaskGeneric::ExecutionResult firstError(TaskGeneric::EResultOK);
50 
51     for (mRepeatIndex = 0; mRepeatIndex < mRepeatCount; mRepeatIndex++) {
52         LOGI("  TaskSequential index %s loop %d-th", mIndexName.string(), mRepeatIndex);
53         if (storeIndex && !getTestCase()->updateIndex(mIndexName, mRepeatIndex)) {
54             return TaskGeneric::EResultError;
55         }
56         std::list<TaskGeneric*>::iterator i = getChildren().begin();
57         std::list<TaskGeneric*>::iterator end = getChildren().end();
58         for (; i != end; i++) {
59             TaskGeneric* child = *i;
60             TaskGeneric::ExecutionResult result = child->run();
61             if ((result != TaskGeneric::EResultOK) && (firstError == TaskGeneric::EResultOK)) {
62                 firstError = result;
63                 break;
64             }
65         }
66         TaskGeneric::ExecutionResult result = runAsyncTasksQueued();
67         if ((result != TaskGeneric::EResultOK) && (firstError == TaskGeneric::EResultOK)) {
68                     firstError = result;
69         }
70         switch (firstError) {
71         case TaskGeneric::EResultOK:
72         case TaskGeneric::EResultContinue:
73             // continue at the last index should be treated as OK
74             firstError = TaskGeneric::EResultOK;
75             break; // continue for loop
76         case TaskGeneric:: EResultBreakOneLoop:
77             return TaskGeneric::EResultOK;
78         case TaskGeneric::EResultError:
79         case TaskGeneric::EResultFail:
80         case TaskGeneric::EResultPass:
81             mRepeatIndex = mRepeatCount; //exit for loop
82             break;
83         }
84     }
85     // update to the loop exit value
86     if (storeIndex && !getTestCase()->updateIndex(mIndexName, mRepeatIndex)) {
87         return TaskGeneric::EResultError;
88     }
89     return firstError;
90 }
91 
queueAsyncTask(TaskAsync * task)92 bool TaskSequential::queueAsyncTask(TaskAsync* task)
93 {
94     std::list<TaskAsync*>::iterator it;
95     it = std::find(mAsyncTasks.begin(), mAsyncTasks.end(), task);
96     if (it != mAsyncTasks.end()) { // already queued
97         return true;
98     }
99     mAsyncTasks.push_back(task);
100     return true;
101 }
102 
runAsyncTasksQueued()103 TaskGeneric::ExecutionResult TaskSequential::runAsyncTasksQueued()
104 {
105     std::list<TaskAsync*>::iterator i = mAsyncTasks.begin();
106     std::list<TaskAsync*>::iterator end = mAsyncTasks.end();
107     TaskGeneric::ExecutionResult firstError(TaskGeneric::EResultOK);
108 
109     for (; i != end; i++) {
110         TaskAsync* child = *i;
111         TaskGeneric::ExecutionResult result = child->complete();
112         if ((result != TaskGeneric::EResultOK) && (firstError == TaskGeneric::EResultOK)) {
113             firstError = result;
114         }
115     }
116     mAsyncTasks.clear();
117     return firstError;
118 }
119 
120 
parseAttribute(const android::String8 & name,const android::String8 & value)121 bool TaskSequential::parseAttribute(const android::String8& name, const android::String8& value)
122 {
123     if (StringUtil::compare(name, "repeat") == 0) {
124         mRepeatCount = atoi(value.string());
125         if (mRepeatCount <= 0) {
126             LOGE("TaskSequential::parseAttribute invalid value %s for key %s",
127                     value.string(), name.string());
128             return false;
129         }
130         return true;
131     } else if (StringUtil::compare(name, "index") == 0) {
132         mIndexName.append(value);
133         LOGD("TaskSequential::parseAttribute index %s", mIndexName.string());
134         return true;
135     } else {
136         return false;
137     }
138 }
139