Loading services/net/java/android/net/ip/IpManager.java +11 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.Context; import android.net.apf.ApfCapabilities; import android.net.apf.ApfFilter; import android.net.DhcpResults; import android.net.INetd; import android.net.InterfaceConfiguration; import android.net.LinkAddress; import android.net.LinkProperties; Loading @@ -34,10 +35,12 @@ import android.net.dhcp.DhcpClient; import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpManagerEvent; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.INetworkManagementService; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.text.TextUtils; import android.util.LocalLog; Loading Loading @@ -1027,14 +1030,16 @@ public class IpManager extends StateMachine { private boolean startIPv6() { // Set privacy extensions. final String PREFER_TEMPADDRS = "2"; try { mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true); NetdService.run((INetd netd) -> { netd.setProcSysNet( INetd.IPV6, INetd.CONF, mInterfaceName, "use_tempaddr", PREFER_TEMPADDRS); }); mNwService.enableIpv6(mInterfaceName); } catch (RemoteException re) { logError("Unable to change interface settings: %s", re); return false; } catch (IllegalStateException ie) { logError("Unable to change interface settings: %s", ie); } catch (IllegalStateException|RemoteException|ServiceSpecificException e) { logError("Unable to change interface settings: %s", e); return false; } Loading services/net/java/android/net/util/NetdService.java +90 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,10 @@ package android.net.util; import android.net.INetd; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.util.Log; Loading @@ -27,15 +30,24 @@ import android.util.Log; public class NetdService { private static final String TAG = NetdService.class.getSimpleName(); 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 * and to handle RemoteException errors from invocations on the returned * interface if, for example, netd dies and is restarted. * * Returned instances of INetd should not be cached. * * @return an INetd instance or null. */ 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( ServiceManager.getService(NETD_SERVICE_NAME)); if (netdInstance == null) { Loading @@ -43,4 +55,82 @@ public class NetdService { } 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); } } } } Loading
services/net/java/android/net/ip/IpManager.java +11 −6 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.Context; import android.net.apf.ApfCapabilities; import android.net.apf.ApfFilter; import android.net.DhcpResults; import android.net.INetd; import android.net.InterfaceConfiguration; import android.net.LinkAddress; import android.net.LinkProperties; Loading @@ -34,10 +35,12 @@ import android.net.dhcp.DhcpClient; import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpManagerEvent; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.INetworkManagementService; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.text.TextUtils; import android.util.LocalLog; Loading Loading @@ -1027,14 +1030,16 @@ public class IpManager extends StateMachine { private boolean startIPv6() { // Set privacy extensions. final String PREFER_TEMPADDRS = "2"; try { mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true); NetdService.run((INetd netd) -> { netd.setProcSysNet( INetd.IPV6, INetd.CONF, mInterfaceName, "use_tempaddr", PREFER_TEMPADDRS); }); mNwService.enableIpv6(mInterfaceName); } catch (RemoteException re) { logError("Unable to change interface settings: %s", re); return false; } catch (IllegalStateException ie) { logError("Unable to change interface settings: %s", ie); } catch (IllegalStateException|RemoteException|ServiceSpecificException e) { logError("Unable to change interface settings: %s", e); return false; } Loading
services/net/java/android/net/util/NetdService.java +90 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,10 @@ package android.net.util; import android.net.INetd; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.os.SystemClock; import android.util.Log; Loading @@ -27,15 +30,24 @@ import android.util.Log; public class NetdService { private static final String TAG = NetdService.class.getSimpleName(); 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 * and to handle RemoteException errors from invocations on the returned * interface if, for example, netd dies and is restarted. * * Returned instances of INetd should not be cached. * * @return an INetd instance or null. */ 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( ServiceManager.getService(NETD_SERVICE_NAME)); if (netdInstance == null) { Loading @@ -43,4 +55,82 @@ public class NetdService { } 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); } } } }