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 24 TaskSequential::TaskSequential() 25 : TaskGeneric(TaskGeneric::ETaskSequential), 26 mRepeatCount(1), 27 mRepeatIndex(-1) 28 { 29 30 } 31 32 TaskSequential::~TaskSequential() 33 { 34 35 } 36 37 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 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 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 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