WifiWatchdogStateMachine.java revision a81ac7c450d9d534c46abc7000cc53779a72c283
1654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy/* 2654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Copyright (C) 2011 The Android Open Source Project 3654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 4654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Licensed under the Apache License, Version 2.0 (the "License"); 5654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * you may not use this file except in compliance with the License. 6654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * You may obtain a copy of the License at 7654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 8654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * http://www.apache.org/licenses/LICENSE-2.0 9654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 10654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Unless required by applicable law or agreed to in writing, software 11654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * distributed under the License is distributed on an "AS IS" BASIS, 12654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * See the License for the specific language governing permissions and 14654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * limitations under the License. 15654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 16654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 17654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levypackage android.net.wifi; 18654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 19d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levyimport android.app.Notification; 20d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levyimport android.app.NotificationManager; 21d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levyimport android.app.PendingIntent; 22654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.content.BroadcastReceiver; 23654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.content.ContentResolver; 24654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.content.Context; 25654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.content.Intent; 26654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.content.IntentFilter; 27d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levyimport android.content.res.Resources; 28654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.database.ContentObserver; 29654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.net.ConnectivityManager; 30654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.net.DnsPinger; 31654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.net.NetworkInfo; 32654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.net.Uri; 33654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.os.Message; 34654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.os.SystemClock; 354ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levyimport android.os.SystemProperties; 36654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport android.provider.Settings; 37d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levyimport android.provider.Settings.Secure; 389b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwaltimport android.util.Log; 39654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 40654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport com.android.internal.util.Protocol; 41654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport com.android.internal.util.State; 42654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport com.android.internal.util.StateMachine; 43654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 44654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport java.io.IOException; 45654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport java.io.PrintWriter; 46654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport java.net.HttpURLConnection; 47d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levyimport java.net.InetAddress; 48654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport java.net.URL; 4979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levyimport java.util.HashMap; 50654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport java.util.HashSet; 51654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levyimport java.util.List; 52654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 53654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy/** 54654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * {@link WifiWatchdogStateMachine} monitors the initial connection to a Wi-Fi 55654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * network with multiple access points. After the framework successfully 56654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * connects to an access point, the watchdog verifies connectivity by 'pinging' 57654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * the configured DNS server using {@link DnsPinger}. 58654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * <p> 59654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * On DNS check failure, the BSSID is blacklisted if it is reasonably likely 60654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * that another AP might have internet access; otherwise the SSID is disabled. 61654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * <p> 62654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * On DNS success, the WatchdogService initiates a walled garden check via an 63654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * http get. A browser window is activated if a walled garden is detected. 64654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 65654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @hide 66654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 67654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levypublic class WifiWatchdogStateMachine extends StateMachine { 68654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 697f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff private static final boolean DBG = false; 707f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff private static final String TAG = "WifiWatchdogStateMachine"; 718dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private static final String WATCHDOG_NOTIFICATION_ID = "Android.System.WifiWatchdog"; 72654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 73654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int WIFI_SIGNAL_LEVELS = 4; 74654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 75654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Low signal is defined as less than or equal to cut off 76654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 77998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final int LOW_SIGNAL_CUTOFF = 0; 78654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 79d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static final long DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS = 2 * 60 * 1000; 80998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final long DEFAULT_DNS_CHECK_LONG_INTERVAL_MS = 60 * 60 * 1000; 81d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static final long DEFAULT_WALLED_GARDEN_INTERVAL_MS = 30 * 60 * 1000; 82654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 83d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static final int DEFAULT_MAX_SSID_BLACKLISTS = 7; 84998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final int DEFAULT_NUM_DNS_PINGS = 5; // Multiple pings to detect setup issues 85998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final int DEFAULT_MIN_DNS_RESPONSES = 1; 86654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 8788bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy private static final int DEFAULT_DNS_PING_TIMEOUT_MS = 2000; 88d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 89d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static final long DEFAULT_BLACKLIST_FOLLOWUP_INTERVAL_MS = 15 * 1000; 90d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 9188bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy // See http://go/clientsdns for usage approval 9288bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy private static final String DEFAULT_WALLED_GARDEN_URL = 9388bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy "http://clients3.google.com/generate_204"; 9488bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy private static final int WALLED_GARDEN_SOCKET_TIMEOUT_MS = 10000; 95a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff 96a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff /* Some carrier apps might have support captive portal handling. Add some delay to allow 97a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff app authentication to be done before our test. 98a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff TODO: This should go away once we provide an API to apps to disable walled garden test 99a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff for certain SSIDs 100a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff */ 101a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int WALLED_GARDEN_START_DELAY_MS = 3000; 102a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff 103998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final int DNS_INTRATEST_PING_INTERVAL_MS = 200; 104998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff /* With some router setups, it takes a few hunder milli-seconds before connection is active */ 105998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final int DNS_START_DELAY_MS = 1000; 106654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 107654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int BASE = Protocol.BASE_WIFI_WATCHDOG; 108654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 109654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 110654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Indicates the enable setting of WWS may have changed 111654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 112a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int EVENT_WATCHDOG_TOGGLED = BASE + 1; 113654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 114654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 115654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Indicates the wifi network state has changed. Passed w/ original intent 116654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * which has a non-null networkInfo object 117654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 118a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int EVENT_NETWORK_STATE_CHANGE = BASE + 2; 119654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 120654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Indicates the signal has changed. Passed with arg1 121654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * {@link #mNetEventCounter} and arg2 [raw signal strength] 122654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 123a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int EVENT_RSSI_CHANGE = BASE + 3; 124a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int EVENT_SCAN_RESULTS_AVAILABLE = BASE + 4; 125a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int EVENT_WIFI_RADIO_STATE_CHANGE = BASE + 5; 126a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int EVENT_WATCHDOG_SETTINGS_CHANGE = BASE + 6; 127654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 128a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int MESSAGE_HANDLE_WALLED_GARDEN = BASE + 100; 129a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int MESSAGE_HANDLE_BAD_AP = BASE + 101; 130654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 131654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * arg1 == mOnlineWatchState.checkCount 132654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 133a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int MESSAGE_SINGLE_DNS_CHECK = BASE + 102; 134a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int MESSAGE_NETWORK_FOLLOWUP = BASE + 103; 135a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private static final int MESSAGE_DELAYED_WALLED_GARDEN_CHECK = BASE + 104; 136654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 137654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private Context mContext; 138654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private ContentResolver mContentResolver; 139654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WifiManager mWifiManager; 140654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DnsPinger mDnsPinger; 141654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private IntentFilter mIntentFilter; 142654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private BroadcastReceiver mBroadcastReceiver; 143654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 144654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DefaultState mDefaultState = new DefaultState(); 145654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WatchdogDisabledState mWatchdogDisabledState = new WatchdogDisabledState(); 146654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WatchdogEnabledState mWatchdogEnabledState = new WatchdogEnabledState(); 147654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private NotConnectedState mNotConnectedState = new NotConnectedState(); 148654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private ConnectedState mConnectedState = new ConnectedState(); 149654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DnsCheckingState mDnsCheckingState = new DnsCheckingState(); 150654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private OnlineWatchState mOnlineWatchState = new OnlineWatchState(); 151654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DnsCheckFailureState mDnsCheckFailureState = new DnsCheckFailureState(); 152a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff private DelayWalledGardenState mDelayWalledGardenState = new DelayWalledGardenState(); 153654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WalledGardenState mWalledGardenState = new WalledGardenState(); 154654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private BlacklistedApState mBlacklistedApState = new BlacklistedApState(); 155654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 156d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mDnsCheckShortIntervalMs; 157d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mDnsCheckLongIntervalMs; 158d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mWalledGardenIntervalMs; 159d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mMaxSsidBlacklists; 160d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mNumDnsPings; 161d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mMinDnsResponses; 162d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mDnsPingTimeoutMs; 163d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mBlacklistFollowupIntervalMs; 164d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private boolean mWalledGardenTestEnabled; 165d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private String mWalledGardenUrl; 166d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 167d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private boolean mShowDisabledNotification; 168654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 169654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * The {@link WifiInfo} object passed to WWSM on network broadcasts 170654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 1718dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private WifiInfo mConnectionInfo; 172654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private int mNetEventCounter = 0; 173654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 174654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 175654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Currently maintained but not used, TODO 176654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 177654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private HashSet<String> mBssids = new HashSet<String>(); 178d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mNumCheckFailures = 0; 179654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 180654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private Long mLastWalledGardenCheckTime = null; 181654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 182654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 183654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * This is set by the blacklisted state and reset when connected to a new AP. 184654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * It triggers a disableNetwork call if a DNS check fails. 185654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 186654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean mDisableAPNextFailure = false; 1879b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt private static boolean sWifiOnly = false; 1888dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private boolean mNotificationShown; 1898dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy public boolean mHasConnectedWifiManager = false; 190654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 191654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 192654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * STATE MAP 193654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Default 194654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * / \ 195654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Disabled Enabled 196654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * / \ 197d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * NotConnected Connected 198654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * /---------\ 199654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * (all other states) 200654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 201654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WifiWatchdogStateMachine(Context context) { 2027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff super(TAG); 203654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext = context; 204654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContentResolver = context.getContentResolver(); 205654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 206d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy mDnsPinger = new DnsPinger(mContext, "WifiWatchdogStateMachine.DnsPinger", 207d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy this.getHandler().getLooper(), this.getHandler(), 208d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy ConnectivityManager.TYPE_WIFI); 209654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 210654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy setupNetworkReceiver(); 211654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 212654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy // The content observer to listen needs a handler 213654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy registerForSettingsChanges(); 214d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy registerForWatchdogToggle(); 215654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mDefaultState); 216654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mWatchdogDisabledState, mDefaultState); 217654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mWatchdogEnabledState, mDefaultState); 218654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mNotConnectedState, mWatchdogEnabledState); 219654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mConnectedState, mWatchdogEnabledState); 220654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mDnsCheckingState, mConnectedState); 221654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mDnsCheckFailureState, mConnectedState); 222a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff addState(mDelayWalledGardenState, mConnectedState); 223654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mWalledGardenState, mConnectedState); 224654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mBlacklistedApState, mConnectedState); 225654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mOnlineWatchState, mConnectedState); 226654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 227654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy setInitialState(mWatchdogDisabledState); 228d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy updateSettings(); 229654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 230654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 231654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public static WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Context context) { 2324ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy ContentResolver contentResolver = context.getContentResolver(); 2339b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt 2349b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt ConnectivityManager cm = (ConnectivityManager) context.getSystemService( 2359b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt Context.CONNECTIVITY_SERVICE); 2369b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt sWifiOnly = (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false); 2379b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt 2384ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy // Disable for wifi only devices. 2394ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy if (Settings.Secure.getString(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON) == null && 2409b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt sWifiOnly) { 2414ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy putSettingsBoolean(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON, false); 2424ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy } 243654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context); 244654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy wwsm.start(); 245654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy wwsm.sendMessage(EVENT_WATCHDOG_TOGGLED); 246654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return wwsm; 247654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 248654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 249654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 250654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 251654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 252654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void setupNetworkReceiver() { 253654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mBroadcastReceiver = new BroadcastReceiver() { 254654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 255654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void onReceive(Context context, Intent intent) { 256654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy String action = intent.getAction(); 257654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 258654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_NETWORK_STATE_CHANGE, intent); 259654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { 260654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy obtainMessage(EVENT_RSSI_CHANGE, mNetEventCounter, 261654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200)).sendToTarget(); 262654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 263654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_SCAN_RESULTS_AVAILABLE); 264654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 265654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_WIFI_RADIO_STATE_CHANGE, 266654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 267654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy WifiManager.WIFI_STATE_UNKNOWN)); 268654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 269654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 270654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy }; 271654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 272654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter = new IntentFilter(); 273654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 274654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 275654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); 276654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 277654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 278654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 279654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 280654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Observes the watchdog on/off setting, and takes action when changed. 281654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 282d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private void registerForWatchdogToggle() { 283654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy ContentObserver contentObserver = new ContentObserver(this.getHandler()) { 284654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 285654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void onChange(boolean selfChange) { 286654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_WATCHDOG_TOGGLED); 287654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 288654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy }; 289654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 290654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.getContentResolver().registerContentObserver( 291654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_ON), 292654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy false, contentObserver); 293654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 294654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 295654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 296d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Observes watchdogs secure setting changes. 297d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 298d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private void registerForSettingsChanges() { 299d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy ContentObserver contentObserver = new ContentObserver(this.getHandler()) { 300d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy @Override 301d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy public void onChange(boolean selfChange) { 302d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy sendMessage(EVENT_WATCHDOG_SETTINGS_CHANGE); 303d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 304d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy }; 305d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 306d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 307d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor( 308d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_DNS_CHECK_SHORT_INTERVAL_MS), 309d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 310d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 311d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_DNS_CHECK_LONG_INTERVAL_MS), 312d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 313d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 314d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS), 315d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 316d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 317d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_MAX_SSID_BLACKLISTS), 318d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 319d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 320d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_NUM_DNS_PINGS), 321d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 322d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 323d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_MIN_DNS_RESPONSES), 324d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 325d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 326d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_DNS_PING_TIMEOUT_MS), 327d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 328d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 329d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor( 330d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS), 331d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 332d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 333d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED), 334d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 335d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 336d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL), 337d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 3388dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mContext.getContentResolver().registerContentObserver( 3398dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP) 3408dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy , false, contentObserver); 341d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 342d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 343d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 344654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * DNS based detection techniques do not work at all hotspots. The one sure 345654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * way to check a walled garden is to see if a URL fetch on a known address 346654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * fetches the data we expect 347654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 348654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean isWalledGardenConnection() { 349654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy HttpURLConnection urlConnection = null; 350654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy try { 351d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy URL url = new URL(mWalledGardenUrl); 352654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy urlConnection = (HttpURLConnection) url.openConnection(); 35388bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setInstanceFollowRedirects(false); 35488bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS); 35588bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS); 35688bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setUseCaches(false); 35788bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.getInputStream(); 35888bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy // We got a valid response, but not from the real google 35988bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy return urlConnection.getResponseCode() != 204; 360654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } catch (IOException e) { 36188bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy if (DBG) { 3627f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Walled garden check - probably not a portal: exception " + e); 36388bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy } 364654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return false; 365654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } finally { 36688bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy if (urlConnection != null) { 367654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy urlConnection.disconnect(); 36888bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy } 369654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 370654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 371654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 372654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean rssiStrengthAboveCutoff(int rssi) { 373654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return WifiManager.calculateSignalLevel(rssi, WIFI_SIGNAL_LEVELS) > LOW_SIGNAL_CUTOFF; 374654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 375654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 376654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void dump(PrintWriter pw) { 377654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.print("WatchdogStatus: "); 378654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.print("State " + getCurrentState()); 3798dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy pw.println(", network [" + mConnectionInfo + "]"); 380d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy pw.print("checkFailures " + mNumCheckFailures); 381654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.println(", bssids: " + mBssids); 382654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.println("lastSingleCheck: " + mOnlineWatchState.lastCheckTime); 383654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 384654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 385654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean isWatchdogEnabled() { 386d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true); 387654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 388654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 389d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private void updateSettings() { 390d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mDnsCheckShortIntervalMs = Secure.getLong(mContentResolver, 391d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_DNS_CHECK_SHORT_INTERVAL_MS, 392d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS); 393d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mDnsCheckLongIntervalMs = Secure.getLong(mContentResolver, 394d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_DNS_CHECK_LONG_INTERVAL_MS, 395d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_DNS_CHECK_LONG_INTERVAL_MS); 396d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mMaxSsidBlacklists = Secure.getInt(mContentResolver, 397d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_MAX_SSID_BLACKLISTS, 398d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_MAX_SSID_BLACKLISTS); 399d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mNumDnsPings = Secure.getInt(mContentResolver, 400d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_NUM_DNS_PINGS, 401d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_NUM_DNS_PINGS); 402d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mMinDnsResponses = Secure.getInt(mContentResolver, 403d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_MIN_DNS_RESPONSES, 404d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_MIN_DNS_RESPONSES); 405d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mDnsPingTimeoutMs = Secure.getInt(mContentResolver, 406d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_DNS_PING_TIMEOUT_MS, 407d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_DNS_PING_TIMEOUT_MS); 408d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mBlacklistFollowupIntervalMs = Secure.getLong(mContentResolver, 409d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS, 410d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_BLACKLIST_FOLLOWUP_INTERVAL_MS); 411d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mWalledGardenTestEnabled = getSettingsBoolean(mContentResolver, 412d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, true); 413d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mWalledGardenUrl = getSettingsStr(mContentResolver, 414d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL, 415d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_WALLED_GARDEN_URL); 416d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mWalledGardenIntervalMs = Secure.getLong(mContentResolver, 417d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS, 418d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_WALLED_GARDEN_INTERVAL_MS); 4198dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mShowDisabledNotification = getSettingsBoolean(mContentResolver, 4208dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP, true); 421d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 422654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 423654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 424654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Helper to return wait time left given a min interval and last run 425654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 426654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @param interval minimum wait interval 427654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @param lastTime last time action was performed in 428654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * SystemClock.elapsedRealtime(). Null if never. 429654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @return non negative time to wait 430654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 431654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static long waitTime(long interval, Long lastTime) { 432654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (lastTime == null) 433654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return 0; 434654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy long wait = interval + lastTime - SystemClock.elapsedRealtime(); 435654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return wait > 0 ? wait : 0; 436654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 437654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 438654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static String wifiInfoToStr(WifiInfo wifiInfo) { 439654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (wifiInfo == null) 440654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return "null"; 441654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return "(" + wifiInfo.getSSID() + ", " + wifiInfo.getBSSID() + ")"; 442654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 443654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 444654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 4458dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy * Uses {@link #mConnectionInfo}. 4468dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy */ 4478dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private void updateBssids() { 4488dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy String curSsid = mConnectionInfo.getSSID(); 4498dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy List<ScanResult> results = mWifiManager.getScanResults(); 4508dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy int oldNumBssids = mBssids.size(); 4518dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 4528dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (results == null) { 4538dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (DBG) { 4547f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("updateBssids: Got null scan results!"); 4558dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4568dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy return; 4578dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4588dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 4598dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy for (ScanResult result : results) { 4608dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (result == null || result.SSID == null) { 4618dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (DBG) { 4627f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Received invalid scan result: " + result); 4638dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4648dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy continue; 4658dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4668dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (curSsid.equals(result.SSID)) 4678dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mBssids.add(result.BSSID); 4688dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4698dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4708dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 471654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void resetWatchdogState() { 4727f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 4737f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Resetting watchdog state..."); 47488bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy } 4758dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mConnectionInfo = null; 476654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mDisableAPNextFailure = false; 477654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mLastWalledGardenCheckTime = null; 478d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mNumCheckFailures = 0; 479654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mBssids.clear(); 4808dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy cancelNetworkNotification(); 481654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 482654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 483654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void popUpBrowser() { 484654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Uri uri = Uri.parse("http://www.google.com"); 485654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Intent intent = new Intent(Intent.ACTION_VIEW, uri); 486654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | 487654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Intent.FLAG_ACTIVITY_NEW_TASK); 488654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.startActivity(intent); 489654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 490654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 4918dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private void displayDisabledNetworkNotification(String ssid) { 492d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Resources r = Resources.getSystem(); 493d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy CharSequence title = 494d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled); 4958dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy String msg = ssid + 496d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled_detailed); 497d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 498d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Notification wifiDisabledWarning = new Notification.Builder(mContext) 499d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning) 500d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setDefaults(Notification.DEFAULT_ALL) 501d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setTicker(title) 502d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setContentTitle(title) 503d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setContentText(msg) 504d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setContentIntent(PendingIntent.getActivity(mContext, 0, 5058dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK) 506d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0)) 507d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setWhen(System.currentTimeMillis()) 508d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setAutoCancel(true) 509d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .getNotification(); 510d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 511d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy NotificationManager notificationManager = (NotificationManager) mContext 512d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .getSystemService(Context.NOTIFICATION_SERVICE); 513d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 5148dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy notificationManager.notify(WATCHDOG_NOTIFICATION_ID, 1, wifiDisabledWarning); 5158dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mNotificationShown = true; 5168dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 5178dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 5188dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy public void cancelNetworkNotification() { 5198dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mNotificationShown) { 5208dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy NotificationManager notificationManager = (NotificationManager) mContext 5218dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy .getSystemService(Context.NOTIFICATION_SERVICE); 5228dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy notificationManager.cancel(WATCHDOG_NOTIFICATION_ID, 1); 5238dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mNotificationShown = false; 5248dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 525654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 526654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 527654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class DefaultState extends State { 528654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 529654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 530d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy switch (msg.what) { 531d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy case EVENT_WATCHDOG_SETTINGS_CHANGE: 532d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy updateSettings(); 5337f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 5347f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Updating wifi-watchdog secure settings"); 535d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 536d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return HANDLED; 537d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 5387f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 5397f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Caught message " + msg.what + " in state " + 540654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy getCurrentState().getName()); 541654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 542654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 543654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 544654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 545654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 546654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class WatchdogDisabledState extends State { 547654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 548654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 549654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 550654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_WATCHDOG_TOGGLED: 551654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (isWatchdogEnabled()) 552654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 553654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 554654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 555654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 556654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 557654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 558654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 559654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class WatchdogEnabledState extends State { 560654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 561654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 562654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy resetWatchdogState(); 563654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.registerReceiver(mBroadcastReceiver, mIntentFilter); 5647f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("WifiWatchdogService enabled"); 565654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 566654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 567654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 568654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 569654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 570654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_WATCHDOG_TOGGLED: 571654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (!isWatchdogEnabled()) 572654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mWatchdogDisabledState); 573654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 574654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_NETWORK_STATE_CHANGE: 575654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Intent stateChangeIntent = (Intent) msg.obj; 576654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy NetworkInfo networkInfo = (NetworkInfo) 577654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 578654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 579654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (networkInfo.getState()) { 580654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case CONNECTED: 5818dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy cancelNetworkNotification(); 58288bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy WifiInfo wifiInfo = (WifiInfo) 58388bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO); 584654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (wifiInfo == null) { 5857f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff loge("Connected --> WifiInfo object null!"); 586654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 587654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 588654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 589654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (wifiInfo.getSSID() == null || wifiInfo.getBSSID() == null) { 5907f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff loge("Received wifiInfo object with null elts: " 591654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy + wifiInfoToStr(wifiInfo)); 592654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 593654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 594654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 595654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy initConnection(wifiInfo); 5968dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mConnectionInfo = wifiInfo; 5978dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy updateBssids(); 598654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mDnsCheckingState); 599654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mNetEventCounter++; 60032f04e9009046f72242932bf4e820802148e423aIrfan Sheriff break; 60132f04e9009046f72242932bf4e820802148e423aIrfan Sheriff default: 602654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mNetEventCounter++; 603654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 60432f04e9009046f72242932bf4e820802148e423aIrfan Sheriff break; 605654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 606654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 607654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_WIFI_RADIO_STATE_CHANGE: 608654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if ((Integer) msg.obj == WifiManager.WIFI_STATE_DISABLING) { 6097f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("WifiStateDisabling -- Resetting WatchdogState"); 610654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy resetWatchdogState(); 611654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mNetEventCounter++; 612654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 613654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 614654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 615654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 616654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 617654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 618654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 619654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 620654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 621654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @param wifiInfo Info object with non-null ssid and bssid 622654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 623654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void initConnection(WifiInfo wifiInfo) { 6247f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 6257f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Connected:: old " + wifiInfoToStr(mConnectionInfo) + 626654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy " ==> new " + wifiInfoToStr(wifiInfo)); 627654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 628654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 6298dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mConnectionInfo == null || !wifiInfo.getSSID().equals(mConnectionInfo.getSSID())) { 630654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy resetWatchdogState(); 6318dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } else if (!wifiInfo.getBSSID().equals(mConnectionInfo.getBSSID())) { 632654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mDisableAPNextFailure = false; 633654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 634654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 635654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 636654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 637654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void exit() { 638654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.unregisterReceiver(mBroadcastReceiver); 6397f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("WifiWatchdogService disabled"); 640654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 641654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 642654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 643654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class NotConnectedState extends State { 644654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 645654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 646654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class ConnectedState extends State { 647654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 648654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 649654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 650654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_SCAN_RESULTS_AVAILABLE: 6518dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy updateBssids(); 652654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 653d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy case EVENT_WATCHDOG_SETTINGS_CHANGE: 654d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy // Stop current checks, but let state update 655d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy transitionTo(mOnlineWatchState); 656d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return NOT_HANDLED; 657654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 658654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 659654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 660654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 661654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 662654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class DnsCheckingState extends State { 66379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy List<InetAddress> mDnsList; 66479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy int[] dnsCheckSuccesses; 66579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy String dnsCheckLogStr; 66679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy String[] dnsResponseStrs; 66779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy /** Keeps track of active dns pings. Map is from pingID to index in mDnsList */ 66879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy HashMap<Integer, Integer> idDnsMap = new HashMap<Integer, Integer>(); 669654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 670654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 671654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 67279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy mDnsList = mDnsPinger.getDnsList(); 67379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy int numDnses = mDnsList.size(); 67479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsCheckSuccesses = new int[numDnses]; 67579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs = new String[numDnses]; 67679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (int i = 0; i < numDnses; i++) 67779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs[i] = ""; 67879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy 679654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 680d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ", 68179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy mDnsList, mConnectionInfo.getSSID()); 6827f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log(dnsCheckLogStr); 683654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 684654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 68579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy idDnsMap.clear(); 686d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy for (int i=0; i < mNumDnsPings; i++) { 68779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (int j = 0; j < numDnses; j++) { 68879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy idDnsMap.put(mDnsPinger.pingDnsAsync(mDnsList.get(j), mDnsPingTimeoutMs, 689998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff DNS_START_DELAY_MS + DNS_INTRATEST_PING_INTERVAL_MS * i), j); 69079e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 691d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 692654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 693654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 694654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 695654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 696d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy if (msg.what != DnsPinger.DNS_PING_RESULT) { 697654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 698654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 699654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 700d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy int pingID = msg.arg1; 701d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy int pingResponseTime = msg.arg2; 702654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 70379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy Integer dnsServerId = idDnsMap.get(pingID); 70479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (dnsServerId == null) { 7057f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff loge("Received a Dns response with unknown ID!"); 706d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy return HANDLED; 707d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 70879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy 70979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy idDnsMap.remove(pingID); 710654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (pingResponseTime >= 0) 71179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsCheckSuccesses[dnsServerId]++; 712654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 713654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 714654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (pingResponseTime >= 0) { 71579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs[dnsServerId] += "|" + pingResponseTime; 716654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 71779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs[dnsServerId] += "|x"; 718654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 719654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 720654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 721654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 722654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * After a full ping count, if we have more responses than this 723654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * cutoff, the outcome is success; else it is 'failure'. 724654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 725654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 726654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 727654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Our final success count will be at least this big, so we're 728654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * guaranteed to succeed. 729654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 73079e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (dnsCheckSuccesses[dnsServerId] >= mMinDnsResponses) { 731654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy // DNS CHECKS OK, NOW WALLED GARDEN 732654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 7337f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log(makeLogString() + " SUCCESS"); 734654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 735654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 736654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (!shouldCheckWalledGarden()) { 737654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mOnlineWatchState); 738654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 739654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 740654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 741a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff transitionTo(mDelayWalledGardenState); 742654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 743654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 744654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 74579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (idDnsMap.isEmpty()) { 746654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 7477f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log(makeLogString() + " FAILURE"); 748654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 749654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mDnsCheckFailureState); 750654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 751654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 752654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 753654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 754654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 755654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 75679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy private String makeLogString() { 75779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy String logStr = dnsCheckLogStr; 75879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (String respStr : dnsResponseStrs) 75979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy logStr += " [" + respStr + "]"; 76079e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy return logStr; 76179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 76279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy 763d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy @Override 764d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy public void exit() { 765d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy mDnsPinger.cancelPings(); 766d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 767d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy 768654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean shouldCheckWalledGarden() { 769d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy if (!mWalledGardenTestEnabled) { 7707f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) 7717f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Skipping walled garden check - disabled"); 772654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return false; 773654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 774d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy long waitTime = waitTime(mWalledGardenIntervalMs, 775654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mLastWalledGardenCheckTime); 776654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (waitTime > 0) { 777654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 7787f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Skipping walled garden check - wait " + 779654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy waitTime + " ms."); 780654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 781654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return false; 782654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 783654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return true; 784654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 785654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 786654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 787a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff class DelayWalledGardenState extends State { 788a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff @Override 789a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff public void enter() { 790a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff sendMessageDelayed(MESSAGE_DELAYED_WALLED_GARDEN_CHECK, WALLED_GARDEN_START_DELAY_MS); 791a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff } 792a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff 793a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff @Override 794a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff public boolean processMessage(Message msg) { 795a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff switch (msg.what) { 796a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff case MESSAGE_DELAYED_WALLED_GARDEN_CHECK: 797a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff mLastWalledGardenCheckTime = SystemClock.elapsedRealtime(); 798a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff if (isWalledGardenConnection()) { 799a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff if (DBG) log("Walled garden test complete - walled garden detected"); 800a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff transitionTo(mWalledGardenState); 801a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff } else { 802a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff if (DBG) log("Walled garden test complete - online"); 803a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff transitionTo(mOnlineWatchState); 804a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff } 805a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff return HANDLED; 806a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff default: 807a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff return NOT_HANDLED; 808a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff } 809a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff } 810a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff } 811a81ac7c450d9d534c46abc7000cc53779a72c283Irfan Sheriff 812654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class OnlineWatchState extends State { 813654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 814654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Signals a short-wait message is enqueued for the current 'guard' counter 815654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 816654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy boolean unstableSignalChecks = false; 817654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 818654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 819654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * The signal is unstable. We should enqueue a short-wait check, if one is enqueued 820654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * already 821654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 822654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy boolean signalUnstable = false; 823654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 824654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 825654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * A monotonic counter to ensure that at most one check message will be processed from any 826654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * set of check messages currently enqueued. Avoids duplicate checks when a low-signal 827654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * event is observed. 828654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 829654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy int checkGuard = 0; 830654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Long lastCheckTime = null; 831654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 83279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy /** Keeps track of dns pings. Map is from pingID to InetAddress used for ping */ 83379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy HashMap<Integer, InetAddress> pingInfoMap = new HashMap<Integer, InetAddress>(); 834d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy 835654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 836654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 837654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy lastCheckTime = SystemClock.elapsedRealtime(); 838654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy signalUnstable = false; 839654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy checkGuard++; 840654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy unstableSignalChecks = false; 84179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.clear(); 842654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy triggerSingleDnsCheck(); 843654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 844654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 845654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 846654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 847654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 848654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_RSSI_CHANGE: 849654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 850654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 8517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Rssi change message out of sync, ignoring"); 852654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 853654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 854654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 855654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy int newRssi = msg.arg2; 856654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy signalUnstable = !rssiStrengthAboveCutoff(newRssi); 8577f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8587f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("OnlineWatchState:: new rssi " + newRssi + " --> level " + 859654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy WifiManager.calculateSignalLevel(newRssi, WIFI_SIGNAL_LEVELS)); 860654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 861654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 862654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (signalUnstable && !unstableSignalChecks) { 8637f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8647f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Sending triggered check msg"); 865654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 866654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy triggerSingleDnsCheck(); 867654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 868654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 869654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case MESSAGE_SINGLE_DNS_CHECK: 870654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != checkGuard) { 8717f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8727f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Single check msg out of sync, ignoring."); 873654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 874654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 875654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 876654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy lastCheckTime = SystemClock.elapsedRealtime(); 87779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.clear(); 87879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (InetAddress curDns: mDnsPinger.getDnsList()) { 87979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.put(mDnsPinger.pingDnsAsync(curDns, mDnsPingTimeoutMs, 0), 88079e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy curDns); 88179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 882d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy return HANDLED; 883d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy case DnsPinger.DNS_PING_RESULT: 88479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy InetAddress curDnsServer = pingInfoMap.get(msg.arg1); 88579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (curDnsServer == null) { 886d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy return HANDLED; 887d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 88879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.remove(msg.arg1); 889d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy int responseTime = msg.arg2; 890654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (responseTime >= 0) { 8917f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Single DNS ping OK. Response time: " 89379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy + responseTime + " from DNS " + curDnsServer); 894654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 89579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.clear(); 896654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 897654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy checkGuard++; 898654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy unstableSignalChecks = false; 899654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy triggerSingleDnsCheck(); 900654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 90179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (pingInfoMap.isEmpty()) { 90279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (DBG) { 9037f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Single dns ping failure. All dns servers failed, " 90479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy + "starting full checks."); 90579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 90679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy transitionTo(mDnsCheckingState); 907654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 908654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 909654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 910654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 911654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 912654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 913654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 914d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy @Override 915d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy public void exit() { 916d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy mDnsPinger.cancelPings(); 917d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 918d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy 919654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 920d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Times a dns check with an interval based on {@link #signalUnstable} 921654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 922654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void triggerSingleDnsCheck() { 923654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy long waitInterval; 924654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (signalUnstable) { 925d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy waitInterval = mDnsCheckShortIntervalMs; 926654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy unstableSignalChecks = true; 927654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 928d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy waitInterval = mDnsCheckLongIntervalMs; 929654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 930654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessageDelayed(obtainMessage(MESSAGE_SINGLE_DNS_CHECK, checkGuard, 0), 931654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy waitTime(waitInterval, lastCheckTime)); 932654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 933654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 934654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 935654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class DnsCheckFailureState extends State { 9364ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy 937654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 938654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 939d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mNumCheckFailures++; 940654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy obtainMessage(MESSAGE_HANDLE_BAD_AP, mNetEventCounter, 0).sendToTarget(); 941654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 942654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 943654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 944654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 945654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.what != MESSAGE_HANDLE_BAD_AP) { 946654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 947654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 948654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 949654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 9507f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 9517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Msg out of sync, ignoring..."); 952654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 953654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 954654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 955654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 9568dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mDisableAPNextFailure || mNumCheckFailures >= mBssids.size() 9578dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy || mNumCheckFailures >= mMaxSsidBlacklists) { 9589b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt if (sWifiOnly) { 9597f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Would disable bad network, but device has no mobile data!" + 9604ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy " Going idle..."); 9614ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy // This state should be called idle -- will be changing flow. 9624ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy transitionTo(mNotConnectedState); 9634ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy return HANDLED; 9644ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy } 9658dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 966654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy // TODO : Unban networks if they had low signal ? 9677f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Disabling current SSID " + wifiInfoToStr(mConnectionInfo) 968d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy + ". " + "numCheckFailures " + mNumCheckFailures 969d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy + ", numAPs " + mBssids.size()); 9708dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy int networkId = mConnectionInfo.getNetworkId(); 9718dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (!mHasConnectedWifiManager) { 9728dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mWifiManager.asyncConnect(mContext, getHandler()); 9738dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mHasConnectedWifiManager = true; 9748dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 9758dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mWifiManager.disableNetwork(networkId, WifiConfiguration.DISABLED_DNS_FAILURE); 9768dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mShowDisabledNotification && mConnectionInfo.isExplicitConnect()) { 9778dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy displayDisabledNetworkNotification(mConnectionInfo.getSSID()); 978d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 979654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 980654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 9817f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Blacklisting current BSSID. " + wifiInfoToStr(mConnectionInfo) 982d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy + "numCheckFailures " + mNumCheckFailures + ", numAPs " + mBssids.size()); 983654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 9848dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mWifiManager.addToBlacklist(mConnectionInfo.getBSSID()); 985654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mWifiManager.reassociate(); 986654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mBlacklistedApState); 987654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 988654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 989654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 990654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 991654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 992654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class WalledGardenState extends State { 993654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 994654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 995654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy obtainMessage(MESSAGE_HANDLE_WALLED_GARDEN, mNetEventCounter, 0).sendToTarget(); 996654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 997654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 998654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 999654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 1000654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.what != MESSAGE_HANDLE_WALLED_GARDEN) { 1001654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 1002654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1003654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 1004654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 10057f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 10067f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("WalledGardenState::Msg out of sync, ignoring..."); 1007654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1008654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 1009654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1010654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy popUpBrowser(); 1011654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mOnlineWatchState); 1012654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 1013654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1014654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1015654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 1016654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class BlacklistedApState extends State { 1017654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 1018654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 1019654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mDisableAPNextFailure = true; 1020654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessageDelayed(obtainMessage(MESSAGE_NETWORK_FOLLOWUP, mNetEventCounter, 0), 1021d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mBlacklistFollowupIntervalMs); 1022654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1023654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 1024654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 1025654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 1026654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.what != MESSAGE_NETWORK_FOLLOWUP) { 1027654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 1028654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1029654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 1030654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 10317f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 10327f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("BlacklistedApState::Msg out of sync, ignoring..."); 1033654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1034654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 1035654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1036654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 1037654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mDnsCheckingState); 1038654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 1039654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1040654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1041d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1042d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1043d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 1044d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Convenience function for retrieving a single secure settings value 1045d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * as a string with a default value. 1046d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1047d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param cr The ContentResolver to access. 1048d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param name The name of the setting to retrieve. 1049d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param def Value to return if the setting is not defined. 1050d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1051d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @return The setting's current value, or 'def' if it is not defined 1052d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 1053d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static String getSettingsStr(ContentResolver cr, String name, String def) { 1054d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy String v = Settings.Secure.getString(cr, name); 1055d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return v != null ? v : def; 1056d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 1057d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1058d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 1059d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Convenience function for retrieving a single secure settings value 1060d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * as a boolean. Note that internally setting values are always 1061d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * stored as strings; this function converts the string to a boolean 1062d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * for you. The default value will be returned if the setting is 1063d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * not defined or not a valid boolean. 1064d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1065d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param cr The ContentResolver to access. 1066d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param name The name of the setting to retrieve. 1067d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param def Value to return if the setting is not defined. 1068d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1069d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @return The setting's current value, or 'def' if it is not defined 1070d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * or not a valid boolean. 1071d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 1072d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static boolean getSettingsBoolean(ContentResolver cr, String name, boolean def) { 1073d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return Settings.Secure.getInt(cr, name, def ? 1 : 0) == 1; 1074d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 1075d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1076d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 1077d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Convenience function for updating a single settings value as an 1078d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * integer. This will either create a new entry in the table if the 1079d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * given name does not exist, or modify the value of the existing row 1080d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * with that name. Note that internally setting values are always 1081d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * stored as strings, so this function converts the given value to a 1082d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * string before storing it. 1083d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1084d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param cr The ContentResolver to access. 1085d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param name The name of the setting to modify. 1086d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param value The new value for the setting. 1087d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @return true if the value was set, false on database errors 1088d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 1089d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static boolean putSettingsBoolean(ContentResolver cr, String name, boolean value) { 1090d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return Settings.Secure.putInt(cr, name, value ? 1 : 0); 1091d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 1092d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 10937f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff private void log(String s) { 10947f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff Log.d(TAG, s); 10957f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff } 1096d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 10977f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff private void loge(String s) { 10987f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff Log.e(TAG, s); 10997f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff } 1100654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy} 1101