Merge "Add blocking and retrying wrappers for INetd uses."
This commit is contained in:
@@ -23,6 +23,7 @@ import android.content.Context;
|
|||||||
import android.net.apf.ApfCapabilities;
|
import android.net.apf.ApfCapabilities;
|
||||||
import android.net.apf.ApfFilter;
|
import android.net.apf.ApfFilter;
|
||||||
import android.net.DhcpResults;
|
import android.net.DhcpResults;
|
||||||
|
import android.net.INetd;
|
||||||
import android.net.InterfaceConfiguration;
|
import android.net.InterfaceConfiguration;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
@@ -34,10 +35,12 @@ import android.net.dhcp.DhcpClient;
|
|||||||
import android.net.metrics.IpConnectivityLog;
|
import android.net.metrics.IpConnectivityLog;
|
||||||
import android.net.metrics.IpManagerEvent;
|
import android.net.metrics.IpManagerEvent;
|
||||||
import android.net.util.MultinetworkPolicyTracker;
|
import android.net.util.MultinetworkPolicyTracker;
|
||||||
|
import android.net.util.NetdService;
|
||||||
import android.os.INetworkManagementService;
|
import android.os.INetworkManagementService;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.ServiceSpecificException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.LocalLog;
|
import android.util.LocalLog;
|
||||||
@@ -1027,14 +1030,16 @@ public class IpManager extends StateMachine {
|
|||||||
|
|
||||||
private boolean startIPv6() {
|
private boolean startIPv6() {
|
||||||
// Set privacy extensions.
|
// Set privacy extensions.
|
||||||
|
final String PREFER_TEMPADDRS = "2";
|
||||||
try {
|
try {
|
||||||
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
|
NetdService.run((INetd netd) -> {
|
||||||
|
netd.setProcSysNet(
|
||||||
|
INetd.IPV6, INetd.CONF, mInterfaceName, "use_tempaddr",
|
||||||
|
PREFER_TEMPADDRS);
|
||||||
|
});
|
||||||
mNwService.enableIpv6(mInterfaceName);
|
mNwService.enableIpv6(mInterfaceName);
|
||||||
} catch (RemoteException re) {
|
} catch (IllegalStateException|RemoteException|ServiceSpecificException e) {
|
||||||
logError("Unable to change interface settings: %s", re);
|
logError("Unable to change interface settings: %s", e);
|
||||||
return false;
|
|
||||||
} catch (IllegalStateException ie) {
|
|
||||||
logError("Unable to change interface settings: %s", ie);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,10 @@
|
|||||||
package android.net.util;
|
package android.net.util;
|
||||||
|
|
||||||
import android.net.INetd;
|
import android.net.INetd;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.ServiceSpecificException;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
@@ -27,15 +30,24 @@ import android.util.Log;
|
|||||||
public class NetdService {
|
public class NetdService {
|
||||||
private static final String TAG = NetdService.class.getSimpleName();
|
private static final String TAG = NetdService.class.getSimpleName();
|
||||||
private static final String NETD_SERVICE_NAME = "netd";
|
private static final String NETD_SERVICE_NAME = "netd";
|
||||||
|
private static final long BASE_TIMEOUT_MS = 100;
|
||||||
|
private static final long MAX_TIMEOUT_MS = 1000;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Return an INetd instance, or null if not available.
|
||||||
|
*
|
||||||
* It is the caller's responsibility to check for a null return value
|
* It is the caller's responsibility to check for a null return value
|
||||||
* and to handle RemoteException errors from invocations on the returned
|
* and to handle RemoteException errors from invocations on the returned
|
||||||
* interface if, for example, netd dies and is restarted.
|
* interface if, for example, netd dies and is restarted.
|
||||||
*
|
*
|
||||||
|
* Returned instances of INetd should not be cached.
|
||||||
|
*
|
||||||
* @return an INetd instance or null.
|
* @return an INetd instance or null.
|
||||||
*/
|
*/
|
||||||
public static INetd getInstance() {
|
public static INetd getInstance() {
|
||||||
|
// NOTE: ServiceManager does no caching for the netd service,
|
||||||
|
// because netd is not one of the defined common services.
|
||||||
final INetd netdInstance = INetd.Stub.asInterface(
|
final INetd netdInstance = INetd.Stub.asInterface(
|
||||||
ServiceManager.getService(NETD_SERVICE_NAME));
|
ServiceManager.getService(NETD_SERVICE_NAME));
|
||||||
if (netdInstance == null) {
|
if (netdInstance == null) {
|
||||||
@@ -43,4 +55,82 @@ public class NetdService {
|
|||||||
}
|
}
|
||||||
return netdInstance;
|
return netdInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks for a specified time until an INetd instance is available.
|
||||||
|
*
|
||||||
|
* It is the caller's responsibility to handle RemoteException errors
|
||||||
|
* from invocations on the returned interface if, for example, netd
|
||||||
|
* dies after this interface was returned.
|
||||||
|
*
|
||||||
|
* Returned instances of INetd should not be cached.
|
||||||
|
*
|
||||||
|
* Special values of maxTimeoutMs include: 0, meaning try to obtain an
|
||||||
|
* INetd instance only once, and -1 (or any value less than 0), meaning
|
||||||
|
* try to obtain an INetd instance indefinitely.
|
||||||
|
*
|
||||||
|
* @param maxTimeoutMs the maximum time to spend getting an INetd instance
|
||||||
|
* @return an INetd instance or null if no instance is available
|
||||||
|
* within |maxTimeoutMs| milliseconds.
|
||||||
|
*/
|
||||||
|
public static INetd get(long maxTimeoutMs) {
|
||||||
|
if (maxTimeoutMs == 0) return getInstance();
|
||||||
|
|
||||||
|
final long stop = (maxTimeoutMs > 0)
|
||||||
|
? SystemClock.elapsedRealtime() + maxTimeoutMs
|
||||||
|
: Long.MAX_VALUE;
|
||||||
|
|
||||||
|
long timeoutMs = 0;
|
||||||
|
while (true) {
|
||||||
|
final INetd netdInstance = getInstance();
|
||||||
|
if (netdInstance != null) {
|
||||||
|
return netdInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
final long remaining = stop - SystemClock.elapsedRealtime();
|
||||||
|
if (remaining <= 0) break;
|
||||||
|
|
||||||
|
// No netdInstance was received; sleep and retry.
|
||||||
|
timeoutMs = Math.min(timeoutMs + BASE_TIMEOUT_MS, MAX_TIMEOUT_MS);
|
||||||
|
timeoutMs = Math.min(timeoutMs, remaining);
|
||||||
|
try {
|
||||||
|
Thread.sleep(timeoutMs);
|
||||||
|
} catch (InterruptedException e) {}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks until an INetd instance is available.
|
||||||
|
*
|
||||||
|
* It is the caller's responsibility to handle RemoteException errors
|
||||||
|
* from invocations on the returned interface if, for example, netd
|
||||||
|
* dies after this interface was returned.
|
||||||
|
*
|
||||||
|
* Returned instances of INetd should not be cached.
|
||||||
|
*
|
||||||
|
* @return an INetd instance.
|
||||||
|
*/
|
||||||
|
public static INetd get() {
|
||||||
|
return get(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface NetdCommand {
|
||||||
|
void run(INetd netd) throws RemoteException;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocks until an INetd instance is availabe, and retries until either
|
||||||
|
* the command succeeds or a runtime exception is thrown.
|
||||||
|
*/
|
||||||
|
public static void run(NetdCommand cmd) {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
cmd.run(get());
|
||||||
|
return;
|
||||||
|
} catch (RemoteException re) {
|
||||||
|
Log.e(TAG, "error communicating with netd: " + re);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user