Use IpManager on Ethernet
Bug: 17733693 Bug: 26991160 Change-Id: Idaee8c64bf452e58b93031d8d7ad666edb0c82ae
This commit is contained in:
@@ -31,8 +31,8 @@ import android.net.NetworkCapabilities;
|
|||||||
import android.net.NetworkFactory;
|
import android.net.NetworkFactory;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkInfo.DetailedState;
|
import android.net.NetworkInfo.DetailedState;
|
||||||
import android.net.NetworkUtils;
|
|
||||||
import android.net.StaticIpConfiguration;
|
import android.net.StaticIpConfiguration;
|
||||||
|
import android.net.ip.IpManager;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.INetworkManagementService;
|
import android.os.INetworkManagementService;
|
||||||
@@ -100,6 +100,8 @@ class EthernetNetworkFactory {
|
|||||||
private static boolean mLinkUp;
|
private static boolean mLinkUp;
|
||||||
private NetworkInfo mNetworkInfo;
|
private NetworkInfo mNetworkInfo;
|
||||||
private LinkProperties mLinkProperties;
|
private LinkProperties mLinkProperties;
|
||||||
|
private IpManager mIpManager;
|
||||||
|
private Thread mIpProvisioningThread;
|
||||||
|
|
||||||
EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) {
|
EthernetNetworkFactory(RemoteCallbackList<IEthernetServiceListener> listeners) {
|
||||||
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_ETHERNET, 0, NETWORK_TYPE, "");
|
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.
|
* Updates interface state variables.
|
||||||
@@ -137,6 +154,7 @@ class EthernetNetworkFactory {
|
|||||||
if (!up) {
|
if (!up) {
|
||||||
// Tell the agent we're disconnected. It will call disconnect().
|
// Tell the agent we're disconnected. It will call disconnect().
|
||||||
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
|
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
|
||||||
|
stopIpProvisioningThreadLocked();
|
||||||
}
|
}
|
||||||
updateAgent();
|
updateAgent();
|
||||||
// set our score lower than any network could go
|
// set our score lower than any network could go
|
||||||
@@ -166,7 +184,6 @@ class EthernetNetworkFactory {
|
|||||||
private void setInterfaceUp(String iface) {
|
private void setInterfaceUp(String iface) {
|
||||||
// Bring up the interface so we get link status indications.
|
// Bring up the interface so we get link status indications.
|
||||||
try {
|
try {
|
||||||
NetworkUtils.stopDhcp(iface);
|
|
||||||
mNMService.setInterfaceUp(iface);
|
mNMService.setInterfaceUp(iface);
|
||||||
String hwAddr = null;
|
String hwAddr = null;
|
||||||
InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
|
InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
|
||||||
@@ -209,7 +226,7 @@ class EthernetNetworkFactory {
|
|||||||
Log.d(TAG, "Stopped tracking interface " + iface);
|
Log.d(TAG, "Stopped tracking interface " + iface);
|
||||||
// TODO: Unify this codepath with stop().
|
// TODO: Unify this codepath with stop().
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
NetworkUtils.stopDhcp(mIface);
|
stopIpProvisioningThreadLocked();
|
||||||
setInterfaceInfoLocked("", null);
|
setInterfaceInfoLocked("", null);
|
||||||
mNetworkInfo.setExtraInfo(null);
|
mNetworkInfo.setExtraInfo(null);
|
||||||
mLinkUp = false;
|
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. */
|
/* Called by the NetworkFactory on the handler thread. */
|
||||||
public void onRequestNetwork() {
|
public void onRequestNetwork() {
|
||||||
|
synchronized(EthernetNetworkFactory.this) {
|
||||||
|
if (mIpProvisioningThread != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Handle DHCP renew.
|
// TODO: Handle DHCP renew.
|
||||||
Thread dhcpThread = new Thread(new Runnable() {
|
final Thread ipProvisioningThread = new Thread(new Runnable() {
|
||||||
public void run() {
|
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;
|
LinkProperties linkProperties;
|
||||||
|
|
||||||
IpConfiguration config = mEthernetManager.getConfiguration();
|
IpConfiguration config = mEthernetManager.getConfiguration();
|
||||||
@@ -275,39 +332,41 @@ class EthernetNetworkFactory {
|
|||||||
linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);
|
linkProperties = config.getStaticIpConfiguration().toLinkProperties(mIface);
|
||||||
} else {
|
} else {
|
||||||
mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
|
mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
|
||||||
|
IpManagerCallback blockingCallback = new IpManagerCallback();
|
||||||
DhcpResults dhcpResults = new DhcpResults();
|
synchronized(EthernetNetworkFactory.this) {
|
||||||
// TODO: Handle DHCP renewals better.
|
stopIpManagerLocked();
|
||||||
// In general runDhcp handles DHCP renewals for us, because
|
mIpManager = new IpManager(mContext, mIface, blockingCallback);
|
||||||
// the dhcp client stays running, but if the renewal fails,
|
mIpManager.startProvisioning();
|
||||||
// we will lose our IP address and connectivity without
|
}
|
||||||
// noticing.
|
linkProperties = blockingCallback.waitForProvisioning();
|
||||||
if (!NetworkUtils.runDhcp(mIface, dhcpResults)) {
|
if (linkProperties == null) {
|
||||||
Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
|
Log.e(TAG, "IP provisioning error");
|
||||||
// set our score lower than any network could go
|
// set our score lower than any network could go
|
||||||
// so we get dropped.
|
// so we get dropped.
|
||||||
mFactory.setScoreFilter(-1);
|
mFactory.setScoreFilter(-1);
|
||||||
// If DHCP timed out (as opposed to failing), the DHCP client will still be
|
synchronized(EthernetNetworkFactory.this) {
|
||||||
// running, because in M we changed its timeout to infinite. Stop it now.
|
stopIpManagerLocked();
|
||||||
NetworkUtils.stopDhcp(mIface);
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
linkProperties = dhcpResults.toLinkProperties(mIface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.getProxySettings() == ProxySettings.STATIC ||
|
if (config.getProxySettings() == ProxySettings.STATIC ||
|
||||||
config.getProxySettings() == ProxySettings.PAC) {
|
config.getProxySettings() == ProxySettings.PAC) {
|
||||||
linkProperties.setHttpProxy(config.getHttpProxy());
|
linkProperties.setHttpProxy(config.getHttpProxy());
|
||||||
}
|
}
|
||||||
|
|
||||||
String tcpBufferSizes = mContext.getResources().getString(
|
final String tcpBufferSizes = mContext.getResources().getString(
|
||||||
com.android.internal.R.string.config_ethernet_tcp_buffers);
|
com.android.internal.R.string.config_ethernet_tcp_buffers);
|
||||||
if (TextUtils.isEmpty(tcpBufferSizes) == false) {
|
if (!TextUtils.isEmpty(tcpBufferSizes)) {
|
||||||
linkProperties.setTcpBufferSizes(tcpBufferSizes);
|
linkProperties.setTcpBufferSizes(tcpBufferSizes);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized(EthernetNetworkFactory.this) {
|
synchronized(EthernetNetworkFactory.this) {
|
||||||
if (mNetworkAgent != null) {
|
if (mNetworkAgent != null) {
|
||||||
Log.e(TAG, "Already have a NetworkAgent - aborting new request");
|
Log.e(TAG, "Already have a NetworkAgent - aborting new request");
|
||||||
|
stopIpManagerLocked();
|
||||||
|
mIpProvisioningThread = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mLinkProperties = linkProperties;
|
mLinkProperties = linkProperties;
|
||||||
@@ -321,7 +380,7 @@ class EthernetNetworkFactory {
|
|||||||
public void unwanted() {
|
public void unwanted() {
|
||||||
synchronized(EthernetNetworkFactory.this) {
|
synchronized(EthernetNetworkFactory.this) {
|
||||||
if (this == mNetworkAgent) {
|
if (this == mNetworkAgent) {
|
||||||
NetworkUtils.stopDhcp(mIface);
|
stopIpManagerLocked();
|
||||||
|
|
||||||
mLinkProperties.clear();
|
mLinkProperties.clear();
|
||||||
mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null,
|
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() {
|
public synchronized void stop() {
|
||||||
NetworkUtils.stopDhcp(mIface);
|
stopIpProvisioningThreadLocked();
|
||||||
// ConnectivityService will only forget our NetworkAgent if we send it a NetworkInfo object
|
// 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:
|
// 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.
|
// that sets the state to IDLE, and ConnectivityService will still think we're connected.
|
||||||
|
|||||||
Reference in New Issue
Block a user