19a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey/* 29a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project 39a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * 49a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 59a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * you may not use this file except in compliance with the License. 69a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * You may obtain a copy of the License at 79a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * 89a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 99a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * 109a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 119a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 129a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * See the License for the specific language governing permissions and 149a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * limitations under the License. 159a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 169a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 179a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeypackage android.net; 189a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 199a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.os.Parcel; 209a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.os.Parcelable; 219a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.os.SystemClock; 2261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.util.SparseBooleanArray; 239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 248b2c3a14603d163d7564e6f60286995079687690Jeff Sharkeyimport com.android.internal.annotations.VisibleForTesting; 25daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport com.android.internal.util.ArrayUtils; 26a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport com.android.internal.util.Objects; 27a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 289a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport java.io.CharArrayWriter; 299a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport java.io.PrintWriter; 304a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkeyimport java.util.Arrays; 3175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.HashSet; 329a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 339a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey/** 3475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collection of active network statistics. Can contain summary details across 3575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * all interfaces, or details with per-UID granularity. Internally stores data 3675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * as a large table, closely matching {@code /proc/} data format. This structure 3775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * optimizes for rapid in-memory comparison, but consider using 3875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * {@link NetworkStatsHistory} when persisting. 399a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * 409a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * @hide 419a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 429a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeypublic class NetworkStats implements Parcelable { 4375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@link #iface} value when interface details unavailable. */ 449a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public static final String IFACE_ALL = null; 4575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@link #uid} value when UID details unavailable. */ 4675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public static final int UID_ALL = -1; 47b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value when all sets combined. */ 48b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_ALL = -1; 49b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value where background data is accounted. */ 50b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_DEFAULT = 0; 51b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value where foreground data is accounted. */ 52b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_FOREGROUND = 1; 53b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #tag} value for total data across all tags. */ 541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey public static final int TAG_NONE = 0; 55eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 56163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // TODO: move fields to "mVariable" notation 57163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 589a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** 599a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * {@link SystemClock#elapsedRealtime()} timestamp when this data was 609a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * generated. 619a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 62d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private final long elapsedRealtime; 63d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int size; 64d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private String[] iface; 65d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int[] uid; 66b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private int[] set; 67d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int[] tag; 68d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] rxBytes; 69d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] rxPackets; 70d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] txBytes; 71d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] txPackets; 7263d27a9233fed934340231f438493746084a681dJeff Sharkey private long[] operations; 73fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 74fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public static class Entry { 75fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public String iface; 76fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int uid; 77b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int set; 78fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int tag; 79fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long rxBytes; 80fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long rxPackets; 81fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long txBytes; 82fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long txPackets; 8363d27a9233fed934340231f438493746084a681dJeff Sharkey public long operations; 84d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 85d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public Entry() { 86b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); 8763d27a9233fed934340231f438493746084a681dJeff Sharkey } 8863d27a9233fed934340231f438493746084a681dJeff Sharkey 8963d27a9233fed934340231f438493746084a681dJeff Sharkey public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { 90b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 91b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey operations); 92d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 93d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 94b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, 95b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long txBytes, long txPackets, long operations) { 96d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.iface = iface; 97d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.uid = uid; 98b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.set = set; 99d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.tag = tag; 100d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxBytes = rxBytes; 101d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxPackets = rxPackets; 102d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txBytes = txBytes; 103d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txPackets = txPackets; 104a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey this.operations = operations; 105d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 106b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey 10763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public boolean isNegative() { 10863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return rxBytes < 0 || rxPackets < 0 || txBytes < 0 || txPackets < 0 || operations < 0; 10963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey } 11063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey 11163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public boolean isEmpty() { 11263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return rxBytes == 0 && rxPackets == 0 && txBytes == 0 && txPackets == 0 11363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey && operations == 0; 11463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey } 11563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey 11670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey public void add(Entry another) { 11770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.rxBytes += another.rxBytes; 11870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.rxPackets += another.rxPackets; 11970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.txBytes += another.txBytes; 12070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.txPackets += another.txPackets; 12170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.operations += another.operations; 12270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey } 12370c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey 124b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey @Override 125b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey public String toString() { 126b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey final StringBuilder builder = new StringBuilder(); 127b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append("iface=").append(iface); 128b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" uid=").append(uid); 129b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" set=").append(setToString(set)); 130b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" tag=").append(tagToString(tag)); 131b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" rxBytes=").append(rxBytes); 132b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" rxPackets=").append(rxPackets); 133b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" txBytes=").append(txBytes); 134b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" txPackets=").append(txPackets); 135b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" operations=").append(operations); 136b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey return builder.toString(); 137b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey } 1389a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey 1399a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey @Override 1409a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey public boolean equals(Object o) { 1419a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey if (o instanceof Entry) { 1429a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey final Entry e = (Entry) o; 1439a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return uid == e.uid && set == e.set && tag == e.tag && rxBytes == e.rxBytes 1449a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey && rxPackets == e.rxPackets && txBytes == e.txBytes 1459a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey && txPackets == e.txPackets && operations == e.operations 1469a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey && iface.equals(e.iface); 1479a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 1489a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey return false; 1499a2c2a6da90abbcc9a064c20e93ed885651f4ae1Jeff Sharkey } 150fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 1519a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1524a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey public NetworkStats(long elapsedRealtime, int initialSize) { 1539a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey this.elapsedRealtime = elapsedRealtime; 1544a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.size = 0; 1554a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.iface = new String[initialSize]; 1564a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.uid = new int[initialSize]; 157b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.set = new int[initialSize]; 1581b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey this.tag = new int[initialSize]; 159d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxBytes = new long[initialSize]; 160fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey this.rxPackets = new long[initialSize]; 161d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txBytes = new long[initialSize]; 162fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey this.txPackets = new long[initialSize]; 16363d27a9233fed934340231f438493746084a681dJeff Sharkey this.operations = new long[initialSize]; 1649a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 1659a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1669a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats(Parcel parcel) { 1679a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey elapsedRealtime = parcel.readLong(); 1684a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey size = parcel.readInt(); 1699a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey iface = parcel.createStringArray(); 1709a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey uid = parcel.createIntArray(); 171b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set = parcel.createIntArray(); 1721b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey tag = parcel.createIntArray(); 173d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes = parcel.createLongArray(); 174fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets = parcel.createLongArray(); 175d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes = parcel.createLongArray(); 176fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets = parcel.createLongArray(); 17763d27a9233fed934340231f438493746084a681dJeff Sharkey operations = parcel.createLongArray(); 178a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 179a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 180bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 181a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void writeToParcel(Parcel dest, int flags) { 182a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLong(elapsedRealtime); 183a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeInt(size); 184a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeStringArray(iface); 185a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeIntArray(uid); 186b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey dest.writeIntArray(set); 187a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeIntArray(tag); 188a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(rxBytes); 189a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(rxPackets); 190a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(txBytes); 191a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(txPackets); 19263d27a9233fed934340231f438493746084a681dJeff Sharkey dest.writeLongArray(operations); 1939a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 1949a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1954abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey @Override 1964abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey public NetworkStats clone() { 1974abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey final NetworkStats clone = new NetworkStats(elapsedRealtime, size); 1984abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey NetworkStats.Entry entry = null; 1994abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey for (int i = 0; i < size; i++) { 2004abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey entry = getValues(i, entry); 2014abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey clone.addValues(entry); 2024abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey } 2034abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey return clone; 2044abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey } 2054abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey 2068b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey @VisibleForTesting 207b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addIfaceValues( 208b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { 209b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues( 210b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L); 211a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 212a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 2138b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey @VisibleForTesting 214b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addValues(String iface, int uid, int set, int tag, long rxBytes, 215b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 216b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues(new Entry( 217b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 218fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 219fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 220fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 221fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Add new stats entry, copying from given {@link Entry}. The {@link Entry} 222fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * object can be recycled across multiple calls. 223fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 224fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public NetworkStats addValues(Entry entry) { 2254a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey if (size >= this.iface.length) { 226fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final int newLength = Math.max(iface.length, 10) * 3 / 2; 227fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface = Arrays.copyOf(iface, newLength); 228fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid = Arrays.copyOf(uid, newLength); 229b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set = Arrays.copyOf(set, newLength); 230fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag = Arrays.copyOf(tag, newLength); 231d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes = Arrays.copyOf(rxBytes, newLength); 232fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets = Arrays.copyOf(rxPackets, newLength); 233d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes = Arrays.copyOf(txBytes, newLength); 234fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets = Arrays.copyOf(txPackets, newLength); 235a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations = Arrays.copyOf(operations, newLength); 2369a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 2379a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 238fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface[size] = entry.iface; 239fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid[size] = entry.uid; 240b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set[size] = entry.set; 241fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag[size] = entry.tag; 242d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[size] = entry.rxBytes; 243fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets[size] = entry.rxPackets; 244d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[size] = entry.txBytes; 245fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets[size] = entry.txPackets; 246a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[size] = entry.operations; 2474a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey size++; 2489a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2494a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return this; 2509a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 2519a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2521b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey /** 253fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Return specific stats entry. 254fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 255fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public Entry getValues(int i, Entry recycle) { 256fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 257fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.iface = iface[i]; 258fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.uid = uid[i]; 259b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.set = set[i]; 260fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.tag = tag[i]; 261d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i]; 262fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i]; 263d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i]; 264fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i]; 265a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i]; 266fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return entry; 267fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 268fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 269fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long getElapsedRealtime() { 270fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return elapsedRealtime; 271fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 272fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 2731059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 2741059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return age of this {@link NetworkStats} object with respect to 2751059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * {@link SystemClock#elapsedRealtime()}. 2761059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 2771059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public long getElapsedRealtimeAge() { 2781059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return SystemClock.elapsedRealtime() - elapsedRealtime; 2791059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 2801059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 281fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int size() { 282fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return size; 283fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 284fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 2858b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey @VisibleForTesting 286d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public int internalSize() { 287d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return iface.length; 288d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 289d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 290b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey @Deprecated 291d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, 29263d27a9233fed934340231f438493746084a681dJeff Sharkey long txBytes, long txPackets, long operations) { 293a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return combineValues( 294b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes, txPackets, operations); 295b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 296b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 297b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes, 298b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 299b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return combineValues(new Entry( 300b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 301d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 302d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 303fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 3041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Combine given values with an existing row, or create a new row if 305b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * {@link #findIndex(String, int, int, int)} is unable to find match. Can 306b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * also be used to subtract values from existing rows. 3071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */ 308d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(Entry entry) { 309b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag); 3101b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (i == -1) { 3111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // only create new entry when positive contribution 312d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey addValues(entry); 3131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } else { 314d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[i] += entry.rxBytes; 315d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxPackets[i] += entry.rxPackets; 316d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[i] += entry.txBytes; 317d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txPackets[i] += entry.txPackets; 318a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] += entry.operations; 3191b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 3201b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return this; 321eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 322eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 3239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** 324905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Combine all values from another {@link NetworkStats} into this object. 325905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 326905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public void combineAllValues(NetworkStats another) { 327905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkStats.Entry entry = null; 328905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < another.size; i++) { 329905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry = another.getValues(i, entry); 330905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey combineValues(entry); 331905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 332905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 333905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 334905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 3359a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * Find first stats index that matches the requested parameters. 3369a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 337b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int findIndex(String iface, int uid, int set, int tag) { 3384a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey for (int i = 0; i < size; i++) { 339163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 340163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 341163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return i; 342163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 343163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 344163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return -1; 345163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 346163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 347163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 348163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Find first stats index that matches the requested parameters, starting 349163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * search around the hinted index as an optimization. 350163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 3518b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey @VisibleForTesting 352163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public int findIndexHinted(String iface, int uid, int set, int tag, int hintIndex) { 353163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int offset = 0; offset < size; offset++) { 354163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int halfOffset = offset / 2; 355163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 356163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // search outwards from hint index, alternating forward and backward 357163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int i; 358163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (offset % 2 == 0) { 359163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (hintIndex + halfOffset) % size; 360163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } else { 361163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (size + hintIndex - halfOffset - 1) % size; 362163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 363163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 364163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 365163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 3669a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return i; 3679a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3689a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3699a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return -1; 3709a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3719a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 372eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey /** 373a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * Splice in {@link #operations} from the given {@link NetworkStats} based 374a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface}, 375a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * since operation counts are at data layer. 376a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey */ 377a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void spliceOperationsFrom(NetworkStats stats) { 378a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < size; i++) { 37921a547823de52806de48f70b8360353344a5ad88Jeff Sharkey final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i]); 380a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (j == -1) { 381a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = 0; 382a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } else { 383a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = stats.operations[j]; 384a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 385a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 386a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 387a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 388a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** 38975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Return list of unique interfaces known by this data structure. 39075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 39161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public String[] getUniqueIfaces() { 39275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final HashSet<String> ifaces = new HashSet<String>(); 39375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey for (String iface : this.iface) { 39475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (iface != IFACE_ALL) { 39575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey ifaces.add(iface); 39675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 39775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 39875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return ifaces.toArray(new String[ifaces.size()]); 39975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 40075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 40175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 40261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey * Return list of unique UIDs known by this data structure. 40361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 40461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public int[] getUniqueUids() { 40561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final SparseBooleanArray uids = new SparseBooleanArray(); 40661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int uid : this.uid) { 40761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey uids.put(uid, true); 40861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 40961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 41061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int size = uids.size(); 41161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int[] result = new int[size]; 41261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int i = 0; i < size; i++) { 41361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey result[i] = uids.keyAt(i); 41461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 41561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey return result; 41661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 41761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 41861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 4198e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * Return total bytes represented by this snapshot object, usually used when 4208e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * checking if a {@link #subtract(NetworkStats)} delta passes a threshold. 4218e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey */ 4228e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey public long getTotalBytes() { 42307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = getTotal(null); 42407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry.rxBytes + entry.txBytes; 42507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey } 42607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 42707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey /** 42807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey * Return total of all fields represented by this snapshot object. 42907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey */ 43007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey public Entry getTotal(Entry recycle) { 43163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, null, UID_ALL, false); 4321059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4331059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4341059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4351059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4361059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #uid}. 4371059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4381059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, int limitUid) { 43963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, null, limitUid, false); 4401059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4411059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4421059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4431059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4441059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface}. 4451059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4461059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, HashSet<String> limitIface) { 44763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, limitIface, UID_ALL, false); 44863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey } 44963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey 45063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public Entry getTotalIncludingTags(Entry recycle) { 45163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, null, UID_ALL, true); 4521059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4531059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4541059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4551059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4561059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface} and {@link #uid}. 4571059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * 4581059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * @param limitIface Set of {@link #iface} to include in total; or {@code 4591059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * null} to include all ifaces. 4601059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 46163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey private Entry getTotal( 46263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey Entry recycle, HashSet<String> limitIface, int limitUid, boolean includeTags) { 46307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 46407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 46507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.iface = IFACE_ALL; 4661059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = limitUid; 46707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.set = SET_ALL; 46807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.tag = TAG_NONE; 46907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxBytes = 0; 47007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxPackets = 0; 47107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txBytes = 0; 47207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txPackets = 0; 4731059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = 0; 47407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 4758e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey for (int i = 0; i < size; i++) { 4761059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesUid = (limitUid == UID_ALL) || (limitUid == uid[i]); 4771059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesIface = (limitIface == null) || (limitIface.contains(iface[i])); 4781059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4791059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (matchesUid && matchesIface) { 4801059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 48163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey if (tag[i] != TAG_NONE && !includeTags) continue; 4821059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4831059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes += rxBytes[i]; 4841059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets += rxPackets[i]; 4851059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes += txBytes[i]; 4861059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets += txPackets[i]; 4871059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations += operations[i]; 4881059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4898e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 49007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry; 4918e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 4928e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 4938e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey /** 494eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * Subtract the given {@link NetworkStats}, effectively leaving the delta 495eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * between two snapshots in time. Assumes that statistics rows collect over 496eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * time, and that none of them have disappeared. 497eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey */ 4985a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey public NetworkStats subtract(NetworkStats right) { 49963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return subtract(this, right, null, null); 500d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 501d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey 502d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey /** 5035a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * Subtract the two given {@link NetworkStats} objects, returning the delta 504d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * between two snapshots in time. Assumes that statistics rows collect over 505d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * time, and that none of them have disappeared. 5065a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * <p> 5075a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * If counters have rolled backwards, they are clamped to {@code 0} and 5085a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * reported to the given {@link NonMonotonicObserver}. 509d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey */ 51063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public static <C> NetworkStats subtract( 51163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie) { 5125a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime; 513163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (deltaRealtime < 0) { 5145a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey if (observer != null) { 51563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey observer.foundNonMonotonic(left, -1, right, -1, cookie); 5165a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey } 5175a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey deltaRealtime = 0; 51875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 519eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 52075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // result will have our rows, and elapsed time between snapshots 521fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = new Entry(); 5225a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey final NetworkStats result = new NetworkStats(deltaRealtime, left.size); 5235a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey for (int i = 0; i < left.size; i++) { 5245a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.iface = left.iface[i]; 5255a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.uid = left.uid[i]; 5265a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.set = left.set[i]; 5275a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.tag = left.tag[i]; 528eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 529eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // find remote row that matches, and subtract 5305a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i); 531eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey if (j == -1) { 532eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // newly appearing row, return entire value 5335a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxBytes = left.rxBytes[i]; 5345a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxPackets = left.rxPackets[i]; 5355a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txBytes = left.txBytes[i]; 5365a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txPackets = left.txPackets[i]; 5375a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.operations = left.operations[i]; 538eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } else { 539eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // existing row, subtract remote value 5405a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxBytes = left.rxBytes[i] - right.rxBytes[j]; 5415a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxPackets = left.rxPackets[i] - right.rxPackets[j]; 5425a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txBytes = left.txBytes[i] - right.txBytes[j]; 5435a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txPackets = left.txPackets[i] - right.txPackets[j]; 5445a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.operations = left.operations[i] - right.operations[j]; 545163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 546163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 547163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey || entry.txPackets < 0 || entry.operations < 0) { 5485a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey if (observer != null) { 54963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey observer.foundNonMonotonic(left, i, right, j, cookie); 550d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 5515a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxBytes = Math.max(entry.rxBytes, 0); 5525a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxPackets = Math.max(entry.rxPackets, 0); 5535a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txBytes = Math.max(entry.txBytes, 0); 5545a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txPackets = Math.max(entry.txPackets, 0); 5555a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.operations = Math.max(entry.operations, 0); 5563f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 557eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 558fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 559fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey result.addValues(entry); 560eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 561eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 5624a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return result; 5639a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 5649a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 565905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 566905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Return total statistics grouped by {@link #iface}; doesn't mutate the 567905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * original structure. 568905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 569905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public NetworkStats groupedByIface() { 570905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 571905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 572905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final Entry entry = new Entry(); 573905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.uid = UID_ALL; 574905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.set = SET_ALL; 575905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.tag = TAG_NONE; 576905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.operations = 0L; 577905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 578905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < size; i++) { 579905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // skip specific tags, since already counted in TAG_NONE 580905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (tag[i] != TAG_NONE) continue; 581905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 582905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.iface = iface[i]; 583905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxBytes = rxBytes[i]; 584905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxPackets = rxPackets[i]; 585905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txBytes = txBytes[i]; 586905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txPackets = txPackets[i]; 587905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey stats.combineValues(entry); 588905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 589905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 590905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return stats; 591905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 592905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 5931059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 5941059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total statistics grouped by {@link #uid}; doesn't mutate the 5951059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * original structure. 5961059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 5971059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public NetworkStats groupedByUid() { 5981059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 5991059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 6001059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final Entry entry = new Entry(); 6011059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.iface = IFACE_ALL; 6021059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.set = SET_ALL; 6031059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.tag = TAG_NONE; 6041059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 6051059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey for (int i = 0; i < size; i++) { 6061059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 6071059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (tag[i] != TAG_NONE) continue; 6081059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 6091059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = uid[i]; 6101059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes = rxBytes[i]; 6111059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets = rxPackets[i]; 6121059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes = txBytes[i]; 6131059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets = txPackets[i]; 6141059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = operations[i]; 6151059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey stats.combineValues(entry); 6161059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 6171059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 6181059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return stats; 6191059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 6201059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 621163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 622163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Return all rows except those attributed to the requested UID; doesn't 623163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * mutate the original structure. 624163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 625daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey public NetworkStats withoutUids(int[] uids) { 626163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 627163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 628163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey Entry entry = new Entry(); 629163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int i = 0; i < size; i++) { 630163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey entry = getValues(i, entry); 631daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey if (!ArrayUtils.contains(uids, entry.uid)) { 632163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey stats.addValues(entry); 633163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 634163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 635163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 636163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return stats; 637163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 638163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 6399a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public void dump(String prefix, PrintWriter pw) { 6409a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 6419a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); 642fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey for (int i = 0; i < size; i++) { 6439a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 6443359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" ["); pw.print(i); pw.print("]"); 6453359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" iface="); pw.print(iface[i]); 6469a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(" uid="); pw.print(uid[i]); 647b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" set="); pw.print(setToString(set[i])); 648b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" tag="); pw.print(tagToString(tag[i])); 649d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" rxBytes="); pw.print(rxBytes[i]); 650fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey pw.print(" rxPackets="); pw.print(rxPackets[i]); 651d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" txBytes="); pw.print(txBytes[i]); 652a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" txPackets="); pw.print(txPackets[i]); 653a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" operations="); pw.println(operations[i]); 6549a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6559a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6569a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 657b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 658b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #set} value. 659b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 660b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String setToString(int set) { 661b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey switch (set) { 662b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_ALL: 663b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "ALL"; 664b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_DEFAULT: 665b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "DEFAULT"; 666b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_FOREGROUND: 667b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "FOREGROUND"; 668b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey default: 669b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "UNKNOWN"; 670b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 671b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 672b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 673b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 674b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #tag} value. 675b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 676b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String tagToString(int tag) { 677b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "0x" + Integer.toHexString(tag); 678b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 679b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 6809a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey @Override 6819a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public String toString() { 6829a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey final CharArrayWriter writer = new CharArrayWriter(); 6839a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey dump("", new PrintWriter(writer)); 6849a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return writer.toString(); 6859a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6869a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 687bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 688eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey public int describeContents() { 689eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey return 0; 690eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 691eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 6929a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public static final Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { 693bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 6949a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats createFromParcel(Parcel in) { 6959a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats(in); 6969a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6979a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 698bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 6999a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats[] newArray(int size) { 7009a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats[size]; 7019a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 7029a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey }; 703163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 70463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public interface NonMonotonicObserver<C> { 7055a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey public void foundNonMonotonic( 70663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie); 707163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 7089a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey} 709