diff --git a/core/java/android/net/BaseNetworkStateTracker.java b/core/java/android/net/BaseNetworkStateTracker.java
deleted file mode 100644
index e4e5b1e..0000000
--- a/core/java/android/net/BaseNetworkStateTracker.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Messenger;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import com.android.internal.util.Preconditions;
-
-/**
- * Interface to control and observe state of a specific network, hiding
- * network-specific details from {@link ConnectivityManager}. Surfaces events
- * through the registered {@link Handler} to enable {@link ConnectivityManager}
- * to respond to state changes over time.
- *
- * @hide
- */
-public abstract class BaseNetworkStateTracker implements NetworkStateTracker {
-    // TODO: better document threading expectations
-    // TODO: migrate to make NetworkStateTracker abstract class
-
-    public static final String PROP_TCP_BUFFER_UNKNOWN = "net.tcp.buffersize.unknown";
-    public static final String PROP_TCP_BUFFER_WIFI = "net.tcp.buffersize.wifi";
-
-    protected Context mContext;
-    private Handler mTarget;
-
-    protected NetworkInfo mNetworkInfo;
-    protected LinkProperties mLinkProperties;
-    protected NetworkCapabilities mNetworkCapabilities;
-    protected Network mNetwork = new Network(ConnectivityManager.NETID_UNSET);
-
-    private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
-    private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
-    private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
-
-    public BaseNetworkStateTracker(int networkType) {
-        mNetworkInfo = new NetworkInfo(
-                networkType, -1, ConnectivityManager.getNetworkTypeName(networkType), null);
-        mLinkProperties = new LinkProperties();
-        mNetworkCapabilities = new NetworkCapabilities();
-    }
-
-    protected BaseNetworkStateTracker() {
-        // By default, let the sub classes construct everything
-    }
-
-    @Deprecated
-    protected Handler getTargetHandler() {
-        return mTarget;
-    }
-
-    protected final void dispatchStateChanged() {
-        // TODO: include snapshot of other fields when sending
-        mTarget.obtainMessage(EVENT_STATE_CHANGED, getNetworkInfo()).sendToTarget();
-    }
-
-    protected final void dispatchConfigurationChanged() {
-        // TODO: include snapshot of other fields when sending
-        mTarget.obtainMessage(EVENT_CONFIGURATION_CHANGED, getNetworkInfo()).sendToTarget();
-    }
-
-    @Override
-    public void startMonitoring(Context context, Handler target) {
-        mContext = Preconditions.checkNotNull(context);
-        mTarget = Preconditions.checkNotNull(target);
-        startMonitoringInternal();
-    }
-
-    protected void startMonitoringInternal() {
-
-    }
-
-    @Override
-    public NetworkInfo getNetworkInfo() {
-        return new NetworkInfo(mNetworkInfo);
-    }
-
-    @Override
-    public LinkProperties getLinkProperties() {
-        return new LinkProperties(mLinkProperties);
-    }
-
-    @Override
-    public NetworkCapabilities getNetworkCapabilities() {
-        return new NetworkCapabilities(mNetworkCapabilities);
-    }
-
-    @Override
-    public LinkQualityInfo getLinkQualityInfo() {
-        return null;
-    }
-
-    @Override
-    public void captivePortalCheckCompleted(boolean isCaptivePortal) {
-        // not implemented
-    }
-
-    @Override
-    public boolean setRadio(boolean turnOn) {
-        // Base tracker doesn't handle radios
-        return true;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return mNetworkInfo.isAvailable();
-    }
-
-    @Override
-    public void setUserDataEnable(boolean enabled) {
-        // Base tracker doesn't handle enabled flags
-    }
-
-    @Override
-    public void setPolicyDataEnable(boolean enabled) {
-        // Base tracker doesn't handle enabled flags
-    }
-
-    @Override
-    public boolean isPrivateDnsRouteSet() {
-        return mPrivateDnsRouteSet.get();
-    }
-
-    @Override
-    public void privateDnsRouteSet(boolean enabled) {
-        mPrivateDnsRouteSet.set(enabled);
-    }
-
-    @Override
-    public boolean isDefaultRouteSet() {
-        return mDefaultRouteSet.get();
-    }
-
-    @Override
-    public void defaultRouteSet(boolean enabled) {
-        mDefaultRouteSet.set(enabled);
-    }
-
-    @Override
-    public boolean isTeardownRequested() {
-        return mTeardownRequested.get();
-    }
-
-    @Override
-    public void setTeardownRequested(boolean isRequested) {
-        mTeardownRequested.set(isRequested);
-    }
-
-    @Override
-    public void setDependencyMet(boolean met) {
-        // Base tracker doesn't handle dependencies
-    }
-
-    @Override
-    public void supplyMessenger(Messenger messenger) {
-        // not supported on this network
-    }
-
-    @Override
-    public String getNetworkInterfaceName() {
-        if (mLinkProperties != null) {
-            return mLinkProperties.getInterfaceName();
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public void startSampling(SamplingDataTracker.SamplingSnapshot s) {
-        // nothing to do
-    }
-
-    @Override
-    public void stopSampling(SamplingDataTracker.SamplingSnapshot s) {
-        // nothing to do
-    }
-
-    @Override
-    public void setNetId(int netId) {
-        mNetwork = new Network(netId);
-    }
-
-    @Override
-    public Network getNetwork() {
-        return mNetwork;
-    }
-}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3b0d567..a00246f 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1793,25 +1793,6 @@
     }
 
     /**
-     * Sets a secondary requirement bit for the given networkType.
-     * This requirement bit is generally under the control of the carrier
-     * or its agents and is not directly controlled by the user.
-     *
-     * @param networkType The network who's dependence has changed
-     * @param met Boolean - true if network use is OK, false if not
-     *
-     * <p>This method requires the call to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
-     * {@hide}
-     */
-    public void setDataDependency(int networkType, boolean met) {
-        try {
-            mService.setDataDependency(networkType, met);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
      * Returns true if the hardware supports the given network type
      * else it returns false.  This doesn't indicate we have coverage
      * or are authorized onto a network, just whether or not the
@@ -1892,20 +1873,6 @@
     }
 
     /**
-     * Supply the backend messenger for a network tracker
-     *
-     * @param networkType NetworkType to set
-     * @param messenger {@link Messenger}
-     * {@hide}
-     */
-    public void supplyMessenger(int networkType, Messenger messenger) {
-        try {
-            mService.supplyMessenger(networkType, messenger);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
      * Check mobile provisioning.
      *
      * @param suggestedTimeOutMs, timeout in milliseconds
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 46af112..d8852f8 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -102,8 +102,6 @@
 
     ProxyInfo getDefaultProxy();
 
-    void setDataDependency(int networkType, boolean met);
-
     boolean prepareVpn(String oldPackage, String newPackage);
 
     void setVpnPackageAuthorization(boolean authorized);
@@ -120,8 +118,6 @@
 
     void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
 
-    void supplyMessenger(int networkType, in Messenger messenger);
-
     int findConnectionTypeForIface(in String iface);
 
     int checkMobileProvisioning(int suggestedTimeOutMs);
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
deleted file mode 100644
index abbb7b8..0000000
--- a/core/java/android/net/MobileDataStateTracker.java
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.NetworkInfo.DetailedState;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.telephony.PhoneStateListener;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Slog;
-
-import com.android.internal.telephony.DctConstants;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-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
- * receiving broadcast intents from the Phone process whenever
- * the state of data connectivity changes.
- *
- * {@hide}
- */
-public class MobileDataStateTracker extends BaseNetworkStateTracker {
-
-    private static final String TAG = "MobileDataStateTracker";
-    private static final boolean DBG = false;
-    private static final boolean VDBG = false;
-
-    private PhoneConstants.DataState mMobileDataState;
-    private ITelephony mPhoneService;
-
-    private String mApnType;
-    private NetworkInfo mNetworkInfo;
-    private boolean mTeardownRequested = false;
-    private Handler mTarget;
-    private Context mContext;
-    private LinkProperties mLinkProperties;
-    private boolean mPrivateDnsRouteSet = false;
-    private boolean mDefaultRouteSet = false;
-
-    // NOTE: these are only kept for debugging output; actual values are
-    // maintained in DataConnectionTracker.
-    protected boolean mUserDataEnabled = true;
-    protected boolean mPolicyDataEnabled = true;
-
-    private Handler mHandler;
-    private AsyncChannel mDataConnectionTrackerAc;
-
-    private AtomicBoolean mIsCaptivePortal = new AtomicBoolean(false);
-
-    private SignalStrength mSignalStrength;
-
-    private SamplingDataTracker mSamplingDataTracker = new SamplingDataTracker();
-
-    private static final int UNKNOWN = LinkQualityInfo.UNKNOWN_INT;
-
-    /**
-     * Create a new MobileDataStateTracker
-     * @param netType the ConnectivityManager network type
-     * @param tag the name of this network
-     */
-    public MobileDataStateTracker(int netType, String tag) {
-        mNetworkInfo = new NetworkInfo(netType,
-                TelephonyManager.getDefault().getNetworkType(), tag,
-                TelephonyManager.getDefault().getNetworkTypeName());
-        mApnType = networkTypeToApnType(netType);
-    }
-
-    /**
-     * Begin monitoring data connectivity.
-     *
-     * @param context is the current Android context
-     * @param target is the Hander to which to return the events.
-     */
-    public void startMonitoring(Context context, Handler target) {
-        mTarget = target;
-        mContext = context;
-
-        mHandler = new MdstHandler(target.getLooper(), this);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
-        filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN);
-        filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
-
-        mContext.registerReceiver(new MobileDataStateReceiver(), filter);
-        mMobileDataState = PhoneConstants.DataState.DISCONNECTED;
-
-        TelephonyManager tm = (TelephonyManager)mContext.getSystemService(
-                Context.TELEPHONY_SERVICE);
-        tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
-    }
-
-    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-        @Override
-        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
-            mSignalStrength = signalStrength;
-        }
-    };
-
-    static class MdstHandler extends Handler {
-        private MobileDataStateTracker mMdst;
-
-        MdstHandler(Looper looper, MobileDataStateTracker mdst) {
-            super(looper);
-            mMdst = mdst;
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        if (VDBG) {
-                            mMdst.log("MdstHandler connected");
-                        }
-                        mMdst.mDataConnectionTrackerAc = (AsyncChannel) msg.obj;
-                    } else {
-                        if (VDBG) {
-                            mMdst.log("MdstHandler %s NOT connected error=" + msg.arg1);
-                        }
-                    }
-                    break;
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                    if (VDBG) mMdst.log("Disconnected from DataStateTracker");
-                    mMdst.mDataConnectionTrackerAc = null;
-                    break;
-                default: {
-                    if (VDBG) mMdst.log("Ignorning unknown message=" + msg);
-                    break;
-                }
-            }
-        }
-    }
-
-    public boolean isPrivateDnsRouteSet() {
-        return mPrivateDnsRouteSet;
-    }
-
-    public void privateDnsRouteSet(boolean enabled) {
-        mPrivateDnsRouteSet = enabled;
-    }
-
-    public NetworkInfo getNetworkInfo() {
-        return mNetworkInfo;
-    }
-
-    public boolean isDefaultRouteSet() {
-        return mDefaultRouteSet;
-    }
-
-    public void defaultRouteSet(boolean enabled) {
-        mDefaultRouteSet = enabled;
-    }
-
-    /**
-     * This is not implemented.
-     */
-    public void releaseWakeLock() {
-    }
-
-    private void updateLinkProperitesAndCapatilities(Intent intent) {
-        mLinkProperties = intent.getParcelableExtra(
-                PhoneConstants.DATA_LINK_PROPERTIES_KEY);
-        if (mLinkProperties == null) {
-            loge("CONNECTED event did not supply link properties.");
-            mLinkProperties = new LinkProperties();
-        }
-        mLinkProperties.setMtu(mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_mobile_mtu));
-        mNetworkCapabilities = intent.getParcelableExtra(
-                PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY);
-        if (mNetworkCapabilities == null) {
-            loge("CONNECTED event did not supply network capabilities.");
-            mNetworkCapabilities = new NetworkCapabilities();
-        }
-    }
-
-    private class MobileDataStateReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(TelephonyIntents.
-                    ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN)) {
-                String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
-                String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
-                if (!TextUtils.equals(mApnType, apnType)) {
-                    return;
-                }
-                if (DBG) {
-                    log("Broadcast received: " + intent.getAction() + " apnType=" + apnType
-                            + " apnName=" + apnName);
-                }
-
-                // Make us in the connecting state until we make a new TYPE_MOBILE_PROVISIONING
-                mMobileDataState = PhoneConstants.DataState.CONNECTING;
-                updateLinkProperitesAndCapatilities(intent);
-                mNetworkInfo.setIsConnectedToProvisioningNetwork(true);
-
-                // Change state to SUSPENDED so setDetailedState
-                // sends EVENT_STATE_CHANGED to connectivityService
-                setDetailedState(DetailedState.SUSPENDED, "", apnName);
-            } else if (intent.getAction().equals(TelephonyIntents.
-                    ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
-                String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
-                if (VDBG) {
-                    log(String.format("Broadcast received: ACTION_ANY_DATA_CONNECTION_STATE_CHANGED"
-                        + "mApnType=%s %s received apnType=%s", mApnType,
-                        TextUtils.equals(apnType, mApnType) ? "==" : "!=", apnType));
-                }
-                if (!TextUtils.equals(apnType, mApnType)) {
-                    return;
-                }
-                // Assume this isn't a provisioning network.
-                mNetworkInfo.setIsConnectedToProvisioningNetwork(false);
-                if (DBG) {
-                    log("Broadcast received: " + intent.getAction() + " apnType=" + apnType);
-                }
-
-                int oldSubtype = mNetworkInfo.getSubtype();
-                int newSubType = TelephonyManager.getDefault().getNetworkType();
-                String subTypeName = TelephonyManager.getDefault().getNetworkTypeName();
-                mNetworkInfo.setSubtype(newSubType, subTypeName);
-                if (newSubType != oldSubtype && mNetworkInfo.isConnected()) {
-                    Message msg = mTarget.obtainMessage(EVENT_NETWORK_SUBTYPE_CHANGED,
-                                                        oldSubtype, 0, mNetworkInfo);
-                    msg.sendToTarget();
-                }
-
-                PhoneConstants.DataState state = Enum.valueOf(PhoneConstants.DataState.class,
-                        intent.getStringExtra(PhoneConstants.STATE_KEY));
-                String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY);
-                String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
-                mNetworkInfo.setRoaming(intent.getBooleanExtra(
-                        PhoneConstants.DATA_NETWORK_ROAMING_KEY, false));
-                if (VDBG) {
-                    log(mApnType + " setting isAvailable to " +
-                            intent.getBooleanExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY,false));
-                }
-                mNetworkInfo.setIsAvailable(!intent.getBooleanExtra(
-                        PhoneConstants.NETWORK_UNAVAILABLE_KEY, false));
-
-                if (DBG) {
-                    log("Received state=" + state + ", old=" + mMobileDataState +
-                        ", reason=" + (reason == null ? "(unspecified)" : reason));
-                }
-                if (mMobileDataState != state) {
-                    mMobileDataState = state;
-                    switch (state) {
-                        case DISCONNECTED:
-                            if(isTeardownRequested()) {
-                                setTeardownRequested(false);
-                            }
-
-                            setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
-                            // can't do this here - ConnectivityService needs it to clear stuff
-                            // it's ok though - just leave it to be refreshed next time
-                            // we connect.
-                            //if (DBG) log("clearing mInterfaceName for "+ mApnType +
-                            //        " as it DISCONNECTED");
-                            //mInterfaceName = null;
-                            break;
-                        case CONNECTING:
-                            setDetailedState(DetailedState.CONNECTING, reason, apnName);
-                            break;
-                        case SUSPENDED:
-                            setDetailedState(DetailedState.SUSPENDED, reason, apnName);
-                            break;
-                        case CONNECTED:
-                            updateLinkProperitesAndCapatilities(intent);
-                            setDetailedState(DetailedState.CONNECTED, reason, apnName);
-                            break;
-                    }
-
-                    if (VDBG) {
-                        Slog.d(TAG, "TelephonyMgr.DataConnectionStateChanged");
-                        if (mNetworkInfo != null) {
-                            Slog.d(TAG, "NetworkInfo = " + mNetworkInfo);
-                            Slog.d(TAG, "subType = " + mNetworkInfo.getSubtype());
-                            Slog.d(TAG, "subType = " + mNetworkInfo.getSubtypeName());
-                        }
-                        if (mLinkProperties != null) {
-                            Slog.d(TAG, "LinkProperties = " + mLinkProperties);
-                        } else {
-                            Slog.d(TAG, "LinkProperties = " );
-                        }
-
-                        if (mNetworkCapabilities != null) {
-                            Slog.d(TAG, mNetworkCapabilities.toString());
-                        } else {
-                            Slog.d(TAG, "NetworkCapabilities = " );
-                        }
-                    }
-
-
-                    /* lets not sample traffic data across state changes */
-                    mSamplingDataTracker.resetSamplingData();
-                } else {
-                    // There was no state change. Check if LinkProperties has been updated.
-                    if (TextUtils.equals(reason, PhoneConstants.REASON_LINK_PROPERTIES_CHANGED)) {
-                        mLinkProperties = intent.getParcelableExtra(
-                                PhoneConstants.DATA_LINK_PROPERTIES_KEY);
-                        if (mLinkProperties == null) {
-                            loge("No link property in LINK_PROPERTIES change event.");
-                            mLinkProperties = new LinkProperties();
-                        }
-                        // Just update reason field in this NetworkInfo
-                        mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason,
-                                                      mNetworkInfo.getExtraInfo());
-                        Message msg = mTarget.obtainMessage(EVENT_CONFIGURATION_CHANGED,
-                                                            mNetworkInfo);
-                        msg.sendToTarget();
-                    }
-                }
-            } else if (intent.getAction().
-                    equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
-                String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY);
-                if (!TextUtils.equals(apnType, mApnType)) {
-                    if (DBG) {
-                        log(String.format(
-                                "Broadcast received: ACTION_ANY_DATA_CONNECTION_FAILED ignore, " +
-                                "mApnType=%s != received apnType=%s", mApnType, apnType));
-                    }
-                    return;
-                }
-                // Assume this isn't a provisioning network.
-                mNetworkInfo.setIsConnectedToProvisioningNetwork(false);
-                String reason = intent.getStringExtra(PhoneConstants.FAILURE_REASON_KEY);
-                String apnName = intent.getStringExtra(PhoneConstants.DATA_APN_KEY);
-                if (DBG) {
-                    log("Broadcast received: " + intent.getAction() +
-                                " reason=" + reason == null ? "null" : reason);
-                }
-                setDetailedState(DetailedState.FAILED, reason, apnName);
-            } else {
-                if (DBG) log("Broadcast received: ignore " + intent.getAction());
-            }
-        }
-    }
-
-    private void getPhoneService(boolean forceRefresh) {
-        if ((mPhoneService == null) || forceRefresh) {
-            mPhoneService = ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
-        }
-    }
-
-    /**
-     * Report whether data connectivity is possible.
-     */
-    public boolean isAvailable() {
-        return mNetworkInfo.isAvailable();
-    }
-
-    /**
-     * Return the system properties name associated with the tcp buffer sizes
-     * for this network.
-     */
-    public String getTcpBufferSizesPropName() {
-        String networkTypeStr = "unknown";
-        TelephonyManager tm = new TelephonyManager(mContext);
-        //TODO We have to edit the parameter for getNetworkType regarding CDMA
-        switch(tm.getNetworkType()) {
-        case TelephonyManager.NETWORK_TYPE_GPRS:
-            networkTypeStr = "gprs";
-            break;
-        case TelephonyManager.NETWORK_TYPE_EDGE:
-            networkTypeStr = "edge";
-            break;
-        case TelephonyManager.NETWORK_TYPE_UMTS:
-            networkTypeStr = "umts";
-            break;
-        case TelephonyManager.NETWORK_TYPE_HSDPA:
-            networkTypeStr = "hsdpa";
-            break;
-        case TelephonyManager.NETWORK_TYPE_HSUPA:
-            networkTypeStr = "hsupa";
-            break;
-        case TelephonyManager.NETWORK_TYPE_HSPA:
-            networkTypeStr = "hspa";
-            break;
-        case TelephonyManager.NETWORK_TYPE_HSPAP:
-            networkTypeStr = "hspap";
-            break;
-        case TelephonyManager.NETWORK_TYPE_CDMA:
-            networkTypeStr = "cdma";
-            break;
-        case TelephonyManager.NETWORK_TYPE_1xRTT:
-            networkTypeStr = "1xrtt";
-            break;
-        case TelephonyManager.NETWORK_TYPE_EVDO_0:
-            networkTypeStr = "evdo";
-            break;
-        case TelephonyManager.NETWORK_TYPE_EVDO_A:
-            networkTypeStr = "evdo";
-            break;
-        case TelephonyManager.NETWORK_TYPE_EVDO_B:
-            networkTypeStr = "evdo";
-            break;
-        case TelephonyManager.NETWORK_TYPE_IDEN:
-            networkTypeStr = "iden";
-            break;
-        case TelephonyManager.NETWORK_TYPE_LTE:
-        case TelephonyManager.NETWORK_TYPE_IWLAN:
-            networkTypeStr = "lte";
-            break;
-        case TelephonyManager.NETWORK_TYPE_EHRPD:
-            networkTypeStr = "ehrpd";
-            break;
-        default:
-            loge("unknown network type: " + tm.getNetworkType());
-        }
-        return "net.tcp.buffersize." + networkTypeStr;
-    }
-
-    /**
-     * Tear down mobile data connectivity, i.e., disable the ability to create
-     * mobile data connections.
-     * TODO - make async and return nothing?
-     */
-    public boolean teardown() {
-        setTeardownRequested(true);
-        return (setEnableApn(mApnType, false) != PhoneConstants.APN_REQUEST_FAILED);
-    }
-
-    /**
-     * @return true if this is ready to operate
-     */
-    public boolean isReady() {
-        return mDataConnectionTrackerAc != null;
-    }
-
-    @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
-     * any listeners.
-     * @param state the new {@code DetailedState}
-     * @param reason a {@code String} indicating a reason for the state change,
-     * if one was supplied. May be {@code null}.
-     * @param extraInfo optional {@code String} providing extra information about the state change
-     */
-    private void setDetailedState(NetworkInfo.DetailedState state, String reason,
-            String extraInfo) {
-        if (DBG) log("setDetailed state, old ="
-                + mNetworkInfo.getDetailedState() + " and new state=" + state);
-        if (state != mNetworkInfo.getDetailedState()) {
-            boolean wasConnecting = (mNetworkInfo.getState() == NetworkInfo.State.CONNECTING);
-            String lastReason = mNetworkInfo.getReason();
-            /*
-             * If a reason was supplied when the CONNECTING state was entered, and no
-             * reason was supplied for entering the CONNECTED state, then retain the
-             * reason that was supplied when going to CONNECTING.
-             */
-            if (wasConnecting && state == NetworkInfo.DetailedState.CONNECTED && reason == null
-                    && lastReason != null)
-                reason = lastReason;
-            mNetworkInfo.setDetailedState(state, reason, extraInfo);
-            Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, new NetworkInfo(mNetworkInfo));
-            msg.sendToTarget();
-        }
-    }
-
-    public void setTeardownRequested(boolean isRequested) {
-        mTeardownRequested = isRequested;
-    }
-
-    public boolean isTeardownRequested() {
-        return mTeardownRequested;
-    }
-
-    /**
-     * Re-enable mobile data connectivity after a {@link #teardown()}.
-     * TODO - make async and always get a notification?
-     */
-    public boolean reconnect() {
-        boolean retValue = false; //connected or expect to be?
-        setTeardownRequested(false);
-        switch (setEnableApn(mApnType, true)) {
-            case PhoneConstants.APN_ALREADY_ACTIVE:
-                // need to set self to CONNECTING so the below message is handled.
-                retValue = true;
-                break;
-            case PhoneConstants.APN_REQUEST_STARTED:
-                // set IDLE here , avoid the following second FAILED not sent out
-                mNetworkInfo.setDetailedState(DetailedState.IDLE, null, null);
-                retValue = true;
-                break;
-            case PhoneConstants.APN_REQUEST_FAILED:
-            case PhoneConstants.APN_TYPE_NOT_AVAILABLE:
-                break;
-            default:
-                loge("Error in reconnect - unexpected response.");
-                break;
-        }
-        return retValue;
-    }
-
-    /**
-     * Turn on or off the mobile radio. No connectivity will be possible while the
-     * radio is off. The operation is a no-op if the radio is already in the desired state.
-     * @param turnOn {@code true} if the radio should be turned on, {@code false} if
-     */
-    public boolean setRadio(boolean turnOn) {
-        getPhoneService(false);
-        /*
-         * If the phone process has crashed in the past, we'll get a
-         * RemoteException and need to re-reference the service.
-         */
-        for (int retry = 0; retry < 2; retry++) {
-            if (mPhoneService == null) {
-                loge("Ignoring mobile radio request because could not acquire PhoneService");
-                break;
-            }
-
-            try {
-                return mPhoneService.setRadio(turnOn);
-            } catch (RemoteException e) {
-                if (retry == 0) getPhoneService(true);
-            }
-        }
-
-        loge("Could not set radio power to " + (turnOn ? "on" : "off"));
-        return false;
-    }
-
-
-    public void setInternalDataEnable(boolean enabled) {
-        if (DBG) log("setInternalDataEnable: E enabled=" + enabled);
-        final AsyncChannel channel = mDataConnectionTrackerAc;
-        if (channel != null) {
-            channel.sendMessage(DctConstants.EVENT_SET_INTERNAL_DATA_ENABLE,
-                    enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
-        }
-        if (VDBG) log("setInternalDataEnable: X enabled=" + enabled);
-    }
-
-    @Override
-    public void setUserDataEnable(boolean enabled) {
-        if (DBG) log("setUserDataEnable: E enabled=" + enabled);
-        final AsyncChannel channel = mDataConnectionTrackerAc;
-        if (channel != null) {
-            channel.sendMessage(DctConstants.CMD_SET_USER_DATA_ENABLE,
-                    enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
-            mUserDataEnabled = enabled;
-        }
-        if (VDBG) log("setUserDataEnable: X enabled=" + enabled);
-    }
-
-    @Override
-    public void setPolicyDataEnable(boolean enabled) {
-        if (DBG) log("setPolicyDataEnable(enabled=" + enabled + ")");
-        final AsyncChannel channel = mDataConnectionTrackerAc;
-        if (channel != null) {
-            channel.sendMessage(DctConstants.CMD_SET_POLICY_DATA_ENABLE,
-                    enabled ? DctConstants.ENABLED : DctConstants.DISABLED);
-            mPolicyDataEnabled = enabled;
-        }
-    }
-
-    /**
-     * Eanble/disable FailFast
-     *
-     * @param enabled is DctConstants.ENABLED/DISABLED
-     */
-    public void setEnableFailFastMobileData(int enabled) {
-        if (DBG) log("setEnableFailFastMobileData(enabled=" + enabled + ")");
-        final AsyncChannel channel = mDataConnectionTrackerAc;
-        if (channel != null) {
-            channel.sendMessage(DctConstants.CMD_SET_ENABLE_FAIL_FAST_MOBILE_DATA, enabled);
-        }
-    }
-
-    /**
-     * carrier dependency is met/unmet
-     * @param met
-     */
-    public void setDependencyMet(boolean met) {
-        Bundle bundle = Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType);
-        try {
-            if (DBG) log("setDependencyMet: E met=" + met);
-            Message msg = Message.obtain();
-            msg.what = DctConstants.CMD_SET_DEPENDENCY_MET;
-            msg.arg1 = (met ? DctConstants.ENABLED : DctConstants.DISABLED);
-            msg.setData(bundle);
-            mDataConnectionTrackerAc.sendMessage(msg);
-            if (VDBG) log("setDependencyMet: X met=" + met);
-        } catch (NullPointerException e) {
-            loge("setDependencyMet: X mAc was null" + e);
-        }
-    }
-
-    /**
-     *  Inform DCT mobile provisioning has started, it ends when provisioning completes.
-     */
-    public void enableMobileProvisioning(String url) {
-        if (DBG) log("enableMobileProvisioning(url=" + url + ")");
-        final AsyncChannel channel = mDataConnectionTrackerAc;
-        if (channel != null) {
-            Message msg = Message.obtain();
-            msg.what = DctConstants.CMD_ENABLE_MOBILE_PROVISIONING;
-            msg.setData(Bundle.forPair(DctConstants.PROVISIONING_URL_KEY, url));
-            channel.sendMessage(msg);
-        }
-    }
-
-    /**
-     * Return if this network is the provisioning network. Valid only if connected.
-     * @param met
-     */
-    public boolean isProvisioningNetwork() {
-        boolean retVal;
-        try {
-            Message msg = Message.obtain();
-            msg.what = DctConstants.CMD_IS_PROVISIONING_APN;
-            msg.setData(Bundle.forPair(DctConstants.APN_TYPE_KEY, mApnType));
-            Message result = mDataConnectionTrackerAc.sendMessageSynchronously(msg);
-            retVal = result.arg1 == DctConstants.ENABLED;
-        } catch (NullPointerException e) {
-            loge("isProvisioningNetwork: X " + e);
-            retVal = false;
-        }
-        if (DBG) log("isProvisioningNetwork: retVal=" + retVal);
-        return retVal;
-    }
-
-    @Override
-    public String toString() {
-        final CharArrayWriter writer = new CharArrayWriter();
-        final PrintWriter pw = new PrintWriter(writer);
-        pw.print("Mobile data state: "); pw.println(mMobileDataState);
-        pw.print("Data enabled: user="); pw.print(mUserDataEnabled);
-        pw.print(", policy="); pw.println(mPolicyDataEnabled);
-        return writer.toString();
-    }
-
-    /**
-     * Internal method supporting the ENABLE_MMS feature.
-     * @param apnType the type of APN to be enabled or disabled (e.g., mms)
-     * @param enable {@code true} to enable the specified APN type,
-     * {@code false} to disable it.
-     * @return an integer value representing the outcome of the request.
-     */
-    private int setEnableApn(String apnType, boolean enable) {
-        getPhoneService(false);
-        /*
-         * If the phone process has crashed in the past, we'll get a
-         * RemoteException and need to re-reference the service.
-         */
-        for (int retry = 0; retry < 2; retry++) {
-            if (mPhoneService == null) {
-                loge("Ignoring feature request because could not acquire PhoneService");
-                break;
-            }
-
-//            try {
-//                if (enable) {
-//                    return mPhoneService.enableApnType(apnType);
-//                } else {
-//                    return mPhoneService.disableApnType(apnType);
-//                }
-//            } catch (RemoteException e) {
-//                if (retry == 0) getPhoneService(true);
-//            }
-        }
-
-        loge("Could not " + (enable ? "enable" : "disable") + " APN type \"" + apnType + "\"");
-        return PhoneConstants.APN_REQUEST_FAILED;
-    }
-
-    public static String networkTypeToApnType(int netType) {
-        switch(netType) {
-            case ConnectivityManager.TYPE_MOBILE:
-                return PhoneConstants.APN_TYPE_DEFAULT;  // TODO - use just one of these
-            case ConnectivityManager.TYPE_MOBILE_MMS:
-                return PhoneConstants.APN_TYPE_MMS;
-            case ConnectivityManager.TYPE_MOBILE_SUPL:
-                return PhoneConstants.APN_TYPE_SUPL;
-            case ConnectivityManager.TYPE_MOBILE_DUN:
-                return PhoneConstants.APN_TYPE_DUN;
-            case ConnectivityManager.TYPE_MOBILE_HIPRI:
-                return PhoneConstants.APN_TYPE_HIPRI;
-            case ConnectivityManager.TYPE_MOBILE_FOTA:
-                return PhoneConstants.APN_TYPE_FOTA;
-            case ConnectivityManager.TYPE_MOBILE_IMS:
-                return PhoneConstants.APN_TYPE_IMS;
-            case ConnectivityManager.TYPE_MOBILE_CBS:
-                return PhoneConstants.APN_TYPE_CBS;
-            case ConnectivityManager.TYPE_MOBILE_IA:
-                return PhoneConstants.APN_TYPE_IA;
-            case ConnectivityManager.TYPE_MOBILE_EMERGENCY:
-                return PhoneConstants.APN_TYPE_EMERGENCY;
-            default:
-                sloge("Error mapping networkType " + netType + " to apnType.");
-                return null;
-        }
-    }
-
-
-    /**
-     * @see android.net.NetworkStateTracker#getLinkProperties()
-     */
-    @Override
-    public LinkProperties getLinkProperties() {
-        return new LinkProperties(mLinkProperties);
-    }
-
-    public void supplyMessenger(Messenger messenger) {
-        if (VDBG) log(mApnType + " got supplyMessenger");
-        AsyncChannel ac = new AsyncChannel();
-        ac.connect(mContext, MobileDataStateTracker.this.mHandler, messenger);
-    }
-
-    private void log(String s) {
-        Slog.d(TAG, mApnType + ": " + s);
-    }
-
-    private void loge(String s) {
-        Slog.e(TAG, mApnType + ": " + s);
-    }
-
-    static private void sloge(String s) {
-        Slog.e(TAG, s);
-    }
-
-    @Override
-    public LinkQualityInfo getLinkQualityInfo() {
-        if (mNetworkInfo == null || mNetworkInfo.getType() == ConnectivityManager.TYPE_NONE) {
-            // no data available yet; just return
-            return null;
-        }
-
-        MobileLinkQualityInfo li = new MobileLinkQualityInfo();
-
-        li.setNetworkType(mNetworkInfo.getType());
-
-        mSamplingDataTracker.setCommonLinkQualityInfoFields(li);
-
-        if (mNetworkInfo.getSubtype() != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-            li.setMobileNetworkType(mNetworkInfo.getSubtype());
-
-            NetworkDataEntry entry = getNetworkDataEntry(mNetworkInfo.getSubtype());
-            if (entry != null) {
-                li.setTheoreticalRxBandwidth(entry.downloadBandwidth);
-                li.setTheoreticalRxBandwidth(entry.uploadBandwidth);
-                li.setTheoreticalLatency(entry.latency);
-            }
-
-            if (mSignalStrength != null) {
-                li.setNormalizedSignalStrength(getNormalizedSignalStrength(
-                        li.getMobileNetworkType(), mSignalStrength));
-            }
-        }
-
-        SignalStrength ss = mSignalStrength;
-        if (ss != null) {
-
-            li.setRssi(ss.getGsmSignalStrength());
-            li.setGsmErrorRate(ss.getGsmBitErrorRate());
-            li.setCdmaDbm(ss.getCdmaDbm());
-            li.setCdmaEcio(ss.getCdmaEcio());
-            li.setEvdoDbm(ss.getEvdoDbm());
-            li.setEvdoEcio(ss.getEvdoEcio());
-            li.setEvdoSnr(ss.getEvdoSnr());
-            li.setLteSignalStrength(ss.getLteSignalStrength());
-            li.setLteRsrp(ss.getLteRsrp());
-            li.setLteRsrq(ss.getLteRsrq());
-            li.setLteRssnr(ss.getLteRssnr());
-            li.setLteCqi(ss.getLteCqi());
-        }
-
-        if (VDBG) {
-            Slog.d(TAG, "Returning LinkQualityInfo with"
-                    + " MobileNetworkType = " + String.valueOf(li.getMobileNetworkType())
-                    + " Theoretical Rx BW = " + String.valueOf(li.getTheoreticalRxBandwidth())
-                    + " gsm Signal Strength = " + String.valueOf(li.getRssi())
-                    + " cdma Signal Strength = " + String.valueOf(li.getCdmaDbm())
-                    + " evdo Signal Strength = " + String.valueOf(li.getEvdoDbm())
-                    + " Lte Signal Strength = " + String.valueOf(li.getLteSignalStrength()));
-        }
-
-        return li;
-    }
-
-    static class NetworkDataEntry {
-        public int networkType;
-        public int downloadBandwidth;               // in kbps
-        public int uploadBandwidth;                 // in kbps
-        public int latency;                         // in millisecond
-
-        NetworkDataEntry(int i1, int i2, int i3, int i4) {
-            networkType = i1;
-            downloadBandwidth = i2;
-            uploadBandwidth = i3;
-            latency = i4;
-        }
-    }
-
-    private static NetworkDataEntry [] mTheoreticalBWTable = new NetworkDataEntry[] {
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EDGE,      237,     118, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_GPRS,       48,      40, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_UMTS,      384,      64, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSDPA,   14400, UNKNOWN, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSUPA,   14400,    5760, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSPA,    14400,    5760, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_HSPAP,   21000,    5760, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_CDMA,  UNKNOWN, UNKNOWN, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_1xRTT, UNKNOWN, UNKNOWN, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_0,   2468,     153, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_A,   3072,    1800, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EVDO_B,  14700,    1800, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_IDEN,  UNKNOWN, UNKNOWN, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_LTE,    100000,   50000, UNKNOWN),
-            new NetworkDataEntry(TelephonyManager.NETWORK_TYPE_EHRPD, UNKNOWN, UNKNOWN, UNKNOWN),
-    };
-
-    private static NetworkDataEntry getNetworkDataEntry(int networkType) {
-        for (NetworkDataEntry entry : mTheoreticalBWTable) {
-            if (entry.networkType == networkType) {
-                return entry;
-            }
-        }
-
-        Slog.e(TAG, "Could not find Theoretical BW entry for " + String.valueOf(networkType));
-        return null;
-    }
-
-    private static int getNormalizedSignalStrength(int networkType, SignalStrength ss) {
-
-        int level;
-
-        switch(networkType) {
-            case TelephonyManager.NETWORK_TYPE_EDGE:
-            case TelephonyManager.NETWORK_TYPE_GPRS:
-            case TelephonyManager.NETWORK_TYPE_UMTS:
-            case TelephonyManager.NETWORK_TYPE_HSDPA:
-            case TelephonyManager.NETWORK_TYPE_HSUPA:
-            case TelephonyManager.NETWORK_TYPE_HSPA:
-            case TelephonyManager.NETWORK_TYPE_HSPAP:
-                level = ss.getGsmLevel();
-                break;
-            case TelephonyManager.NETWORK_TYPE_CDMA:
-            case TelephonyManager.NETWORK_TYPE_1xRTT:
-                level = ss.getCdmaLevel();
-                break;
-            case TelephonyManager.NETWORK_TYPE_EVDO_0:
-            case TelephonyManager.NETWORK_TYPE_EVDO_A:
-            case TelephonyManager.NETWORK_TYPE_EVDO_B:
-                level = ss.getEvdoLevel();
-                break;
-            case TelephonyManager.NETWORK_TYPE_LTE:
-                level = ss.getLteLevel();
-                break;
-            case TelephonyManager.NETWORK_TYPE_IDEN:
-            case TelephonyManager.NETWORK_TYPE_EHRPD:
-            default:
-                return UNKNOWN;
-        }
-
-        return (level * LinkQualityInfo.NORMALIZED_SIGNAL_STRENGTH_RANGE) /
-                SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
-    }
-
-    @Override
-    public void startSampling(SamplingDataTracker.SamplingSnapshot s) {
-        mSamplingDataTracker.startSampling(s);
-    }
-
-    @Override
-    public void stopSampling(SamplingDataTracker.SamplingSnapshot s) {
-        mSamplingDataTracker.stopSampling(s);
-    }
-}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
deleted file mode 100644
index c80782c..0000000
--- a/core/java/android/net/NetworkStateTracker.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Messenger;
-
-import static com.android.internal.util.Protocol.BASE_NETWORK_STATE_TRACKER;
-
-/**
- * Interface provides the {@link com.android.server.ConnectivityService}
- * with three services. Events to the ConnectivityService when
- * changes occur, an API for controlling the network and storage
- * for network specific information.
- *
- * The Connectivity will call startMonitoring before any other
- * method is called.
- *
- * {@hide}
- */
-public interface NetworkStateTracker {
-
-    /**
-     * -------------------------------------------------------------
-     * Event Interface back to ConnectivityService.
-     *
-     * The events that are to be sent back to the Handler passed
-     * to startMonitoring when the particular event occurs.
-     * -------------------------------------------------------------
-     */
-
-    /**
-     * The network state has changed and the NetworkInfo object
-     * contains the new state.
-     *
-     * msg.what = EVENT_STATE_CHANGED
-     * msg.obj = NetworkInfo object
-     */
-    public static final int EVENT_STATE_CHANGED = BASE_NETWORK_STATE_TRACKER;
-
-    /**
-     * msg.what = EVENT_CONFIGURATION_CHANGED
-     * msg.obj = NetworkInfo object
-     */
-    public static final int EVENT_CONFIGURATION_CHANGED = BASE_NETWORK_STATE_TRACKER + 1;
-
-    /**
-     * msg.what = EVENT_RESTORE_DEFAULT_NETWORK
-     * msg.obj = FeatureUser object
-     */
-    public static final int EVENT_RESTORE_DEFAULT_NETWORK = BASE_NETWORK_STATE_TRACKER + 2;
-
-    /**
-     * msg.what = EVENT_NETWORK_SUBTYPE_CHANGED
-     * msg.obj = NetworkInfo object
-     */
-    public static final int EVENT_NETWORK_SUBTYPE_CHANGED = BASE_NETWORK_STATE_TRACKER + 3;
-
-    /**
-     * msg.what = EVENT_NETWORK_CONNECTED
-     * msg.obj = LinkProperties object
-     */
-    public static final int EVENT_NETWORK_CONNECTED = BASE_NETWORK_STATE_TRACKER + 4;
-
-    /**
-     * msg.what = EVENT_NETWORK_CONNECTION_DISCONNECTED
-     * msg.obj = LinkProperties object, same iface name
-     */
-    public static final int EVENT_NETWORK_DISCONNECTED = BASE_NETWORK_STATE_TRACKER + 5;
-
-    /**
-     * -------------------------------------------------------------
-     * Control Interface
-     * -------------------------------------------------------------
-     */
-    /**
-     * Begin monitoring data connectivity.
-     *
-     * This is the first method called when this interface is used.
-     *
-     * @param context is the current Android context
-     * @param target is the Hander to which to return the events.
-     */
-    public void startMonitoring(Context context, Handler target);
-
-    /**
-     * Fetch NetworkInfo for the network
-     */
-    public NetworkInfo getNetworkInfo();
-
-    /**
-     * Return the LinkProperties for the connection.
-     *
-     * @return a copy of the LinkProperties, is never null.
-     */
-    public LinkProperties getLinkProperties();
-
-    /**
-     * @return a copy of this connections capabilities, may be empty but never null.
-     */
-    public NetworkCapabilities getNetworkCapabilities();
-
-    /**
-     * Get interesting information about this network link
-     * @return a copy of link information, null if not available
-     */
-    public LinkQualityInfo getLinkQualityInfo();
-
-    /**
-     * Return the system properties name associated with the tcp buffer sizes
-     * for this network.
-     */
-    public String getTcpBufferSizesPropName();
-
-    /**
-     * Disable connectivity to a network
-     * @return {@code true} if a teardown occurred, {@code false} if the
-     * teardown did not occur.
-     */
-    public boolean teardown();
-
-    /**
-     * Reenable connectivity to a network after a {@link #teardown()}.
-     * @return {@code true} if we're connected or expect to be connected
-     */
-    public boolean reconnect();
-
-    /**
-     * 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}
-     */
-    public boolean setRadio(boolean turnOn);
-
-    /**
-     * Returns an indication of whether this network is available for
-     * connections. A value of {@code false} means that some quasi-permanent
-     * condition prevents connectivity to this network.
-     *
-     * NOTE that this is broken on multi-connection devices.  Should be fixed in J release
-     * TODO - fix on multi-pdp devices
-     */
-    public boolean isAvailable();
-
-    /**
-     * User control of data connection through this network, typically persisted
-     * internally.
-     */
-    public void setUserDataEnable(boolean enabled);
-
-    /**
-     * Policy control of data connection through this network, typically not
-     * persisted internally. Usually used when {@link NetworkPolicy#limitBytes}
-     * is passed.
-     */
-    public void setPolicyDataEnable(boolean enabled);
-
-    /**
-     * -------------------------------------------------------------
-     * Storage API used by ConnectivityService for saving
-     * Network specific information.
-     * -------------------------------------------------------------
-     */
-
-    /**
-     * Check if private DNS route is set for the network
-     */
-    public boolean isPrivateDnsRouteSet();
-
-    /**
-     * Set a flag indicating private DNS route is set
-     */
-    public void privateDnsRouteSet(boolean enabled);
-
-    /**
-     * Check if default route is set
-     */
-    public boolean isDefaultRouteSet();
-
-    /**
-     * Set a flag indicating default route is set for the network
-     */
-    public void defaultRouteSet(boolean enabled);
-
-    /**
-     * Check if tear down was requested
-     */
-    public boolean isTeardownRequested();
-
-    /**
-     * Indicate tear down requested from connectivity
-     */
-    public void setTeardownRequested(boolean isRequested);
-
-    /**
-     * An external dependency has been met/unmet
-     */
-    public void setDependencyMet(boolean met);
-
-    /*
-     * Called once to setup async channel between this and
-     * the underlying network specific code.
-     */
-    public void supplyMessenger(Messenger messenger);
-
-    /*
-     * Network interface name that we'll lookup for sampling data
-     */
-    public String getNetworkInterfaceName();
-
-    /*
-     * Save the starting sample
-     */
-    public void startSampling(SamplingDataTracker.SamplingSnapshot s);
-
-    /*
-     * Save the ending sample
-     */
-    public void stopSampling(SamplingDataTracker.SamplingSnapshot s);
-
-    /*
-     * Record the current netId
-     */
-    public void setNetId(int netId);
-
-    /*
-     * ?
-     */
-    public Network getNetwork();
-
-}
diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java
deleted file mode 100644
index 7d23125..0000000
--- a/core/java/android/net/ProxyDataTracker.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Log;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * A data tracker responsible for bringing up and tearing down the system proxy server.
- *
- * {@hide}
- */
-public class ProxyDataTracker extends BaseNetworkStateTracker {
-    private static final String TAG = "ProxyDataTracker";
-    private static final String NETWORK_TYPE = "PROXY";
-
-    // TODO: investigate how to get these DNS addresses from the system.
-    private static final String DNS1 = "8.8.8.8";
-    private static final String DNS2 = "8.8.4.4";
-    private static final String INTERFACE_NAME = "ifb0";
-    private static final String REASON_ENABLED = "enabled";
-    private static final String REASON_DISABLED = "disabled";
-    private static final String REASON_PROXY_DOWN = "proxy_down";
-
-    private static final int MSG_TEAR_DOWN_REQUEST = 1;
-    private static final int MSG_SETUP_REQUEST = 2;
-
-    private static final String PERMISSION_PROXY_STATUS_SENDER =
-            "android.permission.ACCESS_NETWORK_CONDITIONS";
-    private static final String ACTION_PROXY_STATUS_CHANGE =
-            "com.android.net.PROXY_STATUS_CHANGE";
-    private static final String KEY_IS_PROXY_AVAILABLE = "is_proxy_available";
-    private static final String KEY_REPLY_TO_MESSENGER_BINDER = "reply_to_messenger_binder";
-    private static final String KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE =
-            "reply_to_messenger_binder_bundle";
-
-    private Handler mTarget;
-    private Messenger mProxyStatusService;
-    private AtomicBoolean mReconnectRequested = new AtomicBoolean(false);
-    private AtomicBoolean mIsProxyAvailable = new AtomicBoolean(false);
-    private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
-
-    private final BroadcastReceiver mProxyStatusServiceListener = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(ACTION_PROXY_STATUS_CHANGE)) {
-                mIsProxyAvailable.set(intent.getBooleanExtra(KEY_IS_PROXY_AVAILABLE, false));
-                if (mIsProxyAvailable.get()) {
-                    Bundle bundle = intent.getBundleExtra(KEY_REPLY_TO_MESSENGER_BINDER_BUNDLE);
-                    if (bundle == null || bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER) == null) {
-                        Log.e(TAG, "no messenger binder in the intent to send future requests");
-                        mIsProxyAvailable.set(false);
-                        return;
-                    }
-                    mProxyStatusService =
-                            new Messenger(bundle.getBinder(KEY_REPLY_TO_MESSENGER_BINDER));
-                    // If there is a pending reconnect request, do it now.
-                    if (mReconnectRequested.get()) {
-                        reconnect();
-                    }
-                } else {
-                    setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
-                            REASON_PROXY_DOWN, null);
-                }
-            } else {
-                Log.d(TAG, "Unrecognized broadcast intent");
-            }
-        }
-    };
-
-    /**
-     * Create a new ProxyDataTracker
-     */
-    public ProxyDataTracker() {
-        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, "");
-        mLinkProperties = new LinkProperties();
-        mNetworkCapabilities = new NetworkCapabilities();
-        mNetworkInfo.setIsAvailable(true);
-        try {
-            mLinkProperties.addDnsServer(InetAddress.getByName(DNS1));
-            mLinkProperties.addDnsServer(InetAddress.getByName(DNS2));
-            mLinkProperties.setInterfaceName(INTERFACE_NAME);
-        } catch (UnknownHostException e) {
-            Log.e(TAG, "Could not add DNS address", e);
-        }
-    }
-
-    @Override
-    public Object clone() throws CloneNotSupportedException {
-        throw new CloneNotSupportedException();
-    }
-
-    @Override
-    public void startMonitoring(Context context, Handler target) {
-        mContext = context;
-        mTarget = target;
-        mContext.registerReceiver(mProxyStatusServiceListener,
-                new IntentFilter(ACTION_PROXY_STATUS_CHANGE),
-                PERMISSION_PROXY_STATUS_SENDER,
-                null);
-    }
-
-    /**
-     * Disable connectivity to the network.
-     */
-    public boolean teardown() {
-        setTeardownRequested(true);
-        mReconnectRequested.set(false);
-        try {
-            if (mIsProxyAvailable.get() && mProxyStatusService != null) {
-                mProxyStatusService.send(Message.obtain(null, MSG_TEAR_DOWN_REQUEST));
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Unable to connect to proxy status service", e);
-            return false;
-        }
-        setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_DISABLED, null);
-        return true;
-    }
-
-    /**
-     * Re-enable proxy data connectivity after a {@link #teardown()}.
-     */
-    public boolean reconnect() {
-        mReconnectRequested.set(true);
-        setTeardownRequested(false);
-        if (!mIsProxyAvailable.get()) {
-            Log.w(TAG, "Reconnect requested even though proxy service is not up. Bailing.");
-            return false;
-        }
-        setDetailedState(NetworkInfo.DetailedState.CONNECTING, REASON_ENABLED, null);
-
-        try {
-            mProxyStatusService.send(Message.obtain(null, MSG_SETUP_REQUEST));
-        } catch (RemoteException e) {
-            Log.e(TAG, "Unable to connect to proxy status service", e);
-            setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, REASON_PROXY_DOWN, null);
-            return false;
-        }
-        // We'll assume proxy is set up successfully. If not, a status change broadcast will be
-        // received afterwards to indicate any failure.
-        setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null);
-        return true;
-    }
-
-    /**
-     * Fetch default gateway address for the network
-     */
-    public int getDefaultGatewayAddr() {
-        return mDefaultGatewayAddr.get();
-    }
-
-    /**
-     * Return the system properties name associated with the tcp buffer sizes
-     * for this network.
-     */
-    public String getTcpBufferSizesPropName() {
-        return "net.tcp.buffersize.wifi";
-    }
-
-    /**
-     * Record the detailed state of a network, and if it is a
-     * change from the previous state, send a notification to
-     * any listeners.
-     * @param state the new @{code DetailedState}
-     * @param reason a {@code String} indicating a reason for the state change,
-     * if one was supplied. May be {@code null}.
-     * @param extraInfo optional {@code String} providing extra information about the state change
-     */
-    private void setDetailedState(NetworkInfo.DetailedState state, String reason,
-            String extraInfo) {
-        mNetworkInfo.setDetailedState(state, reason, extraInfo);
-        Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
-        msg.sendToTarget();
-    }
-}
diff --git a/core/java/android/net/SamplingDataTracker.java b/core/java/android/net/SamplingDataTracker.java
deleted file mode 100644
index acd56f2..0000000
--- a/core/java/android/net/SamplingDataTracker.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-
-import android.os.SystemClock;
-import android.util.Slog;
-
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * @hide
- */
-public class SamplingDataTracker
-{
-    private static final boolean DBG = false;
-    private static final String  TAG = "SamplingDataTracker";
-
-    public static class SamplingSnapshot
-    {
-        public long mTxByteCount;
-        public long mRxByteCount;
-        public long mTxPacketCount;
-        public long mRxPacketCount;
-        public long mTxPacketErrorCount;
-        public long mRxPacketErrorCount;
-        public long mTimestamp;
-    }
-
-    public static void getSamplingSnapshots(Map<String, SamplingSnapshot> mapIfaceToSample) {
-
-        BufferedReader reader = null;
-        try {
-            reader = new BufferedReader(new FileReader("/proc/net/dev"));
-
-            // Skip over the line bearing column titles (there are 2 lines)
-            String line;
-            reader.readLine();
-            reader.readLine();
-
-            while ((line = reader.readLine()) != null) {
-
-                // remove leading whitespace
-                line = line.trim();
-
-                String[] tokens = line.split("[ ]+");
-                if (tokens.length < 17) {
-                    continue;
-                }
-
-                /* column format is
-                 * Interface  (Recv)bytes packets errs drop fifo frame compressed multicast \
-                 *            (Transmit)bytes packets errs drop fifo colls carrier compress
-                */
-
-                String currentIface = tokens[0].split(":")[0];
-                if (DBG) Slog.d(TAG, "Found data for interface " + currentIface);
-                if (mapIfaceToSample.containsKey(currentIface)) {
-
-                    try {
-                        SamplingSnapshot ss = new SamplingSnapshot();
-
-                        ss.mTxByteCount        = Long.parseLong(tokens[1]);
-                        ss.mTxPacketCount      = Long.parseLong(tokens[2]);
-                        ss.mTxPacketErrorCount = Long.parseLong(tokens[3]);
-                        ss.mRxByteCount        = Long.parseLong(tokens[9]);
-                        ss.mRxPacketCount      = Long.parseLong(tokens[10]);
-                        ss.mRxPacketErrorCount = Long.parseLong(tokens[11]);
-
-                        ss.mTimestamp          = SystemClock.elapsedRealtime();
-
-                        if (DBG) {
-                            Slog.d(TAG, "Interface = " + currentIface);
-                            Slog.d(TAG, "ByteCount = " + String.valueOf(ss.mTxByteCount));
-                            Slog.d(TAG, "TxPacketCount = " + String.valueOf(ss.mTxPacketCount));
-                            Slog.d(TAG, "TxPacketErrorCount = "
-                                    + String.valueOf(ss.mTxPacketErrorCount));
-                            Slog.d(TAG, "RxByteCount = " + String.valueOf(ss.mRxByteCount));
-                            Slog.d(TAG, "RxPacketCount = " + String.valueOf(ss.mRxPacketCount));
-                            Slog.d(TAG, "RxPacketErrorCount = "
-                                    + String.valueOf(ss.mRxPacketErrorCount));
-                            Slog.d(TAG, "Timestamp = " + String.valueOf(ss.mTimestamp));
-                            Slog.d(TAG, "---------------------------");
-                        }
-
-                        mapIfaceToSample.put(currentIface, ss);
-
-                    } catch (NumberFormatException e) {
-                        // just ignore this data point
-                    }
-                }
-            }
-
-            if (DBG) {
-                Iterator it = mapIfaceToSample.entrySet().iterator();
-                while (it.hasNext()) {
-                    Map.Entry kvpair = (Map.Entry)it.next();
-                    if (kvpair.getValue() == null) {
-                        Slog.d(TAG, "could not find snapshot for interface " + kvpair.getKey());
-                    }
-                }
-            }
-        } catch(FileNotFoundException e) {
-            Slog.e(TAG, "could not find /proc/net/dev");
-        } catch (IOException e) {
-            Slog.e(TAG, "could not read /proc/net/dev");
-        } finally {
-            try {
-                if (reader != null) {
-                    reader.close();
-                }
-            } catch (IOException e) {
-                Slog.e(TAG, "could not close /proc/net/dev");
-            }
-        }
-    }
-
-    // Snapshots from previous sampling interval
-    private SamplingSnapshot mBeginningSample;
-    private SamplingSnapshot mEndingSample;
-
-    // Starting snapshot of current interval
-    private SamplingSnapshot mLastSample;
-
-    // Protects sampling data from concurrent access
-    public final Object mSamplingDataLock = new Object();
-
-    // We need long enough time for a good sample
-    private final int MINIMUM_SAMPLING_INTERVAL = 15 * 1000;
-
-    // statistics is useless unless we have enough data
-    private final int MINIMUM_SAMPLED_PACKETS   = 30;
-
-    public void startSampling(SamplingSnapshot s) {
-        synchronized(mSamplingDataLock) {
-            mLastSample = s;
-        }
-    }
-
-    public void stopSampling(SamplingSnapshot s) {
-        synchronized(mSamplingDataLock) {
-            if (mLastSample != null) {
-                if (s.mTimestamp - mLastSample.mTimestamp > MINIMUM_SAMPLING_INTERVAL
-                        && getSampledPacketCount(mLastSample, s) > MINIMUM_SAMPLED_PACKETS) {
-                    mBeginningSample = mLastSample;
-                    mEndingSample = s;
-                    mLastSample = null;
-                } else {
-                    if (DBG) Slog.d(TAG, "Throwing current sample away because it is too small");
-                }
-            }
-        }
-    }
-
-    public void resetSamplingData() {
-        if (DBG) Slog.d(TAG, "Resetting sampled network data");
-        synchronized(mSamplingDataLock) {
-
-            // We could just take another sample here and treat it as an
-            // 'ending sample' effectively shortening sampling interval, but that
-            // requires extra work (specifically, reading the sample needs to be
-            // done asynchronously)
-
-            mLastSample = null;
-        }
-    }
-
-    public long getSampledTxByteCount() {
-        synchronized(mSamplingDataLock) {
-            if (mBeginningSample != null && mEndingSample != null) {
-                return mEndingSample.mTxByteCount - mBeginningSample.mTxByteCount;
-            } else {
-                return LinkQualityInfo.UNKNOWN_LONG;
-            }
-        }
-    }
-
-    public long getSampledTxPacketCount() {
-        synchronized(mSamplingDataLock) {
-            if (mBeginningSample != null && mEndingSample != null) {
-                return mEndingSample.mTxPacketCount - mBeginningSample.mTxPacketCount;
-            } else {
-                return LinkQualityInfo.UNKNOWN_LONG;
-            }
-        }
-    }
-
-    public long getSampledTxPacketErrorCount() {
-        synchronized(mSamplingDataLock) {
-            if (mBeginningSample != null && mEndingSample != null) {
-                return mEndingSample.mTxPacketErrorCount - mBeginningSample.mTxPacketErrorCount;
-            } else {
-                return LinkQualityInfo.UNKNOWN_LONG;
-            }
-        }
-    }
-
-    public long getSampledRxByteCount() {
-        synchronized(mSamplingDataLock) {
-            if (mBeginningSample != null && mEndingSample != null) {
-                return mEndingSample.mRxByteCount - mBeginningSample.mRxByteCount;
-            } else {
-                return LinkQualityInfo.UNKNOWN_LONG;
-            }
-        }
-    }
-
-    public long getSampledRxPacketCount() {
-        synchronized(mSamplingDataLock) {
-            if (mBeginningSample != null && mEndingSample != null) {
-                return mEndingSample.mRxPacketCount - mBeginningSample.mRxPacketCount;
-            } else {
-                return LinkQualityInfo.UNKNOWN_LONG;
-            }
-        }
-    }
-
-    public long getSampledPacketCount() {
-        return getSampledPacketCount(mBeginningSample, mEndingSample);
-    }
-
-    public long getSampledPacketCount(SamplingSnapshot begin, SamplingSnapshot end) {
-        if (begin != null && end != null) {
-            long rxPacketCount = end.mRxPacketCount - begin.mRxPacketCount;
-            long txPacketCount = end.mTxPacketCount - begin.mTxPacketCount;
-            return rxPacketCount + txPacketCount;
-        } else {
-            return LinkQualityInfo.UNKNOWN_LONG;
-        }
-    }
-
-    public long getSampledPacketErrorCount() {
-        if (mBeginningSample != null && mEndingSample != null) {
-            long rxPacketErrorCount = getSampledRxPacketErrorCount();
-            long txPacketErrorCount = getSampledTxPacketErrorCount();
-            return rxPacketErrorCount + txPacketErrorCount;
-        } else {
-            return LinkQualityInfo.UNKNOWN_LONG;
-        }
-    }
-
-    public long getSampledRxPacketErrorCount() {
-        synchronized(mSamplingDataLock) {
-            if (mBeginningSample != null && mEndingSample != null) {
-                return mEndingSample.mRxPacketErrorCount - mBeginningSample.mRxPacketErrorCount;
-            } else {
-                return LinkQualityInfo.UNKNOWN_LONG;
-            }
-        }
-    }
-
-    public long getSampleTimestamp() {
-        synchronized(mSamplingDataLock) {
-            if (mEndingSample != null) {
-                return mEndingSample.mTimestamp;
-            } else {
-                return LinkQualityInfo.UNKNOWN_LONG;
-            }
-        }
-    }
-
-    public int getSampleDuration() {
-        synchronized(mSamplingDataLock) {
-            if (mBeginningSample != null && mEndingSample != null) {
-                return (int) (mEndingSample.mTimestamp - mBeginningSample.mTimestamp);
-            } else {
-                return LinkQualityInfo.UNKNOWN_INT;
-            }
-        }
-    }
-
-    public void setCommonLinkQualityInfoFields(LinkQualityInfo li) {
-        synchronized(mSamplingDataLock) {
-            li.setLastDataSampleTime(getSampleTimestamp());
-            li.setDataSampleDuration(getSampleDuration());
-            li.setPacketCount(getSampledPacketCount());
-            li.setPacketErrorCount(getSampledPacketErrorCount());
-        }
-    }
-}
-
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b72b29d..d9ef766 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -48,7 +48,6 @@
 import android.net.INetworkStatsService;
 import android.net.LinkProperties;
 import android.net.LinkProperties.CompareResult;
-import android.net.MobileDataStateTracker;
 import android.net.Network;
 import android.net.NetworkAgent;
 import android.net.NetworkCapabilities;
@@ -59,12 +58,10 @@
 import android.net.NetworkQuotaInfo;
 import android.net.NetworkRequest;
 import android.net.NetworkState;
-import android.net.NetworkStateTracker;
 import android.net.NetworkUtils;
 import android.net.Proxy;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
-import android.net.SamplingDataTracker;
 import android.net.UidRange;
 import android.net.Uri;
 import android.os.Binder;
@@ -153,9 +150,6 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
-    // network sampling debugging
-    private static final boolean SAMPLE_DBG = false;
-
     private static final boolean LOGD_RULES = false;
 
     // TODO: create better separation between radio types and network types
@@ -166,33 +160,10 @@
     private static final String NETWORK_RESTORE_DELAY_PROP_NAME =
             "android.telephony.apn-restore";
 
-    // Default value if FAIL_FAST_TIME_MS is not set
-    private static final int DEFAULT_FAIL_FAST_TIME_MS = 1 * 60 * 1000;
-    // system property that can override DEFAULT_FAIL_FAST_TIME_MS
-    private static final String FAIL_FAST_TIME_MS =
-            "persist.radio.fail_fast_time_ms";
-
-    private static final String ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED =
-            "android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED";
-
-    private static final int SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE = 0;
-
     // How long to delay to removal of a pending intent based request.
     // See Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS
     private final int mReleasePendingIntentDelayMs;
 
-    private PendingIntent mSampleIntervalElapsedIntent;
-
-    // Set network sampling interval at 12 minutes, this way, even if the timers get
-    // aggregated, it will fire at around 15 minutes, which should allow us to
-    // aggregate this timer with other timers (specially the socket keep alive timers)
-    private static final int DEFAULT_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 12 * 60);
-
-    // start network sampling a minute after booting ...
-    private static final int DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS = (SAMPLE_DBG ? 30 : 60);
-
-    AlarmManager mAlarmManager;
-
     private Tethering mTethering;
 
     private final PermissionMonitor mPermissionMonitor;
@@ -212,13 +183,6 @@
     /** Set of ifaces that are costly. */
     private HashSet<String> mMeteredIfaces = Sets.newHashSet();
 
-    /**
-     * Sometimes we want to refer to the individual network state
-     * trackers separately, and sometimes we just want to treat them
-     * abstractly.
-     */
-    private NetworkStateTracker mNetTrackers[];
-
     private Context mContext;
     private int mNetworkPreference;
     // 0 is full bad, 100 is full good
@@ -278,28 +242,11 @@
     private static final int EVENT_APPLY_GLOBAL_HTTP_PROXY = 9;
 
     /**
-     * used internally to set external dependency met/unmet
-     * arg1 = ENABLED (met) or DISABLED (unmet)
-     * arg2 = NetworkType
-     */
-    private static final int EVENT_SET_DEPENDENCY_MET = 10;
-
-    /**
      * used internally to send a sticky broadcast delayed.
      */
     private static final int EVENT_SEND_STICKY_BROADCAST_INTENT = 11;
 
     /**
-     * Used internally to disable fail fast of mobile data
-     */
-    private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
-
-    /**
-     * used internally to indicate that data sampling interval is up
-     */
-    private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
-
-    /**
      * PAC manager has received new port.
      */
     private static final int EVENT_PROXY_HAS_CHANGED = 16;
@@ -419,8 +366,6 @@
 
     private DataConnectionStats mDataConnectionStats;
 
-    private AtomicInteger mEnableFailFastMobileDataTag = new AtomicInteger(0);
-
     TelephonyManager mTelephonyManager;
 
     // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp
@@ -650,9 +595,6 @@
                 com.android.internal.R.integer.config_networkTransitionTimeout);
         mPendingIntentWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
 
-        mNetTrackers = new NetworkStateTracker[
-                ConnectivityManager.MAX_NETWORK_TYPE+1];
-
         mNetConfigs = new NetworkConfig[ConnectivityManager.MAX_NETWORK_TYPE+1];
 
         // TODO: What is the "correct" way to do determine if this is a wifi only device?
@@ -740,23 +682,6 @@
         mDataConnectionStats = new DataConnectionStats(mContext);
         mDataConnectionStats.startMonitoring();
 
-        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        String action = intent.getAction();
-                        if (action.equals(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED)) {
-                            mHandler.sendMessage(mHandler.obtainMessage
-                                    (EVENT_SAMPLE_INTERVAL_ELAPSED));
-                        }
-                    }
-                },
-                new IntentFilter(filter));
-
         mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
 
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
@@ -782,15 +707,6 @@
         throw new IllegalStateException("No free netIds");
     }
 
-    private boolean teardown(NetworkStateTracker netTracker) {
-        if (netTracker.teardown()) {
-            netTracker.setTeardownRequested(true);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
     private NetworkState getFilteredNetworkState(int networkType, int uid) {
         NetworkInfo info = null;
         LinkProperties lp = null;
@@ -1350,22 +1266,6 @@
         return true;
     }
 
-    public void setDataDependency(int networkType, boolean met) {
-        enforceConnectivityInternalPermission();
-
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_DEPENDENCY_MET,
-                (met ? ENABLED : DISABLED), networkType));
-    }
-
-    private void handleSetDependencyMet(int networkType, boolean met) {
-        if (mNetTrackers[networkType] != null) {
-            if (DBG) {
-                log("handleSetDependencyMet(" + networkType + ", " + met + ")");
-            }
-            mNetTrackers[networkType].setDependencyMet(met);
-        }
-    }
-
     private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() {
         @Override
         public void onUidRulesChanged(int uid, int uidRules) {
@@ -1406,21 +1306,6 @@
             if (LOGD_RULES) {
                 log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
             }
-
-            // kick off connectivity change broadcast for active network, since
-            // global background policy change is radical.
-            // TODO: Dead code; remove.
-            //
-            // final int networkType = mActiveDefaultNetwork;
-            // if (isNetworkTypeValid(networkType)) {
-            //     final NetworkStateTracker tracker = mNetTrackers[networkType];
-            //     if (tracker != null) {
-            //         final NetworkInfo info = tracker.getNetworkInfo();
-            //         if (info != null && info.isConnected()) {
-            //             sendConnectedBroadcast(info);
-            //         }
-            //     }
-            // }
         }
     };
 
@@ -1536,14 +1421,6 @@
     }
 
     void systemReady() {
-        // start network sampling ..
-        Intent intent = new Intent(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
-        intent.setPackage(mContext.getPackageName());
-
-        mSampleIntervalElapsedIntent = PendingIntent.getBroadcast(mContext,
-                SAMPLE_INTERVAL_ELAPSED_REQUEST_CODE, intent, 0);
-        setAlarm(DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS * 1000, mSampleIntervalElapsedIntent);
-
         loadGlobalProxy();
 
         synchronized(this) {
@@ -2015,66 +1892,6 @@
                     }
                     break;
                 }
-                case NetworkStateTracker.EVENT_STATE_CHANGED: {
-                    info = (NetworkInfo) msg.obj;
-                    NetworkInfo.State state = info.getState();
-
-                    if (VDBG || (state == NetworkInfo.State.CONNECTED) ||
-                            (state == NetworkInfo.State.DISCONNECTED) ||
-                            (state == NetworkInfo.State.SUSPENDED)) {
-                        log("ConnectivityChange for " +
-                            info.getTypeName() + ": " +
-                            state + "/" + info.getDetailedState());
-                    }
-
-                    EventLogTags.writeConnectivityStateChanged(
-                            info.getType(), info.getSubtype(), info.getDetailedState().ordinal());
-
-                    if (info.isConnectedToProvisioningNetwork()) {
-                        /**
-                         * TODO: Create ConnectivityManager.TYPE_MOBILE_PROVISIONING
-                         * for now its an in between network, its a network that
-                         * is actually a default network but we don't want it to be
-                         * announced as such to keep background applications from
-                         * trying to use it. It turns out that some still try so we
-                         * take the additional step of clearing any default routes
-                         * to the link that may have incorrectly setup by the lower
-                         * levels.
-                         */
-                        LinkProperties lp = getLinkPropertiesForType(info.getType());
-                        if (DBG) {
-                            log("EVENT_STATE_CHANGED: connected to provisioning network, lp=" + lp);
-                        }
-
-                        // Clear any default routes setup by the radio so
-                        // any activity by applications trying to use this
-                        // connection will fail until the provisioning network
-                        // is enabled.
-                        /*
-                        for (RouteInfo r : lp.getRoutes()) {
-                            removeRoute(lp, r, TO_DEFAULT_TABLE,
-                                        mNetTrackers[info.getType()].getNetwork().netId);
-                        }
-                        */
-                    } else if (state == NetworkInfo.State.DISCONNECTED) {
-                    } else if (state == NetworkInfo.State.SUSPENDED) {
-                    } else if (state == NetworkInfo.State.CONNECTED) {
-                    //    handleConnect(info);
-                    }
-                    notifyLockdownVpn(null);
-                    break;
-                }
-                case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED: {
-                    info = (NetworkInfo) msg.obj;
-                    // TODO: Temporary allowing network configuration
-                    //       change not resetting sockets.
-                    //       @see bug/4455071
-                    /*
-                    handleConnectivityChange(info.getType(), mCurrentLinkProperties[info.getType()],
-                            false);
-                    */
-                    break;
-                }
             }
         }
     }
@@ -2439,34 +2256,11 @@
                     handleDeprecatedGlobalHttpProxy();
                     break;
                 }
-                case EVENT_SET_DEPENDENCY_MET: {
-                    boolean met = (msg.arg1 == ENABLED);
-                    handleSetDependencyMet(msg.arg2, met);
-                    break;
-                }
                 case EVENT_SEND_STICKY_BROADCAST_INTENT: {
                     Intent intent = (Intent)msg.obj;
                     sendStickyBroadcast(intent);
                     break;
                 }
-                case EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: {
-                    int tag = mEnableFailFastMobileDataTag.get();
-                    if (msg.arg1 == tag) {
-                        MobileDataStateTracker mobileDst =
-                            (MobileDataStateTracker) mNetTrackers[ConnectivityManager.TYPE_MOBILE];
-                        if (mobileDst != null) {
-                            mobileDst.setEnableFailFastMobileData(msg.arg2);
-                        }
-                    } else {
-                        log("EVENT_ENABLE_FAIL_FAST_MOBILE_DATA: stale arg1:" + msg.arg1
-                                + " != tag:" + tag);
-                    }
-                    break;
-                }
-                case EVENT_SAMPLE_INTERVAL_ELAPSED: {
-                    handleNetworkSamplingTimeout();
-                    break;
-                }
                 case EVENT_PROXY_HAS_CHANGED: {
                     handleApplyDefaultProxy((ProxyInfo)msg.obj);
                     break;
@@ -3066,14 +2860,6 @@
         }
     }
 
-    public void supplyMessenger(int networkType, Messenger messenger) {
-        enforceConnectivityInternalPermission();
-
-        if (isNetworkTypeValid(networkType) && mNetTrackers[networkType] != null) {
-            mNetTrackers[networkType].supplyMessenger(messenger);
-        }
-    }
-
     public int findConnectionTypeForIface(String iface) {
         enforceConnectivityInternalPermission();
 
@@ -3091,23 +2877,6 @@
         return ConnectivityManager.TYPE_NONE;
     }
 
-    /**
-     * Have mobile data fail fast if enabled.
-     *
-     * @param enabled DctConstants.ENABLED/DISABLED
-     */
-    private void setEnableFailFastMobileData(int enabled) {
-        int tag;
-
-        if (enabled == DctConstants.ENABLED) {
-            tag = mEnableFailFastMobileDataTag.incrementAndGet();
-        } else {
-            tag = mEnableFailFastMobileDataTag.get();
-        }
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_ENABLE_FAIL_FAST_MOBILE_DATA, tag,
-                         enabled));
-    }
-
     @Override
     public int checkMobileProvisioning(int suggestedTimeOutMs) {
         // TODO: Remove?  Any reason to trigger a provisioning check?
@@ -3392,69 +3161,6 @@
         }
     };
 
-    /* Infrastructure for network sampling */
-
-    private void handleNetworkSamplingTimeout() {
-
-        if (SAMPLE_DBG) log("Sampling interval elapsed, updating statistics ..");
-
-        // initialize list of interfaces ..
-        Map<String, SamplingDataTracker.SamplingSnapshot> mapIfaceToSample =
-                new HashMap<String, SamplingDataTracker.SamplingSnapshot>();
-        for (NetworkStateTracker tracker : mNetTrackers) {
-            if (tracker != null) {
-                String ifaceName = tracker.getNetworkInterfaceName();
-                if (ifaceName != null) {
-                    mapIfaceToSample.put(ifaceName, null);
-                }
-            }
-        }
-
-        // Read samples for all interfaces
-        SamplingDataTracker.getSamplingSnapshots(mapIfaceToSample);
-
-        // process samples for all networks
-        for (NetworkStateTracker tracker : mNetTrackers) {
-            if (tracker != null) {
-                String ifaceName = tracker.getNetworkInterfaceName();
-                SamplingDataTracker.SamplingSnapshot ss = mapIfaceToSample.get(ifaceName);
-                if (ss != null) {
-                    // end the previous sampling cycle
-                    tracker.stopSampling(ss);
-                    // start a new sampling cycle ..
-                    tracker.startSampling(ss);
-                }
-            }
-        }
-
-        if (SAMPLE_DBG) log("Done.");
-
-        int samplingIntervalInSeconds = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS,
-                DEFAULT_SAMPLING_INTERVAL_IN_SECONDS);
-
-        if (SAMPLE_DBG) {
-            log("Setting timer for " + String.valueOf(samplingIntervalInSeconds) + "seconds");
-        }
-
-        setAlarm(samplingIntervalInSeconds * 1000, mSampleIntervalElapsedIntent);
-    }
-
-    /**
-     * Sets a network sampling alarm.
-     */
-    void setAlarm(int timeoutInMilliseconds, PendingIntent intent) {
-        long wakeupTime = SystemClock.elapsedRealtime() + timeoutInMilliseconds;
-        int alarmType;
-        if (Resources.getSystem().getBoolean(
-                R.bool.config_networkSamplingWakesDevice)) {
-            alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
-        } else {
-            alarmType = AlarmManager.ELAPSED_REALTIME;
-        }
-        mAlarmManager.set(alarmType, wakeupTime, intent);
-    }
-
     private final HashMap<Messenger, NetworkFactoryInfo> mNetworkFactoryInfos =
             new HashMap<Messenger, NetworkFactoryInfo>();
     private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index beb353a..c198900 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -20,7 +20,6 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.getNetworkTypeName;
-import static android.net.NetworkStateTracker.EVENT_STATE_CHANGED;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isA;
