Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 338241de authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by android-build-merger
Browse files

Rename AvoidBadWifiTracker to MultinetworkPolicyTracker am: 58ebe1c6

am: 0bc8070f

Change-Id: I0ff0169ebc5e53cc9f57f224225fb0c93dc241ed
parents 94380838 0bc8070f
Loading
Loading
Loading
Loading
+11 −11
Original line number Original line Diff line number Diff line
@@ -78,7 +78,7 @@ import android.net.Uri;
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.DefaultNetworkEvent;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.metrics.NetworkEvent;
import android.net.util.AvoidBadWifiTracker;
import android.net.util.MultinetworkPolicyTracker;
import android.os.Binder;
import android.os.Binder;
import android.os.Build;
import android.os.Build;
import android.os.Bundle;
import android.os.Bundle;
@@ -499,7 +499,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
    private final IpConnectivityLog mMetricsLog;
    private final IpConnectivityLog mMetricsLog;


    @VisibleForTesting
    @VisibleForTesting
    final AvoidBadWifiTracker mAvoidBadWifiTracker;
    final MultinetworkPolicyTracker mMultinetworkPolicyTracker;


    /**
    /**
     * Implements support for the legacy "one network per network type" model.
     * Implements support for the legacy "one network per network type" model.
@@ -849,9 +849,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
                LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
                LingerMonitor.DEFAULT_NOTIFICATION_RATE_LIMIT_MILLIS);
        mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);
        mLingerMonitor = new LingerMonitor(mContext, mNotifier, dailyLimit, rateLimit);


        mAvoidBadWifiTracker = createAvoidBadWifiTracker(
        mMultinetworkPolicyTracker = createMultinetworkPolicyTracker(
                mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
                mContext, mHandler, () -> rematchForAvoidBadWifiUpdate());
        mAvoidBadWifiTracker.start();
        mMultinetworkPolicyTracker.start();
    }
    }


    private NetworkRequest createInternetRequestForTransport(
    private NetworkRequest createInternetRequestForTransport(
@@ -2793,7 +2793,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
    }
    }


    public boolean avoidBadWifi() {
    public boolean avoidBadWifi() {
        return mAvoidBadWifiTracker.currentValue();
        return mMultinetworkPolicyTracker.getAvoidBadWifi();
    }
    }


    private void rematchForAvoidBadWifiUpdate() {
    private void rematchForAvoidBadWifiUpdate() {
@@ -2806,9 +2806,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
    }
    }


    // TODO: Evaluate whether this is of interest to other consumers of
    // TODO: Evaluate whether this is of interest to other consumers of
    // AvoidBadWifiTracker and worth moving out of here.
    // MultinetworkPolicyTracker and worth moving out of here.
    private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
    private void dumpAvoidBadWifiSettings(IndentingPrintWriter pw) {
        final boolean configRestrict = mAvoidBadWifiTracker.configRestrictsAvoidBadWifi();
        final boolean configRestrict = mMultinetworkPolicyTracker.configRestrictsAvoidBadWifi();
        if (!configRestrict) {
        if (!configRestrict) {
            pw.println("Bad Wi-Fi avoidance: unrestricted");
            pw.println("Bad Wi-Fi avoidance: unrestricted");
            return;
            return;
@@ -2818,7 +2818,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        pw.increaseIndent();
        pw.increaseIndent();
        pw.println("Config restrict:   " + configRestrict);
        pw.println("Config restrict:   " + configRestrict);


        final String value = mAvoidBadWifiTracker.getSettingsValue();
        final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
        String description;
        String description;
        // Can't use a switch statement because strings are legal case labels, but null is not.
        // Can't use a switch statement because strings are legal case labels, but null is not.
        if ("0".equals(value)) {
        if ("0".equals(value)) {
@@ -2886,7 +2886,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc);
        if (DBG) log("handleNetworkUnvalidated " + nai.name() + " cap=" + nc);


        if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
        if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) &&
            mAvoidBadWifiTracker.shouldNotifyWifiUnvalidated()) {
            mMultinetworkPolicyTracker.shouldNotifyWifiUnvalidated()) {
            showValidationNotification(nai, NotificationType.LOST_INTERNET);
            showValidationNotification(nai, NotificationType.LOST_INTERNET);
        }
        }
    }
    }
@@ -5534,8 +5534,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
    }
    }


    @VisibleForTesting
    @VisibleForTesting
    AvoidBadWifiTracker createAvoidBadWifiTracker(Context c, Handler h, Runnable r) {
    MultinetworkPolicyTracker createMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
        return new AvoidBadWifiTracker(c, h, r);
        return new MultinetworkPolicyTracker(c, h, r);
    }
    }


    @VisibleForTesting
    @VisibleForTesting
+7 −7
Original line number Original line Diff line number Diff line
@@ -33,7 +33,7 @@ import android.net.StaticIpConfiguration;
import android.net.dhcp.DhcpClient;
import android.net.dhcp.DhcpClient;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpManagerEvent;
import android.net.metrics.IpManagerEvent;
import android.net.util.AvoidBadWifiTracker;
import android.net.util.MultinetworkPolicyTracker;
import android.os.INetworkManagementService;
import android.os.INetworkManagementService;
import android.os.Message;
import android.os.Message;
import android.os.RemoteException;
import android.os.RemoteException;
@@ -398,7 +398,7 @@ public class IpManager extends StateMachine {
    private final NetlinkTracker mNetlinkTracker;
    private final NetlinkTracker mNetlinkTracker;
    private final WakeupMessage mProvisioningTimeoutAlarm;
    private final WakeupMessage mProvisioningTimeoutAlarm;
    private final WakeupMessage mDhcpActionTimeoutAlarm;
    private final WakeupMessage mDhcpActionTimeoutAlarm;
    private final AvoidBadWifiTracker mAvoidBadWifiTracker;
    private final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
    private final LocalLog mLocalLog;
    private final LocalLog mLocalLog;
    private final LocalLog mConnectivityPacketLog;
    private final LocalLog mConnectivityPacketLog;
    private final MessageHandlingLogger mMsgStateLogger;
    private final MessageHandlingLogger mMsgStateLogger;
@@ -492,7 +492,7 @@ public class IpManager extends StateMachine {
        mLinkProperties = new LinkProperties();
        mLinkProperties = new LinkProperties();
        mLinkProperties.setInterfaceName(mInterfaceName);
        mLinkProperties.setInterfaceName(mInterfaceName);


        mAvoidBadWifiTracker = new AvoidBadWifiTracker(mContext, getHandler(),
        mMultinetworkPolicyTracker = new MultinetworkPolicyTracker(mContext, getHandler(),
                () -> { mLocalLog.log("OBSERVED AvoidBadWifi changed"); });
                () -> { mLocalLog.log("OBSERVED AvoidBadWifi changed"); });


        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
        mProvisioningTimeoutAlarm = new WakeupMessage(mContext, getHandler(),
@@ -527,7 +527,7 @@ public class IpManager extends StateMachine {
            Log.e(mTag, "Couldn't register NetlinkTracker: " + e.toString());
            Log.e(mTag, "Couldn't register NetlinkTracker: " + e.toString());
        }
        }


        mAvoidBadWifiTracker.start();
        mMultinetworkPolicyTracker.start();
    }
    }


    @Override
    @Override
@@ -538,7 +538,7 @@ public class IpManager extends StateMachine {
    // Shut down this IpManager instance altogether.
    // Shut down this IpManager instance altogether.
    public void shutdown() {
    public void shutdown() {
        stop();
        stop();
        mAvoidBadWifiTracker.shutdown();
        mMultinetworkPolicyTracker.shutdown();
        quit();
        quit();
    }
    }


@@ -767,7 +767,7 @@ public class IpManager extends StateMachine {
        // Note that we can still be disconnected by IpReachabilityMonitor
        // Note that we can still be disconnected by IpReachabilityMonitor
        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
        // if the IPv6 default gateway (but not the IPv6 DNS servers; see
        // accompanying code in IpReachabilityMonitor) is unreachable.
        // accompanying code in IpReachabilityMonitor) is unreachable.
        final boolean ignoreIPv6ProvisioningLoss = !mAvoidBadWifiTracker.currentValue();
        final boolean ignoreIPv6ProvisioningLoss = !mMultinetworkPolicyTracker.getAvoidBadWifi();


        // Additionally:
        // Additionally:
        //
        //
@@ -1045,7 +1045,7 @@ public class IpManager extends StateMachine {
                            mCallback.onReachabilityLost(logMsg);
                            mCallback.onReachabilityLost(logMsg);
                        }
                        }
                    },
                    },
                    mAvoidBadWifiTracker);
                    mMultinetworkPolicyTracker);
        } catch (IllegalArgumentException iae) {
        } catch (IllegalArgumentException iae) {
            // Failed to start IpReachabilityMonitor. Log it and call
            // Failed to start IpReachabilityMonitor. Log it and call
            // onProvisioningFailure() immediately.
            // onProvisioningFailure() immediately.
+5 −5
Original line number Original line Diff line number Diff line
@@ -34,7 +34,7 @@ import android.net.netlink.RtNetlinkNeighborMessage;
import android.net.netlink.StructNdaCacheInfo;
import android.net.netlink.StructNdaCacheInfo;
import android.net.netlink.StructNdMsg;
import android.net.netlink.StructNdMsg;
import android.net.netlink.StructNlMsgHdr;
import android.net.netlink.StructNlMsgHdr;
import android.net.util.AvoidBadWifiTracker;
import android.net.util.MultinetworkPolicyTracker;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.SystemClock;
import android.system.ErrnoException;
import android.system.ErrnoException;
@@ -151,7 +151,7 @@ public class IpReachabilityMonitor {
    private final String mInterfaceName;
    private final String mInterfaceName;
    private final int mInterfaceIndex;
    private final int mInterfaceIndex;
    private final Callback mCallback;
    private final Callback mCallback;
    private final AvoidBadWifiTracker mAvoidBadWifiTracker;
    private final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
    private final NetlinkSocketObserver mNetlinkSocketObserver;
    private final NetlinkSocketObserver mNetlinkSocketObserver;
    private final Thread mObserverThread;
    private final Thread mObserverThread;
    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
    private final IpConnectivityLog mMetricsLog = new IpConnectivityLog();
@@ -226,7 +226,7 @@ public class IpReachabilityMonitor {
    }
    }


    public IpReachabilityMonitor(Context context, String ifName, Callback callback,
    public IpReachabilityMonitor(Context context, String ifName, Callback callback,
            AvoidBadWifiTracker tracker) throws IllegalArgumentException {
            MultinetworkPolicyTracker tracker) throws IllegalArgumentException {
        mInterfaceName = ifName;
        mInterfaceName = ifName;
        int ifIndex = -1;
        int ifIndex = -1;
        try {
        try {
@@ -238,7 +238,7 @@ public class IpReachabilityMonitor {
        mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
        mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
                PowerManager.PARTIAL_WAKE_LOCK, TAG + "." + mInterfaceName);
                PowerManager.PARTIAL_WAKE_LOCK, TAG + "." + mInterfaceName);
        mCallback = callback;
        mCallback = callback;
        mAvoidBadWifiTracker = tracker;
        mMultinetworkPolicyTracker = tracker;
        mNetlinkSocketObserver = new NetlinkSocketObserver();
        mNetlinkSocketObserver = new NetlinkSocketObserver();
        mObserverThread = new Thread(mNetlinkSocketObserver);
        mObserverThread = new Thread(mNetlinkSocketObserver);
        mObserverThread.start();
        mObserverThread.start();
@@ -379,7 +379,7 @@ public class IpReachabilityMonitor {
    }
    }


    private boolean avoidingBadLinks() {
    private boolean avoidingBadLinks() {
        return (mAvoidBadWifiTracker != null) ? mAvoidBadWifiTracker.currentValue() : true;
        return (mMultinetworkPolicyTracker == null) || mMultinetworkPolicyTracker.getAvoidBadWifi();
    }
    }


    public void probeAll() {
    public void probeAll() {
+19 −17
Original line number Original line Diff line number Diff line
@@ -42,8 +42,8 @@ import static android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI;
 * This enables the device to switch to another form of connectivity, like
 * This enables the device to switch to another form of connectivity, like
 * mobile, if it's available and working.
 * mobile, if it's available and working.
 *
 *
 * The Runnable |cb|, if given, is called on the supplied Handler's thread
 * The Runnable |avoidBadWifiCallback|, if given, is posted to the supplied
 * whether the computed "avoid bad wifi" value changes.
 * Handler' whenever the computed "avoid bad wifi" value changes.
 *
 *
 * Disabling this reverts the device to a level of networking sophistication
 * Disabling this reverts the device to a level of networking sophistication
 * circa 2012-13 by disabling disparate code paths each of which contribute to
 * circa 2012-13 by disabling disparate code paths each of which contribute to
@@ -51,28 +51,30 @@ import static android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI;
 *
 *
 * @hide
 * @hide
 */
 */
public class AvoidBadWifiTracker {
public class MultinetworkPolicyTracker {
    private static String TAG = AvoidBadWifiTracker.class.getSimpleName();
    private static String TAG = MultinetworkPolicyTracker.class.getSimpleName();


    private final Context mContext;
    private final Context mContext;
    private final Handler mHandler;
    private final Handler mHandler;
    private final Runnable mReevaluateRunnable;
    private final Runnable mReevaluateRunnable;
    private final Uri mUri;
    private final Uri mAvoidBadWifiUri;
    private final ContentResolver mResolver;
    private final ContentResolver mResolver;
    private final SettingObserver mSettingObserver;
    private final SettingObserver mSettingObserver;
    private final BroadcastReceiver mBroadcastReceiver;
    private final BroadcastReceiver mBroadcastReceiver;


    private volatile boolean mAvoidBadWifi = true;
    private volatile boolean mAvoidBadWifi = true;


    public AvoidBadWifiTracker(Context ctx, Handler handler) {
    public MultinetworkPolicyTracker(Context ctx, Handler handler) {
        this(ctx, handler, null);
        this(ctx, handler, null);
    }
    }


    public AvoidBadWifiTracker(Context ctx, Handler handler, Runnable cb) {
    public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) {
        mContext = ctx;
        mContext = ctx;
        mHandler = handler;
        mHandler = handler;
        mReevaluateRunnable = () -> { if (update() && cb != null) cb.run(); };
        mReevaluateRunnable = () -> {
        mUri = Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI);
            if (updateAvoidBadWifi() && avoidBadWifiCallback != null) avoidBadWifiCallback.run();
        };
        mAvoidBadWifiUri = Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI);
        mResolver = mContext.getContentResolver();
        mResolver = mContext.getContentResolver();
        mSettingObserver = new SettingObserver();
        mSettingObserver = new SettingObserver();
        mBroadcastReceiver = new BroadcastReceiver() {
        mBroadcastReceiver = new BroadcastReceiver() {
@@ -82,11 +84,11 @@ public class AvoidBadWifiTracker {
            }
            }
        };
        };


        update();
        updateAvoidBadWifi();
    }
    }


    public void start() {
    public void start() {
        mResolver.registerContentObserver(mUri, false, mSettingObserver);
        mResolver.registerContentObserver(mAvoidBadWifiUri, false, mSettingObserver);


        final IntentFilter intentFilter = new IntentFilter();
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
        intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
@@ -102,7 +104,7 @@ public class AvoidBadWifiTracker {
        mContext.unregisterReceiver(mBroadcastReceiver);
        mContext.unregisterReceiver(mBroadcastReceiver);
    }
    }


    public boolean currentValue() {
    public boolean getAvoidBadWifi() {
        return mAvoidBadWifi;
        return mAvoidBadWifi;
    }
    }


@@ -117,10 +119,10 @@ public class AvoidBadWifiTracker {
     * Whether we should display a notification when wifi becomes unvalidated.
     * Whether we should display a notification when wifi becomes unvalidated.
     */
     */
    public boolean shouldNotifyWifiUnvalidated() {
    public boolean shouldNotifyWifiUnvalidated() {
        return configRestrictsAvoidBadWifi() && getSettingsValue() == null;
        return configRestrictsAvoidBadWifi() && getAvoidBadWifiSetting() == null;
    }
    }


    public String getSettingsValue() {
    public String getAvoidBadWifiSetting() {
        return Settings.Global.getString(mResolver, NETWORK_AVOID_BAD_WIFI);
        return Settings.Global.getString(mResolver, NETWORK_AVOID_BAD_WIFI);
    }
    }


@@ -129,8 +131,8 @@ public class AvoidBadWifiTracker {
        mHandler.post(mReevaluateRunnable);
        mHandler.post(mReevaluateRunnable);
    }
    }


    public boolean update() {
    public boolean updateAvoidBadWifi() {
        final boolean settingAvoidBadWifi = "1".equals(getSettingsValue());
        final boolean settingAvoidBadWifi = "1".equals(getAvoidBadWifiSetting());
        final boolean prev = mAvoidBadWifi;
        final boolean prev = mAvoidBadWifi;
        mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
        mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
        return mAvoidBadWifi != prev;
        return mAvoidBadWifi != prev;
@@ -148,7 +150,7 @@ public class AvoidBadWifiTracker {


        @Override
        @Override
        public void onChange(boolean selfChange, Uri uri) {
        public void onChange(boolean selfChange, Uri uri) {
            if (!mUri.equals(uri)) return;
            if (!mAvoidBadWifiUri.equals(uri)) return;
            reevaluate();
            reevaluate();
        }
        }
    }
    }
+10 −10
Original line number Original line Diff line number Diff line
@@ -53,7 +53,7 @@ import android.net.NetworkMisc;
import android.net.NetworkRequest;
import android.net.NetworkRequest;
import android.net.RouteInfo;
import android.net.RouteInfo;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpConnectivityLog;
import android.net.util.AvoidBadWifiTracker;
import android.net.util.MultinetworkPolicyTracker;
import android.os.ConditionVariable;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.HandlerThread;
@@ -593,10 +593,10 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        }
        }
    }
    }


    private class WrappedAvoidBadWifiTracker extends AvoidBadWifiTracker {
    private class WrappedMultinetworkPolicyTracker extends MultinetworkPolicyTracker {
        public volatile boolean configRestrictsAvoidBadWifi;
        public volatile boolean configRestrictsAvoidBadWifi;


        public WrappedAvoidBadWifiTracker(Context c, Handler h, Runnable r) {
        public WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
            super(c, h, r);
            super(c, h, r);
        }
        }


@@ -607,7 +607,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
    }
    }


    private class WrappedConnectivityService extends ConnectivityService {
    private class WrappedConnectivityService extends ConnectivityService {
        public WrappedAvoidBadWifiTracker wrappedAvoidBadWifiTracker;
        public WrappedMultinetworkPolicyTracker wrappedMultinetworkPolicyTracker;
        private WrappedNetworkMonitor mLastCreatedNetworkMonitor;
        private WrappedNetworkMonitor mLastCreatedNetworkMonitor;


        public WrappedConnectivityService(Context context, INetworkManagementService netManager,
        public WrappedConnectivityService(Context context, INetworkManagementService netManager,
@@ -654,14 +654,14 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        }
        }


        @Override
        @Override
        public AvoidBadWifiTracker createAvoidBadWifiTracker(
        public MultinetworkPolicyTracker createMultinetworkPolicyTracker(
                Context c, Handler h, Runnable r) {
                Context c, Handler h, Runnable r) {
            final WrappedAvoidBadWifiTracker tracker = new WrappedAvoidBadWifiTracker(c, h, r);
            final WrappedMultinetworkPolicyTracker tracker = new WrappedMultinetworkPolicyTracker(c, h, r);
            return tracker;
            return tracker;
        }
        }


        public WrappedAvoidBadWifiTracker getAvoidBadWifiTracker() {
        public WrappedMultinetworkPolicyTracker getMultinetworkPolicyTracker() {
            return (WrappedAvoidBadWifiTracker) mAvoidBadWifiTracker;
            return (WrappedMultinetworkPolicyTracker) mMultinetworkPolicyTracker;
        }
        }


        @Override
        @Override
@@ -2140,7 +2140,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
    @SmallTest
    @SmallTest
    public void testAvoidBadWifiSetting() throws Exception {
    public void testAvoidBadWifiSetting() throws Exception {
        final ContentResolver cr = mServiceContext.getContentResolver();
        final ContentResolver cr = mServiceContext.getContentResolver();
        final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
        final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();
        final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
        final String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;


        tracker.configRestrictsAvoidBadWifi = false;
        tracker.configRestrictsAvoidBadWifi = false;
@@ -2178,7 +2178,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
    @SmallTest
    @SmallTest
    public void testAvoidBadWifi() throws Exception {
    public void testAvoidBadWifi() throws Exception {
        final ContentResolver cr = mServiceContext.getContentResolver();
        final ContentResolver cr = mServiceContext.getContentResolver();
        final WrappedAvoidBadWifiTracker tracker = mService.getAvoidBadWifiTracker();
        final WrappedMultinetworkPolicyTracker tracker = mService.getMultinetworkPolicyTracker();


        // Pretend we're on a carrier that restricts switching away from bad wifi.
        // Pretend we're on a carrier that restricts switching away from bad wifi.
        tracker.configRestrictsAvoidBadWifi = true;
        tracker.configRestrictsAvoidBadWifi = true;