Grab a wakelock while doing ARP/ND probing
Bug: 23197666 Change-Id: I5bf6e83b37fcd924f5f8e750f65bb5061f931e56
This commit is contained in:
@@ -18,6 +18,7 @@ package android.net;
|
|||||||
|
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.LinkProperties.ProvisioningChange;
|
import android.net.LinkProperties.ProvisioningChange;
|
||||||
@@ -31,6 +32,7 @@ import android.net.netlink.RtNetlinkNeighborMessage;
|
|||||||
import android.net.netlink.StructNdaCacheInfo;
|
import android.net.netlink.StructNdaCacheInfo;
|
||||||
import android.net.netlink.StructNdMsg;
|
import android.net.netlink.StructNdMsg;
|
||||||
import android.net.netlink.StructNlMsgHdr;
|
import android.net.netlink.StructNlMsgHdr;
|
||||||
|
import android.os.PowerManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.system.ErrnoException;
|
import android.system.ErrnoException;
|
||||||
import android.system.NetlinkSocketAddress;
|
import android.system.NetlinkSocketAddress;
|
||||||
@@ -74,6 +76,7 @@ public class IpReachabilityMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
private final PowerManager.WakeLock mWakeLock;
|
||||||
private final String mInterfaceName;
|
private final String mInterfaceName;
|
||||||
private final int mInterfaceIndex;
|
private final int mInterfaceIndex;
|
||||||
private final Callback mCallback;
|
private final Callback mCallback;
|
||||||
@@ -136,7 +139,8 @@ public class IpReachabilityMonitor {
|
|||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IpReachabilityMonitor(String ifName, Callback callback) throws IllegalArgumentException {
|
public IpReachabilityMonitor(Context context, String ifName, Callback callback)
|
||||||
|
throws IllegalArgumentException {
|
||||||
mInterfaceName = ifName;
|
mInterfaceName = ifName;
|
||||||
int ifIndex = -1;
|
int ifIndex = -1;
|
||||||
try {
|
try {
|
||||||
@@ -145,6 +149,8 @@ public class IpReachabilityMonitor {
|
|||||||
} catch (SocketException | NullPointerException e) {
|
} catch (SocketException | NullPointerException e) {
|
||||||
throw new IllegalArgumentException("invalid interface '" + ifName + "': ", e);
|
throw new IllegalArgumentException("invalid interface '" + ifName + "': ", e);
|
||||||
}
|
}
|
||||||
|
mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock(
|
||||||
|
PowerManager.PARTIAL_WAKE_LOCK, TAG + "." + mInterfaceName);
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
mNetlinkSocketObserver = new NetlinkSocketObserver();
|
mNetlinkSocketObserver = new NetlinkSocketObserver();
|
||||||
mObserverThread = new Thread(mNetlinkSocketObserver);
|
mObserverThread = new Thread(mNetlinkSocketObserver);
|
||||||
@@ -291,6 +297,17 @@ public class IpReachabilityMonitor {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
ipProbeList.addAll(mIpWatchList.keySet());
|
ipProbeList.addAll(mIpWatchList.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ipProbeList.isEmpty() && stillRunning()) {
|
||||||
|
// Keep the CPU awake long enough to allow all ARP/ND
|
||||||
|
// probes a reasonable chance at success. See b/23197666.
|
||||||
|
//
|
||||||
|
// The wakelock we use is (by default) refcounted, and this version
|
||||||
|
// of acquire(timeout) queues a release message to keep acquisitions
|
||||||
|
// and releases balanced.
|
||||||
|
mWakeLock.acquire(getProbeWakeLockDuration());
|
||||||
|
}
|
||||||
|
|
||||||
for (InetAddress target : ipProbeList) {
|
for (InetAddress target : ipProbeList) {
|
||||||
if (!stillRunning()) {
|
if (!stillRunning()) {
|
||||||
break;
|
break;
|
||||||
@@ -299,6 +316,22 @@ public class IpReachabilityMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long getProbeWakeLockDuration() {
|
||||||
|
// Ideally, this would be computed by examining the values of:
|
||||||
|
//
|
||||||
|
// /proc/sys/net/ipv[46]/neigh/<ifname>/ucast_solicit
|
||||||
|
//
|
||||||
|
// and:
|
||||||
|
//
|
||||||
|
// /proc/sys/net/ipv[46]/neigh/<ifname>/retrans_time_ms
|
||||||
|
//
|
||||||
|
// For now, just make some assumptions.
|
||||||
|
final long numUnicastProbes = 3;
|
||||||
|
final long retransTimeMs = 1000;
|
||||||
|
final long gracePeriodMs = 500;
|
||||||
|
return (numUnicastProbes * retransTimeMs) + gracePeriodMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: simply the number of objects by making this extend Thread.
|
// TODO: simply the number of objects by making this extend Thread.
|
||||||
private final class NetlinkSocketObserver implements Runnable {
|
private final class NetlinkSocketObserver implements Runnable {
|
||||||
|
|||||||
Reference in New Issue
Block a user