Merge "[AF01] Move NetworkStatsCollection comparison code to NetworkStatsCollection" into main
This commit is contained in:
commit
2f67e0f2d4
2 changed files with 97 additions and 88 deletions
|
|
@ -26,6 +26,7 @@ import static android.net.NetworkStats.ROAMING_NO;
|
|||
import static android.net.NetworkStats.ROAMING_YES;
|
||||
import static android.net.NetworkStats.SET_ALL;
|
||||
import static android.net.NetworkStats.SET_DEFAULT;
|
||||
import static android.net.NetworkStats.SET_FOREGROUND;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.NetworkStats.UID_ALL;
|
||||
import static android.net.NetworkTemplate.MATCH_BLUETOOTH;
|
||||
|
|
@ -50,6 +51,7 @@ import android.service.NetworkStatsCollectionStatsProto;
|
|||
import android.telephony.SubscriptionPlan;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.Log;
|
||||
|
|
@ -924,6 +926,100 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static String str(NetworkStatsCollection.Key key) {
|
||||
StringBuilder sb = new StringBuilder()
|
||||
.append(key.ident.toString())
|
||||
.append(" uid=").append(key.uid);
|
||||
if (key.set != SET_FOREGROUND) {
|
||||
sb.append(" set=").append(key.set);
|
||||
}
|
||||
if (key.tag != 0) {
|
||||
sb.append(" tag=").append(key.tag);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// The importer will modify some keys when importing them.
|
||||
// In order to keep the comparison code simple, add such special cases here and simply
|
||||
// ignore them. This should not impact fidelity much because the start/end checks and the total
|
||||
// bytes check still need to pass.
|
||||
private static boolean couldKeyChangeOnImport(NetworkStatsCollection.Key key) {
|
||||
if (key.ident.isEmpty()) return false;
|
||||
final NetworkIdentity firstIdent = key.ident.iterator().next();
|
||||
|
||||
// Non-mobile network with non-empty RAT type.
|
||||
// This combination is invalid and the NetworkIdentity.Builder will throw if it is passed
|
||||
// in, but it looks like it was previously possible to persist it to disk. The importer sets
|
||||
// the RAT type to NETWORK_TYPE_ALL.
|
||||
if (firstIdent.getType() != ConnectivityManager.TYPE_MOBILE
|
||||
&& firstIdent.getRatType() != NetworkTemplate.NETWORK_TYPE_ALL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two {@link NetworkStatsCollection} instances and returning a human-readable
|
||||
* string description of difference for debugging purpose.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Nullable
|
||||
public static String compareStats(
|
||||
NetworkStatsCollection migrated, NetworkStatsCollection legacy) {
|
||||
final Map<NetworkStatsCollection.Key, NetworkStatsHistory> migEntries =
|
||||
migrated.getEntries();
|
||||
final Map<NetworkStatsCollection.Key, NetworkStatsHistory> legEntries = legacy.getEntries();
|
||||
|
||||
final ArraySet<NetworkStatsCollection.Key> unmatchedLegKeys =
|
||||
new ArraySet<>(legEntries.keySet());
|
||||
|
||||
for (NetworkStatsCollection.Key legKey : legEntries.keySet()) {
|
||||
final NetworkStatsHistory legHistory = legEntries.get(legKey);
|
||||
final NetworkStatsHistory migHistory = migEntries.get(legKey);
|
||||
|
||||
if (migHistory == null && couldKeyChangeOnImport(legKey)) {
|
||||
unmatchedLegKeys.remove(legKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (migHistory == null) {
|
||||
return "Missing migrated history for legacy key " + str(legKey)
|
||||
+ ", legacy history was " + legHistory;
|
||||
}
|
||||
if (!migHistory.isSameAs(legHistory)) {
|
||||
return "Difference in history for key " + legKey + "; legacy history " + legHistory
|
||||
+ ", migrated history " + migHistory;
|
||||
}
|
||||
unmatchedLegKeys.remove(legKey);
|
||||
}
|
||||
|
||||
if (!unmatchedLegKeys.isEmpty()) {
|
||||
final NetworkStatsHistory first = legEntries.get(unmatchedLegKeys.valueAt(0));
|
||||
return "Found unmatched legacy keys: count=" + unmatchedLegKeys.size()
|
||||
+ ", first unmatched collection " + first;
|
||||
}
|
||||
|
||||
if (migrated.getStartMillis() != legacy.getStartMillis()
|
||||
|| migrated.getEndMillis() != legacy.getEndMillis()) {
|
||||
return "Start / end of the collections "
|
||||
+ migrated.getStartMillis() + "/" + legacy.getStartMillis() + " and "
|
||||
+ migrated.getEndMillis() + "/" + legacy.getEndMillis()
|
||||
+ " don't match";
|
||||
}
|
||||
|
||||
if (migrated.getTotalBytes() != legacy.getTotalBytes()) {
|
||||
return "Total bytes " + migrated.getTotalBytes() + " and " + legacy.getTotalBytes()
|
||||
+ " don't match for collections with start/end "
|
||||
+ migrated.getStartMillis()
|
||||
+ "/" + legacy.getStartMillis();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* the identifier that associate with the {@link NetworkStatsHistory} object to identify
|
||||
* a certain record in the {@link NetworkStatsCollection} object.
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import static android.net.NetworkStats.STATS_PER_UID;
|
|||
import static android.net.NetworkStats.TAG_ALL;
|
||||
import static android.net.NetworkStats.TAG_NONE;
|
||||
import static android.net.NetworkStats.UID_ALL;
|
||||
import static android.net.NetworkStatsCollection.compareStats;
|
||||
import static android.net.NetworkStatsHistory.FIELD_ALL;
|
||||
import static android.net.NetworkTemplate.MATCH_MOBILE;
|
||||
import static android.net.NetworkTemplate.MATCH_TEST;
|
||||
|
|
@ -95,7 +96,6 @@ import android.content.pm.ApplicationInfo;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.DataUsageRequest;
|
||||
import android.net.INetd;
|
||||
import android.net.INetworkStatsService;
|
||||
|
|
@ -1272,93 +1272,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
|
|||
return true;
|
||||
}
|
||||
|
||||
private static String str(NetworkStatsCollection.Key key) {
|
||||
StringBuilder sb = new StringBuilder()
|
||||
.append(key.ident.toString())
|
||||
.append(" uid=").append(key.uid);
|
||||
if (key.set != SET_FOREGROUND) {
|
||||
sb.append(" set=").append(key.set);
|
||||
}
|
||||
if (key.tag != 0) {
|
||||
sb.append(" tag=").append(key.tag);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// The importer will modify some keys when importing them.
|
||||
// In order to keep the comparison code simple, add such special cases here and simply
|
||||
// ignore them. This should not impact fidelity much because the start/end checks and the total
|
||||
// bytes check still need to pass.
|
||||
private static boolean couldKeyChangeOnImport(NetworkStatsCollection.Key key) {
|
||||
if (key.ident.isEmpty()) return false;
|
||||
final NetworkIdentity firstIdent = key.ident.iterator().next();
|
||||
|
||||
// Non-mobile network with non-empty RAT type.
|
||||
// This combination is invalid and the NetworkIdentity.Builder will throw if it is passed
|
||||
// in, but it looks like it was previously possible to persist it to disk. The importer sets
|
||||
// the RAT type to NETWORK_TYPE_ALL.
|
||||
if (firstIdent.getType() != ConnectivityManager.TYPE_MOBILE
|
||||
&& firstIdent.getRatType() != NetworkTemplate.NETWORK_TYPE_ALL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String compareStats(
|
||||
NetworkStatsCollection migrated, NetworkStatsCollection legacy) {
|
||||
final Map<NetworkStatsCollection.Key, NetworkStatsHistory> migEntries =
|
||||
migrated.getEntries();
|
||||
final Map<NetworkStatsCollection.Key, NetworkStatsHistory> legEntries = legacy.getEntries();
|
||||
|
||||
final ArraySet<NetworkStatsCollection.Key> unmatchedLegKeys =
|
||||
new ArraySet<>(legEntries.keySet());
|
||||
|
||||
for (NetworkStatsCollection.Key legKey : legEntries.keySet()) {
|
||||
final NetworkStatsHistory legHistory = legEntries.get(legKey);
|
||||
final NetworkStatsHistory migHistory = migEntries.get(legKey);
|
||||
|
||||
if (migHistory == null && couldKeyChangeOnImport(legKey)) {
|
||||
unmatchedLegKeys.remove(legKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (migHistory == null) {
|
||||
return "Missing migrated history for legacy key " + str(legKey)
|
||||
+ ", legacy history was " + legHistory;
|
||||
}
|
||||
if (!migHistory.isSameAs(legHistory)) {
|
||||
return "Difference in history for key " + legKey + "; legacy history " + legHistory
|
||||
+ ", migrated history " + migHistory;
|
||||
}
|
||||
unmatchedLegKeys.remove(legKey);
|
||||
}
|
||||
|
||||
if (!unmatchedLegKeys.isEmpty()) {
|
||||
final NetworkStatsHistory first = legEntries.get(unmatchedLegKeys.valueAt(0));
|
||||
return "Found unmatched legacy keys: count=" + unmatchedLegKeys.size()
|
||||
+ ", first unmatched collection " + first;
|
||||
}
|
||||
|
||||
if (migrated.getStartMillis() != legacy.getStartMillis()
|
||||
|| migrated.getEndMillis() != legacy.getEndMillis()) {
|
||||
return "Start / end of the collections "
|
||||
+ migrated.getStartMillis() + "/" + legacy.getStartMillis() + " and "
|
||||
+ migrated.getEndMillis() + "/" + legacy.getEndMillis()
|
||||
+ " don't match";
|
||||
}
|
||||
|
||||
if (migrated.getTotalBytes() != legacy.getTotalBytes()) {
|
||||
return "Total bytes " + migrated.getTotalBytes() + " and " + legacy.getTotalBytes()
|
||||
+ " don't match for collections with start/end "
|
||||
+ migrated.getStartMillis()
|
||||
+ "/" + legacy.getStartMillis();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@GuardedBy("mStatsLock")
|
||||
@NonNull
|
||||
private NetworkStatsCollection readPlatformCollectionForRecorder(
|
||||
|
|
|
|||
Loading…
Reference in a new issue