Skip to content

Commit 0412423

Browse files
author
Haoyu Bai
committed
Setup idletimer for network interface.
Cherry-picked from commit f71ca8a in master. DO NOT MERGE Change-Id: I6101c7ae041b4cc1237ce7a9983753dbdfa301d3
1 parent c47f80f commit 0412423

File tree

4 files changed

+162
-0
lines changed

4 files changed

+162
-0
lines changed

core/java/android/os/INetworkManagementService.aidl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,27 @@ interface INetworkManagementService
322322
*/
323323
int getInterfaceTxThrottle(String iface);
324324

325+
/**
326+
* Sets idletimer for an interface.
327+
*
328+
* This either initializes a new idletimer or increases its
329+
* reference-counting if an idletimer already exists for given
330+
* {@code iface}.
331+
*
332+
* {@code label} usually represents the network type of {@code iface}.
333+
* Caller should ensure that {@code label} for an {@code iface} remains the
334+
* same for all calls to addIdleTimer.
335+
*
336+
* Every {@code addIdleTimer} should be paired with a
337+
* {@link removeIdleTimer} to cleanup when the network disconnects.
338+
*/
339+
void addIdleTimer(String iface, int timeout, String label);
340+
341+
/**
342+
* Removes idletimer for an interface.
343+
*/
344+
void removeIdleTimer(String iface);
345+
325346
/**
326347
* Sets the name of the default interface in the DNS resolver.
327348
*/

core/java/android/provider/Settings.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,6 +2852,29 @@ public static final String getBluetoothInputDevicePriorityKey(String address) {
28522852
*/
28532853
public static final String TETHER_DUN_APN = "tether_dun_apn";
28542854

2855+
/** Inactivity timeout to track mobile data activity.
2856+
*
2857+
* If set to a positive integer, it indicates the inactivity timeout value in seconds to
2858+
* infer the data activity of mobile network. After a period of no activity on mobile
2859+
* networks with length specified by the timeout, an {@code ACTION_DATA_ACTIVITY_CHANGE}
2860+
* intent is fired to indicate a transition of network status from "active" to "idle". Any
2861+
* subsequent activity on mobile networks triggers the firing of {@code
2862+
* ACTION_DATA_ACTIVITY_CHANGE} intent indicating transition from "idle" to "active".
2863+
*
2864+
* Network activity refers to transmitting or receiving data on the network interfaces.
2865+
*
2866+
* Tracking is disabled if set to zero or negative value.
2867+
*
2868+
* @hide
2869+
*/
2870+
public static final String DATA_ACTIVITY_TIMEOUT_MOBILE = "data_activity_timeout_mobile";
2871+
2872+
/** Timeout to tracking Wifi data activity. Same as {@code DATA_ACTIVITY_TIMEOUT_MOBILE}
2873+
* but for Wifi network.
2874+
* @hide
2875+
*/
2876+
public static final String DATA_ACTIVITY_TIMEOUT_WIFI = "data_activity_timeout_wifi";
2877+
28552878
/**
28562879
* No longer supported.
28572880
*/

services/java/com/android/server/ConnectivityService.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,10 @@ private void handleDisconnect(NetworkInfo info) {
16251625
int prevNetType = info.getType();
16261626

16271627
mNetTrackers[prevNetType].setTeardownRequested(false);
1628+
1629+
// Remove idletimer previously setup in {@code handleConnect}
1630+
removeDataActivityTracking(prevNetType);
1631+
16281632
/*
16291633
* If the disconnected network is not the active one, then don't report
16301634
* this as a loss of connectivity. What probably happened is that we're
@@ -1905,6 +1909,8 @@ void systemReady() {
19051909
private void handleConnect(NetworkInfo info) {
19061910
final int type = info.getType();
19071911

1912+
setupDataActivityTracking(type);
1913+
19081914
// snapshot isFailover, because sendConnectedBroadcast() resets it
19091915
boolean isFailover = info.isFailover();
19101916
final NetworkStateTracker thisNet = mNetTrackers[type];
@@ -1976,6 +1982,58 @@ private void handleConnect(NetworkInfo info) {
19761982
}
19771983
}
19781984

1985+
/**
1986+
* Setup data activity tracking for the given network interface.
1987+
*
1988+
* Every {@code setupDataActivityTracking} should be paired with a
1989+
* {@link removeDataActivityTracking} for cleanup.
1990+
*/
1991+
private void setupDataActivityTracking(int type) {
1992+
final NetworkStateTracker thisNet = mNetTrackers[type];
1993+
final String iface = thisNet.getLinkProperties().getInterfaceName();
1994+
1995+
final int timeout;
1996+
1997+
if (ConnectivityManager.isNetworkTypeMobile(type)) {
1998+
timeout = Settings.Secure.getInt(mContext.getContentResolver(),
1999+
Settings.Secure.DATA_ACTIVITY_TIMEOUT_MOBILE,
2000+
0);
2001+
// Canonicalize mobile network type
2002+
type = ConnectivityManager.TYPE_MOBILE;
2003+
} else if (ConnectivityManager.TYPE_WIFI == type) {
2004+
timeout = Settings.Secure.getInt(mContext.getContentResolver(),
2005+
Settings.Secure.DATA_ACTIVITY_TIMEOUT_WIFI,
2006+
0);
2007+
} else {
2008+
// do not track any other networks
2009+
timeout = 0;
2010+
}
2011+
2012+
if (timeout > 0 && iface != null) {
2013+
try {
2014+
mNetd.addIdleTimer(iface, timeout, Integer.toString(type));
2015+
} catch (RemoteException e) {
2016+
}
2017+
}
2018+
}
2019+
2020+
/**
2021+
* Remove data activity tracking when network disconnects.
2022+
*/
2023+
private void removeDataActivityTracking(int type) {
2024+
final NetworkStateTracker net = mNetTrackers[type];
2025+
final String iface = net.getLinkProperties().getInterfaceName();
2026+
2027+
if (iface != null && (ConnectivityManager.isNetworkTypeMobile(type) ||
2028+
ConnectivityManager.TYPE_WIFI == type)) {
2029+
try {
2030+
// the call fails silently if no idletimer setup for this interface
2031+
mNetd.removeIdleTimer(iface);
2032+
} catch (RemoteException e) {
2033+
}
2034+
}
2035+
}
2036+
19792037
/**
19802038
* After a change in the connectivity state of a network. We're mainly
19812039
* concerned with making sure that the list of DNS servers is set up

services/java/com/android/server/NetworkManagementService.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,21 @@ class NetdResponseCode {
153153
/** Set of UIDs with active reject rules. */
154154
private SparseBooleanArray mUidRejectOnQuota = new SparseBooleanArray();
155155

156+
private Object mIdleTimerLock = new Object();
157+
/** Set of interfaces with active idle timers. */
158+
private static class IdleTimerParams {
159+
public final int timeout;
160+
public final String label;
161+
public int networkCount;
162+
163+
IdleTimerParams(int timeout, String label) {
164+
this.timeout = timeout;
165+
this.label = label;
166+
this.networkCount = 1;
167+
}
168+
}
169+
private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
170+
156171
private volatile boolean mBandwidthControlEnabled;
157172

158173
/**
@@ -1046,6 +1061,51 @@ public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface) {
10461061
}
10471062
}
10481063

1064+
@Override
1065+
public void addIdleTimer(String iface, int timeout, String label) {
1066+
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1067+
1068+
if (DBG) Slog.d(TAG, "Adding idletimer");
1069+
1070+
synchronized (mIdleTimerLock) {
1071+
IdleTimerParams params = mActiveIdleTimers.get(iface);
1072+
if (params != null) {
1073+
// the interface already has idletimer, update network count
1074+
params.networkCount++;
1075+
return;
1076+
}
1077+
1078+
try {
1079+
mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
1080+
} catch (NativeDaemonConnectorException e) {
1081+
throw e.rethrowAsParcelableException();
1082+
}
1083+
mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
1084+
}
1085+
}
1086+
1087+
@Override
1088+
public void removeIdleTimer(String iface) {
1089+
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1090+
1091+
if (DBG) Slog.d(TAG, "Removing idletimer");
1092+
1093+
synchronized (mIdleTimerLock) {
1094+
IdleTimerParams params = mActiveIdleTimers.get(iface);
1095+
if (params == null || --(params.networkCount) > 0) {
1096+
return;
1097+
}
1098+
1099+
try {
1100+
mConnector.execute("idletimer", "remove", iface,
1101+
Integer.toString(params.timeout), params.label);
1102+
} catch (NativeDaemonConnectorException e) {
1103+
throw e.rethrowAsParcelableException();
1104+
}
1105+
mActiveIdleTimers.remove(iface);
1106+
}
1107+
}
1108+
10491109
@Override
10501110
public NetworkStats getNetworkStatsSummaryDev() {
10511111
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);

0 commit comments

Comments
 (0)