From d747cbc898ef44e59c3fbf74a8327b6a12aad397 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Wed, 7 Aug 2013 16:22:47 -0700 Subject: [PATCH] If in a mobile captive portal is detected enable fail fast. When captive portal checking completes pass back the result. This is used to enable/disable failing fast for mobile. When failing fast is enabled we don't check for data stalls and thus won't be continually trying to do recovery operations, such as restarting the radio. Bug: 9462512 Change-Id: I0dea0eee519f8ee7f94e79d40e82c18f30d7fe2e --- .../BluetoothTetheringDataTracker.java | 5 +++++ .../android/net/BaseNetworkStateTracker.java | 5 +++++ .../android/net/CaptivePortalTracker.java | 15 +++++++++++++++ .../java/android/net/ConnectivityManager.java | 19 +++++++++++++++++++ .../android/net/DummyDataStateTracker.java | 6 ++++++ .../java/android/net/EthernetDataTracker.java | 5 +++++ .../android/net/IConnectivityManager.aidl | 2 ++ .../android/net/MobileDataStateTracker.java | 12 ++++++++++++ .../java/android/net/NetworkStateTracker.java | 5 +++++ .../android/server/ConnectivityService.java | 11 +++++++++++ .../android/net/wifi/WifiStateMachine.java | 6 ++++++ .../android/net/wifi/WifiStateTracker.java | 5 +++++ 12 files changed, 96 insertions(+) diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java index 81c0a6a87eaf2..0aedecb82dd2b 100644 --- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java +++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java @@ -152,6 +152,11 @@ public class BluetoothTetheringDataTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Re-enable connectivity to a network after a {@link #teardown()}. */ diff --git a/core/java/android/net/BaseNetworkStateTracker.java b/core/java/android/net/BaseNetworkStateTracker.java index 1165281e39bb7..e87f84c56a21c 100644 --- a/core/java/android/net/BaseNetworkStateTracker.java +++ b/core/java/android/net/BaseNetworkStateTracker.java @@ -101,6 +101,11 @@ public abstract class BaseNetworkStateTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + @Override public boolean setRadio(boolean turnOn) { // Base tracker doesn't handle radios diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java index 21995c021ca50..e3662beb8150a 100644 --- a/core/java/android/net/CaptivePortalTracker.java +++ b/core/java/android/net/CaptivePortalTracker.java @@ -270,6 +270,7 @@ public class CaptivePortalTracker extends StateMachine { } else { if (DBG) log("Not captive network " + mNetworkInfo); } + notifyPortalCheckCompleted(mNetworkInfo, captive); if (mDeviceProvisioned) { if (captive) { // Setup Wizard will assist the user in connecting to a captive @@ -300,12 +301,26 @@ public class CaptivePortalTracker extends StateMachine { return; } try { + if (DBG) log("notifyPortalCheckComplete: ni=" + info); mConnService.captivePortalCheckComplete(info); } catch(RemoteException e) { e.printStackTrace(); } } + private void notifyPortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) { + if (info == null) { + loge("notifyPortalCheckComplete on null"); + return; + } + try { + if (DBG) log("notifyPortalCheckCompleted: captive=" + isCaptivePortal + " ni=" + info); + mConnService.captivePortalCheckCompleted(info, isCaptivePortal); + } catch(RemoteException e) { + e.printStackTrace(); + } + } + private boolean isActiveNetwork(NetworkInfo info) { try { NetworkInfo active = mConnService.getActiveNetworkInfo(); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 697bde99a2d1f..855a2ef93ba56 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -1282,6 +1282,25 @@ public class ConnectivityManager { } } + /** + * Signal that the captive portal check on the indicated network + * is complete and whether its a captive portal or not. + * + * @param info the {@link NetworkInfo} object for the networkType + * in question. + * @param isCaptivePortal true/false. + * + *

This method requires the call to hold the permission + * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}. + * {@hide} + */ + public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) { + try { + mService.captivePortalCheckCompleted(info, isCaptivePortal); + } catch (RemoteException e) { + } + } + /** * Supply the backend messenger for a network tracker * diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java index 15a81f3e45e8b..ee738fd9c715e 100644 --- a/core/java/android/net/DummyDataStateTracker.java +++ b/core/java/android/net/DummyDataStateTracker.java @@ -120,10 +120,16 @@ public class DummyDataStateTracker implements NetworkStateTracker { return true; } + @Override public void captivePortalCheckComplete() { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Record the detailed state of a network, and if it is a * change from the previous state, send a notification to diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java index 27d5a58e49188..ac2b0d9a8bd4f 100644 --- a/core/java/android/net/EthernetDataTracker.java +++ b/core/java/android/net/EthernetDataTracker.java @@ -279,6 +279,11 @@ public class EthernetDataTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Turn the wireless radio off for a network. * @param turnOn {@code true} to turn the radio on, {@code false} diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index 4600c1a4dc27e..45bb184e48e46 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -129,6 +129,8 @@ interface IConnectivityManager void captivePortalCheckComplete(in NetworkInfo info); + void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal); + void supplyMessenger(int networkType, in Messenger messenger); int findConnectionTypeForIface(in String iface); diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 5a1daed9511a8..adad8decca897 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -40,6 +40,7 @@ import com.android.internal.util.AsyncChannel; import java.io.CharArrayWriter; import java.io.PrintWriter; +import java.util.concurrent.atomic.AtomicBoolean; /** * Track the state of mobile data connectivity. This is done by @@ -75,6 +76,8 @@ public class MobileDataStateTracker implements NetworkStateTracker { private Handler mHandler; private AsyncChannel mDataConnectionTrackerAc; + private AtomicBoolean mIsCaptivePortal = new AtomicBoolean(false); + /** * Create a new MobileDataStateTracker * @param netType the ConnectivityManager network type @@ -377,6 +380,15 @@ public class MobileDataStateTracker implements NetworkStateTracker { // not implemented } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + if (mIsCaptivePortal.getAndSet(isCaptivePortal) != isCaptivePortal) { + // Captive portal change enable/disable failing fast + setEnableFailFastMobileData( + isCaptivePortal ? DctConstants.ENABLED : DctConstants.DISABLED); + } + } + /** * Record the detailed state of a network, and if it is a * change from the previous state, send a notification to diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java index cf77a1cdbe617..9ed7533719073 100644 --- a/core/java/android/net/NetworkStateTracker.java +++ b/core/java/android/net/NetworkStateTracker.java @@ -143,6 +143,11 @@ public interface NetworkStateTracker { */ public void captivePortalCheckComplete(); + /** + * Captive portal check has completed + */ + public void captivePortalCheckCompleted(boolean isCaptive); + /** * Turn the wireless radio off for a network. * @param turnOn {@code true} to turn the radio on, {@code false} diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index cb4e89cc0f38c..f3dc7257f9589 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -2169,15 +2169,26 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } + if (DBG) log("handleCaptivePortalTrackerCheck: call captivePortalCheckComplete ni=" + info); thisNet.captivePortalCheckComplete(); } /** @hide */ + @Override public void captivePortalCheckComplete(NetworkInfo info) { enforceConnectivityInternalPermission(); + if (DBG) log("captivePortalCheckComplete: ni=" + info); mNetTrackers[info.getType()].captivePortalCheckComplete(); } + /** @hide */ + @Override + public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) { + enforceConnectivityInternalPermission(); + if (DBG) log("captivePortalCheckCompleted: ni=" + info + " captive=" + isCaptivePortal); + mNetTrackers[info.getType()].captivePortalCheckCompleted(isCaptivePortal); + } + /** * Setup data activity tracking for the given network interface. * diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 007735459aa78..6589ff5a83366 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -3166,6 +3166,7 @@ public class WifiStateMachine extends StateMachine { class VerifyingLinkState extends State { @Override public void enter() { + log(getName() + " enter"); setNetworkDetailedState(DetailedState.VERIFYING_POOR_LINK); mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.VERIFYING_POOR_LINK); sendNetworkStateChangeBroadcast(mLastBssid); @@ -3175,11 +3176,14 @@ public class WifiStateMachine extends StateMachine { switch (message.what) { case WifiWatchdogStateMachine.POOR_LINK_DETECTED: //stay here + log(getName() + " POOR_LINK_DETECTED: no transition"); break; case WifiWatchdogStateMachine.GOOD_LINK_DETECTED: + log(getName() + " GOOD_LINK_DETECTED: transition to captive portal check"); transitionTo(mCaptivePortalCheckState); break; default: + log(getName() + " what=" + message.what + " NOT_HANDLED"); return NOT_HANDLED; } return HANDLED; @@ -3189,6 +3193,7 @@ public class WifiStateMachine extends StateMachine { class CaptivePortalCheckState extends State { @Override public void enter() { + log(getName() + " enter"); setNetworkDetailedState(DetailedState.CAPTIVE_PORTAL_CHECK); mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CAPTIVE_PORTAL_CHECK); sendNetworkStateChangeBroadcast(mLastBssid); @@ -3197,6 +3202,7 @@ public class WifiStateMachine extends StateMachine { public boolean processMessage(Message message) { switch (message.what) { case CMD_CAPTIVE_CHECK_COMPLETE: + log(getName() + " CMD_CAPTIVE_CHECK_COMPLETE"); try { mNwService.enableIpv6(mInterfaceName); } catch (RemoteException re) { diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index cf75381e6c454..461dedb8a04bd 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -120,6 +120,11 @@ public class WifiStateTracker implements NetworkStateTracker { mWifiManager.captivePortalCheckComplete(); } + @Override + public void captivePortalCheckCompleted(boolean isCaptivePortal) { + // not implemented + } + /** * Turn the wireless radio off for a network. * @param turnOn {@code true} to turn the radio on, {@code false}