Merge "Introduce network link quality statistics" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5b8b6751f3
@@ -1442,4 +1442,43 @@ public class ConnectivityManager {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the information about a specific network link
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public LinkInfo getLinkInfo(int networkType) {
|
||||||
|
try {
|
||||||
|
LinkInfo li = mService.getLinkInfo(networkType);
|
||||||
|
return li;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the information of currently active network link
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public LinkInfo getActiveLinkInfo() {
|
||||||
|
try {
|
||||||
|
LinkInfo li = mService.getActiveLinkInfo();
|
||||||
|
return li;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the information of all network links
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public LinkInfo[] getAllLinkInfo() {
|
||||||
|
try {
|
||||||
|
LinkInfo[] li = mService.getAllLinkInfo();
|
||||||
|
return li;
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package android.net;
|
package android.net;
|
||||||
|
|
||||||
|
import android.net.LinkInfo;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
import android.net.NetworkQuotaInfo;
|
import android.net.NetworkQuotaInfo;
|
||||||
@@ -145,4 +146,11 @@ interface IConnectivityManager
|
|||||||
String getMobileProvisioningUrl();
|
String getMobileProvisioningUrl();
|
||||||
|
|
||||||
String getMobileRedirectedProvisioningUrl();
|
String getMobileRedirectedProvisioningUrl();
|
||||||
|
|
||||||
|
LinkInfo getLinkInfo(int networkType);
|
||||||
|
|
||||||
|
LinkInfo getActiveLinkInfo();
|
||||||
|
|
||||||
|
LinkInfo[] getAllLinkInfo();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import static android.net.ConnectivityManager.isNetworkTypeValid;
|
|||||||
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
|
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
|
||||||
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
|
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@@ -56,6 +57,7 @@ import android.net.INetworkPolicyManager;
|
|||||||
import android.net.INetworkStatsService;
|
import android.net.INetworkStatsService;
|
||||||
import android.net.LinkAddress;
|
import android.net.LinkAddress;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
|
import android.net.LinkInfo;
|
||||||
import android.net.LinkProperties.CompareResult;
|
import android.net.LinkProperties.CompareResult;
|
||||||
import android.net.MobileDataStateTracker;
|
import android.net.MobileDataStateTracker;
|
||||||
import android.net.NetworkConfig;
|
import android.net.NetworkConfig;
|
||||||
@@ -68,6 +70,7 @@ import android.net.NetworkUtils;
|
|||||||
import android.net.Proxy;
|
import android.net.Proxy;
|
||||||
import android.net.ProxyProperties;
|
import android.net.ProxyProperties;
|
||||||
import android.net.RouteInfo;
|
import android.net.RouteInfo;
|
||||||
|
import android.net.SamplingDataTracker;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.wifi.WifiStateTracker;
|
import android.net.wifi.WifiStateTracker;
|
||||||
import android.net.wimax.WimaxManagerConstants;
|
import android.net.wimax.WimaxManagerConstants;
|
||||||
@@ -144,8 +147,10 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@@ -174,6 +179,23 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
private static final String FAIL_FAST_TIME_MS =
|
private static final String FAIL_FAST_TIME_MS =
|
||||||
"persist.radio.fail_fast_time_ms";
|
"persist.radio.fail_fast_time_ms";
|
||||||
|
|
||||||
|
private static final String ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED =
|
||||||
|
"android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED";
|
||||||
|
|
||||||
|
private static final int SAMPLE_INTERVAL_ELAPSED_REQURST_CODE = 0;
|
||||||
|
|
||||||
|
private PendingIntent mSampleIntervalElapsedIntent;
|
||||||
|
|
||||||
|
// Set network sampling interval at 12 minutes, this way, even if the timers get
|
||||||
|
// aggregated, it will fire at around 15 minutes, which should allow us to
|
||||||
|
// aggregate this timer with other timers (specially the socket keep alive timers)
|
||||||
|
private static final int DEFAULT_SAMPLING_INTERVAL_IN_SECONDS = (VDBG ? 30 : 12 * 60);
|
||||||
|
|
||||||
|
// start network sampling a minute after booting ...
|
||||||
|
private static final int DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS = (VDBG ? 30 : 60);
|
||||||
|
|
||||||
|
AlarmManager mAlarmManager;
|
||||||
|
|
||||||
// used in recursive route setting to add gateways for the host for which
|
// used in recursive route setting to add gateways for the host for which
|
||||||
// a host route was requested.
|
// a host route was requested.
|
||||||
private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
|
private static final int MAX_HOSTROUTE_CYCLE_COUNT = 10;
|
||||||
@@ -326,6 +348,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
*/
|
*/
|
||||||
private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
|
private static final int EVENT_ENABLE_FAIL_FAST_MOBILE_DATA = 14;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* user internally to indicate that data sampling interval is up
|
||||||
|
*/
|
||||||
|
private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
|
||||||
|
|
||||||
/** Handler used for internal events. */
|
/** Handler used for internal events. */
|
||||||
private InternalHandler mHandler;
|
private InternalHandler mHandler;
|
||||||
/** Handler used for incoming {@link NetworkStateTracker} events. */
|
/** Handler used for incoming {@link NetworkStateTracker} events. */
|
||||||
@@ -392,6 +419,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
List mProtectedNetworks;
|
List mProtectedNetworks;
|
||||||
|
|
||||||
private DataConnectionStats mDataConnectionStats;
|
private DataConnectionStats mDataConnectionStats;
|
||||||
|
|
||||||
private AtomicInteger mEnableFailFastMobileDataTag = new AtomicInteger(0);
|
private AtomicInteger mEnableFailFastMobileDataTag = new AtomicInteger(0);
|
||||||
|
|
||||||
TelephonyManager mTelephonyManager;
|
TelephonyManager mTelephonyManager;
|
||||||
@@ -634,6 +662,29 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
mDataConnectionStats = new DataConnectionStats(mContext);
|
mDataConnectionStats = new DataConnectionStats(mContext);
|
||||||
mDataConnectionStats.startMonitoring();
|
mDataConnectionStats.startMonitoring();
|
||||||
|
|
||||||
|
// start network sampling ..
|
||||||
|
Intent intent = new Intent(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED, null);
|
||||||
|
mSampleIntervalElapsedIntent = PendingIntent.getBroadcast(mContext,
|
||||||
|
SAMPLE_INTERVAL_ELAPSED_REQURST_CODE, intent, 0);
|
||||||
|
|
||||||
|
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
setAlarm(DEFAULT_START_SAMPLING_INTERVAL_IN_SECONDS * 1000, mSampleIntervalElapsedIntent);
|
||||||
|
|
||||||
|
IntentFilter filter = new IntentFilter();
|
||||||
|
filter.addAction(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED);
|
||||||
|
mContext.registerReceiver(
|
||||||
|
new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (action.equals(ACTION_PKT_CNT_SAMPLE_INTERVAL_ELAPSED)) {
|
||||||
|
mHandler.sendMessage(mHandler.obtainMessage
|
||||||
|
(EVENT_SAMPLE_INTERVAL_ELAPSED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new IntentFilter(filter));
|
||||||
|
|
||||||
mPacManager = new PacManager(mContext);
|
mPacManager = new PacManager(mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1911,6 +1962,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
// if (mActiveDefaultNetwork != -1) {
|
// if (mActiveDefaultNetwork != -1) {
|
||||||
// currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
|
// currentPriority = mNetConfigs[mActiveDefaultNetwork].mPriority;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
|
for (int checkType=0; checkType <= ConnectivityManager.MAX_NETWORK_TYPE; checkType++) {
|
||||||
if (checkType == prevNetType) continue;
|
if (checkType == prevNetType) continue;
|
||||||
if (mNetConfigs[checkType] == null) continue;
|
if (mNetConfigs[checkType] == null) continue;
|
||||||
@@ -1925,6 +1977,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
// optimization should work and we need to investigate why it doesn't work.
|
// optimization should work and we need to investigate why it doesn't work.
|
||||||
// This could be related to how DEACTIVATE_DATA_CALL is reporting its
|
// This could be related to how DEACTIVATE_DATA_CALL is reporting its
|
||||||
// complete before it is really complete.
|
// complete before it is really complete.
|
||||||
|
|
||||||
// if (!mNetTrackers[checkType].isAvailable()) continue;
|
// if (!mNetTrackers[checkType].isAvailable()) continue;
|
||||||
|
|
||||||
// if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
|
// if (currentPriority >= mNetConfigs[checkType].mPriority) continue;
|
||||||
@@ -2520,12 +2573,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the network specific TCP buffer sizes from SystemProperties
|
* Reads the network specific TCP buffer sizes from SystemProperties
|
||||||
* net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
|
* net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
|
||||||
* wide use
|
* wide use
|
||||||
*/
|
*/
|
||||||
private void updateNetworkSettings(NetworkStateTracker nt) {
|
private void updateNetworkSettings(NetworkStateTracker nt) {
|
||||||
String key = nt.getTcpBufferSizesPropName();
|
String key = nt.getTcpBufferSizesPropName();
|
||||||
String bufferSizes = key == null ? null : SystemProperties.get(key);
|
String bufferSizes = key == null ? null : SystemProperties.get(key);
|
||||||
|
|
||||||
@@ -2547,7 +2600,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
|
* Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
|
||||||
* which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
|
* which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
|
||||||
*
|
*
|
||||||
@@ -2956,6 +3009,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
+ " != tag:" + tag);
|
+ " != tag:" + tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case EVENT_SAMPLE_INTERVAL_ELAPSED:
|
||||||
|
handleNetworkSamplingTimeout();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4357,4 +4413,92 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkInfo getLinkInfo(int networkType) {
|
||||||
|
enforceAccessPermission();
|
||||||
|
if (isNetworkTypeValid(networkType)) {
|
||||||
|
return mNetTrackers[networkType].getLinkInfo();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkInfo getActiveLinkInfo() {
|
||||||
|
enforceAccessPermission();
|
||||||
|
if (isNetworkTypeValid(mActiveDefaultNetwork)) {
|
||||||
|
return mNetTrackers[mActiveDefaultNetwork].getLinkInfo();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkInfo[] getAllLinkInfo() {
|
||||||
|
enforceAccessPermission();
|
||||||
|
final ArrayList<LinkInfo> result = Lists.newArrayList();
|
||||||
|
for (NetworkStateTracker tracker : mNetTrackers) {
|
||||||
|
if (tracker != null) {
|
||||||
|
LinkInfo li = tracker.getLinkInfo();
|
||||||
|
if (li != null) {
|
||||||
|
result.add(li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toArray(new LinkInfo[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Infrastructure for network sampling */
|
||||||
|
|
||||||
|
private void handleNetworkSamplingTimeout() {
|
||||||
|
|
||||||
|
log("Sampling interval elapsed, updating statistics ..");
|
||||||
|
|
||||||
|
// initialize list of interfaces ..
|
||||||
|
Map<String, SamplingDataTracker.SamplingSnapshot> mapIfaceToSample =
|
||||||
|
new HashMap<String, SamplingDataTracker.SamplingSnapshot>();
|
||||||
|
for (NetworkStateTracker tracker : mNetTrackers) {
|
||||||
|
if (tracker != null) {
|
||||||
|
String ifaceName = tracker.getNetworkInterfaceName();
|
||||||
|
if (ifaceName != null) {
|
||||||
|
mapIfaceToSample.put(ifaceName, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read samples for all interfaces
|
||||||
|
SamplingDataTracker.getSamplingSnapshots(mapIfaceToSample);
|
||||||
|
|
||||||
|
// process samples for all networks
|
||||||
|
for (NetworkStateTracker tracker : mNetTrackers) {
|
||||||
|
if (tracker != null) {
|
||||||
|
String ifaceName = tracker.getNetworkInterfaceName();
|
||||||
|
SamplingDataTracker.SamplingSnapshot ss = mapIfaceToSample.get(ifaceName);
|
||||||
|
if (ss != null) {
|
||||||
|
// end the previous sampling cycle
|
||||||
|
tracker.stopSampling(ss);
|
||||||
|
// start a new sampling cycle ..
|
||||||
|
tracker.startSampling(ss);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log("Done.");
|
||||||
|
|
||||||
|
int samplingIntervalInSeconds = Settings.Global.getInt(mContext.getContentResolver(),
|
||||||
|
Settings.Global.CONNECTIVITY_SAMPLING_INTERVAL_IN_SECONDS,
|
||||||
|
DEFAULT_SAMPLING_INTERVAL_IN_SECONDS);
|
||||||
|
|
||||||
|
if (DBG) log("Setting timer for " + String.valueOf(samplingIntervalInSeconds) + "seconds");
|
||||||
|
|
||||||
|
setAlarm(samplingIntervalInSeconds * 1000, mSampleIntervalElapsedIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAlarm(int timeoutInMilliseconds, PendingIntent intent) {
|
||||||
|
long wakeupTime = SystemClock.elapsedRealtime() + timeoutInMilliseconds;
|
||||||
|
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeupTime, intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user