Setup idletimer for network interface.

Change-Id: I1251b60f4c3c31c75c2acd531495ca75bbb35ff5
This commit is contained in:
Haoyu Bai
2012-06-28 15:26:19 -07:00
parent db9d339d4b
commit f71ca8a572
4 changed files with 163 additions and 1 deletions

View File

@@ -1593,6 +1593,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
int prevNetType = info.getType();
mNetTrackers[prevNetType].setTeardownRequested(false);
// Remove idletimer previously setup in {@code handleConnect}
removeDataActivityTracking(prevNetType);
/*
* If the disconnected network is not the active one, then don't report
* this as a loss of connectivity. What probably happened is that we're
@@ -1869,10 +1873,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
private void handleConnect(NetworkInfo info) {
final int type = info.getType();
final NetworkStateTracker thisNet = mNetTrackers[type];
setupDataActivityTracking(type);
// snapshot isFailover, because sendConnectedBroadcast() resets it
boolean isFailover = info.isFailover();
final NetworkStateTracker thisNet = mNetTrackers[type];
// if this is a default net and other default is running
// kill the one not preferred
@@ -1941,6 +1947,58 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
}
/**
* Setup data activity tracking for the given network interface.
*
* Every {@code setupDataActivityTracking} should be paired with a
* {@link removeDataActivityTracking} for cleanup.
*/
private void setupDataActivityTracking(int type) {
final NetworkStateTracker thisNet = mNetTrackers[type];
final String iface = thisNet.getLinkProperties().getInterfaceName();
final int timeout;
if (ConnectivityManager.isNetworkTypeMobile(type)) {
timeout = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.DATA_ACTIVITY_TIMEOUT_MOBILE,
0);
// Canonicalize mobile network type
type = ConnectivityManager.TYPE_MOBILE;
} else if (ConnectivityManager.TYPE_WIFI == type) {
timeout = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.DATA_ACTIVITY_TIMEOUT_WIFI,
0);
} else {
// do not track any other networks
timeout = 0;
}
if (timeout > 0 && iface != null) {
try {
mNetd.addIdleTimer(iface, timeout, Integer.toString(type));
} catch (RemoteException e) {
}
}
}
/**
* Remove data activity tracking when network disconnects.
*/
private void removeDataActivityTracking(int type) {
final NetworkStateTracker net = mNetTrackers[type];
final String iface = net.getLinkProperties().getInterfaceName();
if (iface != null && (ConnectivityManager.isNetworkTypeMobile(type) ||
ConnectivityManager.TYPE_WIFI == type)) {
try {
// the call fails silently if no idletimer setup for this interface
mNetd.removeIdleTimer(iface);
} catch (RemoteException e) {
}
}
}
/**
* After a change in the connectivity state of a network. We're mainly
* concerned with making sure that the list of DNS servers is set up

View File

@@ -153,6 +153,21 @@ public class NetworkManagementService extends INetworkManagementService.Stub
/** Set of UIDs with active reject rules. */
private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
private Object mIdleTimerLock = new Object();
/** Set of interfaces with active idle timers. */
private static class IdleTimerParams {
public final int timeout;
public final String label;
public int networkCount;
IdleTimerParams(int timeout, String label) {
this.timeout = timeout;
this.label = label;
this.networkCount = 1;
}
}
private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
private volatile boolean mBandwidthControlEnabled;
/**
@@ -1046,6 +1061,51 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
}
@Override
public void addIdleTimer(String iface, int timeout, String label) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
if (DBG) Slog.d(TAG, "Adding idletimer");
synchronized (mIdleTimerLock) {
IdleTimerParams params = mActiveIdleTimers.get(iface);
if (params != null) {
// the interface already has idletimer, update network count
params.networkCount++;
return;
}
try {
mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
}
}
@Override
public void removeIdleTimer(String iface) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
if (DBG) Slog.d(TAG, "Removing idletimer");
synchronized (mIdleTimerLock) {
IdleTimerParams params = mActiveIdleTimers.get(iface);
if (params == null || --(params.networkCount) > 0) {
return;
}
try {
mConnector.execute("idletimer", "remove", iface,
Integer.toString(params.timeout), params.label);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
mActiveIdleTimers.remove(iface);
}
}
@Override
public NetworkStats getNetworkStatsSummaryDev() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);