Add BT - DataTracker connection

Allows the external BT stack the means to communicate with
ConnectivityService during reverse tethering.

bug:8445208
Change-Id: Ice7dfb0b50c9481d359aed14a51372878185171c
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
index 43c2392..81c0a6a 100644
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -21,6 +21,7 @@
 import android.os.INetworkManagementService;
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.DhcpResults;
 import android.net.LinkCapabilities;
 import android.net.LinkProperties;
 import android.net.NetworkInfo;
@@ -28,7 +29,10 @@
 import android.net.NetworkStateTracker;
 import android.net.NetworkUtils;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
+import android.os.Messenger;
+import android.text.TextUtils;
 import android.util.Log;
 import java.net.InterfaceAddress;
 import android.net.LinkAddress;
@@ -36,8 +40,11 @@
 import java.net.Inet4Address;
 import android.os.SystemProperties;
 
+import com.android.internal.util.AsyncChannel;
+
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * This class tracks the data connection associated with Bluetooth
@@ -51,24 +58,29 @@
     private static final String NETWORKTYPE = "BLUETOOTH_TETHER";
     private static final String TAG = "BluetoothTethering";
     private static final boolean DBG = true;
-    private static final boolean VDBG = false;
+    private static final boolean VDBG = true;
 
     private AtomicBoolean mTeardownRequested = new AtomicBoolean(false);
     private AtomicBoolean mPrivateDnsRouteSet = new AtomicBoolean(false);
     private AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0);
     private AtomicBoolean mDefaultRouteSet = new AtomicBoolean(false);
 
+    private final Object mLinkPropertiesLock = new Object();
     private LinkProperties mLinkProperties;
+
     private LinkCapabilities mLinkCapabilities;
+
+    private final Object mNetworkInfoLock = new Object();
     private NetworkInfo mNetworkInfo;
 
     private BluetoothPan mBluetoothPan;
-    private static String mIface;
-    private Thread mDhcpThread;
+    private static String mRevTetheredIface;
     /* For sending events to connectivity service handler */
     private Handler mCsHandler;
-    private Context mContext;
-    public static BluetoothTetheringDataTracker sInstance;
+    protected Context mContext;
+    private static BluetoothTetheringDataTracker sInstance;
+    private BtdtHandler mBtdtHandler;
+    private AtomicReference<AsyncChannel> mAsyncChannel = new AtomicReference<AsyncChannel>(null);
 
     private BluetoothTetheringDataTracker() {
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_BLUETOOTH, 0, NETWORKTYPE, "");
@@ -108,6 +120,7 @@
         if (adapter != null) {
             adapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.PAN);
         }
+        mBtdtHandler = new BtdtHandler(target.getLooper(), this);
     }
 
     private BluetoothProfile.ServiceListener mProfileServiceListener =
@@ -224,15 +237,19 @@
     /**
      * Fetch NetworkInfo for the network
      */
-    public synchronized NetworkInfo getNetworkInfo() {
-        return mNetworkInfo;
+    public NetworkInfo getNetworkInfo() {
+        synchronized (mNetworkInfoLock) {
+            return new NetworkInfo(mNetworkInfo);
+        }
     }
 
     /**
      * Fetch LinkProperties for the network
      */
-    public synchronized LinkProperties getLinkProperties() {
-        return new LinkProperties(mLinkProperties);
+    public LinkProperties getLinkProperties() {
+        synchronized (mLinkPropertiesLock) {
+            return new LinkProperties(mLinkProperties);
+        }
     }
 
    /**
@@ -286,88 +303,68 @@
         return count;
     }
 
-
-    private boolean readLinkProperty(String iface) {
-        String DhcpPrefix = "dhcp." + iface + ".";
-        String ip = SystemProperties.get(DhcpPrefix + "ipaddress");
-        String dns1 = SystemProperties.get(DhcpPrefix + "dns1");
-        String dns2 = SystemProperties.get(DhcpPrefix + "dns2");
-        String gateway = SystemProperties.get(DhcpPrefix + "gateway");
-        String mask = SystemProperties.get(DhcpPrefix + "mask");
-        if(ip.isEmpty() || gateway.isEmpty()) {
-            Log.e(TAG, "readLinkProperty, ip: " +  ip + ", gateway: " + gateway + ", can not be empty");
-            return false;
+    void startReverseTether(final LinkProperties linkProperties) {
+        if (linkProperties == null || TextUtils.isEmpty(linkProperties.getInterfaceName())) {
+            Log.e(TAG, "attempted to reverse tether with empty interface");
+            return;
         }
-        int PrefixLen = countPrefixLength(NetworkUtils.numericToInetAddress(mask).getAddress());
-        mLinkProperties.addLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(ip), PrefixLen));
-        RouteInfo ri = new RouteInfo(NetworkUtils.numericToInetAddress(gateway));
-        mLinkProperties.addRoute(ri);
-        if(!dns1.isEmpty())
-            mLinkProperties.addDns(NetworkUtils.numericToInetAddress(dns1));
-        if(!dns2.isEmpty())
-            mLinkProperties.addDns(NetworkUtils.numericToInetAddress(dns2));
-        mLinkProperties.setInterfaceName(iface);
-        return true;
-    }
-    public synchronized void startReverseTether(String iface) {
-        mIface = iface;
-        if (DBG) Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
-         mDhcpThread = new Thread(new Runnable() {
+        synchronized (mLinkPropertiesLock) {
+            if (mLinkProperties.getInterfaceName() != null) {
+                Log.e(TAG, "attempted to reverse tether while already in process");
+                return;
+            }
+            mLinkProperties = linkProperties;
+        }
+        Thread dhcpThread = new Thread(new Runnable() {
             public void run() {
-                //TODO(): Add callbacks for failure and success case.
                 //Currently this thread runs independently.
-                if (DBG) Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
-                String DhcpResultName = "dhcp." + mIface + ".result";;
-                String result = "";
-                if (VDBG) Log.d(TAG, "waiting for change of sys prop dhcp result: " + DhcpResultName);
-                for(int i = 0; i < 30*5; i++) {
-                    try { Thread.sleep(200); } catch (InterruptedException ie) { return;}
-                    result = SystemProperties.get(DhcpResultName);
-                    if (VDBG) Log.d(TAG, "read " + DhcpResultName + ": " + result);
-                    if(result.equals("failed")) {
-                        Log.e(TAG, "startReverseTether, failed to start dhcp service");
+                DhcpResults dhcpResults = new DhcpResults();
+                boolean success = NetworkUtils.runDhcp(linkProperties.getInterfaceName(),
+                        dhcpResults);
+                synchronized (mLinkPropertiesLock) {
+                    if (linkProperties.getInterfaceName() != mLinkProperties.getInterfaceName()) {
+                        Log.e(TAG, "obsolete DHCP run aborted");
                         return;
                     }
-                    if(result.equals("ok")) {
-                        if (VDBG) Log.d(TAG, "startReverseTether, dhcp resut: " + result);
-                        if(readLinkProperty(mIface)) {
-
-                            mNetworkInfo.setIsAvailable(true);
-                            mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
-
-                            if (VDBG) Log.d(TAG, "startReverseTether mCsHandler: " + mCsHandler);
-                            if(mCsHandler != null) {
-                                Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
-                                msg.sendToTarget();
-
-                                msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
-                                msg.sendToTarget();
-                            }
-                        }
+                    if (!success) {
+                        Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
                         return;
                     }
+                    mLinkProperties = dhcpResults.linkProperties;
+                    synchronized (mNetworkInfoLock) {
+                        mNetworkInfo.setIsAvailable(true);
+                        mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
+                        if (mCsHandler != null) {
+                            Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED,
+                                    new NetworkInfo(mNetworkInfo));
+                            msg.sendToTarget();
+                       }
+                    }
+                    return;
                 }
-                Log.e(TAG, "startReverseTether, dhcp failed, resut: " + result);
             }
         });
-        mDhcpThread.start();
+        dhcpThread.start();
     }
 
-    public synchronized void stopReverseTether() {
-        //NetworkUtils.stopDhcp(iface);
-        if(mDhcpThread != null && mDhcpThread.isAlive()) {
-            mDhcpThread.interrupt();
-            try { mDhcpThread.join(); } catch (InterruptedException ie) { return; }
+    void stopReverseTether() {
+        synchronized (mLinkPropertiesLock) {
+            if (TextUtils.isEmpty(mLinkProperties.getInterfaceName())) {
+                Log.e(TAG, "attempted to stop reverse tether with nothing tethered");
+                return;
+            }
+            NetworkUtils.stopDhcp(mLinkProperties.getInterfaceName());
+            mLinkProperties.clear();
+            synchronized (mNetworkInfoLock) {
+                mNetworkInfo.setIsAvailable(false);
+                mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
+
+                if (mCsHandler != null) {
+                    mCsHandler.obtainMessage(EVENT_STATE_CHANGED, new NetworkInfo(mNetworkInfo)).
+                            sendToTarget();
+                }
+            }
         }
-        mLinkProperties.clear();
-        mNetworkInfo.setIsAvailable(false);
-        mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
-
-        Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
-        msg.sendToTarget();
-
-        msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
-        msg.sendToTarget();
     }
 
     public void setDependencyMet(boolean met) {
@@ -383,4 +380,54 @@
     public void removeStackedLink(LinkProperties link) {
         mLinkProperties.removeStackedLink(link);
     }
+
+    static class BtdtHandler extends Handler {
+        private AsyncChannel mStackChannel;
+        private final BluetoothTetheringDataTracker mBtdt;
+
+        BtdtHandler(Looper looper, BluetoothTetheringDataTracker parent) {
+            super(looper);
+            mBtdt = parent;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                    if (VDBG) Log.d(TAG, "got CMD_CHANNEL_HALF_CONNECTED");
+                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
+                        AsyncChannel ac = (AsyncChannel)msg.obj;
+                        if (mBtdt.mAsyncChannel.compareAndSet(null, ac) == false) {
+                            Log.e(TAG, "Trying to set mAsyncChannel twice!");
+                        } else {
+                            ac.sendMessage(
+                                    AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+                        }
+                    }
+                    break;
+                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+                    if (VDBG) Log.d(TAG, "got CMD_CHANNEL_DISCONNECTED");
+                    mBtdt.stopReverseTether();
+                    mBtdt.mAsyncChannel.set(null);
+                    break;
+                case NetworkStateTracker.EVENT_NETWORK_CONNECTED:
+                    LinkProperties linkProperties = (LinkProperties)(msg.obj);
+                    if (VDBG) Log.d(TAG, "got EVENT_NETWORK_CONNECTED, " + linkProperties);
+                    mBtdt.startReverseTether(linkProperties);
+                    break;
+                case NetworkStateTracker.EVENT_NETWORK_DISCONNECTED:
+                    linkProperties = (LinkProperties)(msg.obj);
+                    if (VDBG) Log.d(TAG, "got EVENT_NETWORK_DISCONNECTED, " + linkProperties);
+                    mBtdt.stopReverseTether();
+                    break;
+            }
+        }
+    }
+
+    @Override
+    public void supplyMessenger(Messenger messenger) {
+        if (messenger != null) {
+            new AsyncChannel().connect(mContext, mBtdtHandler, messenger);
+        }
+    }
 }
diff --git a/core/java/android/net/BaseNetworkStateTracker.java b/core/java/android/net/BaseNetworkStateTracker.java
index a554611..1165281 100644
--- a/core/java/android/net/BaseNetworkStateTracker.java
+++ b/core/java/android/net/BaseNetworkStateTracker.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.Handler;
+import android.os.Messenger;
 
 import com.android.internal.util.Preconditions;
 
@@ -165,4 +166,9 @@
     public void removeStackedLink(LinkProperties link) {
         mLinkProperties.removeStackedLink(link);
     }
+
+    @Override
+    public void supplyMessenger(Messenger messenger) {
+        // not supported on this network
+    }
 }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 3a04c27..4e4980d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
+import android.os.Messenger;
 import android.os.RemoteException;
 import android.provider.Settings;
 
@@ -1280,4 +1281,17 @@
         }
     }
 
+    /**
+     * Supply the backend messenger for a network tracker
+     *
+     * @param type NetworkType to set
+     * @param messenger {@link Messenger}
+     * {@hide}
+     */
+    public void supplyMessenger(int networkType, Messenger messenger) {
+        try {
+            mService.supplyMessenger(networkType, messenger);
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
index db8f0bc..15a81f3 100644
--- a/core/java/android/net/DummyDataStateTracker.java
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Messenger;
 import android.util.Slog;
 
 /**
@@ -213,6 +214,11 @@
         mLinkProperties.removeStackedLink(link);
     }
 
+    @Override
+    public void supplyMessenger(Messenger messenger) {
+        // not supported on this network
+    }
+
     static private void log(String s) {
         Slog.d(TAG, s);
     }
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index b744a47..27d5a58 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -22,6 +22,7 @@
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Message;
+import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
@@ -417,4 +418,9 @@
     public void removeStackedLink(LinkProperties link) {
         mLinkProperties.removeStackedLink(link);
     }
+
+    @Override
+    public void supplyMessenger(Messenger messenger) {
+        // not supported on this network
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 056fa03..9e9b43d 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -22,6 +22,7 @@
 import android.net.NetworkState;
 import android.net.ProxyProperties;
 import android.os.IBinder;
+import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
 
 import com.android.internal.net.LegacyVpnInfo;
@@ -126,4 +127,6 @@
     boolean updateLockdownVpn();
 
     void captivePortalCheckComplete(in NetworkInfo info);
+
+    void supplyMessenger(int networkType, in Messenger messenger);
 }
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index faf739b..e85dbcd 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -74,7 +74,6 @@
 
     private Handler mHandler;
     private AsyncChannel mDataConnectionTrackerAc;
-    private Messenger mMessenger;
 
     /**
      * Create a new MobileDataStateTracker
@@ -103,7 +102,6 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
-        filter.addAction(DctConstants.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);
 
         mContext.registerReceiver(new MobileDataStateReceiver(), filter);
         mMobileDataState = PhoneConstants.DataState.DISCONNECTED;
@@ -285,13 +283,6 @@
                                 " broadcast" + reason == null ? "" : "(" + reason + ")");
                 }
                 setDetailedState(DetailedState.FAILED, reason, apnName);
-            } else if (intent.getAction().equals(DctConstants
-                    .ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
-                if (VDBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER");
-                mMessenger =
-                    intent.getParcelableExtra(DctConstants.EXTRA_MESSENGER);
-                AsyncChannel ac = new AsyncChannel();
-                ac.connect(mContext, MobileDataStateTracker.this.mHandler, mMessenger);
             } else {
                 if (DBG) log("Broadcast received: ignore " + intent.getAction());
             }
@@ -613,6 +604,12 @@
         return new LinkCapabilities(mLinkCapabilities);
     }
 
+    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);
     }
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index b22159c..cf77a1c 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -18,6 +18,9 @@
 
 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}
@@ -48,25 +51,38 @@
      * msg.what = EVENT_STATE_CHANGED
      * msg.obj = NetworkInfo object
      */
-    public static final int EVENT_STATE_CHANGED = 1;
+    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 = 3;
+    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 = 6;
+    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 = 7;
+    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;
+
 
     /**
      * -------------------------------------------------------------
@@ -207,4 +223,10 @@
      * Informs the state tracker that a stacked interface has been removed.
      **/
     public void removeStackedLink(LinkProperties link);
+
+    /*
+     * Called once to setup async channel between this and
+     * the underlying network specific code.
+     */
+    public void supplyMessenger(Messenger messenger);
 }
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 4b83611..45524c8 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -152,16 +152,6 @@
     boolean isTetheringStarted();
 
     /**
-     * Start bluetooth reverse tethering services
-     */
-    void startReverseTethering(in String iface);
-
-    /**
-     * Stop currently running bluetooth reserse tethering services
-     */
-    void stopReverseTethering();
-
-    /**
      * Tethers the specified interface
      */
     void tetherInterface(String iface);
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
index 91b109e..b380403 100644
--- a/core/java/com/android/internal/util/Protocol.java
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -52,5 +52,6 @@
     public static final int BASE_DATA_CONNECTION_TRACKER                            = 0x00042000;
     public static final int BASE_DNS_PINGER                                         = 0x00050000;
     public static final int BASE_NSD_MANAGER                                        = 0x00060000;
+    public static final int BASE_NETWORK_STATE_TRACKER                              = 0x00070000;
     //TODO: define all used protocols
 }
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 33e712a..924b9df 100755
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -1081,9 +1081,9 @@
                         if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) return true;
                     } else if (off) {
                         if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) return true;
-		    } else {
+                    } else {
                         if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) return true;
-		    }
+                    }
                 } catch (RemoteException e) {
                     Log.e(TAG, "getState()", e);
                     break;
@@ -1091,9 +1091,9 @@
             }
             if (on || off) {
                 SystemClock.sleep(300);
-	    } else {
+            } else {
                 SystemClock.sleep(50);
-	    }
+            }
             i++;
         }
         Log.e(TAG,"waitForOnOff time out");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 6dcb403..0bb0366 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -74,6 +74,7 @@
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
 import android.os.Process;
@@ -3220,7 +3221,7 @@
         throwIfLockdownEnabled();
         try {
             int type = mActiveDefaultNetwork;
-            if (ConnectivityManager.isNetworkTypeValid(type)) {
+            if (ConnectivityManager.isNetworkTypeValid(type) && mNetTrackers[type] != null) {
                 mVpn.protect(socket, mNetTrackers[type].getLinkProperties().getInterfaceName());
                 return true;
             }
@@ -3425,4 +3426,12 @@
             throw new IllegalStateException("Unavailable in lockdown mode");
         }
     }
+
+    public void supplyMessenger(int networkType, Messenger messenger) {
+        enforceConnectivityInternalPermission();
+
+        if (isNetworkTypeValid(networkType) && mNetTrackers[networkType] != null) {
+            mNetTrackers[networkType].supplyMessenger(messenger);
+        }
+    }
 }
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 2210a18..d2acb40 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -839,33 +839,6 @@
         return event.getMessage().endsWith("started");
     }
 
-    // TODO(BT) Remove
-    @Override
-    public void startReverseTethering(String iface) {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        // cmd is "tether start first_start first_stop second_start second_stop ..."
-        // an odd number of addrs will fail
-        try {
-            mConnector.execute("tether", "start-reverse", iface);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
-        }
-        BluetoothTetheringDataTracker.getInstance().startReverseTether(iface);
-
-    }
-
-    // TODO(BT) Remove
-    @Override
-    public void stopReverseTethering() {
-        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        try {
-            mConnector.execute("tether", "stop-reverse");
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
-        }
-        BluetoothTetheringDataTracker.getInstance().stopReverseTether();
-    }
-
     @Override
     public void tetherInterface(String iface) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index cacafd4..9d556c0 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -111,7 +111,4 @@
     public static final int ENABLED = 1;
 
     public static final String APN_TYPE_KEY = "apnType";
-    public static String ACTION_DATA_CONNECTION_TRACKER_MESSENGER =
-        "com.android.internal.telephony";
-    public static String EXTRA_MESSENGER = "EXTRA_MESSENGER";
 }
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 81d2e11..cf75381 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -27,6 +27,7 @@
 import android.net.NetworkStateTracker;
 import android.os.Handler;
 import android.os.Message;
+import android.os.Messenger;
 import android.util.Slog;
 
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -262,4 +263,9 @@
     public void removeStackedLink(LinkProperties link) {
         mLinkProperties.removeStackedLink(link);
     }
+
+    @Override
+    public void supplyMessenger(Messenger messenger) {
+        // not supported on this network
+    }
 }