Home | History | Annotate | Download | only in connectivitymanagertest
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of 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,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.connectivitymanagertest;
     18 
     19 import android.net.NetworkInfo.State;
     20 import android.util.Log;
     21 
     22 import java.util.List;
     23 import java.util.ArrayList;
     24 
     25 public class NetworkState {
     26     public static final int TO_DISCONNECTION = 0; // transition to disconnection
     27     public static final int TO_CONNECTION = 1; // transition to connection
     28     public static final int DO_NOTHING = -1;   // no state change
     29     private final String LOG_TAG = "NetworkState";
     30     private List<State> mStateDepository;
     31     private State mTransitionTarget;
     32     private int mTransitionDirection;
     33     private String mReason = null;         // record mReason of state transition failure
     34 
     35     public NetworkState() {
     36         mStateDepository = new ArrayList<State>();
     37         mTransitionDirection = DO_NOTHING;
     38         mTransitionTarget = State.UNKNOWN;
     39     }
     40 
     41     public NetworkState(State currentState) {
     42         mStateDepository = new ArrayList<State>();
     43         mStateDepository.add(currentState);
     44         mTransitionDirection = DO_NOTHING;
     45         mTransitionTarget = State.UNKNOWN;
     46     }
     47 
     48     // Reinitialize the network state
     49     public void resetNetworkState() {
     50         mStateDepository.clear();
     51         mTransitionDirection = DO_NOTHING;
     52         mTransitionTarget = State.UNKNOWN;
     53     }
     54 
     55     // set the transition criteria, transitionDir could be:
     56     // DO_NOTHING, TO_CONNECTION, TO_DISCONNECTION
     57     public void setStateTransitionCriteria(State initState, int transitionDir, State targetState) {
     58         if (!mStateDepository.isEmpty()) {
     59             mStateDepository.clear();
     60         }
     61         mStateDepository.add(initState);
     62         mTransitionDirection = transitionDir;
     63         mTransitionTarget = targetState;
     64         Log.v(LOG_TAG, "setStateTransitionCriteria: " + printStates());
     65     }
     66 
     67     public void recordState(State currentState) {
     68         mStateDepository.add(currentState);
     69     }
     70 
     71     // Verify state transition
     72     public boolean validateStateTransition() {
     73         Log.v(LOG_TAG, "print state depository: " + printStates());
     74         if (mTransitionDirection == DO_NOTHING) {
     75             if (mStateDepository.isEmpty()) {
     76                 Log.v(LOG_TAG, "no state is recorded");
     77                 mReason = "no state is recorded.";
     78                 return false;
     79             } else if (mStateDepository.size() > 1) {
     80                 for (int i = 0; i < mStateDepository.size(); i++) {
     81                     if (mStateDepository.get(i) != mTransitionTarget) {
     82                         Log.v(LOG_TAG, "state changed.");
     83                         mReason = "Unexpected state change";
     84                         return false;
     85                     }
     86                 }
     87             } else if (mStateDepository.get(0) != mTransitionTarget) {
     88                 Log.v(LOG_TAG, mTransitionTarget + " is expected, but it is " +
     89                         mStateDepository.get(0));
     90                 mReason = mTransitionTarget + " is expected, but it is " + mStateDepository.get(0);
     91                 return false;
     92             }
     93             return true;
     94         } else if (mTransitionDirection == TO_CONNECTION) {
     95             Log.v(LOG_TAG, "transition to CONNECTED");
     96             return transitToConnection();
     97         } else {
     98             Log.v(LOG_TAG, "transition to DISCONNECTED");
     99             return transitToDisconnection();
    100         }
    101     }
    102 
    103     /*
    104      * Transition from CONNECTED -> DISCONNECTED:
    105      *    CONNECTED->DISCONNECTING->DISCONNECTED
    106      * return false if any state transition is not valid and save a message in mReason
    107      */
    108     public boolean transitToDisconnection () {
    109         mReason = "states: " + printStates();
    110         if (mStateDepository.get(0) != State.CONNECTED) {
    111             mReason += " initial state should be CONNECTED, but it is " +
    112                     mStateDepository.get(0) + ".";
    113             return false;
    114         }
    115         State lastState = mStateDepository.get(mStateDepository.size() - 1);
    116         if ( lastState != mTransitionTarget) {
    117             mReason += " the last state should be DISCONNECTED, but it is " + lastState;
    118             return false;
    119         }
    120         for (int i = 1; i < mStateDepository.size() - 1; i++) {
    121             State preState = mStateDepository.get(i-1);
    122             State curState = mStateDepository.get(i);
    123             if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) ||
    124                     (curState == State.DISCONNECTED))) {
    125                 continue;
    126             } else if ((preState == State.DISCONNECTING) && (curState == State.DISCONNECTED)) {
    127                 continue;
    128             } else if ((preState == State.DISCONNECTED) && (curState == State.DISCONNECTED)) {
    129                 continue;
    130             } else {
    131                 mReason += " Transition state from " + preState.toString() + " to " +
    132                         curState.toString() + " is not valid.";
    133                 return false;
    134             }
    135         }
    136         return true;
    137     }
    138 
    139     // DISCONNECTED->CONNECTING->CONNECTED
    140     public boolean transitToConnection() {
    141         mReason = "states: " + printStates();
    142         if (mStateDepository.get(0) != State.DISCONNECTED) {
    143             mReason += " initial state should be DISCONNECTED, but it is " +
    144                     mStateDepository.get(0) + ".";
    145             return false;
    146         }
    147         State lastState = mStateDepository.get(mStateDepository.size() - 1);
    148         if ( lastState != mTransitionTarget) {
    149             mReason += "The last state should be " + mTransitionTarget + ", but it is " + lastState;
    150             return false;
    151         }
    152         for (int i = 1; i < mStateDepository.size(); i++) {
    153             State preState = mStateDepository.get(i-1);
    154             State curState = mStateDepository.get(i);
    155             if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) ||
    156                     (curState == State.CONNECTED) || (curState == State.DISCONNECTED))) {
    157                 continue;
    158             } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
    159                 continue;
    160             } else if ((preState == State.CONNECTED) && (curState == State.CONNECTED)) {
    161                 continue;
    162             } else {
    163                 mReason += " Transition state from " + preState.toString() + " to " +
    164                         curState.toString() + " is not valid.";
    165                 return false;
    166             }
    167         }
    168         return true;
    169     }
    170 
    171     public List<State> getTransitionStates() {
    172         return mStateDepository;
    173     }
    174 
    175     // return state failure mReason
    176     public String getReason() {
    177         return mReason;
    178     }
    179 
    180     public String printStates() {
    181         StringBuilder stateBuilder = new StringBuilder("");
    182         for (int i = 0; i < mStateDepository.size(); i++) {
    183             stateBuilder.append(" ").append(mStateDepository.get(i).toString()).append("->");
    184         }
    185         return stateBuilder.toString();
    186     }
    187 
    188     @Override
    189     public String toString() {
    190         StringBuilder builder = new StringBuilder(" ");
    191         builder.append("mTransitionDirection: ").append(Integer.toString(mTransitionDirection)).
    192                 append("; ").append("states:").
    193                 append(printStates()).append("; ");
    194         return builder.toString();
    195     }
    196 }
    197