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 11833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); 11933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 12033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang initializeNetworkStates(); 12133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 12233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 123a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang } 124a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang 125a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang /** 126a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang * Additional initialization needed for wifi related tests. 127a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang */ 128a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang public void wifiTestInit() { 129a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang mWifiManager.setWifiEnabled(true); 13033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Clear Wifi before we start the test."); 13133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang sleep(SHORT_TIMEOUT); 13233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang removeConfiguredNetworksAndDisableWifi(); 13333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 13433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 13533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 13633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 13733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * A wrapper of a broadcast receiver which provides network connectivity information 13833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * for all kinds of network: wifi, mobile, etc. 13933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 14033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class ConnectivityReceiver extends BroadcastReceiver { 14133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 14233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 14333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 14433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 14533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void onReceive(Context context, Intent intent) { 14633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (isInitialStickyBroadcast()) { 14733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.d(LOG_TAG, "This is a sticky broadcast don't do anything."); 14833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return; 14933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 15033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "ConnectivityReceiver: onReceive() is called with " + intent); 15133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String action = intent.getAction(); 15233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 15333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v("ConnectivityReceiver", "onReceive() called with " + intent); 15433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return; 15533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 156a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang 157a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang final ConnectivityManager connManager = (ConnectivityManager) context 158a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang .getSystemService(Context.CONNECTIVITY_SERVICE); 159a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang mNetworkInfo = connManager.getActiveNetworkInfo(); 16033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 16133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (intent.hasExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO)) { 16233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mOtherNetworkInfo = (NetworkInfo) 16333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO); 16433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 16533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 16633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString()); 16733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState()); 16833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mOtherNetworkInfo != null) { 16933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString()); 17033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState()); 17133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 17233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyNetworkConnectivityChange(); 17333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 17433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 17533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 17633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 17733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * A wrapper of a broadcast receiver which provides wifi information. 17833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 17933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class WifiReceiver extends BroadcastReceiver { 18033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 18133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 18233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 18333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 18433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void onReceive(Context context, Intent intent) { 18533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String action = intent.getAction(); 18633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v("WifiReceiver", "onReceive() is calleld with " + intent); 18733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 18833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Scan results are available"); 18933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyScanResult(); 19033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 19133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiNetworkInfo = 19233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 19333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "mWifiNetworkInfo: " + mWifiNetworkInfo.toString()); 19433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiNetworkInfo.getState() == State.CONNECTED) { 19533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang intent.getStringExtra(WifiManager.EXTRA_BSSID); 19633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 19733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyWifiState(); 19833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 19933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 20033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang WifiManager.WIFI_STATE_UNKNOWN); 20133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyWifiState(); 20233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { 20333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifyWifiAPState(); 20433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 20533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return; 20633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 20733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 20833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 20933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 21033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 21133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * A wrapper of a broadcast receiver which provides download manager information. 21233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 21333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class DownloadReceiver extends BroadcastReceiver { 21433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 21533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 21633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 21733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 21833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void onReceive(Context context, Intent intent) { 21933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String action = intent.getAction(); 22033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v("DownloadReceiver", "onReceive() is called with " + intent); 22133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Download complete 22233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { 22333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang notifiyDownloadState(); 22433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 22533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 22633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 22733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 22833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private class WifiServiceHandler extends Handler { 22933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 23033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * {@inheritDoc} 23133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 23233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang @Override 23333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void handleMessage(Message msg) { 23433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang switch (msg.what) { 23533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 23633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 23733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // AsyncChannel in msg.obj 23833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 23933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Failed to establish AsyncChannel connection"); 24033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang break; 24233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang default: 24333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Ignore 24433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang break; 24533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 24833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 24933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 25033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Initialize all the network states. 25133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 25233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void initializeNetworkStates() { 25333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // For each network type, initialize network states to UNKNOWN, and no verification 25433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // flag is set. 25533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (int networkType = NUM_NETWORK_TYPES - 1; networkType >= 0; networkType--) { 25633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType] = new NetworkState(); 25733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Initialize network state for " + networkType + ": " + 25833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].toString()); 25933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 26033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 26133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 26233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void recordNetworkState(int networkType, State networkState) { 26333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // deposit a network state 26433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "record network state for network " + networkType + 26533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang ", state is " + networkState); 26633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].recordState(networkState); 26733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 26833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 269212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang /** 270212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * Set the state transition criteria 271212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * 272212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param networkType 273212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param initState 274212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param transitionDir 275212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @param targetState 276212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang */ 27733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void setStateTransitionCriteria(int networkType, State initState, 27833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang StateTransitionDirection transitionDir, State targetState) { 27933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].setStateTransitionCriteria( 28033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang initState, transitionDir, targetState); 28133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 28233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 28333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 28433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Validate the states recorded. 28533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param networkType 28633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return 28733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 28833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean validateNetworkStates(int networkType) { 28933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "validate network state for " + networkType + ": "); 29033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mConnectivityState[networkType].validateStateTransition(); 29133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 29233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 29333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 29433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Fetch the failure reason for the transition. 29533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param networkType 29633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return result from network state validation 29733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 29833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public String getTransitionFailureReason(int networkType) { 29933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "get network state transition failure reason for " + networkType + ": " + 30033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityState[networkType].toString()); 30133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mConnectivityState[networkType].getFailureReason(); 30233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 30333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 30433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 30533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification via the mConnectivityMonitor when the network connectivity changes. 30633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 30733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyNetworkConnectivityChange() { 30833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized(mConnectivityMonitor) { 30933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify network connectivity changed"); 31033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityMonitor.notifyAll(); 31133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 31233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 31333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 31433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 31533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification when a scan for the wifi network is done. 31633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 31733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyScanResult() { 31833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (this) { 31933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify that scan results are available"); 32033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang this.notify(); 32133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 32233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 32333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 32433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 32533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification via the mWifiMonitor when the wifi state changes. 32633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 32733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyWifiState() { 32833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mWifiMonitor) { 32933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify wifi state changed."); 33033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiMonitor.notify(); 33133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 33233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 33333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 33433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 33533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification via the mDownloadMonitor when a download is complete. 33633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 33733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifiyDownloadState() { 33833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mDownloadMonitor) { 33933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notifiy download manager state changed."); 34033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mDownloadMonitor.notify(); 34133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 34233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 34333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 34433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 34533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Send a notification when the wifi ap state changes. 34633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 34733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void notifyWifiAPState() { 34833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (this) { 34933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "notify wifi AP state changed."); 35033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang this.notify(); 35133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 35233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 35333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 35433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 35533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Start a download on a given url and wait for completion. 35633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 35733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param targetUrl the target to download.x 35833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param timeout to wait for download to finish 35933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if we successfully downloaded the requestedUrl, false otherwise. 36033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 36133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean startDownloadAndWait(String targetUrl, long timeout) { 36233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (targetUrl.length() == 0 || targetUrl == null) { 36333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Empty or Null target url requested to DownloadManager"); 36433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 36533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 36633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Request request = new Request(Uri.parse(targetUrl)); 36733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long enqueue = mDownloadManager.enqueue(request); 36833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Sending download request of " + targetUrl + " to DownloadManager"); 36933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 37033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (true) { 37133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > timeout) { 37233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "startDownloadAndWait timed out, failed to fetch " + targetUrl + 37333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang " within " + timeout); 37433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return downloadSuccessful(enqueue); 37533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 37633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Waiting for the download to finish " + targetUrl); 37733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mDownloadMonitor) { 37833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 37933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mDownloadMonitor.wait(SHORT_TIMEOUT); 38033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 38133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 38233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 38333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!downloadSuccessful(enqueue)) { 38433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 38533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 38633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 38733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 38833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 38933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 39033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 39133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 39233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Fetch the Download Manager's UID. 39333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return the Download Manager's UID 39433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 39533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public int downloadManagerUid() { 39633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 39733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang PackageManager pm = mContext.getPackageManager(); 39833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang ApplicationInfo appInfo = pm.getApplicationInfo(DOWNLOAD_MANAGER_PKG_NAME, 39933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang PackageManager.GET_META_DATA); 40033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return appInfo.uid; 40133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (NameNotFoundException e) { 40233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.d(LOG_TAG, "Did not find the package for the download service."); 40333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return -1; 40433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 40533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 40633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 40733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 40833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Determines if a given download was successful by querying the DownloadManager. 40933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * 41033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param enqueue the id used to identify/query the DownloadManager with. 41133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if download was successful, false otherwise. 41233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 41333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private boolean downloadSuccessful(long enqueue) { 41433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Query query = new Query(); 41533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang query.setFilterById(enqueue); 41633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Cursor c = mDownloadManager.query(query); 41733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (c.moveToFirst()) { 41833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS); 41933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) { 42033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Successfully downloaded file!"); 42133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 42233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 42333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 42433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 42533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 42633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 42733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 42833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Wait for network connectivity state. 42933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param networkType the network to check for 43033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param expectedState the desired state 43133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param timeout in milliseconds 43233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if the network connectivity state matched what was expected 43333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 43433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean waitForNetworkState(int networkType, State expectedState, long timeout) { 43533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 43633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (true) { 43733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > timeout) { 43833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "waitForNetworkState time out, the state of network type " + networkType + 43933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang " is: " + mCM.getNetworkInfo(networkType).getState()); 44033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mCM.getNetworkInfo(networkType).getState() != expectedState) { 44133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 44233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 44333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // the broadcast has been sent out. the state has been changed. 44433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "networktype: " + networkType + " state: " + 44533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mCM.getNetworkInfo(networkType)); 44633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 44733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 44833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 44933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType + 45033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang " to be " + expectedState.toString()); 45133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mConnectivityMonitor) { 45233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 45333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mConnectivityMonitor.wait(SHORT_TIMEOUT); 45433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 45533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 45633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 4574fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang if (mNetworkInfo == null) { 4584fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang Log.v(LOG_TAG, "Do not have networkInfo! Force fetch of network info."); 4594fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang mNetworkInfo = mCM.getActiveNetworkInfo(); 4604b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang } 4614b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang // Still null after force fetch? Maybe the network did not have time to be brought 4624b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang // up yet. 4634b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang if (mNetworkInfo == null) { 4644b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang Log.v(LOG_TAG, "Failed to force fetch networkInfo. " + 4654b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang "The network is still not ready. Wait for the next broadcast"); 4664b1afab106f3959ba56fba08fbdccee5d15068bcTsu Chiang Chuang continue; 4674fe25f693ad311556fb232c352ed0b84d59343a5Tsu Chiang Chuang } 46833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((mNetworkInfo.getType() != networkType) || 46933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang (mNetworkInfo.getState() != expectedState)) { 47033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "network state for " + mNetworkInfo.getType() + 47133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang "is: " + mNetworkInfo.getState()); 47233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 47333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 47533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 47833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 47933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 48033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Wait for a given wifi state to occur within a given timeout. 48133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param expectedState the expected wifi state. 48233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param timeout for the state to be set in milliseconds. 48333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if the state was achieved within the timeout, false otherwise. 48433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 48533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean waitForWifiState(int expectedState, long timeout) { 48633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED, 48733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN 48833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 48933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (true) { 49033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > timeout) { 49133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiState != expectedState) { 49233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 49333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 49433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 49533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 49633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 49733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState); 49833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (mWifiMonitor) { 49933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 50033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiMonitor.wait(SHORT_TIMEOUT); 50133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 50233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 50333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 50433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiState != expectedState) { 50533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wifi state is: " + mWifiState); 50633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 50733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 50833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 50933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 51033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 51133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 51233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 51333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 51433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Convenience method to determine if we are connected to a mobile network. 51533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if connected to a mobile network, false otherwise. 51633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 51733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean isConnectedToMobile() { 518212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 519212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return networkInfo.isConnected(); 52033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 52133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 52233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 52333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Convenience method to determine if we are connected to wifi. 52433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if connected to wifi, false otherwise. 52533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 52633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean isConnectedToWifi() { 527212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 528212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return networkInfo.isConnected(); 52933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 53033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 53133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 53233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Associate the device to given SSID 53333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * If the device is already associated with a WiFi, disconnect and forget it, 53433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * We don't verify whether the connection is successful or not, leave this to the test 53533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 53633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean connectToWifi(String knownSSID) { 53733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang WifiConfiguration config = new WifiConfiguration(); 53833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang config.SSID = knownSSID; 53933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang config.allowedKeyManagement.set(KeyMgmt.NONE); 54033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return connectToWifiWithConfiguration(config); 54133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 54233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 54333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 54433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Connect to Wi-Fi with the given configuration. 54533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param config 546a8c57bf6adf3bdd477ce4d6ed8cca031c66830cdTsu Chiang Chuang * @return true if we are connected to a given AP. 54733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 54833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean connectToWifiWithConfiguration(WifiConfiguration config) { 54933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // The SSID in the configuration is a pure string, need to convert it to a quoted string. 55033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang String ssid = config.SSID; 55133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang config.SSID = convertToQuotedString(ssid); 55233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 55333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // If wifi is not enabled, enable it 55433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!mWifiManager.isWifiEnabled()) { 55533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wifi is not enabled, enable it"); 55633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mWifiManager.setWifiEnabled(true); 55733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // wait for the wifi state change before start scanning. 55833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2 * SHORT_TIMEOUT)) { 55933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Wait for WIFI_STATE_ENABLED failed"); 56033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 56133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 56233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 56333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 56433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang boolean foundApInScanResults = false; 56533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (int retry = 0; retry < 5; retry++) { 56633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang List<ScanResult> netList = mWifiManager.getScanResults(); 56733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (netList != null) { 56833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "size of scan result list: " + netList.size()); 56933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (int i = 0; i < netList.size(); i++) { 57033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang ScanResult sr= netList.get(i); 57133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (sr.SSID.equals(ssid)) { 57233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Found " + ssid + " in the scan result list."); 57333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Retry: " + retry); 57433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang foundApInScanResults = true; 57588759bbd31e05a4163e1f8e72804ca83000afd53Irfan Sheriff mWifiManager.connect(config, new WifiManager.ActionListener() { 576d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff public void onSuccess() { 577d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff } 578d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff public void onFailure(int reason) { 579d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff Log.e(LOG_TAG, "connect failed " + reason); 580d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff } 581d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff }); 582d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff 58333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang break; 58433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 58533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 58633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 58733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (foundApInScanResults) { 58833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 58933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } else { 59033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Start an active scan 591bcc97ca43a339c3356b5c8d9eaf1cbdfb0de3165Irfan Sheriff mWifiManager.startScan(); 59233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mScanResultIsAvailable = false; 59333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang long startTime = System.currentTimeMillis(); 59433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang while (!mScanResultIsAvailable) { 59533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) { 59633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "wait for scan results timeout"); 59733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 59833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 59933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // wait for the scan results to be available 60033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang synchronized (this) { 60133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // wait for the scan result to be available 60233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 60333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang this.wait(WAIT_FOR_SCAN_RESULT); 60433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) { 60533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang e.printStackTrace(); 60633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 60733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if ((mWifiManager.getScanResults() == null) || 60833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang (mWifiManager.getScanResults().size() <= 0)) { 60933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang continue; 61033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mScanResultIsAvailable = true; 61233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 61733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 61833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 61933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /* 62033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Disconnect from the current AP and remove configured networks. 62133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 62233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean disconnectAP() { 62333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // remove saved networks 62433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks(); 62533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "size of wifiConfigList: " + wifiConfigList.size()); 62633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang for (WifiConfiguration wifiConfig: wifiConfigList) { 62733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "Remove wifi configuration: " + wifiConfig.networkId); 62833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang int netId = wifiConfig.networkId; 62988759bbd31e05a4163e1f8e72804ca83000afd53Irfan Sheriff mWifiManager.forget(netId, new WifiManager.ActionListener() { 630d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff public void onSuccess() { 631d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff } 632d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff public void onFailure(int reason) { 633d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff Log.e(LOG_TAG, "forget failed " + reason); 634d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff } 635d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff }); 63633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 63733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 63833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 63933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 64033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 64133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Enable Wifi 64233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if Wifi is enabled successfully 64333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 64433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean enableWifi() { 64533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mWifiManager.setWifiEnabled(true); 64633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 64733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 64833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 64933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Disable Wifi 65033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return true if Wifi is disabled successfully 65133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 65233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean disableWifi() { 65333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return mWifiManager.setWifiEnabled(false); 65433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 65533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 65633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 65733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Remove configured networks and disable wifi 65833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 65933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public boolean removeConfiguredNetworksAndDisableWifi() { 66033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!disconnectAP()) { 66133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 66233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 66333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang sleep(SHORT_TIMEOUT); 66433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (!mWifiManager.setWifiEnabled(false)) { 66533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return false; 66633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 66733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang sleep(SHORT_TIMEOUT); 66833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return true; 66933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 67033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 67133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 67233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Make the current thread sleep. 67333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param sleeptime the time to sleep in milliseconds 67433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 67533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang private void sleep(long sleeptime) { 67633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang try { 67733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Thread.sleep(sleeptime); 67833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } catch (InterruptedException e) {} 67933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 68033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 68133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 68233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Set airplane mode on device, caller is responsible to ensuring correct state. 68333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param context {@link Context} 68433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param enableAM to enable or disable airplane mode. 68533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 68633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void setAirplaneMode(Context context, boolean enableAM) { 68733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang //set the airplane mode 68833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 68933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang enableAM ? 1 : 0); 69033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Post the intent 69133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 69233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang intent.putExtra("state", enableAM); 69333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang context.sendBroadcast(intent); 69433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 69533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 69633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang /** 69733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * Add quotes around the string. 69833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @param string to convert 69933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang * @return string with quotes around it 70033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang */ 70133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang protected static String convertToQuotedString(String string) { 70233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang return "\"" + string + "\""; 70333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 70433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang 70533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang public void cleanUp() { 70633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang // Unregister receivers if defined. 70733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mConnectivityReceiver != null) { 70833f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.unregisterReceiver(mConnectivityReceiver); 70933f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 71033f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mWifiReceiver != null) { 71133f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.unregisterReceiver(mWifiReceiver); 71233f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 71333f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang if (mDownloadReceiver != null) { 71433f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang mContext.unregisterReceiver(mDownloadReceiver); 71533f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 71633f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode())); 71733f869951fde247927e66c3aa4ab86fc61f783adTsu Chiang Chuang } 718212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang 719212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang /** 720212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * Helper method used to test data connectivity by pinging a series of popular sites. 721212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang * @return true if device has data connectivity, false otherwise. 722212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang */ 723212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang public boolean hasData() { 724212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang String[] hostList = {"www.google.com", "www.yahoo.com", 725212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang "www.bing.com", "www.facebook.com", "www.ask.com"}; 726212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang try { 727212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang for (int i = 0; i < hostList.length; ++i) { 728212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang String host = hostList[i]; 729212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host); 730212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang int status = p.waitFor(); 731212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang if (status == 0) { 732212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return true; 733212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 734212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 735212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } catch (UnknownHostException e) { 736212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Log.e(LOG_TAG, "Ping test Failed: Unknown Host"); 737212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } catch (IOException e) { 738212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Log.e(LOG_TAG, "Ping test Failed: IOException"); 739212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } catch (InterruptedException e) { 740212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang Log.e(LOG_TAG, "Ping test Failed: InterruptedException"); 741212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 742212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang return false; 743212efacb848f13b1565ef434e331a69e930d8935Tsu Chiang Chuang } 744d3975a917799b85cacaf382b65c5832813066b51Irfan Sheriff} 745