Home | History | Annotate | Download | only in task
      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