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                 Log.v(LOG_TAG, "no broadcast is expected, " +
     81                         "instead broadcast is probably received");
     82                 mReason = "no broadcast is expected, instead broadcast is probably received";
     83                 return false;
     84             } else if (mStateDepository.get(0) != mTransitionTarget) {
     85                 Log.v(LOG_TAG, mTransitionTarget + " is expected, but it is " +
     86                         mStateDepository.get(0));
     87                 mReason = mTransitionTarget + " is expected, but it is " + mStateDepository.get(0);
     88                 return false;
     89             }
     90             return true;
     91         } else if (mTransitionDirection == TO_CONNECTION) {
     92             Log.v(LOG_TAG, "transition to CONNECTED");
     93             return transitToConnection();
     94         } else {
     95             Log.v(LOG_TAG, "transition to DISCONNECTED");
     96             return transitToDisconnection();
     97         }
     98     }
     99 
    100     /*
    101      * Transition from CONNECTED -> DISCONNECTED:
    102      *    CONNECTED->DISCONNECTING->DISCONNECTED
    103      * return false if any state transition is not valid and save a message in mReason
    104      */
    105     public boolean transitToDisconnection () {
    106         mReason = "states: " + printStates();
    107         if (mStateDepository.get(0) != State.CONNECTED) {
    108             mReason += " initial state should be CONNECTED, but it is " +
    109                     mStateDepository.get(0) + ".";
    110             return false;
    111         }
    112         State lastState = mStateDepository.get(mStateDepository.size() - 1);
    113         if ( lastState != mTransitionTarget) {
    114             mReason += " the last state should be DISCONNECTED, but it is " + lastState;
    115             return false;
    116         }
    117         for (int i = 1; i < mStateDepository.size() - 1; i++) {
    118             State preState = mStateDepository.get(i-1);
    119             State curState = mStateDepository.get(i);
    120             if ((preState == State.CONNECTED) && ((curState == State.DISCONNECTING) ||
    121                     (curState == State.DISCONNECTED))) {
    122                 continue;
    123             } else if ((preState == State.DISCONNECTING) && (curState == State.DISCONNECTED)) {
    124                 continue;
    125             } else if ((preState == State.DISCONNECTED) && (curState == State.DISCONNECTED)) {
    126                 continue;
    127             } else {
    128                 mReason += " Transition state from " + preState.toString() + " to " +
    129                         curState.toString() + " is not valid.";
    130                 return false;
    131             }
    132         }
    133         return true;
    134     }
    135 
    136     // DISCONNECTED->CONNECTING->CONNECTED
    137     public boolean transitToConnection() {
    138         mReason = "states: " + printStates();
    139         if (mStateDepository.get(0) != State.DISCONNECTED) {
    140             mReason += " initial state should be DISCONNECTED, but it is " +
    141                     mStateDepository.get(0) + ".";
    142             return false;
    143         }
    144         State lastState = mStateDepository.get(mStateDepository.size() - 1);
    145         if ( lastState != mTransitionTarget) {
    146             mReason += "The last state should be " + mTransitionTarget + ", but it is " + lastState;
    147             return false;
    148         }
    149         for (int i = 1; i < mStateDepository.size(); i++) {
    150             State preState = mStateDepository.get(i-1);
    151             State curState = mStateDepository.get(i);
    152             if ((preState == State.DISCONNECTED) && ((curState == State.CONNECTING) ||
    153                     (curState == State.CONNECTED) || (curState == State.DISCONNECTED))) {
    154                 continue;
    155             } else if ((preState == State.CONNECTING) && (curState == State.CONNECTED)) {
    156                 continue;
    157             } else if ((preState == State.CONNECTED) && (curState == State.CONNECTED)) {
    158                 continue;
    159             } else {
    160                 mReason += " Transition state from " + preState.toString() + " to " +
    161                         curState.toString() + " is not valid.";
    162                 return false;
    163             }
    164         }
    165         return true;
    166     }
    167 
    168     public List<State> getTransitionStates() {
    169         return mStateDepository;
    170     }
    171 
    172     // return state failure mReason
    173     public String getReason() {
    174         return mReason;
    175     }
    176 
    177     public String printStates() {
    178         StringBuilder stateBuilder = new StringBuilder("");
    179         for (int i = 0; i < mStateDepository.size(); i++) {
    180             stateBuilder.append(" ").append(mStateDepository.get(i).toString()).append("->");
    181         }
    182         return stateBuilder.toString();
    183     }
    184 
    185     @Override
    186     public String toString() {
    187         StringBuilder builder = new StringBuilder(" ");
    188         builder.append("mTransitionDirection: ").append(Integer.toString(mTransitionDirection)).
    189                 append("; ").append("states:").
    190                 append(printStates()).append("; ");
    191         return builder.toString();
    192     }
    193 }
    194