ConnectionUtil.java revision 4b1afab106f3959ba56fba08fbdccee5d15068bc
133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang/* 233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Copyright (C) 2011, The Android Open Source Project 333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Licensed under the Apache License, Version 2.0 (the "License"); 533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * you may not use this file except in compliance with the License. 633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * You may obtain a copy of the License at 733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * http://www.apache.org/licenses/LICENSE-2.0 933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 1033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Unless required by applicable law or agreed to in writing, software 1133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * distributed under the License is distributed on an "AS IS" BASIS, 1233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * See the License for the specific language governing permissions and 1433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * limitations under the License. 1533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 1633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 1733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangpackage com.android.bandwidthtest.util; 1833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 1933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.app.DownloadManager; 2033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.app.DownloadManager.Query; 2133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.app.DownloadManager.Request; 2233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.BroadcastReceiver; 2333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.Context; 2433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.Intent; 2533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.IntentFilter; 2633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.pm.ApplicationInfo; 2733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.pm.PackageManager; 2833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.content.pm.PackageManager.NameNotFoundException; 2933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.database.Cursor; 3033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.ConnectivityManager; 3133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.NetworkInfo; 3233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.NetworkInfo.State; 3333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.Uri; 3433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.wifi.ScanResult; 3533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.wifi.WifiConfiguration; 3633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.wifi.WifiConfiguration.KeyMgmt; 3733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.net.wifi.WifiManager; 3833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.os.Handler; 3933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.os.Message; 4033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.provider.Settings; 4133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport android.util.Log; 4233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 4333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport com.android.bandwidthtest.NetworkState; 4433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport com.android.bandwidthtest.NetworkState.StateTransitionDirection; 4533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport com.android.internal.util.AsyncChannel; 4633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 474fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuangimport junit.framework.Assert; 484fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang 49212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuangimport java.io.IOException; 50212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuangimport java.net.UnknownHostException; 5133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangimport java.util.List; 5233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 5333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang/* 5433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Utility class used to set the connectivity of the device and to download files. 5533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 5633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuangpublic class ConnectionUtil { 5733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private static final String LOG_TAG = "ConnectionUtil"; 5833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private static final String DOWNLOAD_MANAGER_PKG_NAME = "com.android.providers.downloads"; 5933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; // 10 seconds 6033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private static final int WIFI_SCAN_TIMEOUT = 50 * 1000; 6133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public static final int SHORT_TIMEOUT = 5 * 1000; 624b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang public static final int LONG_TIMEOUT = 5 * 60 * 1000; // 5 minutes 6333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private ConnectivityReceiver mConnectivityReceiver = null; 6433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private WifiReceiver mWifiReceiver = null; 6533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private DownloadReceiver mDownloadReceiver = null; 6633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private DownloadManager mDownloadManager; 6733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private NetworkInfo mNetworkInfo; 6833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private NetworkInfo mOtherNetworkInfo; 6933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private boolean mScanResultIsAvailable = false; 7033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private ConnectivityManager mCM; 7133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private Object mWifiMonitor = new Object(); 7233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private Object mConnectivityMonitor = new Object(); 7333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private Object mDownloadMonitor = new Object(); 7433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private int mWifiState; 7533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private NetworkInfo mWifiNetworkInfo; 7633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private WifiManager mWifiManager; 7733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private Context mContext; 7833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Verify connectivity state 7933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1; 8033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private NetworkState[] mConnectivityState = new NetworkState[NUM_NETWORK_TYPES]; 8133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 8233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public ConnectionUtil(Context context) { 8333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext = context; 8433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 8533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 8633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 8733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Initialize the class. Needs to be called before any other methods in {@link ConnectionUtil} 8833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 8933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @throws Exception 9033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 9133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void initialize() throws Exception { 9233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Register a connectivity receiver for CONNECTIVITY_ACTION 9333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityReceiver = new ConnectivityReceiver(); 9433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.registerReceiver(mConnectivityReceiver, 9533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); 9633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 9733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Register a download receiver for ACTION_DOWNLOAD_COMPLETE 9833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mDownloadReceiver = new DownloadReceiver(); 9933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.registerReceiver(mDownloadReceiver, 10033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 10133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 10233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Register a wifi receiver 10333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiReceiver = new WifiReceiver(); 10433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang IntentFilter mIntentFilter = new IntentFilter(); 10533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 10633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 10733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 10833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); 10933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 11033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.registerReceiver(mWifiReceiver, mIntentFilter); 11133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 11233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Get an instance of ConnectivityManager 11333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mCM = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 11433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 11533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Get an instance of WifiManager 11633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); 11733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiManager.asyncConnect(mContext, new WifiServiceHandler()); 11833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 11933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); 12033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 12133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang initializeNetworkStates(); 12233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 12333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 124a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang } 125a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang 126a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang /** 127a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang * Additional initialization needed for wifi related tests. 128a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang */ 129a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang public void wifiTestInit() { 130a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang mWifiManager.setWifiEnabled(true); 13133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Clear Wifi before we start the test."); 13233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang sleep(SHORT_TIMEOUT); 13333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang removeConfiguredNetworksAndDisableWifi(); 13433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 13533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 13633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 13733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 13833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * A wrapper of a broadcast receiver which provides network connectivity information 13933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * for all kinds of network: wifi, mobile, etc. 14033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 14133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class ConnectivityReceiver extends BroadcastReceiver { 14233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 14333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 14433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 14533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 14633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void onReceive(Context context, Intent intent) { 14733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (isInitialStickyBroadcast()) { 14833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.d(LOG_TAG, "This is a sticky broadcast don't do anything."); 14933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return; 15033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 15133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "ConnectivityReceiver: onReceive() is called with " + intent); 15233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String action = intent.getAction(); 15333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 15433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v("ConnectivityReceiver", "onReceive() called with " + intent); 15533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return; 15633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 157a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang 158a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang final ConnectivityManager connManager = (ConnectivityManager) context 159a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang .getSystemService(Context.CONNECTIVITY_SERVICE); 160a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang mNetworkInfo = connManager.getActiveNetworkInfo(); 16133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 16233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (intent.hasExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO)) { 16333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mOtherNetworkInfo = (NetworkInfo) 16433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO); 16533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 16633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 16733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString()); 16833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState()); 16933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mOtherNetworkInfo != null) { 17033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString()); 17133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState()); 17233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 17333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyNetworkConnectivityChange(); 17433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 17533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 17633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 17733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 17833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * A wrapper of a broadcast receiver which provides wifi information. 17933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 18033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class WifiReceiver extends BroadcastReceiver { 18133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 18233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 18333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 18433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 18533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void onReceive(Context context, Intent intent) { 18633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String action = intent.getAction(); 18733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v("WifiReceiver", "onReceive() is calleld with " + intent); 18833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 18933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Scan results are available"); 19033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyScanResult(); 19133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 19233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiNetworkInfo = 19333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 19433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "mWifiNetworkInfo: " + mWifiNetworkInfo.toString()); 19533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiNetworkInfo.getState() == State.CONNECTED) { 19633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang intent.getStringExtra(WifiManager.EXTRA_BSSID); 19733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 19833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyWifiState(); 19933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 20033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 20133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang WifiManager.WIFI_STATE_UNKNOWN); 20233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyWifiState(); 20333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { 20433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyWifiAPState(); 20533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 20633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return; 20733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 20833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 20933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 21033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 21133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 21233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * A wrapper of a broadcast receiver which provides download manager information. 21333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 21433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class DownloadReceiver extends BroadcastReceiver { 21533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 21633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 21733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 21833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 21933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void onReceive(Context context, Intent intent) { 22033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String action = intent.getAction(); 22133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v("DownloadReceiver", "onReceive() is called with " + intent); 22233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Download complete 22333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { 22433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifiyDownloadState(); 22533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 22633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 22733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 22833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 22933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class WifiServiceHandler extends Handler { 23033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 23133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 23233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 23333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 23433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void handleMessage(Message msg) { 23533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang switch (msg.what) { 23633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 23733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 23833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // AsyncChannel in msg.obj 23933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 24033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Failed to establish AsyncChannel connection"); 24133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang break; 24333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang default: 24433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Ignore 24533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang break; 24633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 25033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 25133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Initialize all the network states. 25233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 25333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void initializeNetworkStates() { 25433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // For each network type, initialize network states to UNKNOWN, and no verification 25533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // flag is set. 25633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (int networkType = NUM_NETWORK_TYPES - 1; networkType >= 0; networkType--) { 25733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType] = new NetworkState(); 25833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Initialize network state for " + networkType + ": " + 25933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].toString()); 26033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 26133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 26233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 26333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void recordNetworkState(int networkType, State networkState) { 26433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // deposit a network state 26533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "record network state for network " + networkType + 26633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang ", state is " + networkState); 26733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].recordState(networkState); 26833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 26933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 270212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang /** 271212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * Set the state transition criteria 272212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * 273212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param networkType 274212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param initState 275212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param transitionDir 276212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param targetState 277212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang */ 27833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void setStateTransitionCriteria(int networkType, State initState, 27933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang StateTransitionDirection transitionDir, State targetState) { 28033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].setStateTransitionCriteria( 28133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang initState, transitionDir, targetState); 28233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 28333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 28433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 28533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Validate the states recorded. 28633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param networkType 28733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return 28833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 28933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean validateNetworkStates(int networkType) { 29033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "validate network state for " + networkType + ": "); 29133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mConnectivityState[networkType].validateStateTransition(); 29233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 29333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 29433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 29533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Fetch the failure reason for the transition. 29633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param networkType 29733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return result from network state validation 29833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 29933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public String getTransitionFailureReason(int networkType) { 30033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "get network state transition failure reason for " + networkType + ": " + 30133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].toString()); 30233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mConnectivityState[networkType].getFailureReason(); 30333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 30433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 30533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 30633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification via the mConnectivityMonitor when the network connectivity changes. 30733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 30833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyNetworkConnectivityChange() { 30933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized(mConnectivityMonitor) { 31033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify network connectivity changed"); 31133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityMonitor.notifyAll(); 31233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 31333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 31433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 31533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 31633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification when a scan for the wifi network is done. 31733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 31833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyScanResult() { 31933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (this) { 32033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify that scan results are available"); 32133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang this.notify(); 32233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 32333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 32433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 32533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 32633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification via the mWifiMonitor when the wifi state changes. 32733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 32833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyWifiState() { 32933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mWifiMonitor) { 33033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify wifi state changed."); 33133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiMonitor.notify(); 33233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 33333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 33433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 33533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 33633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification via the mDownloadMonitor when a download is complete. 33733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 33833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifiyDownloadState() { 33933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mDownloadMonitor) { 34033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notifiy download manager state changed."); 34133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mDownloadMonitor.notify(); 34233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 34333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 34433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 34533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 34633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification when the wifi ap state changes. 34733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 34833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyWifiAPState() { 34933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (this) { 35033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify wifi AP state changed."); 35133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang this.notify(); 35233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 35333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 35433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 35533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 35633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Start a download on a given url and wait for completion. 35733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 35833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param targetUrl the target to download.x 35933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param timeout to wait for download to finish 36033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if we successfully downloaded the requestedUrl, false otherwise. 36133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 36233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean startDownloadAndWait(String targetUrl, long timeout) { 36333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (targetUrl.length() == 0 || targetUrl == null) { 36433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Empty or Null target url requested to DownloadManager"); 36533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 36633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 36733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Request request = new Request(Uri.parse(targetUrl)); 36833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long enqueue = mDownloadManager.enqueue(request); 36933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Sending download request of " + targetUrl + " to DownloadManager"); 37033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 37133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (true) { 37233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > timeout) { 37333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "startDownloadAndWait timed out, failed to fetch " + targetUrl + 37433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang " within " + timeout); 37533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return downloadSuccessful(enqueue); 37633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 37733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Waiting for the download to finish " + targetUrl); 37833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mDownloadMonitor) { 37933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 38033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mDownloadMonitor.wait(SHORT_TIMEOUT); 38133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 38233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 38333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 38433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!downloadSuccessful(enqueue)) { 38533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 38633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 38733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 38833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 38933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 39033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 39133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 39233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 39333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Fetch the Download Manager's UID. 39433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return the Download Manager's UID 39533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 39633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public int downloadManagerUid() { 39733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 39833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang PackageManager pm = mContext.getPackageManager(); 39933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang ApplicationInfo appInfo = pm.getApplicationInfo(DOWNLOAD_MANAGER_PKG_NAME, 40033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang PackageManager.GET_META_DATA); 40133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return appInfo.uid; 40233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (NameNotFoundException e) { 40333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.d(LOG_TAG, "Did not find the package for the download service."); 40433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return -1; 40533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 40633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 40733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 40833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 40933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Determines if a given download was successful by querying the DownloadManager. 41033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 41133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param enqueue the id used to identify/query the DownloadManager with. 41233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if download was successful, false otherwise. 41333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 41433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private boolean downloadSuccessful(long enqueue) { 41533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Query query = new Query(); 41633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang query.setFilterById(enqueue); 41733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Cursor c = mDownloadManager.query(query); 41833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (c.moveToFirst()) { 41933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS); 42033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) { 42133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Successfully downloaded file!"); 42233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 42333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 42433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 42533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 42633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 42733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 42833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 42933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Wait for network connectivity state. 43033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param networkType the network to check for 43133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param expectedState the desired state 43233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param timeout in milliseconds 43333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if the network connectivity state matched what was expected 43433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 43533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean waitForNetworkState(int networkType, State expectedState, long timeout) { 43633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 43733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (true) { 43833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > timeout) { 43933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "waitForNetworkState time out, the state of network type " + networkType + 44033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang " is: " + mCM.getNetworkInfo(networkType).getState()); 44133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mCM.getNetworkInfo(networkType).getState() != expectedState) { 44233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 44333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 44433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // the broadcast has been sent out. the state has been changed. 44533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "networktype: " + networkType + " state: " + 44633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mCM.getNetworkInfo(networkType)); 44733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 44833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 44933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 45033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType + 45133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang " to be " + expectedState.toString()); 45233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mConnectivityMonitor) { 45333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 45433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityMonitor.wait(SHORT_TIMEOUT); 45533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 45633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 45733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 4584fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang if (mNetworkInfo == null) { 4594fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang Log.v(LOG_TAG, "Do not have networkInfo! Force fetch of network info."); 4604fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang mNetworkInfo = mCM.getActiveNetworkInfo(); 4614b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang } 4624b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang // Still null after force fetch? Maybe the network did not have time to be brought 4634b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang // up yet. 4644b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang if (mNetworkInfo == null) { 4654b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang Log.v(LOG_TAG, "Failed to force fetch networkInfo. " + 4664b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang "The network is still not ready. Wait for the next broadcast"); 4674b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang continue; 4684fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang } 46933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((mNetworkInfo.getType() != networkType) || 47033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang (mNetworkInfo.getState() != expectedState)) { 47133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "network state for " + mNetworkInfo.getType() + 47233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang "is: " + mNetworkInfo.getState()); 47333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 47433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 47633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 48033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 48133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Wait for a given wifi state to occur within a given timeout. 48233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param expectedState the expected wifi state. 48333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param timeout for the state to be set in milliseconds. 48433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if the state was achieved within the timeout, false otherwise. 48533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 48633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean waitForWifiState(int expectedState, long timeout) { 48733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED, 48833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN 48933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 49033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (true) { 49133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > timeout) { 49233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiState != expectedState) { 49333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 49433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 49533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 49633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 49733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 49833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState); 49933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mWifiMonitor) { 50033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 50133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiMonitor.wait(SHORT_TIMEOUT); 50233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 50333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 50433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 50533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiState != expectedState) { 50633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wifi state is: " + mWifiState); 50733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 50833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 50933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 51033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 51133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 51233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 51333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 51433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 51533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Convenience method to determine if we are connected to a mobile network. 51633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if connected to a mobile network, false otherwise. 51733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 51833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean isConnectedToMobile() { 519212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 520212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return networkInfo.isConnected(); 52133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 52233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 52333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 52433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Convenience method to determine if we are connected to wifi. 52533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if connected to wifi, false otherwise. 52633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 52733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean isConnectedToWifi() { 528212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 529212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return networkInfo.isConnected(); 53033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 53133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 53233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 53333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Associate the device to given SSID 53433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * If the device is already associated with a WiFi, disconnect and forget it, 53533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * We don't verify whether the connection is successful or not, leave this to the test 53633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 53733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean connectToWifi(String knownSSID) { 53833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang WifiConfiguration config = new WifiConfiguration(); 53933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang config.SSID = knownSSID; 54033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang config.allowedKeyManagement.set(KeyMgmt.NONE); 54133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return connectToWifiWithConfiguration(config); 54233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 54333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 54433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 54533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Connect to Wi-Fi with the given configuration. 54633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param config 547a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang * @return true if we are connected to a given AP. 54833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 54933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean connectToWifiWithConfiguration(WifiConfiguration config) { 55033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // The SSID in the configuration is a pure string, need to convert it to a quoted string. 55133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String ssid = config.SSID; 55233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang config.SSID = convertToQuotedString(ssid); 55333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 55433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // If wifi is not enabled, enable it 55533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!mWifiManager.isWifiEnabled()) { 55633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wifi is not enabled, enable it"); 55733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiManager.setWifiEnabled(true); 55833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // wait for the wifi state change before start scanning. 55933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2 * SHORT_TIMEOUT)) { 56033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wait for WIFI_STATE_ENABLED failed"); 56133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 56233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 56333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 56433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 56533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang boolean foundApInScanResults = false; 56633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (int retry = 0; retry < 5; retry++) { 56733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang List<ScanResult> netList = mWifiManager.getScanResults(); 56833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (netList != null) { 56933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "size of scan result list: " + netList.size()); 57033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (int i = 0; i < netList.size(); i++) { 57133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang ScanResult sr= netList.get(i); 57233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (sr.SSID.equals(ssid)) { 57333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Found " + ssid + " in the scan result list."); 57433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Retry: " + retry); 57533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang foundApInScanResults = true; 57633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiManager.connectNetwork(config); 57733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang break; 57833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 57933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 58033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 58133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (foundApInScanResults) { 58233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 58333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 58433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Start an active scan 58533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiManager.startScanActive(); 58633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mScanResultIsAvailable = false; 58733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 58833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (!mScanResultIsAvailable) { 58933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) { 59033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "wait for scan results timeout"); 59133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 59233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 59333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // wait for the scan results to be available 59433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (this) { 59533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // wait for the scan result to be available 59633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 59733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang this.wait(WAIT_FOR_SCAN_RESULT); 59833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 59933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 60033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 60133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((mWifiManager.getScanResults() == null) || 60233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang (mWifiManager.getScanResults().size() <= 0)) { 60333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 60433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 60533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mScanResultIsAvailable = true; 60633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 60733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 60833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 60933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 61133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 61333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /* 61433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Disconnect from the current AP and remove configured networks. 61533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 61633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean disconnectAP() { 61733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // remove saved networks 61833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks(); 61933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "size of wifiConfigList: " + wifiConfigList.size()); 62033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (WifiConfiguration wifiConfig: wifiConfigList) { 62133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Remove wifi configuration: " + wifiConfig.networkId); 62233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang int netId = wifiConfig.networkId; 62333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiManager.forgetNetwork(netId); 62433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 62533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 62633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 62733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 62833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 62933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Enable Wifi 63033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if Wifi is enabled successfully 63133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 63233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean enableWifi() { 63333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mWifiManager.setWifiEnabled(true); 63433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 63533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 63633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 63733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Disable Wifi 63833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if Wifi is disabled successfully 63933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 64033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean disableWifi() { 64133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mWifiManager.setWifiEnabled(false); 64233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 64333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 64433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 64533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Remove configured networks and disable wifi 64633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 64733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean removeConfiguredNetworksAndDisableWifi() { 64833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!disconnectAP()) { 64933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 65033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 65133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang sleep(SHORT_TIMEOUT); 65233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!mWifiManager.setWifiEnabled(false)) { 65333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 65433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 65533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang sleep(SHORT_TIMEOUT); 65633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 65733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 65833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 65933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 66033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Make the current thread sleep. 66133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param sleeptime the time to sleep in milliseconds 66233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 66333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void sleep(long sleeptime) { 66433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 66533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Thread.sleep(sleeptime); 66633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) {} 66733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 66833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 66933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 67033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Set airplane mode on device, caller is responsible to ensuring correct state. 67133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param context {@link Context} 67233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param enableAM to enable or disable airplane mode. 67333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 67433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void setAirplaneMode(Context context, boolean enableAM) { 67533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang //set the airplane mode 67633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 67733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang enableAM ? 1 : 0); 67833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Post the intent 67933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 68033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang intent.putExtra("state", enableAM); 68133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang context.sendBroadcast(intent); 68233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 68333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 68433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 68533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Add quotes around the string. 68633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param string to convert 68733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return string with quotes around it 68833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 68933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang protected static String convertToQuotedString(String string) { 69033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return "\"" + string + "\""; 69133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 69233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 69333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void cleanUp() { 69433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Unregister receivers if defined. 69533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mConnectivityReceiver != null) { 69633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.unregisterReceiver(mConnectivityReceiver); 69733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 69833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiReceiver != null) { 69933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.unregisterReceiver(mWifiReceiver); 70033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 70133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mDownloadReceiver != null) { 70233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.unregisterReceiver(mDownloadReceiver); 70333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 70433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode())); 70533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 706212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang 707212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang /** 708212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * Helper method used to test data connectivity by pinging a series of popular sites. 709212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @return true if device has data connectivity, false otherwise. 710212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang */ 711212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang public boolean hasData() { 712212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang String[] hostList = {"www.google.com", "www.yahoo.com", 713212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang "www.bing.com", "www.facebook.com", "www.ask.com"}; 714212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang try { 715212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang for (int i = 0; i < hostList.length; ++i) { 716212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang String host = hostList[i]; 717212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host); 718212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang int status = p.waitFor(); 719212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang if (status == 0) { 720212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return true; 721212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 722212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 723212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } catch (UnknownHostException e) { 724212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Log.e(LOG_TAG, "Ping test Failed: Unknown Host"); 725212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } catch (IOException e) { 726212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Log.e(LOG_TAG, "Ping test Failed: IOException"); 727212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } catch (InterruptedException e) { 728212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Log.e(LOG_TAG, "Ping test Failed: InterruptedException"); 729212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 730212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return false; 731212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 73233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang}