WifiWatchdogStateMachine.java revision 7f8a12c75cf2b376fce58fc22b5ecb1b64acf110
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; 95998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final int DNS_INTRATEST_PING_INTERVAL_MS = 200; 96998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff /* With some router setups, it takes a few hunder milli-seconds before connection is active */ 97998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff private static final int DNS_START_DELAY_MS = 1000; 98654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 99654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int BASE = Protocol.BASE_WIFI_WATCHDOG; 100654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 101654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 102654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Indicates the enable setting of WWS may have changed 103654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 104654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int EVENT_WATCHDOG_TOGGLED = BASE + 1; 105654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 106654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 107654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Indicates the wifi network state has changed. Passed w/ original intent 108654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * which has a non-null networkInfo object 109654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 110654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int EVENT_NETWORK_STATE_CHANGE = BASE + 2; 111654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 112654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Indicates the signal has changed. Passed with arg1 113654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * {@link #mNetEventCounter} and arg2 [raw signal strength] 114654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 115654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int EVENT_RSSI_CHANGE = BASE + 3; 116654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int EVENT_SCAN_RESULTS_AVAILABLE = BASE + 4; 117654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int EVENT_WIFI_RADIO_STATE_CHANGE = BASE + 5; 118d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static final int EVENT_WATCHDOG_SETTINGS_CHANGE = BASE + 6; 119654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 120d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy private static final int MESSAGE_HANDLE_WALLED_GARDEN = BASE + 100; 121d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy private static final int MESSAGE_HANDLE_BAD_AP = BASE + 101; 122654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 123654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * arg1 == mOnlineWatchState.checkCount 124654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 125654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int MESSAGE_SINGLE_DNS_CHECK = BASE + 103; 126654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static final int MESSAGE_NETWORK_FOLLOWUP = BASE + 104; 127654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 128654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private Context mContext; 129654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private ContentResolver mContentResolver; 130654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WifiManager mWifiManager; 131654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DnsPinger mDnsPinger; 132654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private IntentFilter mIntentFilter; 133654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private BroadcastReceiver mBroadcastReceiver; 134654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 135654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DefaultState mDefaultState = new DefaultState(); 136654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WatchdogDisabledState mWatchdogDisabledState = new WatchdogDisabledState(); 137654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WatchdogEnabledState mWatchdogEnabledState = new WatchdogEnabledState(); 138654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private NotConnectedState mNotConnectedState = new NotConnectedState(); 139654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private ConnectedState mConnectedState = new ConnectedState(); 140654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DnsCheckingState mDnsCheckingState = new DnsCheckingState(); 141654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private OnlineWatchState mOnlineWatchState = new OnlineWatchState(); 142654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private DnsCheckFailureState mDnsCheckFailureState = new DnsCheckFailureState(); 143654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WalledGardenState mWalledGardenState = new WalledGardenState(); 144654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private BlacklistedApState mBlacklistedApState = new BlacklistedApState(); 145654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 146d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mDnsCheckShortIntervalMs; 147d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mDnsCheckLongIntervalMs; 148d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mWalledGardenIntervalMs; 149d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mMaxSsidBlacklists; 150d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mNumDnsPings; 151d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mMinDnsResponses; 152d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mDnsPingTimeoutMs; 153d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private long mBlacklistFollowupIntervalMs; 154d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private boolean mWalledGardenTestEnabled; 155d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private String mWalledGardenUrl; 156d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 157d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private boolean mShowDisabledNotification; 158654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 159654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * The {@link WifiInfo} object passed to WWSM on network broadcasts 160654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 1618dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private WifiInfo mConnectionInfo; 162654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private int mNetEventCounter = 0; 163654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 164654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 165654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Currently maintained but not used, TODO 166654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 167654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private HashSet<String> mBssids = new HashSet<String>(); 168d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private int mNumCheckFailures = 0; 169654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 170654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private Long mLastWalledGardenCheckTime = null; 171654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 172654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 173654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * This is set by the blacklisted state and reset when connected to a new AP. 174654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * It triggers a disableNetwork call if a DNS check fails. 175654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 176654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean mDisableAPNextFailure = false; 1779b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt private static boolean sWifiOnly = false; 1788dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private boolean mNotificationShown; 1798dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy public boolean mHasConnectedWifiManager = false; 180654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 181654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 182654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * STATE MAP 183654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Default 184654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * / \ 185654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Disabled Enabled 186654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * / \ 187d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * NotConnected Connected 188654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * /---------\ 189654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * (all other states) 190654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 191654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private WifiWatchdogStateMachine(Context context) { 1927f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff super(TAG); 193654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext = context; 194654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContentResolver = context.getContentResolver(); 195654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 196d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy mDnsPinger = new DnsPinger(mContext, "WifiWatchdogStateMachine.DnsPinger", 197d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy this.getHandler().getLooper(), this.getHandler(), 198d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy ConnectivityManager.TYPE_WIFI); 199654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 200654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy setupNetworkReceiver(); 201654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 202654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy // The content observer to listen needs a handler 203654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy registerForSettingsChanges(); 204d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy registerForWatchdogToggle(); 205654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mDefaultState); 206654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mWatchdogDisabledState, mDefaultState); 207654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mWatchdogEnabledState, mDefaultState); 208654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mNotConnectedState, mWatchdogEnabledState); 209654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mConnectedState, mWatchdogEnabledState); 210654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mDnsCheckingState, mConnectedState); 211654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mDnsCheckFailureState, mConnectedState); 212654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mWalledGardenState, mConnectedState); 213654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mBlacklistedApState, mConnectedState); 214654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy addState(mOnlineWatchState, mConnectedState); 215654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 216654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy setInitialState(mWatchdogDisabledState); 217d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy updateSettings(); 218654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 219654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 220654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public static WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Context context) { 2214ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy ContentResolver contentResolver = context.getContentResolver(); 2229b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt 2239b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt ConnectivityManager cm = (ConnectivityManager) context.getSystemService( 2249b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt Context.CONNECTIVITY_SERVICE); 2259b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt sWifiOnly = (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false); 2269b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt 2274ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy // Disable for wifi only devices. 2284ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy if (Settings.Secure.getString(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON) == null && 2299b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt sWifiOnly) { 2304ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy putSettingsBoolean(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON, false); 2314ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy } 232654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context); 233654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy wwsm.start(); 234654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy wwsm.sendMessage(EVENT_WATCHDOG_TOGGLED); 235654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return wwsm; 236654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 237654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 238654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 239654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 240654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 241654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void setupNetworkReceiver() { 242654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mBroadcastReceiver = new BroadcastReceiver() { 243654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 244654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void onReceive(Context context, Intent intent) { 245654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy String action = intent.getAction(); 246654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 247654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_NETWORK_STATE_CHANGE, intent); 248654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { 249654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy obtainMessage(EVENT_RSSI_CHANGE, mNetEventCounter, 250654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200)).sendToTarget(); 251654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 252654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_SCAN_RESULTS_AVAILABLE); 253654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 254654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_WIFI_RADIO_STATE_CHANGE, 255654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 256654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy WifiManager.WIFI_STATE_UNKNOWN)); 257654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 258654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 259654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy }; 260654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 261654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter = new IntentFilter(); 262654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 263654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 264654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); 265654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 266654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 267654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 268654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 269654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Observes the watchdog on/off setting, and takes action when changed. 270654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 271d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private void registerForWatchdogToggle() { 272654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy ContentObserver contentObserver = new ContentObserver(this.getHandler()) { 273654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 274654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void onChange(boolean selfChange) { 275654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessage(EVENT_WATCHDOG_TOGGLED); 276654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 277654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy }; 278654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 279654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.getContentResolver().registerContentObserver( 280654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_ON), 281654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy false, contentObserver); 282654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 283654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 284654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 285d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Observes watchdogs secure setting changes. 286d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 287d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private void registerForSettingsChanges() { 288d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy ContentObserver contentObserver = new ContentObserver(this.getHandler()) { 289d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy @Override 290d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy public void onChange(boolean selfChange) { 291d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy sendMessage(EVENT_WATCHDOG_SETTINGS_CHANGE); 292d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 293d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy }; 294d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 295d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 296d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor( 297d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_DNS_CHECK_SHORT_INTERVAL_MS), 298d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 299d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 300d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_DNS_CHECK_LONG_INTERVAL_MS), 301d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 302d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 303d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS), 304d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 305d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 306d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_MAX_SSID_BLACKLISTS), 307d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 308d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 309d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_NUM_DNS_PINGS), 310d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 311d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 312d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_MIN_DNS_RESPONSES), 313d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 314d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 315d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_DNS_PING_TIMEOUT_MS), 316d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 317d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 318d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor( 319d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS), 320d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 321d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 322d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED), 323d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 324d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mContext.getContentResolver().registerContentObserver( 325d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL), 326d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy false, contentObserver); 3278dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mContext.getContentResolver().registerContentObserver( 3288dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy Settings.Secure.getUriFor(Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP) 3298dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy , false, contentObserver); 330d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 331d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 332d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 333654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * DNS based detection techniques do not work at all hotspots. The one sure 334654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * way to check a walled garden is to see if a URL fetch on a known address 335654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * fetches the data we expect 336654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 337654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean isWalledGardenConnection() { 338654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy HttpURLConnection urlConnection = null; 339654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy try { 340d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy URL url = new URL(mWalledGardenUrl); 341654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy urlConnection = (HttpURLConnection) url.openConnection(); 34288bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setInstanceFollowRedirects(false); 34388bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setConnectTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS); 34488bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setReadTimeout(WALLED_GARDEN_SOCKET_TIMEOUT_MS); 34588bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.setUseCaches(false); 34688bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy urlConnection.getInputStream(); 34788bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy // We got a valid response, but not from the real google 34888bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy return urlConnection.getResponseCode() != 204; 349654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } catch (IOException e) { 35088bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy if (DBG) { 3517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Walled garden check - probably not a portal: exception " + e); 35288bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy } 353654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return false; 354654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } finally { 35588bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy if (urlConnection != null) { 356654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy urlConnection.disconnect(); 35788bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy } 358654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 359654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 360654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 361654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean rssiStrengthAboveCutoff(int rssi) { 362654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return WifiManager.calculateSignalLevel(rssi, WIFI_SIGNAL_LEVELS) > LOW_SIGNAL_CUTOFF; 363654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 364654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 365654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void dump(PrintWriter pw) { 366654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.print("WatchdogStatus: "); 367654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.print("State " + getCurrentState()); 3688dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy pw.println(", network [" + mConnectionInfo + "]"); 369d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy pw.print("checkFailures " + mNumCheckFailures); 370654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.println(", bssids: " + mBssids); 371654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy pw.println("lastSingleCheck: " + mOnlineWatchState.lastCheckTime); 372654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 373654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 374654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean isWatchdogEnabled() { 375d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return getSettingsBoolean(mContentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true); 376654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 377654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 378d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private void updateSettings() { 379d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mDnsCheckShortIntervalMs = Secure.getLong(mContentResolver, 380d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_DNS_CHECK_SHORT_INTERVAL_MS, 381d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_DNS_CHECK_SHORT_INTERVAL_MS); 382d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mDnsCheckLongIntervalMs = Secure.getLong(mContentResolver, 383d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_DNS_CHECK_LONG_INTERVAL_MS, 384d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_DNS_CHECK_LONG_INTERVAL_MS); 385d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mMaxSsidBlacklists = Secure.getInt(mContentResolver, 386d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_MAX_SSID_BLACKLISTS, 387d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_MAX_SSID_BLACKLISTS); 388d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mNumDnsPings = Secure.getInt(mContentResolver, 389d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_NUM_DNS_PINGS, 390d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_NUM_DNS_PINGS); 391d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mMinDnsResponses = Secure.getInt(mContentResolver, 392d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_MIN_DNS_RESPONSES, 393d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_MIN_DNS_RESPONSES); 394d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mDnsPingTimeoutMs = Secure.getInt(mContentResolver, 395d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_DNS_PING_TIMEOUT_MS, 396d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_DNS_PING_TIMEOUT_MS); 397d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mBlacklistFollowupIntervalMs = Secure.getLong(mContentResolver, 398d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_BLACKLIST_FOLLOWUP_INTERVAL_MS, 399d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_BLACKLIST_FOLLOWUP_INTERVAL_MS); 400d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mWalledGardenTestEnabled = getSettingsBoolean(mContentResolver, 401d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_TEST_ENABLED, true); 402d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mWalledGardenUrl = getSettingsStr(mContentResolver, 403d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Settings.Secure.WIFI_WATCHDOG_WALLED_GARDEN_URL, 404d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_WALLED_GARDEN_URL); 405d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mWalledGardenIntervalMs = Secure.getLong(mContentResolver, 406d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Secure.WIFI_WATCHDOG_WALLED_GARDEN_INTERVAL_MS, 407d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy DEFAULT_WALLED_GARDEN_INTERVAL_MS); 4088dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mShowDisabledNotification = getSettingsBoolean(mContentResolver, 4098dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy Settings.Secure.WIFI_WATCHDOG_SHOW_DISABLED_NETWORK_POPUP, true); 410d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 411654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 412654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 413654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Helper to return wait time left given a min interval and last run 414654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * 415654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @param interval minimum wait interval 416654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @param lastTime last time action was performed in 417654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * SystemClock.elapsedRealtime(). Null if never. 418654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @return non negative time to wait 419654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 420654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static long waitTime(long interval, Long lastTime) { 421654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (lastTime == null) 422654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return 0; 423654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy long wait = interval + lastTime - SystemClock.elapsedRealtime(); 424654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return wait > 0 ? wait : 0; 425654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 426654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 427654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private static String wifiInfoToStr(WifiInfo wifiInfo) { 428654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (wifiInfo == null) 429654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return "null"; 430654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return "(" + wifiInfo.getSSID() + ", " + wifiInfo.getBSSID() + ")"; 431654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 432654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 433654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 4348dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy * Uses {@link #mConnectionInfo}. 4358dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy */ 4368dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private void updateBssids() { 4378dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy String curSsid = mConnectionInfo.getSSID(); 4388dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy List<ScanResult> results = mWifiManager.getScanResults(); 4398dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy int oldNumBssids = mBssids.size(); 4408dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 4418dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (results == null) { 4428dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (DBG) { 4437f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("updateBssids: Got null scan results!"); 4448dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4458dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy return; 4468dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4478dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 4488dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy for (ScanResult result : results) { 4498dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (result == null || result.SSID == null) { 4508dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (DBG) { 4517f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Received invalid scan result: " + result); 4528dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4538dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy continue; 4548dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4558dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (curSsid.equals(result.SSID)) 4568dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mBssids.add(result.BSSID); 4578dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4588dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 4598dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 460654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void resetWatchdogState() { 4617f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 4627f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Resetting watchdog state..."); 46388bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy } 4648dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mConnectionInfo = null; 465654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mDisableAPNextFailure = false; 466654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mLastWalledGardenCheckTime = null; 467d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mNumCheckFailures = 0; 468654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mBssids.clear(); 4698dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy cancelNetworkNotification(); 470654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 471654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 472654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void popUpBrowser() { 473654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Uri uri = Uri.parse("http://www.google.com"); 474654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Intent intent = new Intent(Intent.ACTION_VIEW, uri); 475654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | 476654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Intent.FLAG_ACTIVITY_NEW_TASK); 477654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.startActivity(intent); 478654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 479654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 4808dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy private void displayDisabledNetworkNotification(String ssid) { 481d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Resources r = Resources.getSystem(); 482d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy CharSequence title = 483d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled); 4848dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy String msg = ssid + 485d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy r.getText(com.android.internal.R.string.wifi_watchdog_network_disabled_detailed); 486d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 487d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy Notification wifiDisabledWarning = new Notification.Builder(mContext) 488d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning) 489d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setDefaults(Notification.DEFAULT_ALL) 490d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setTicker(title) 491d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setContentTitle(title) 492d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setContentText(msg) 493d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setContentIntent(PendingIntent.getActivity(mContext, 0, 4948dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK) 495d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), 0)) 496d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setWhen(System.currentTimeMillis()) 497d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .setAutoCancel(true) 498d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .getNotification(); 499d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 500d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy NotificationManager notificationManager = (NotificationManager) mContext 501d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy .getSystemService(Context.NOTIFICATION_SERVICE); 502d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 5038dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy notificationManager.notify(WATCHDOG_NOTIFICATION_ID, 1, wifiDisabledWarning); 5048dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mNotificationShown = true; 5058dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 5068dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 5078dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy public void cancelNetworkNotification() { 5088dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mNotificationShown) { 5098dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy NotificationManager notificationManager = (NotificationManager) mContext 5108dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy .getSystemService(Context.NOTIFICATION_SERVICE); 5118dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy notificationManager.cancel(WATCHDOG_NOTIFICATION_ID, 1); 5128dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mNotificationShown = false; 5138dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 514654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 515654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 516654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class DefaultState extends State { 517654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 518654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 519d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy switch (msg.what) { 520d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy case EVENT_WATCHDOG_SETTINGS_CHANGE: 521d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy updateSettings(); 5227f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 5237f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Updating wifi-watchdog secure settings"); 524d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 525d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return HANDLED; 526d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 5277f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 5287f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Caught message " + msg.what + " in state " + 529654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy getCurrentState().getName()); 530654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 531654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 532654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 533654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 534654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 535654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class WatchdogDisabledState extends State { 536654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 537654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 538654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 539654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_WATCHDOG_TOGGLED: 540654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (isWatchdogEnabled()) 541654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 542654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 543654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 544654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 545654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 546654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 547654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 548654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class WatchdogEnabledState extends State { 549654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 550654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 551654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy resetWatchdogState(); 552654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.registerReceiver(mBroadcastReceiver, mIntentFilter); 5537f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("WifiWatchdogService enabled"); 554654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 555654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 556654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 557654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 558654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 559654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_WATCHDOG_TOGGLED: 560654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (!isWatchdogEnabled()) 561654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mWatchdogDisabledState); 562654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 563654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_NETWORK_STATE_CHANGE: 564654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Intent stateChangeIntent = (Intent) msg.obj; 565654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy NetworkInfo networkInfo = (NetworkInfo) 566654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 567654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 568654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (networkInfo.getState()) { 569654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case CONNECTED: 5708dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy cancelNetworkNotification(); 57188bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy WifiInfo wifiInfo = (WifiInfo) 57288bae17cfd3de40758c5296d15f012f06f08748aIsaac Levy stateChangeIntent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO); 573654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (wifiInfo == null) { 5747f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff loge("Connected --> WifiInfo object null!"); 575654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 576654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 577654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 578654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (wifiInfo.getSSID() == null || wifiInfo.getBSSID() == null) { 5797f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff loge("Received wifiInfo object with null elts: " 580654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy + wifiInfoToStr(wifiInfo)); 581654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 582654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 583654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 584654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy initConnection(wifiInfo); 5858dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mConnectionInfo = wifiInfo; 5868dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy updateBssids(); 587654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mDnsCheckingState); 588654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mNetEventCounter++; 58932f04e9009046f72242932bf4e820802148e423aIrfan Sheriff break; 59032f04e9009046f72242932bf4e820802148e423aIrfan Sheriff default: 591654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mNetEventCounter++; 592654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 59332f04e9009046f72242932bf4e820802148e423aIrfan Sheriff break; 594654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 595654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 596654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_WIFI_RADIO_STATE_CHANGE: 597654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if ((Integer) msg.obj == WifiManager.WIFI_STATE_DISABLING) { 5987f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("WifiStateDisabling -- Resetting WatchdogState"); 599654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy resetWatchdogState(); 600654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mNetEventCounter++; 601654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 602654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 603654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 604654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 605654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 606654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 607654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 608654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 609654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 610654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * @param wifiInfo Info object with non-null ssid and bssid 611654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 612654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void initConnection(WifiInfo wifiInfo) { 6137f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 6147f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Connected:: old " + wifiInfoToStr(mConnectionInfo) + 615654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy " ==> new " + wifiInfoToStr(wifiInfo)); 616654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 617654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 6188dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mConnectionInfo == null || !wifiInfo.getSSID().equals(mConnectionInfo.getSSID())) { 619654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy resetWatchdogState(); 6208dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } else if (!wifiInfo.getBSSID().equals(mConnectionInfo.getBSSID())) { 621654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mDisableAPNextFailure = false; 622654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 623654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 624654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 625654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 626654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void exit() { 627654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mContext.unregisterReceiver(mBroadcastReceiver); 6287f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("WifiWatchdogService disabled"); 629654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 630654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 631654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 632654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class NotConnectedState extends State { 633654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 634654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 635654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class ConnectedState extends State { 636654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 637654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 638654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 639654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_SCAN_RESULTS_AVAILABLE: 6408dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy updateBssids(); 641654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 642d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy case EVENT_WATCHDOG_SETTINGS_CHANGE: 643d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy // Stop current checks, but let state update 644d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy transitionTo(mOnlineWatchState); 645d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return NOT_HANDLED; 646654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 647654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 648654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 649654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 650654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 651654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class DnsCheckingState extends State { 65279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy List<InetAddress> mDnsList; 65379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy int[] dnsCheckSuccesses; 65479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy String dnsCheckLogStr; 65579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy String[] dnsResponseStrs; 65679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy /** Keeps track of active dns pings. Map is from pingID to index in mDnsList */ 65779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy HashMap<Integer, Integer> idDnsMap = new HashMap<Integer, Integer>(); 658654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 659654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 660654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 66179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy mDnsList = mDnsPinger.getDnsList(); 66279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy int numDnses = mDnsList.size(); 66379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsCheckSuccesses = new int[numDnses]; 66479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs = new String[numDnses]; 66579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (int i = 0; i < numDnses; i++) 66679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs[i] = ""; 66779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy 668654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 669d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy dnsCheckLogStr = String.format("Pinging %s on ssid [%s]: ", 67079e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy mDnsList, mConnectionInfo.getSSID()); 6717f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log(dnsCheckLogStr); 672654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 673654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 67479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy idDnsMap.clear(); 675d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy for (int i=0; i < mNumDnsPings; i++) { 67679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (int j = 0; j < numDnses; j++) { 67779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy idDnsMap.put(mDnsPinger.pingDnsAsync(mDnsList.get(j), mDnsPingTimeoutMs, 678998196d64d35c1767dbb08f059fe3af171e44e1dIrfan Sheriff DNS_START_DELAY_MS + DNS_INTRATEST_PING_INTERVAL_MS * i), j); 67979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 680d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 681654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 682654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 683654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 684654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 685d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy if (msg.what != DnsPinger.DNS_PING_RESULT) { 686654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 687654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 688654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 689d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy int pingID = msg.arg1; 690d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy int pingResponseTime = msg.arg2; 691654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 69279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy Integer dnsServerId = idDnsMap.get(pingID); 69379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (dnsServerId == null) { 6947f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff loge("Received a Dns response with unknown ID!"); 695d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy return HANDLED; 696d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 69779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy 69879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy idDnsMap.remove(pingID); 699654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (pingResponseTime >= 0) 70079e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsCheckSuccesses[dnsServerId]++; 701654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 702654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 703654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (pingResponseTime >= 0) { 70479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs[dnsServerId] += "|" + pingResponseTime; 705654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 70679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy dnsResponseStrs[dnsServerId] += "|x"; 707654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 708654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 709654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 710654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 711654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * After a full ping count, if we have more responses than this 712654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * cutoff, the outcome is success; else it is 'failure'. 713654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 714654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 715654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 716654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Our final success count will be at least this big, so we're 717654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * guaranteed to succeed. 718654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 71979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (dnsCheckSuccesses[dnsServerId] >= mMinDnsResponses) { 720654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy // DNS CHECKS OK, NOW WALLED GARDEN 721654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 7227f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log(makeLogString() + " SUCCESS"); 723654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 724654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 725654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (!shouldCheckWalledGarden()) { 726654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mOnlineWatchState); 727654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 728654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 729654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 730654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mLastWalledGardenCheckTime = SystemClock.elapsedRealtime(); 731654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (isWalledGardenConnection()) { 7327f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("Walled garden test complete - walled garden detected"); 733654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mWalledGardenState); 734654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 7357f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) log("Walled garden test complete - online"); 736654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mOnlineWatchState); 737654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 738654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 739654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 740654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 74179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (idDnsMap.isEmpty()) { 742654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 7437f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log(makeLogString() + " FAILURE"); 744654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 745654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mDnsCheckFailureState); 746654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 747654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 748654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 749654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 750654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 751654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 75279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy private String makeLogString() { 75379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy String logStr = dnsCheckLogStr; 75479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (String respStr : dnsResponseStrs) 75579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy logStr += " [" + respStr + "]"; 75679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy return logStr; 75779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 75879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy 759d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy @Override 760d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy public void exit() { 761d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy mDnsPinger.cancelPings(); 762d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 763d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy 764654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private boolean shouldCheckWalledGarden() { 765d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy if (!mWalledGardenTestEnabled) { 7667f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) 7677f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Skipping walled garden check - disabled"); 768654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return false; 769654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 770d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy long waitTime = waitTime(mWalledGardenIntervalMs, 771654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mLastWalledGardenCheckTime); 772654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (waitTime > 0) { 773654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 7747f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Skipping walled garden check - wait " + 775654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy waitTime + " ms."); 776654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 777654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return false; 778654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 779654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return true; 780654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 781654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 782654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 783654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class OnlineWatchState extends State { 784654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 785654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * Signals a short-wait message is enqueued for the current 'guard' counter 786654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 787654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy boolean unstableSignalChecks = false; 788654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 789654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 790654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * The signal is unstable. We should enqueue a short-wait check, if one is enqueued 791654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * already 792654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 793654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy boolean signalUnstable = false; 794654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 795654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 796654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * A monotonic counter to ensure that at most one check message will be processed from any 797654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * set of check messages currently enqueued. Avoids duplicate checks when a low-signal 798654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy * event is observed. 799654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 800654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy int checkGuard = 0; 801654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy Long lastCheckTime = null; 802654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 80379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy /** Keeps track of dns pings. Map is from pingID to InetAddress used for ping */ 80479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy HashMap<Integer, InetAddress> pingInfoMap = new HashMap<Integer, InetAddress>(); 805d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy 806654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 807654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 808654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy lastCheckTime = SystemClock.elapsedRealtime(); 809654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy signalUnstable = false; 810654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy checkGuard++; 811654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy unstableSignalChecks = false; 81279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.clear(); 813654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy triggerSingleDnsCheck(); 814654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 815654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 816654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 817654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 818654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy switch (msg.what) { 819654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case EVENT_RSSI_CHANGE: 820654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 821654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (DBG) { 8227f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Rssi change message out of sync, ignoring"); 823654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 824654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 825654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 826654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy int newRssi = msg.arg2; 827654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy signalUnstable = !rssiStrengthAboveCutoff(newRssi); 8287f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8297f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("OnlineWatchState:: new rssi " + newRssi + " --> level " + 830654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy WifiManager.calculateSignalLevel(newRssi, WIFI_SIGNAL_LEVELS)); 831654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 832654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 833654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (signalUnstable && !unstableSignalChecks) { 8347f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8357f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Sending triggered check msg"); 836654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 837654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy triggerSingleDnsCheck(); 838654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 839654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 840654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy case MESSAGE_SINGLE_DNS_CHECK: 841654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != checkGuard) { 8427f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8437f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Single check msg out of sync, ignoring."); 844654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 845654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 846654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 847654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy lastCheckTime = SystemClock.elapsedRealtime(); 84879e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.clear(); 84979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy for (InetAddress curDns: mDnsPinger.getDnsList()) { 85079e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.put(mDnsPinger.pingDnsAsync(curDns, mDnsPingTimeoutMs, 0), 85179e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy curDns); 85279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 853d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy return HANDLED; 854d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy case DnsPinger.DNS_PING_RESULT: 85579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy InetAddress curDnsServer = pingInfoMap.get(msg.arg1); 85679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (curDnsServer == null) { 857d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy return HANDLED; 858d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 85979e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.remove(msg.arg1); 860d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy int responseTime = msg.arg2; 861654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (responseTime >= 0) { 8627f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 8637f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Single DNS ping OK. Response time: " 86479e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy + responseTime + " from DNS " + curDnsServer); 865654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 86679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy pingInfoMap.clear(); 867654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 868654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy checkGuard++; 869654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy unstableSignalChecks = false; 870654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy triggerSingleDnsCheck(); 871654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 87279e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (pingInfoMap.isEmpty()) { 87379e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy if (DBG) { 8747f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Single dns ping failure. All dns servers failed, " 87579e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy + "starting full checks."); 87679e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy } 87779e43f679d6102066ee9eff862912806f53bb0e8Isaac Levy transitionTo(mDnsCheckingState); 878654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 879654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 880654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 881654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 882654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 883654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 884654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 885d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy @Override 886d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy public void exit() { 887d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy mDnsPinger.cancelPings(); 888d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy } 889d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy 890654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy /** 891d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Times a dns check with an interval based on {@link #signalUnstable} 892654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy */ 893654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy private void triggerSingleDnsCheck() { 894654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy long waitInterval; 895654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (signalUnstable) { 896d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy waitInterval = mDnsCheckShortIntervalMs; 897654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy unstableSignalChecks = true; 898654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 899d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy waitInterval = mDnsCheckLongIntervalMs; 900654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 901654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessageDelayed(obtainMessage(MESSAGE_SINGLE_DNS_CHECK, checkGuard, 0), 902654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy waitTime(waitInterval, lastCheckTime)); 903654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 904654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 905654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 906654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class DnsCheckFailureState extends State { 9074ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy 908654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 909654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 910d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mNumCheckFailures++; 911654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy obtainMessage(MESSAGE_HANDLE_BAD_AP, mNetEventCounter, 0).sendToTarget(); 912654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 913654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 914654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 915654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 916654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.what != MESSAGE_HANDLE_BAD_AP) { 917654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 918654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 919654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 920654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 9217f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 9227f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Msg out of sync, ignoring..."); 923654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 924654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 925654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 926654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 9278dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mDisableAPNextFailure || mNumCheckFailures >= mBssids.size() 9288dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy || mNumCheckFailures >= mMaxSsidBlacklists) { 9299b2886e24301e5d4e7052ec4a6eaff273d3f516cRobert Greenwalt if (sWifiOnly) { 9307f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Would disable bad network, but device has no mobile data!" + 9314ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy " Going idle..."); 9324ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy // This state should be called idle -- will be changing flow. 9334ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy transitionTo(mNotConnectedState); 9344ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy return HANDLED; 9354ad39d6ac16961df0e7a3e4b4e7075aaa5202787Isaac Levy } 9368dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy 937654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy // TODO : Unban networks if they had low signal ? 9387f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Disabling current SSID " + wifiInfoToStr(mConnectionInfo) 939d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy + ". " + "numCheckFailures " + mNumCheckFailures 940d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy + ", numAPs " + mBssids.size()); 9418dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy int networkId = mConnectionInfo.getNetworkId(); 9428dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (!mHasConnectedWifiManager) { 9438dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mWifiManager.asyncConnect(mContext, getHandler()); 9448dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mHasConnectedWifiManager = true; 9458dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy } 9468dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mWifiManager.disableNetwork(networkId, WifiConfiguration.DISABLED_DNS_FAILURE); 9478dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy if (mShowDisabledNotification && mConnectionInfo.isExplicitConnect()) { 9488dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy displayDisabledNetworkNotification(mConnectionInfo.getSSID()); 949d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 950654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mNotConnectedState); 951654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } else { 9527f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("Blacklisting current BSSID. " + wifiInfoToStr(mConnectionInfo) 953d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy + "numCheckFailures " + mNumCheckFailures + ", numAPs " + mBssids.size()); 954654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 9558dc6a1b2823f374a176fb21b8a174664a5f825faIsaac Levy mWifiManager.addToBlacklist(mConnectionInfo.getBSSID()); 956654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mWifiManager.reassociate(); 957654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mBlacklistedApState); 958654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 959654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 960654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 961654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 962654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 963654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class WalledGardenState extends State { 964654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 965654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 966654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy obtainMessage(MESSAGE_HANDLE_WALLED_GARDEN, mNetEventCounter, 0).sendToTarget(); 967654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 968654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 969654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 970654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 971654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.what != MESSAGE_HANDLE_WALLED_GARDEN) { 972654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 973654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 974654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 975654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 9767f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 9777f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("WalledGardenState::Msg out of sync, ignoring..."); 978654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 979654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 980654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 981654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy popUpBrowser(); 982654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mOnlineWatchState); 983654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 984654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 985654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 986654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 987654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy class BlacklistedApState extends State { 988654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 989654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public void enter() { 990654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy mDisableAPNextFailure = true; 991654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy sendMessageDelayed(obtainMessage(MESSAGE_NETWORK_FOLLOWUP, mNetEventCounter, 0), 992d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy mBlacklistFollowupIntervalMs); 993654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 994654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 995654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy @Override 996654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy public boolean processMessage(Message msg) { 997654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.what != MESSAGE_NETWORK_FOLLOWUP) { 998654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return NOT_HANDLED; 999654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1000654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 1001654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy if (msg.arg1 != mNetEventCounter) { 10027f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff if (DBG) { 10037f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff log("BlacklistedApState::Msg out of sync, ignoring..."); 1004654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1005654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 1006654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1007654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy 1008654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy transitionTo(mDnsCheckingState); 1009654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy return HANDLED; 1010654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1011654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy } 1012d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1013d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1014d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 1015d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Convenience function for retrieving a single secure settings value 1016d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * as a string with a default value. 1017d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1018d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param cr The ContentResolver to access. 1019d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param name The name of the setting to retrieve. 1020d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param def Value to return if the setting is not defined. 1021d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1022d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @return The setting's current value, or 'def' if it is not defined 1023d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 1024d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static String getSettingsStr(ContentResolver cr, String name, String def) { 1025d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy String v = Settings.Secure.getString(cr, name); 1026d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return v != null ? v : def; 1027d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 1028d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1029d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 1030d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Convenience function for retrieving a single secure settings value 1031d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * as a boolean. Note that internally setting values are always 1032d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * stored as strings; this function converts the string to a boolean 1033d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * for you. The default value will be returned if the setting is 1034d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * not defined or not a valid boolean. 1035d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1036d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param cr The ContentResolver to access. 1037d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param name The name of the setting to retrieve. 1038d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param def Value to return if the setting is not defined. 1039d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1040d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @return The setting's current value, or 'def' if it is not defined 1041d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * or not a valid boolean. 1042d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 1043d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static boolean getSettingsBoolean(ContentResolver cr, String name, boolean def) { 1044d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return Settings.Secure.getInt(cr, name, def ? 1 : 0) == 1; 1045d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 1046d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 1047d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy /** 1048d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * Convenience function for updating a single settings value as an 1049d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * integer. This will either create a new entry in the table if the 1050d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * given name does not exist, or modify the value of the existing row 1051d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * with that name. Note that internally setting values are always 1052d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * stored as strings, so this function converts the given value to a 1053d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * string before storing it. 1054d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * 1055d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param cr The ContentResolver to access. 1056d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param name The name of the setting to modify. 1057d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @param value The new value for the setting. 1058d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy * @return true if the value was set, false on database errors 1059d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy */ 1060d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy private static boolean putSettingsBoolean(ContentResolver cr, String name, boolean value) { 1061d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy return Settings.Secure.putInt(cr, name, value ? 1 : 0); 1062d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy } 1063d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 10647f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff private void log(String s) { 10657f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff Log.d(TAG, s); 10667f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff } 1067d7b3e6a39b6b2e155b24ef470023bafb3b9fa35aIsaac Levy 10687f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff private void loge(String s) { 10697f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff Log.e(TAG, s); 10707f8a12c75cf2b376fce58fc22b5ecb1b64acf110Irfan Sheriff } 1071654f5090754e4e1bf4c1736d0a24769a15a6037eIsaac Levy} 1072