OSDN Git Service

Use IpManager when feeling Pan-tastic
authorErik Kline <ek@google.com>
Wed, 17 Feb 2016 13:52:02 +0000 (22:52 +0900)
committerErik Kline <ek@google.com>
Mon, 22 Feb 2016 07:32:59 +0000 (16:32 +0900)
Convert Bluetooth PAN from dhcpcd to IpManager.

Bug: 26991160
Change-Id: Iec8a48294702a8d214f43bea5ef9a041fa52d20f

Android.mk
src/com/android/bluetooth/pan/BluetoothTetheringNetworkFactory.java

index 09cbaf4..65f08b6 100644 (file)
@@ -22,8 +22,8 @@ LOCAL_PACKAGE_NAME := Bluetooth
 LOCAL_CERTIFICATE := platform
 
 LOCAL_JNI_SHARED_LIBRARIES := libbluetooth_jni
-LOCAL_JAVA_LIBRARIES := javax.obex telephony-common libprotobuf-java-micro
-LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard  bluetooth.mapsapi sap-api-java-static android-support-v4
+LOCAL_JAVA_LIBRARIES := javax.obex telephony-common libprotobuf-java-micro services.net
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard bluetooth.mapsapi sap-api-java-static android-support-v4 services.net
 LOCAL_PROTOC_OPTIMIZE_TYPE := micro
 
 LOCAL_REQUIRED_MODULES := bluetooth.default
index 9437794..22b3bc6 100644 (file)
@@ -27,7 +27,8 @@ import android.net.NetworkFactory;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkRequest;
-import android.net.NetworkUtils;
+import android.net.ip.IpManager;
+import android.net.ip.IpManager.WaitForProvisioningCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
@@ -56,7 +57,8 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory {
 
     // All accesses to these must be synchronized(this).
     private final NetworkInfo mNetworkInfo;
-    private LinkProperties mLinkProperties;
+    private IpManager mIpManager;
+    private String mInterfaceName;
     private NetworkAgent mNetworkAgent;
 
     public BluetoothTetheringNetworkFactory(Context context, Looper looper, PanService panService) {
@@ -66,54 +68,72 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory {
         mPanService = panService;
 
         mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_BLUETOOTH, 0, NETWORK_TYPE, "");
-        mLinkProperties = new LinkProperties();
         mNetworkCapabilities = new NetworkCapabilities();
         initNetworkCapabilities();
         setCapabilityFilter(mNetworkCapabilities);
     }
 
+    private void stopIpManagerLocked() {
+        if (mIpManager != null) {
+            mIpManager.shutdown();
+            mIpManager = null;
+        }
+    }
+
     // Called by NetworkFactory when PanService and NetworkFactory both desire a Bluetooth
     // reverse-tether connection.  A network interface for Bluetooth reverse-tethering can be
     // assumed to be available because we only register our NetworkFactory when it is so.
     @Override
     protected void startNetwork() {
-        // TODO: Handle DHCP renew.
-        Thread dhcpThread = new Thread(new Runnable() {
+        // TODO: Figure out how to replace this thread with simple invocations
+        // of IpManager. This will likely necessitate a rethink about
+        // NetworkAgent, NetworkInfo, and associated instance lifetimes.
+        Thread ipProvisioningThread = new Thread(new Runnable() {
             public void run() {
                 LinkProperties linkProperties;
+                final WaitForProvisioningCallback ipmCallback = new WaitForProvisioningCallback() {
+                    @Override
+                    public void onLinkPropertiesChange(LinkProperties newLp) {
+                        synchronized (BluetoothTetheringNetworkFactory.this) {
+                            if (mNetworkAgent != null && mNetworkInfo.isConnected()) {
+                                mNetworkAgent.sendLinkProperties(newLp);
+                            }
+                        }
+                    }
+                };
+
                 synchronized (BluetoothTetheringNetworkFactory.this) {
-                    linkProperties = mLinkProperties;
-                    if (linkProperties.getInterfaceName() == null) {
+                    if (TextUtils.isEmpty(mInterfaceName)) {
                         Slog.e(TAG, "attempted to reverse tether without interface name");
                         return;
                     }
-                    log("dhcpThread(+" + linkProperties.getInterfaceName() +
-                            "): mNetworkInfo=" + mNetworkInfo);
+                    log("ipProvisioningThread(+" + mInterfaceName + "): " +
+                            "mNetworkInfo=" + mNetworkInfo);
+                    mIpManager = new IpManager(mContext, mInterfaceName, ipmCallback);
+                    mIpManager.startProvisioning(
+                            mIpManager.buildProvisioningConfiguration()
+                                    .withoutIpReachabilityMonitor()
+                                    .build());
+                    mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, null);
                 }
 
-                DhcpResults dhcpResults = new DhcpResults();
-                // TODO: Handle DHCP renewals better.
-                // In general runDhcp handles DHCP renewals for us, because
-                // the dhcp client stays running, but if the renewal fails,
-                // we will lose our IP address and connectivity without
-                // noticing.
-                if (!NetworkUtils.runDhcp(linkProperties.getInterfaceName(), dhcpResults)) {
-                    Slog.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
+                linkProperties = ipmCallback.waitForProvisioning();
+                if (linkProperties == null) {
+                    Slog.e(TAG, "IP provisioning error.");
                     synchronized(BluetoothTetheringNetworkFactory.this) {
+                        stopIpManagerLocked();
                         setScoreFilter(-1);
                     }
                     return;
                 }
 
                 synchronized(BluetoothTetheringNetworkFactory.this) {
-                    mLinkProperties = dhcpResults.toLinkProperties(
-                            linkProperties.getInterfaceName());
                     mNetworkInfo.setIsAvailable(true);
                     mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null);
 
                     // Create our NetworkAgent.
                     mNetworkAgent = new NetworkAgent(getLooper(), mContext, NETWORK_TYPE,
-                            mNetworkInfo, mNetworkCapabilities, mLinkProperties, NETWORK_SCORE) {
+                            mNetworkInfo, mNetworkCapabilities, linkProperties, NETWORK_SCORE) {
                         public void unwanted() {
                             BluetoothTetheringNetworkFactory.this.onCancelRequest();
                         };
@@ -121,7 +141,7 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory {
                 }
             }
         });
-        dhcpThread.start();
+        ipProvisioningThread.start();
     }
 
     // Called from NetworkFactory to indicate ConnectivityService no longer desires a Bluetooth
@@ -133,10 +153,9 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory {
 
     // Called by the NetworkFactory, NetworkAgent or PanService to tear down network.
     private synchronized void onCancelRequest() {
-        if (!TextUtils.isEmpty(mLinkProperties.getInterfaceName())) {
-            NetworkUtils.stopDhcp(mLinkProperties.getInterfaceName());
-        }
-        mLinkProperties.clear();
+        stopIpManagerLocked();
+        mInterfaceName = "";
+
         mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
         if (mNetworkAgent != null) {
             mNetworkAgent.sendNetworkInfo(mNetworkInfo);
@@ -155,12 +174,11 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory {
             return;
         }
         synchronized(this) {
-            if (mLinkProperties.getInterfaceName() != null) {
+            if (!TextUtils.isEmpty(mInterfaceName)) {
                 Slog.e(TAG, "attempted to reverse tether while already in process");
                 return;
             }
-            mLinkProperties = new LinkProperties();
-            mLinkProperties.setInterfaceName(iface);
+            mInterfaceName = iface;
             // Advertise ourselves to ConnectivityService.
             register();
             setScoreFilter(NETWORK_SCORE);
@@ -170,7 +188,7 @@ public class BluetoothTetheringNetworkFactory extends NetworkFactory {
     // Called by PanService when a network interface for Bluetooth reverse-tethering
     // goes away.  We stop advertising ourselves to ConnectivityService at this point.
     public synchronized void stopReverseTether() {
-        if (TextUtils.isEmpty(mLinkProperties.getInterfaceName())) {
+        if (TextUtils.isEmpty(mInterfaceName)) {
             Slog.e(TAG, "attempted to stop reverse tether with nothing tethered");
             return;
         }