diff options
author | Erik Kline <ek@google.com> | 2016-02-11 22:06:48 +0900 |
---|---|---|
committer | Erik Kline <ek@google.com> | 2016-02-17 22:19:22 +0900 |
commit | 5972bfdf382db384946ba10a8caf2a04270fef43 (patch) | |
tree | da50f9cd775d589503dca6bbf829d81f74d7f5fe | |
parent | 3e81fb6ecfc5aa401baf5b07ba74acb772c89b0b (diff) | |
download | ethernet-5972bfdf382db384946ba10a8caf2a04270fef43.tar.gz |
Use IpManager on Ethernet
Bug: 17733693
Bug: 26991160
Change-Id: Idaee8c64bf452e58b93031d8d7ad666edb0c82ae
-rw-r--r-- | java/com/android/server/ethernet/EthernetNetworkFactory.java | 118 |
1 files changed, 95 insertions, 23 deletions
diff --git a/java/com/android/server/ethernet/EthernetNetworkFactory.java b/java/com/android/server/ethernet/EthernetNetworkFactory.java index 6074dda..3c230fb 100644 --- a/java/com/android/server/ethernet/EthernetNetworkFactory.java +++ b/java/com/android/server/ethernet/EthernetNetworkFactory.java @@ -31,8 +31,8 @@ import android.net.NetworkCapabilities; import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; -import android.net.NetworkUtils; import android.net.StaticIpConfiguration; +import android.net.ip.IpManager; import android.os.Handler; import android.os.IBinder; import android.os.INetworkManagementService; @@ -100,6 +100,8 @@ class EthernetNetworkFactory { private static boolean mLinkUp; private NetworkInfo mNetworkInfo; private LinkProperties mLinkProperties; + private IpManager mIpManager; + private Thread mIpProvisioningThread; EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) { mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, ""); @@ -120,6 +122,21 @@ class EthernetNetworkFactory { } } + private void stopIpManagerLocked() { + if (mIpManager != null) { + mIpManager.shutdown(); + mIpManager = null; + } + } + + private void stopIpProvisioningThreadLocked() { + stopIpManagerLocked(); + + if (mIpProvisioningThread != null) { + mIpProvisioningThread.interrupt(); + mIpProvisioningThread = null; + } + } /** * Updates interface state variables. @@ -137,6 +154,7 @@ class EthernetNetworkFactory { if (!up) { // Tell the agent we're disconnected. It will call disconnect(). mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr); + stopIpProvisioningThreadLocked(); } updateAgent(); // set our score lower than any network could go @@ -166,7 +184,6 @@ class EthernetNetworkFactory { private void setInterfaceUp(String iface) { // Bring up the interface so we get link status indications. try { - NetworkUtils.stopDhcp(iface); mNMService.setInterfaceUp(iface); String hwAddr = null; InterfaceConfiguration config = mNMService.getInterfaceConfig(iface); @@ -209,7 +226,7 @@ class EthernetNetworkFactory { Log.d(TAG, "Stopped tracking interface " + iface); // TODO: Unify this codepath with stop(). synchronized (this) { - NetworkUtils.stopDhcp(mIface); + stopIpProvisioningThreadLocked(); setInterfaceInfoLocked("", null); mNetworkInfo.setExtraInfo(null); mLinkUp = false; @@ -257,12 +274,52 @@ class EthernetNetworkFactory { } } + private class IpManagerCallback extends IpManager.Callback { + private LinkProperties mCallbackLinkProperties; + + public LinkProperties waitForProvisioning() { + synchronized (this) { + try { + wait(); + } catch (InterruptedException e) {} + return mCallbackLinkProperties; + } + } + + @Override + public void onProvisioningSuccess(LinkProperties newLp) { + synchronized (this) { + mCallbackLinkProperties = newLp; + notify(); + } + } + + @Override + public void onProvisioningFailure(LinkProperties newLp) { + synchronized (this) { + mCallbackLinkProperties = null; + notify(); + } + } + } + + /* Called by the NetworkFactory on the handler thread. */ public void onRequestNetwork() { + synchronized(EthernetNetworkFactory.this) { + if (mIpProvisioningThread != null) { + return; + } + } + // TODO: Handle DHCP renew. - Thread dhcpThread = new Thread(new Runnable() { + final Thread ipProvisioningThread = new Thread(new Runnable() { public void run() { - if (DBG) Log.i(TAG, "dhcpThread(" + mIface + "): mNetworkInfo=" + mNetworkInfo); + if (DBG) { + Log.d(TAG, String.format("starting ipProvisioningThread(%s): mNetworkInfo=%s", + mIface, mNetworkInfo)); + } + LinkProperties linkProperties; IpConfiguration config = mEthernetManager.getConfiguration(); @@ -275,39 +332,41 @@ class EthernetNetworkFactory { linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface); } else { mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr); - - 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(mIface, dhcpResults)) { - Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError()); + IpManagerCallback blockingCallback = new IpManagerCallback(); + synchronized(EthernetNetworkFactory.this) { + stopIpManagerLocked(); + mIpManager = new IpManager(mContext, mIface, blockingCallback); + mIpManager.startProvisioning(); + } + linkProperties = blockingCallback.waitForProvisioning(); + if (linkProperties == null) { + Log.e(TAG, "IP provisioning error"); // set our score lower than any network could go // so we get dropped. mFactory.setScoreFilter(-1); - // If DHCP timed out (as opposed to failing), the DHCP client will still be - // running, because in M we changed its timeout to infinite. Stop it now. - NetworkUtils.stopDhcp(mIface); + synchronized(EthernetNetworkFactory.this) { + stopIpManagerLocked(); + } return; } - linkProperties = dhcpResults.toLinkProperties(mIface); } + if (config.getProxySettings() == ProxySettings.STATIC || config.getProxySettings() == ProxySettings.PAC) { linkProperties.setHttpProxy(config.getHttpProxy()); } - String tcpBufferSizes = mContext.getResources().getString( + final String tcpBufferSizes = mContext.getResources().getString( com.android.internal.R.string.config_ethernet_tcp_buffers); - if (TextUtils.isEmpty(tcpBufferSizes) == false) { + if (!TextUtils.isEmpty(tcpBufferSizes)) { linkProperties.setTcpBufferSizes(tcpBufferSizes); } synchronized(EthernetNetworkFactory.this) { if (mNetworkAgent != null) { Log.e(TAG, "Already have a NetworkAgent - aborting new request"); + stopIpManagerLocked(); + mIpProvisioningThread = null; return; } mLinkProperties = linkProperties; @@ -321,7 +380,7 @@ class EthernetNetworkFactory { public void unwanted() { synchronized(EthernetNetworkFactory.this) { if (this == mNetworkAgent) { - NetworkUtils.stopDhcp(mIface); + stopIpManagerLocked(); mLinkProperties.clear(); mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, @@ -340,10 +399,23 @@ class EthernetNetworkFactory { } }; }; + + mIpProvisioningThread = null; + } + + if (DBG) { + Log.d(TAG, String.format("exiting ipProvisioningThread(%s): mNetworkInfo=%s", + mIface, mNetworkInfo)); } } }); - dhcpThread.start(); + + synchronized(EthernetNetworkFactory.this) { + if (mIpProvisioningThread == null) { + mIpProvisioningThread = ipProvisioningThread; + mIpProvisioningThread.start(); + } + } } /** @@ -402,7 +474,7 @@ class EthernetNetworkFactory { } public synchronized void stop() { - NetworkUtils.stopDhcp(mIface); + stopIpProvisioningThreadLocked(); // ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object // with a state of DISCONNECTED or SUSPENDED. So we can't simply clear our NetworkInfo here: // that sets the state to IDLE, and ConnectivityService will still think we're connected. |