content: /*
   * CDDL HEADER START
   *
   * The contents of this file are subject to the terms of the Common Development
   * and Distribution License (the "License").
   * You may not use this file except in compliance with the License.
   *
   * You can obtain a copy of the license at
   * src/com/vodafone360/people/VODAFONE.LICENSE.txt or
   * http://github.com/360/360-Engine-for-Android
   * See the License for the specific language governing permissions and
   * limitations under the License.
   *
   * When distributing Covered Code, include this CDDL HEADER in each file and
   * include the License file at src/com/vodafone360/people/VODAFONE.LICENSE.txt.
   * If applicable, add the following below this CDDL HEADER, with the fields
   * enclosed by brackets "[]" replaced with your own identifying information:
   * Portions Copyright [yyyy] [name of copyright owner]
   *
   * CDDL HEADER END
   *
   * Copyright 2010 Vodafone Sales & Services Ltd.  All rights reserved.
   * Use is subject to license terms.
   */
  
  package com.vodafone360.people.service.agent;
  
  import java.security.InvalidParameterException;
  
  import android.content.BroadcastReceiver;
  import android.content.ContentResolver;
  import android.content.Context;
  import android.content.Intent;
  import android.content.IntentFilter;
  import android.database.ContentObserver;
  import android.net.ConnectivityManager;
  import android.net.NetworkInfo;
  import android.os.Bundle;
  import android.os.Handler;
  import android.provider.Settings;
  import android.provider.Settings.SettingNotFoundException;
  import android.telephony.TelephonyManager;
  import android.text.format.DateUtils;
  
  import com.vodafone360.people.Intents;
  import com.vodafone360.people.MainApplication;
  import com.vodafone360.people.engine.EngineManager;
  import com.vodafone360.people.service.PersistSettings;
  import com.vodafone360.people.service.RemoteService;
  import com.vodafone360.people.service.ServiceStatus;
  import com.vodafone360.people.service.PersistSettings.InternetAvail;
  import com.vodafone360.people.service.interfaces.IConnectionManagerInterface;
  import com.vodafone360.people.service.interfaces.IWorkerThreadControl;
  import com.vodafone360.people.utils.LogUtils;
  
  /**
   * The network Agent monitors the connectivity status of the device and makes
   * decisions about the communication strategy. The Agent has the following
   * states {connected | disconnected}, with changes reported to various listeners
   * in the service.
   */
  public class NetworkAgent {
  
      /** Roaming notification is on */
      public static final int ROAMING_DIALOG_GLOBAL_ON = 0;
  
      /** Roaming notification is off */
      public static final int ROAMING_DIALOG_GLOBAL_OFF = 1;
  
      private static final int TYPE_WIFI = 1;
  
      private static AgentState mAgentState = AgentState.UNKNOWN;
  
      private ConnectivityManager mConnectivityManager;
  
      private ContentResolver mContentResolver;
  
      private static AgentDisconnectReason sDisconnectReason = AgentDisconnectReason.UNKNOWN;
  
      private SettingsContentObserver mDataRoamingSettingObserver;
  
      private boolean mInternetConnected;
  
      private boolean mDataRoaming;
  
      private boolean mBackgroundData;
  
      private boolean mIsRoaming;
  
      private boolean mIsInBackground;
  
      private boolean mNetworkWorking = true;
  
      // dateTime value in milliseconds
      private Long mDisableRoamingNotificationUntil = null;
  
      private IWorkerThreadControl mWorkerThreadControl;
  
      private IConnectionManagerInterface mConnectionMgrIf;
  
      private Context mContext;
      
      /**
       * 2G Voice call started string
       */
      private static final String VOICE_CALL_STARTED_2G_STRING = "2GVoiceCallStarted";
      
      /**
       * 2G Voice call finished string.
       */
      private static final String VOICE_CALL_ENDED_2G_STRING = "2GVoiceCallEnded";
      
      /**
       * To hold network info
       */
      private NetworkInfo mNetworkInfo = null;
      
      /**
       * Resume contact sync if 2G call has finished.
       */
      private boolean mIsResumeSync = false;
      
      public enum AgentState {
          CONNECTED,
          DISCONNECTED,
          UNKNOWN
      };
      
      private boolean mWifiNetworkAvailable;
      private boolean mMobileNetworkAvailable;
  
      /**
       * Reasons for Service Agent changing state to disconnected
       */
      public enum AgentDisconnectReason {
          AGENT_IS_CONNECTED, // Sanity check
          NO_INTERNET_CONNECTION,
          NO_WORKING_NETWORK,
          DATA_SETTING_SET_TO_MANUAL_CONNECTION,
          DATA_ROAMING_DISABLED,
          BACKGROUND_CONNECTION_DISABLED,
          // WIFI_INACTIVE,
          UNKNOWN
      }
  
      public enum StatesOfService {
          IS_CONNECTED_TO_INTERNET,
          IS_NETWORK_WORKING,
          IS_ROAMING,
          IS_ROAMING_ALLOWED,
          IS_INBACKGROUND,
          IS_BG_CONNECTION_ALLOWED,
          IS_WIFI_ACTIVE
      };
  
      /**
       * Listens for changes made to People client's status. The NetworkAgent is
       * specifically interested in changes to the data settings (e.g. data
       * disabled, only in home network or roaming).
       */
      private class SettingsContentObserver extends ContentObserver {
          private String mSettingName;
  
          private SettingsContentObserver(String settingName) {
              super(new Handler());
              mSettingName = settingName;
          }
  
          /**
           * Start content observer.
           */
          private void start() {
              if (mContentResolver != null) {
                  mContentResolver.registerContentObserver(Settings.Secure.getUriFor(mSettingName),
                          true, this);
              }
          }
  
          /**
           * De-activate content observer.
           */
          private void close() {
              if (mContentResolver != null) {
                  mContentResolver.unregisterContentObserver(this);
              }
          }
  
          @Override
          public void onChange(boolean selfChange) {
              onDataSettingChanged(mSettingName);
          }
  
          public boolean getBooleanValue() {
              if (mContentResolver != null) {
                  try {
                      return (Settings.Secure.getInt(mContentResolver, mSettingName) != 0);
                  } catch (SettingNotFoundException e) {
                      LogUtils.logE("NetworkAgent.SettingsContentObserver.getBooleanValue() "
                              + "SettingNotFoundException", e);
                      return false;
                  }
              }
              return false;
          }
      }
  
      /**
       * The constructor.
       * 
       * @param context Android context.
       * @param workerThreadControl Handle to kick the worker thread.
       * @param connMgrIf Handler to signal the connection manager.
       * @throws InvalidParameterException Context is NULL.
       * @throws InvalidParameterException IWorkerThreadControl is NULL.
       * @throws InvalidParameterException IConnectionManagerInterface is NULL.
       */
      public NetworkAgent(Context context, IWorkerThreadControl workerThreadControl,
              IConnectionManagerInterface connMgrIf) {
          if (context == null) {
              throw new InvalidParameterException("NetworkAgent() Context canot be NULL");
          }
          if (workerThreadControl == null) {
              throw new InvalidParameterException("NetworkAgent() IWorkerThreadControl canot be NULL");
          }
          if (connMgrIf == null) {
              throw new InvalidParameterException(
                      "NetworkAgent() IConnectionManagerInterface canot be NULL");
          }
          mContext = context;
          mWorkerThreadControl = workerThreadControl;
          mConnectionMgrIf = connMgrIf;
          mContentResolver = context.getContentResolver();
          mConnectivityManager = (ConnectivityManager)context
                  .getSystemService(Context.CONNECTIVITY_SERVICE);
  
          mDataRoamingSettingObserver = new SettingsContentObserver(Settings.Secure.DATA_ROAMING);
      }
  
      /**
       * Create NetworkAgent and start observers of device connectivity state.
       * 
       * @throws InvalidParameterException DataRoamingSettingObserver is NULL.
       * @throws InvalidParameterException Context is NULL.
       * @throws InvalidParameterException ConnectivityManager is NULL.
       */
      public void onCreate() {
          if (mDataRoamingSettingObserver == null) {
              throw new InvalidParameterException(
                      "NetworkAgent.onCreate() DataRoamingSettingObserver canot be NULL");
          }
          if (mContext == null) {
              throw new InvalidParameterException("NetworkAgent.onCreate() Context canot be NULL");
          }
          if (mConnectivityManager == null) {
              throw new InvalidParameterException(
                      "NetworkAgent.onCreate() ConnectivityManager canot be NULL");
          }
  
          mDataRoamingSettingObserver.start();
          mDataRoaming = mDataRoamingSettingObserver.getBooleanValue();
          mContext.registerReceiver(mBackgroundDataBroadcastReceiver, new IntentFilter(
                  ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED));
          mContext.registerReceiver(mInternetConnectivityReceiver, new IntentFilter(
                  ConnectivityManager.CONNECTIVITY_ACTION));
          mContext.registerReceiver(mServiceStateRoamingReceiver, new IntentFilter(
                  "android.intent.action.SERVICE_STATE"));
          NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
          if (info != null) {
              mInternetConnected = (info.getState() == NetworkInfo.State.CONNECTED);
              mWifiNetworkAvailable = (info.getType() == TYPE_WIFI);
              mIsRoaming = info.isRoaming();
          }
          mBackgroundData = mConnectivityManager.getBackgroundDataSetting();
          onConnectionStateChanged();
      }
  
      /**
       * Destroy NetworkAgent and un-register observers.
       * 
       * @throws InvalidParameterException Context is NULL.
       * @throws InvalidParameterException DataRoamingSettingObserver is NULL.
       */
      public void onDestroy() {
          if (mContext == null) {
              throw new InvalidParameterException("NetworkAgent.onCreate() Context canot be NULL");
          }
          if (mDataRoamingSettingObserver == null) {
              throw new InvalidParameterException(
                      "NetworkAgent.onDestroy() DataRoamingSettingObserver canot be NULL");
          }
  
          mContext.unregisterReceiver(mInternetConnectivityReceiver);
          mContext.unregisterReceiver(mBackgroundDataBroadcastReceiver);
          mContext.unregisterReceiver(mServiceStateRoamingReceiver);
          mDataRoamingSettingObserver.close();
          mDataRoamingSettingObserver = null;
      }
  
      /**
       * Receive notification from
       * ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED
       */
      private final BroadcastReceiver mBackgroundDataBroadcastReceiver = new BroadcastReceiver() {
          public void onReceive(Context context, Intent intent) {
              LogUtils
                      .logV("NetworkAgent.broadcastReceiver.onReceive() ACTION_BACKGROUND_DATA_SETTING_CHANGED");
              synchronized (NetworkAgent.this) {
                  if (mConnectivityManager != null) {
                      mBackgroundData = mConnectivityManager.getBackgroundDataSetting();
                      onConnectionStateChanged();
                  }
              }
          }
      };
  
      /**
       * Receive notification from ConnectivityManager.CONNECTIVITY_ACTION
       */
      private final BroadcastReceiver mInternetConnectivityReceiver = new BroadcastReceiver() {
          public void onReceive(Context context, Intent intent) {
              LogUtils.logV("NetworkAgent.broadcastReceiver.onReceive() CONNECTIVITY_ACTION");
              synchronized (NetworkAgent.this) {
                  NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                  mNetworkInfo = info;
                  boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                  
                  if (info != null) {
                      // Check network type              
                      if (info.getType() == TYPE_WIFI) {
                          mWifiNetworkAvailable = (info.getState() == NetworkInfo.State.CONNECTED);
                      } else {
                          mMobileNetworkAvailable = (info.getState() == NetworkInfo.State.CONNECTED);
                      }
                  } else {
                      LogUtils.logW("NetworkAgent.broadcastReceiver.onReceive() EXTRA_NETWORK_INFO not found.");
                  }
                  
                  if (noConnectivity) {
                  	LogUtils.logV("NetworkAgent.broadcastReceiver.onReceive() EXTRA_NO_CONNECTIVITY found!");
                  	mInternetConnected = false;
                  } else {
                  	mInternetConnected = mWifiNetworkAvailable || mMobileNetworkAvailable;
                  }
                  
                  LogUtils.logV("NetworkAgent.broadcastReceiver.onReceive() mInternetConnected = " + mInternetConnected +
                  								", mWifiNetworkAvailable = " + mWifiNetworkAvailable +
                  								", mMobileNetworkAvailable = " + mMobileNetworkAvailable);
                  
                  onConnectionStateChanged();
              }
          }
      };
  
      /**
       * Receive notification from android.intent.action.SERVICE_STATE
       */
      private final BroadcastReceiver mServiceStateRoamingReceiver = new BroadcastReceiver() {
          public void onReceive(Context context, Intent intent) {
              LogUtils.logV("NetworkAgent.broadcastReceiver.onReceive() SERVICE_STATE");
              synchronized (NetworkAgent.this) {
                  // //ConnectivityManager provides wrong information about
                  // roaming
                  // NetworkInfo info =
                  // mConnectivityManager.getActiveNetworkInfo();
                  // if (info != null) {
                  // mIsRoaming = info.isRoaming();
                  // }
  
                  LogUtils.logV("NetworkAgent.broadcastReceiver.onReceive() Extras are: "
                          + intent.getExtras());
                  Bundle bu = intent.getExtras();
                  // int state = bu.getInt("state");
                  boolean roam = bu.getBoolean("roaming");
                  mIsRoaming = roam;
                  onConnectionStateChanged();
  
                  LogUtils.logV("NetworkAgent.broadcastReceiver.onReceive() Network Roaming = "
                          + mIsRoaming);
                  LogUtils.logV("NetworkAgent.broadcastReceiver.onReceive() WiFi active	   = "
                          + mWifiNetworkAvailable);
              }
              processRoaming(null);
          }
      };
  
      /**
       * Notify interested parties of changes in Internet setting.
       * 
       * @param val updated InternetAvail value.
       */
      public void notifyDataSettingChanged(InternetAvail val) {
          processRoaming(val);
          onConnectionStateChanged();
      }
  
      /**
       * Displaying notification to the user about roaming
       * 
       * @param InternetAvail value.
       */
      private void processRoaming(InternetAvail val) {
          InternetAvail internetAvail;
          if (val != null) {
              internetAvail = val;
          } else {
              internetAvail = getInternetAvailSetting();
          }
  
          Intent intent = new Intent();
  
          if (mContext != null
                  && mIsRoaming
                  && (internetAvail == InternetAvail.ALWAYS_CONNECT)
                  && (mDisableRoamingNotificationUntil == null || mDisableRoamingNotificationUntil < System
                          .currentTimeMillis())) {
              LogUtils.logV("NetworkAgent.processRoaming() "
                      + "Displaying notification - DisplayRoaming[" + mIsRoaming + "]");
             
              intent.setAction(Intents.ROAMING_ON);
          } else {
              /*
               * We are not roaming then we should remove notification, if no
               * notification were before nothing happens
               */
              LogUtils.logV("NetworkAgent.processRoaming() Removing notification - "
                      + " DisplayRoaming[" + mIsRoaming + "]");
  
              intent.setAction(Intents.ROAMING_OFF);
          }
          
          mContext.sendBroadcast(intent);
      }
  
      private InternetAvail getInternetAvailSetting() {
          if (mContext != null) {
              PersistSettings setting = ((MainApplication)((RemoteService)mContext).getApplication())
                      .getDatabase().fetchOption(PersistSettings.Option.INTERNETAVAIL);
              if (setting != null) {
                  return setting.getInternetAvail();
              }
          }
          return null;
      }
  
      public int getRoamingNotificationType() {
          int type;
          if (mDataRoaming) {
              type = ROAMING_DIALOG_GLOBAL_ON;
          } else {
              type = ROAMING_DIALOG_GLOBAL_OFF;
          }
          return type;
      }
  
      /**
       * Get current device roaming setting.
       * 
       * @return current device roaming setting.
       */
      public boolean getRoamingDeviceSetting() {
          return mDataRoaming;
      }
  
      public void setShowRoamingNotificationAgain(boolean showAgain) {
          LogUtils.logV("NetworkAgent.setShowRoamingNotificationAgain() " + "showAgain[" + showAgain
                  + "]");
          if (showAgain) {
              mDisableRoamingNotificationUntil = null;
          } else {
              mDisableRoamingNotificationUntil = System.currentTimeMillis() + DateUtils.DAY_IN_MILLIS;
              if (mContext != null) {
                  LogUtils.logV("NetworkAgent.setShowRoamingNotificationAgain() "
                          + "Next notification on ["
                          + DateUtils.formatDateTime(mContext, mDisableRoamingNotificationUntil,
                                  DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME
                                          | DateUtils.FORMAT_SHOW_YEAR) + "]");
              }
          }
          processRoaming(null);
      }
  
      /**
       * Received when user modifies one of the system settings
       */
      private synchronized void onDataSettingChanged(String settingName) {
          LogUtils.logV("NetworkAgent.onDataSettingChanged() settingName[" + settingName + "]"
                  + " has changed");
          if (settingName.equals(Settings.Secure.DATA_ROAMING)) {
              if (mDataRoamingSettingObserver != null) {
                  mDataRoaming = mDataRoamingSettingObserver.getBooleanValue();
                  onConnectionStateChanged();
              }
          }
      }
  
      /**
       * Contains the main logic that determines the agent state for network
       * access
       */
      private void onConnectionStateChanged() {
          if (mContext != null) {
              MainApplication app = (MainApplication)((RemoteService)mContext).getApplication();
              if ((app.getInternetAvail() == InternetAvail.MANUAL_CONNECT)) {
                  LogUtils.logV("NetworkAgent.onConnectionStateChanged()"
                          + " Internet allowed only in manual mode");
                  sDisconnectReason = AgentDisconnectReason.DATA_SETTING_SET_TO_MANUAL_CONNECTION;
                  setNewState(AgentState.DISCONNECTED);
                  return;
              }
          }
          if (!mNetworkWorking) {
              LogUtils.logV("NetworkAgent.onConnectionStateChanged() Network is not working");
              sDisconnectReason = AgentDisconnectReason.NO_WORKING_NETWORK;
              setNewState(AgentState.DISCONNECTED);
              return;
          }
          if (mIsRoaming && !mDataRoaming && !mWifiNetworkAvailable) {
              LogUtils.logV("NetworkAgent.onConnectionStateChanged() "
                      + "Connect while roaming not allowed");
              sDisconnectReason = AgentDisconnectReason.DATA_ROAMING_DISABLED;
              setNewState(AgentState.DISCONNECTED);
              return;
          }
          if (mIsInBackground && !mBackgroundData) {
              LogUtils.logV("NetworkAgent.onConnectionStateChanged() Background connection not allowed");
              sDisconnectReason = AgentDisconnectReason.BACKGROUND_CONNECTION_DISABLED;
              setNewState(AgentState.DISCONNECTED);
              return;
          }
          if (!mInternetConnected) {
              LogUtils.logV("NetworkAgent.onConnectionStateChanged() No internet connection");
              sDisconnectReason = AgentDisconnectReason.NO_INTERNET_CONNECTION;
              // If 2g call is started, notify contact sync engine to pause.
              if (mNetworkInfo != null && 
                         VOICE_CALL_STARTED_2G_STRING.equals(mNetworkInfo.getReason())) {
                  EngineManager.getInstance().getContactSyncEngine().pauseSync();
              }
              
              setNewState(AgentState.DISCONNECTED);
              return;
          } 
          
          // If 2g voice call is finished, set resume state
          if (mNetworkInfo != null && 
                     VOICE_CALL_ENDED_2G_STRING.equals(mNetworkInfo.getReason())) {
              mIsResumeSync = true;
          }
   
          
          if (mWifiNetworkAvailable) {
              LogUtils.logV("NetworkAgent.onConnectionStateChanged() WIFI connected");
          } else {
              LogUtils.logV("NetworkAgent.onConnectionStateChanged() Cellular connected");
          }
          
          LogUtils.logV("NetworkAgent.onConnectionStateChanged() Connection available");
          setNewState(AgentState.CONNECTED);
      }
  
      public static AgentState getAgentState() {
          LogUtils.logV("NetworkAgent.getAgentState() mAgentState[" + mAgentState.name() + "]");
          return mAgentState;
      }
  
      public static ServiceStatus getServiceStatusfromDisconnectReason() {
          
          if (sDisconnectReason != null)
  	    	switch (sDisconnectReason)
  	    	{
  				case AGENT_IS_CONNECTED:
  					return ServiceStatus.SUCCESS;
  	    		case NO_WORKING_NETWORK:
  	    			return ServiceStatus.ERROR_NO_INTERNET;
  	    		case NO_INTERNET_CONNECTION:
  	    			return ServiceStatus.ERROR_NO_INTERNET;
  	    		case DATA_ROAMING_DISABLED:
  	    			return ServiceStatus.ERROR_ROAMING_INTERNET_NOT_ALLOWED;
  	    		case DATA_SETTING_SET_TO_MANUAL_CONNECTION:
  	    			return ServiceStatus.ERROR_NO_AUTO_CONNECT;
  	    		case BACKGROUND_CONNECTION_DISABLED:
  	    			// TODO: define appropriate ServiceStatus
  	    			return ServiceStatus.ERROR_COMMS;
  	    	}
          
          return ServiceStatus.ERROR_COMMS;
      }
  
      private void setNewState(AgentState newState) {
          if (newState == mAgentState) {
              return;
          }
          LogUtils.logI("NetworkAgent.setNewState(): " + mAgentState + " -> " + newState);
          mAgentState = newState;
  
          if (newState == AgentState.CONNECTED) {
              sDisconnectReason = AgentDisconnectReason.AGENT_IS_CONNECTED;
              onConnected();
          } else if (newState == AgentState.DISCONNECTED) {
              onDisconnected();
          }
      }
  
      private void onConnected() {
          checkActiveNetworkState();
          if (mWorkerThreadControl != null) {
              mWorkerThreadControl.kickWorkerThread();
          }
          if (mConnectionMgrIf != null) {
              mConnectionMgrIf.signalConnectionManager(true);
          }
                  
          // If resume sync is set, signal contact sync engine to resume sync.
          if (mIsResumeSync) {
              EngineManager.getInstance().getContactSyncEngine().resumeSync();
              mIsResumeSync = false;
          }
      }
  
      private void onDisconnected() {
          // AA:need to kick it to make engines run and set the
          if (mWorkerThreadControl != null) {
              mWorkerThreadControl.kickWorkerThread();
          }
          if (mConnectionMgrIf != null) {
              mConnectionMgrIf.signalConnectionManager(false);
          }
      }
  
      private void checkActiveNetworkState() {
          if (mConnectivityManager != null) {
              NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
  
              if (mNetworkInfo == null) {
                  LogUtils.logW("NetworkAgent.checkActiveNetworkInfoy() "
                          + "mConnectivityManager.getActiveNetworkInfo() Returned null");
                  return;
              } else {
                  if (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                      LogUtils.logV("NetworkAgent.checkActiveNetworkInfoy() WIFI network");
                      // TODO: Do something
  
                  } else if (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
  
                      LogUtils.logV("NetworkAgent.checkActiveNetworkInfoy() MOBILE and ROAMING");
                      // TODO: Do something
                      // Only works when you are registering with network
  
                      switch (mNetworkInfo.getSubtype()) {
                          case TelephonyManager.NETWORK_TYPE_EDGE:
                              LogUtils
                                      .logV("NetworkAgent.checkActiveNetworkInfoy() MOBILE EDGE network");
                              // TODO: Do something
                              break;
  
                          case TelephonyManager.NETWORK_TYPE_GPRS:
                              LogUtils
                                      .logV("NetworkAgent.checkActiveNetworkInfoy() MOBILE GPRS network");
                              // TODO: Do something
                              break;
  
                          case TelephonyManager.NETWORK_TYPE_UMTS:
                              LogUtils
                                      .logV("NetworkAgent.checkActiveNetworkInfoy() MOBILE UMTS network");
                              // TODO: Do something
                              break;
  
                          case TelephonyManager.NETWORK_TYPE_UNKNOWN:
                              LogUtils
                                      .logV("NetworkAgent.checkActiveNetworkInfoy() MOBILE UNKNOWN network");
                              // TODO: Do something
                              break;
                              
                          default:
                              // Do nothing.
                              break;
                      }
                      ;
                  }
              }
          } else {
              LogUtils.logW("NetworkAgent.checkActiveNetworkInfoy() mConnectivityManager is null");
          }
      }
  
      public void setNetworkAgentState(NetworkAgentState state) {
          LogUtils.logD("NetworkAgent.setNetworkAgentState() state[" + state + "]");
          // TODO: make assignments if any changes
          boolean changes[] = state.getChanges();
  
          if (changes[StatesOfService.IS_CONNECTED_TO_INTERNET.ordinal()])
              mInternetConnected = state.isInternetConnected();
          if (changes[StatesOfService.IS_NETWORK_WORKING.ordinal()])
              mNetworkWorking = state.isNetworkWorking();
          if (changes[StatesOfService.IS_ROAMING_ALLOWED.ordinal()])
              mDataRoaming = state.isRoamingAllowed();
          if (changes[StatesOfService.IS_INBACKGROUND.ordinal()])
              mIsInBackground = state.isInBackGround();
          if (changes[StatesOfService.IS_BG_CONNECTION_ALLOWED.ordinal()])
              mBackgroundData = state.isBackDataAllowed();
          if (changes[StatesOfService.IS_WIFI_ACTIVE.ordinal()])
              mWifiNetworkAvailable = state.isWifiActive();
          if (changes[StatesOfService.IS_ROAMING.ordinal()]) {// special case for
                                                              // roaming
              mIsRoaming = state.isRoaming();
              // This method sets the mAgentState, and mDisconnectReason as well
              // by calling setNewState();
              onConnectionStateChanged();
              processRoaming(null);
          } else
              // This method sets the mAgentState, and mDisconnectReason as well
              // by calling setNewState();
              onConnectionStateChanged();
      }
  
      public NetworkAgentState getNetworkAgentState() {
  
          NetworkAgentState state = new NetworkAgentState();
          state.setRoaming(mIsRoaming);
          state.setRoamingAllowed(mDataRoaming);
  
          state.setBackgroundDataAllowed(mBackgroundData);
          state.setInBackGround(mIsInBackground);
  
          state.setInternetConnected(mInternetConnected);
          state.setNetworkWorking(mNetworkWorking);
          state.setWifiActive(mWifiNetworkAvailable);
  
          state.setDisconnectReason(sDisconnectReason);
          state.setAgentState(mAgentState);
  
          LogUtils.logD("NetworkAgent.getNetworkAgentState() state[" + state + "]");
  
          return state;
      }
  
      // /////////////////////////////
      // FOR TESTING PURPOSES ONLY //
      // /////////////////////////////
  
      /**
       * Forces the AgentState to a specific value.
       * 
       * @param newState the state to set Note: to be used only for test purposes
       */
      public static void setAgentState(AgentState newState) {
          mAgentState = newState;
      }
  
  }
  