NetworkStatsService to adjust VPN stats before recording.

* Creates a new Parcelable class VpnInfo to hold required
  parameters for VPN stats adjustments.
* ConnectivityService to collect infomation and provide
  a list of VpnInfo, one for each user.
* NetworkStatsService passes the VpnInfo array to
  NetworkStatsRecorder.
* NetworkStatsRecorder calls NetworkStats.migrateTun()
  to do the math.
* Poll NetworkStats when the vpn application calls
  setUnderlyingNetworks().

Bug: 19536273
Change-Id: I7a4c7726b8243fead10416f7ec6eb5cf95f20183
This commit is contained in:
Wenchao Tong
2015-03-04 13:26:38 -08:00
parent 0fc8eeb07f
commit fccef1da81
3 changed files with 45 additions and 23 deletions

View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.net;
parcelable VpnInfo;

View File

@@ -31,6 +31,7 @@ import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
import com.google.android.collect.Sets;
@@ -163,7 +164,8 @@ public class NetworkStatsRecorder {
* snapshot is considered bootstrap, and is not counted as delta.
*/
public void recordSnapshotLocked(NetworkStats snapshot,
Map<String, NetworkIdentitySet> ifaceIdent, long currentTimeMillis) {
Map<String, NetworkIdentitySet> ifaceIdent, VpnInfo[] vpnArray,
long currentTimeMillis) {
final HashSet<String> unknownIfaces = Sets.newHashSet();
// skip recording when snapshot missing
@@ -182,6 +184,12 @@ public class NetworkStatsRecorder {
final long end = currentTimeMillis;
final long start = end - delta.getElapsedRealtime();
if (vpnArray != null) {
for (VpnInfo info : vpnArray) {
delta.migrateTun(info.ownerUid, info.vpnIface, info.primaryUnderlyingIface);
}
}
NetworkStats.Entry entry = null;
for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);

View File

@@ -111,6 +111,7 @@ import android.util.SparseIntArray;
import android.util.TrustedTime;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
@@ -855,6 +856,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return ident;
}
private void recordSnapshotLocked(long currentTime) throws RemoteException {
// snapshot and record current counters; read UID stats first to
// avoid overcounting dev stats.
final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
VpnInfo[] vpnArray = mConnManager.getAllVpnInfo();
mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, null, currentTime);
mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, null, currentTime);
mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
}
/**
* Bootstrap initial stats snapshot, usually during {@link #systemReady()}
* so we have baseline values without double-counting.
@@ -864,17 +879,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
: System.currentTimeMillis();
try {
// snapshot and record current counters; read UID stats first to
// avoid overcounting dev stats.
final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
recordSnapshotLocked(currentTime);
} catch (IllegalStateException e) {
Slog.w(TAG, "problem reading network stats: " + e);
} catch (RemoteException e) {
@@ -918,17 +923,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
: System.currentTimeMillis();
try {
// snapshot and record current counters; read UID stats first to
// avoid overcounting dev stats.
final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
recordSnapshotLocked(currentTime);
} catch (IllegalStateException e) {
Log.wtf(TAG, "problem reading network stats", e);
return;