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 24daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport com.android.internal.util.ArrayUtils; 25a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport com.android.internal.util.Objects; 26a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 279a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport java.io.CharArrayWriter; 289a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport java.io.PrintWriter; 294a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkeyimport java.util.Arrays; 3075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.HashSet; 319a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 329a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey/** 3375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collection of active network statistics. Can contain summary details across 3475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * all interfaces, or details with per-UID granularity. Internally stores data 3575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * as a large table, closely matching {@code /proc/} data format. This structure 3675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * optimizes for rapid in-memory comparison, but consider using 3775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * {@link NetworkStatsHistory} when persisting. 389a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * 399a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * @hide 409a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 419a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeypublic class NetworkStats implements Parcelable { 4275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@link #iface} value when interface details unavailable. */ 439a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public static final String IFACE_ALL = null; 4475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@link #uid} value when UID details unavailable. */ 4575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public static final int UID_ALL = -1; 46b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value when all sets combined. */ 47b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_ALL = -1; 48b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value where background data is accounted. */ 49b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_DEFAULT = 0; 50b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value where foreground data is accounted. */ 51b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_FOREGROUND = 1; 52b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #tag} value for total data across all tags. */ 531b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey public static final int TAG_NONE = 0; 54eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 55163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // TODO: move fields to "mVariable" notation 56163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 579a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** 589a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * {@link SystemClock#elapsedRealtime()} timestamp when this data was 599a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * generated. 609a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 61d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private final long elapsedRealtime; 62d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int size; 63d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private String[] iface; 64d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int[] uid; 65b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private int[] set; 66d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int[] tag; 67d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] rxBytes; 68d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] rxPackets; 69d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] txBytes; 70d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] txPackets; 7163d27a9233fed934340231f438493746084a681dJeff Sharkey private long[] operations; 72fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 73fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public static class Entry { 74fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public String iface; 75fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int uid; 76b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int set; 77fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int tag; 78fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long rxBytes; 79fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long rxPackets; 80fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long txBytes; 81fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long txPackets; 8263d27a9233fed934340231f438493746084a681dJeff Sharkey public long operations; 83d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 84d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public Entry() { 85b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); 8663d27a9233fed934340231f438493746084a681dJeff Sharkey } 8763d27a9233fed934340231f438493746084a681dJeff Sharkey 8863d27a9233fed934340231f438493746084a681dJeff Sharkey public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { 89b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 90b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey operations); 91d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 92d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 93b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, 94b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long txBytes, long txPackets, long operations) { 95d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.iface = iface; 96d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.uid = uid; 97b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.set = set; 98d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.tag = tag; 99d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxBytes = rxBytes; 100d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxPackets = rxPackets; 101d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txBytes = txBytes; 102d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txPackets = txPackets; 103a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey this.operations = operations; 104d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 105b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey 10663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public boolean isNegative() { 10763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return rxBytes < 0 || rxPackets < 0 || txBytes < 0 || txPackets < 0 || operations < 0; 10863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey } 10963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey 11063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public boolean isEmpty() { 11163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return rxBytes == 0 && rxPackets == 0 && txBytes == 0 && txPackets == 0 11263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey && operations == 0; 11363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey } 11463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey 11570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey public void add(Entry another) { 11670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.rxBytes += another.rxBytes; 11770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.rxPackets += another.rxPackets; 11870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.txBytes += another.txBytes; 11970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.txPackets += another.txPackets; 12070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey this.operations += another.operations; 12170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey } 12270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey 123b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey @Override 124b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey public String toString() { 125b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey final StringBuilder builder = new StringBuilder(); 126b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append("iface=").append(iface); 127b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" uid=").append(uid); 128b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" set=").append(setToString(set)); 129b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" tag=").append(tagToString(tag)); 130b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" rxBytes=").append(rxBytes); 131b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" rxPackets=").append(rxPackets); 132b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" txBytes=").append(txBytes); 133b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" txPackets=").append(txPackets); 134b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" operations=").append(operations); 135b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey return builder.toString(); 136b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey } 137fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 1389a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1394a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey public NetworkStats(long elapsedRealtime, int initialSize) { 1409a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey this.elapsedRealtime = elapsedRealtime; 1414a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.size = 0; 1424a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.iface = new String[initialSize]; 1434a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.uid = new int[initialSize]; 144b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.set = new int[initialSize]; 1451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey this.tag = new int[initialSize]; 146d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxBytes = new long[initialSize]; 147fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey this.rxPackets = new long[initialSize]; 148d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txBytes = new long[initialSize]; 149fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey this.txPackets = new long[initialSize]; 15063d27a9233fed934340231f438493746084a681dJeff Sharkey this.operations = new long[initialSize]; 1519a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 1529a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1539a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats(Parcel parcel) { 1549a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey elapsedRealtime = parcel.readLong(); 1554a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey size = parcel.readInt(); 1569a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey iface = parcel.createStringArray(); 1579a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey uid = parcel.createIntArray(); 158b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set = parcel.createIntArray(); 1591b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey tag = parcel.createIntArray(); 160d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes = parcel.createLongArray(); 161fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets = parcel.createLongArray(); 162d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes = parcel.createLongArray(); 163fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets = parcel.createLongArray(); 16463d27a9233fed934340231f438493746084a681dJeff Sharkey operations = parcel.createLongArray(); 165a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 166a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 167bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 168a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void writeToParcel(Parcel dest, int flags) { 169a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLong(elapsedRealtime); 170a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeInt(size); 171a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeStringArray(iface); 172a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeIntArray(uid); 173b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey dest.writeIntArray(set); 174a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeIntArray(tag); 175a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(rxBytes); 176a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(rxPackets); 177a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(txBytes); 178a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(txPackets); 17963d27a9233fed934340231f438493746084a681dJeff Sharkey dest.writeLongArray(operations); 1809a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 1819a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1824abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey @Override 1834abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey public NetworkStats clone() { 1844abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey final NetworkStats clone = new NetworkStats(elapsedRealtime, size); 1854abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey NetworkStats.Entry entry = null; 1864abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey for (int i = 0; i < size; i++) { 1874abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey entry = getValues(i, entry); 1884abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey clone.addValues(entry); 1894abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey } 1904abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey return clone; 1914abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey } 1924abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey 193b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // @VisibleForTesting 194b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addIfaceValues( 195b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { 196b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues( 197b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L); 198a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 199a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 200b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // @VisibleForTesting 201b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addValues(String iface, int uid, int set, int tag, long rxBytes, 202b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 203b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues(new Entry( 204b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 205fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 206fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 207fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 208fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Add new stats entry, copying from given {@link Entry}. The {@link Entry} 209fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * object can be recycled across multiple calls. 210fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 211fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public NetworkStats addValues(Entry entry) { 2124a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey if (size >= this.iface.length) { 213fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final int newLength = Math.max(iface.length, 10) * 3 / 2; 214fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface = Arrays.copyOf(iface, newLength); 215fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid = Arrays.copyOf(uid, newLength); 216b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set = Arrays.copyOf(set, newLength); 217fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag = Arrays.copyOf(tag, newLength); 218d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes = Arrays.copyOf(rxBytes, newLength); 219fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets = Arrays.copyOf(rxPackets, newLength); 220d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes = Arrays.copyOf(txBytes, newLength); 221fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets = Arrays.copyOf(txPackets, newLength); 222a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations = Arrays.copyOf(operations, newLength); 2239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 2249a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 225fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface[size] = entry.iface; 226fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid[size] = entry.uid; 227b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set[size] = entry.set; 228fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag[size] = entry.tag; 229d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[size] = entry.rxBytes; 230fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets[size] = entry.rxPackets; 231d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[size] = entry.txBytes; 232fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets[size] = entry.txPackets; 233a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[size] = entry.operations; 2344a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey size++; 2359a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2364a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return this; 2379a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 2389a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey /** 240fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Return specific stats entry. 241fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 242fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public Entry getValues(int i, Entry recycle) { 243fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 244fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.iface = iface[i]; 245fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.uid = uid[i]; 246b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.set = set[i]; 247fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.tag = tag[i]; 248d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i]; 249fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i]; 250d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i]; 251fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i]; 252a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i]; 253fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return entry; 254fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 255fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 256fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long getElapsedRealtime() { 257fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return elapsedRealtime; 258fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 259fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 2601059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 2611059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return age of this {@link NetworkStats} object with respect to 2621059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * {@link SystemClock#elapsedRealtime()}. 2631059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 2641059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public long getElapsedRealtimeAge() { 2651059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return SystemClock.elapsedRealtime() - elapsedRealtime; 2661059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 2671059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 268fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int size() { 269fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return size; 270fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 271fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 272d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey // @VisibleForTesting 273d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public int internalSize() { 274d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return iface.length; 275d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 276d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 277b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey @Deprecated 278d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, 27963d27a9233fed934340231f438493746084a681dJeff Sharkey long txBytes, long txPackets, long operations) { 280a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return combineValues( 281b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes, txPackets, operations); 282b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 283b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 284b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes, 285b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 286b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return combineValues(new Entry( 287b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 288d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 289d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 290fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 2911b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Combine given values with an existing row, or create a new row if 292b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * {@link #findIndex(String, int, int, int)} is unable to find match. Can 293b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * also be used to subtract values from existing rows. 2941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */ 295d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(Entry entry) { 296b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag); 2971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (i == -1) { 2981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // only create new entry when positive contribution 299d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey addValues(entry); 3001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } else { 301d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[i] += entry.rxBytes; 302d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxPackets[i] += entry.rxPackets; 303d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[i] += entry.txBytes; 304d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txPackets[i] += entry.txPackets; 305a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] += entry.operations; 3061b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 3071b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return this; 308eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 309eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 3109a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** 311905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Combine all values from another {@link NetworkStats} into this object. 312905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 313905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public void combineAllValues(NetworkStats another) { 314905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkStats.Entry entry = null; 315905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < another.size; i++) { 316905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry = another.getValues(i, entry); 317905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey combineValues(entry); 318905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 319905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 320905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 321905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 3229a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * Find first stats index that matches the requested parameters. 3239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 324b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int findIndex(String iface, int uid, int set, int tag) { 3254a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey for (int i = 0; i < size; i++) { 326163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 327163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 328163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return i; 329163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 330163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 331163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return -1; 332163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 333163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 334163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 335163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Find first stats index that matches the requested parameters, starting 336163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * search around the hinted index as an optimization. 337163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 338163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // @VisibleForTesting 339163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public int findIndexHinted(String iface, int uid, int set, int tag, int hintIndex) { 340163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int offset = 0; offset < size; offset++) { 341163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int halfOffset = offset / 2; 342163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 343163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // search outwards from hint index, alternating forward and backward 344163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int i; 345163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (offset % 2 == 0) { 346163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (hintIndex + halfOffset) % size; 347163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } else { 348163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (size + hintIndex - halfOffset - 1) % size; 349163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 350163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 351163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 352163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 3539a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return i; 3549a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3559a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3569a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return -1; 3579a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3589a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 359eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey /** 360a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * Splice in {@link #operations} from the given {@link NetworkStats} based 361a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface}, 362a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * since operation counts are at data layer. 363a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey */ 364a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void spliceOperationsFrom(NetworkStats stats) { 365a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < size; i++) { 36621a547823de52806de48f70b8360353344a5ad88Jeff Sharkey final int j = stats.findIndex(iface[i], uid[i], set[i], tag[i]); 367a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (j == -1) { 368a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = 0; 369a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } else { 370a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = stats.operations[j]; 371a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 372a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 373a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 374a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 375a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** 37675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Return list of unique interfaces known by this data structure. 37775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 37861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public String[] getUniqueIfaces() { 37975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final HashSet<String> ifaces = new HashSet<String>(); 38075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey for (String iface : this.iface) { 38175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (iface != IFACE_ALL) { 38275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey ifaces.add(iface); 38375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 38475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 38575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return ifaces.toArray(new String[ifaces.size()]); 38675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 38775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 38875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 38961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey * Return list of unique UIDs known by this data structure. 39061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 39161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public int[] getUniqueUids() { 39261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final SparseBooleanArray uids = new SparseBooleanArray(); 39361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int uid : this.uid) { 39461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey uids.put(uid, true); 39561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 39661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 39761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int size = uids.size(); 39861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int[] result = new int[size]; 39961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int i = 0; i < size; i++) { 40061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey result[i] = uids.keyAt(i); 40161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 40261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey return result; 40361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 40461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 40561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 4068e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * Return total bytes represented by this snapshot object, usually used when 4078e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * checking if a {@link #subtract(NetworkStats)} delta passes a threshold. 4088e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey */ 4098e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey public long getTotalBytes() { 41007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = getTotal(null); 41107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry.rxBytes + entry.txBytes; 41207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey } 41307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 41407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey /** 41507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey * Return total of all fields represented by this snapshot object. 41607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey */ 41707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey public Entry getTotal(Entry recycle) { 41863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, null, UID_ALL, false); 4191059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4201059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4211059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4221059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4231059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #uid}. 4241059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4251059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, int limitUid) { 42663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, null, limitUid, false); 4271059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4281059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4291059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4301059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4311059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface}. 4321059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4331059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, HashSet<String> limitIface) { 43463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, limitIface, UID_ALL, false); 43563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey } 43663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey 43763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public Entry getTotalIncludingTags(Entry recycle) { 43863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return getTotal(recycle, null, UID_ALL, true); 4391059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4401059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4411059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4421059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4431059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface} and {@link #uid}. 4441059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * 4451059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * @param limitIface Set of {@link #iface} to include in total; or {@code 4461059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * null} to include all ifaces. 4471059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 44863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey private Entry getTotal( 44963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey Entry recycle, HashSet<String> limitIface, int limitUid, boolean includeTags) { 45007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 45107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 45207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.iface = IFACE_ALL; 4531059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = limitUid; 45407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.set = SET_ALL; 45507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.tag = TAG_NONE; 45607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxBytes = 0; 45707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxPackets = 0; 45807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txBytes = 0; 45907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txPackets = 0; 4601059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = 0; 46107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 4628e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey for (int i = 0; i < size; i++) { 4631059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesUid = (limitUid == UID_ALL) || (limitUid == uid[i]); 4641059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesIface = (limitIface == null) || (limitIface.contains(iface[i])); 4651059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4661059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (matchesUid && matchesIface) { 4671059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 46863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey if (tag[i] != TAG_NONE && !includeTags) continue; 4691059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4701059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes += rxBytes[i]; 4711059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets += rxPackets[i]; 4721059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes += txBytes[i]; 4731059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets += txPackets[i]; 4741059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations += operations[i]; 4751059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4768e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 47707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry; 4788e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 4798e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 4808e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey /** 481eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * Subtract the given {@link NetworkStats}, effectively leaving the delta 482eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * between two snapshots in time. Assumes that statistics rows collect over 483eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * time, and that none of them have disappeared. 484eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey */ 4855a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey public NetworkStats subtract(NetworkStats right) { 48663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey return subtract(this, right, null, null); 487d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 488d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey 489d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey /** 4905a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * Subtract the two given {@link NetworkStats} objects, returning the delta 491d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * between two snapshots in time. Assumes that statistics rows collect over 492d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * time, and that none of them have disappeared. 4935a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * <p> 4945a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * If counters have rolled backwards, they are clamped to {@code 0} and 4955a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey * reported to the given {@link NonMonotonicObserver}. 496d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey */ 49763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public static <C> NetworkStats subtract( 49863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie) { 4995a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime; 500163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (deltaRealtime < 0) { 5015a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey if (observer != null) { 50263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey observer.foundNonMonotonic(left, -1, right, -1, cookie); 5035a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey } 5045a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey deltaRealtime = 0; 50575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 506eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 50775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // result will have our rows, and elapsed time between snapshots 508fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = new Entry(); 5095a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey final NetworkStats result = new NetworkStats(deltaRealtime, left.size); 5105a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey for (int i = 0; i < left.size; i++) { 5115a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.iface = left.iface[i]; 5125a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.uid = left.uid[i]; 5135a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.set = left.set[i]; 5145a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.tag = left.tag[i]; 515eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 516eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // find remote row that matches, and subtract 5175a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey final int j = right.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i); 518eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey if (j == -1) { 519eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // newly appearing row, return entire value 5205a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxBytes = left.rxBytes[i]; 5215a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxPackets = left.rxPackets[i]; 5225a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txBytes = left.txBytes[i]; 5235a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txPackets = left.txPackets[i]; 5245a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.operations = left.operations[i]; 525eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } else { 526eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // existing row, subtract remote value 5275a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxBytes = left.rxBytes[i] - right.rxBytes[j]; 5285a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxPackets = left.rxPackets[i] - right.rxPackets[j]; 5295a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txBytes = left.txBytes[i] - right.txBytes[j]; 5305a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txPackets = left.txPackets[i] - right.txPackets[j]; 5315a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.operations = left.operations[i] - right.operations[j]; 532163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 533163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 534163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey || entry.txPackets < 0 || entry.operations < 0) { 5355a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey if (observer != null) { 53663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey observer.foundNonMonotonic(left, i, right, j, cookie); 537d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 5385a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxBytes = Math.max(entry.rxBytes, 0); 5395a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.rxPackets = Math.max(entry.rxPackets, 0); 5405a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txBytes = Math.max(entry.txBytes, 0); 5415a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.txPackets = Math.max(entry.txPackets, 0); 5425a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey entry.operations = Math.max(entry.operations, 0); 5433f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 544eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 545fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 546fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey result.addValues(entry); 547eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 548eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 5494a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return result; 5509a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 5519a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 552905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 553905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Return total statistics grouped by {@link #iface}; doesn't mutate the 554905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * original structure. 555905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 556905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public NetworkStats groupedByIface() { 557905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 558905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 559905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final Entry entry = new Entry(); 560905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.uid = UID_ALL; 561905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.set = SET_ALL; 562905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.tag = TAG_NONE; 563905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.operations = 0L; 564905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 565905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < size; i++) { 566905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // skip specific tags, since already counted in TAG_NONE 567905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (tag[i] != TAG_NONE) continue; 568905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 569905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.iface = iface[i]; 570905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxBytes = rxBytes[i]; 571905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxPackets = rxPackets[i]; 572905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txBytes = txBytes[i]; 573905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txPackets = txPackets[i]; 574905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey stats.combineValues(entry); 575905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 576905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 577905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return stats; 578905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 579905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 5801059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 5811059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total statistics grouped by {@link #uid}; doesn't mutate the 5821059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * original structure. 5831059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 5841059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public NetworkStats groupedByUid() { 5851059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 5861059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5871059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final Entry entry = new Entry(); 5881059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.iface = IFACE_ALL; 5891059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.set = SET_ALL; 5901059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.tag = TAG_NONE; 5911059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5921059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey for (int i = 0; i < size; i++) { 5931059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 5941059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (tag[i] != TAG_NONE) continue; 5951059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5961059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = uid[i]; 5971059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes = rxBytes[i]; 5981059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets = rxPackets[i]; 5991059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes = txBytes[i]; 6001059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets = txPackets[i]; 6011059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = operations[i]; 6021059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey stats.combineValues(entry); 6031059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 6041059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 6051059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return stats; 6061059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 6071059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 608163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 609163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Return all rows except those attributed to the requested UID; doesn't 610163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * mutate the original structure. 611163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 612daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey public NetworkStats withoutUids(int[] uids) { 613163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 614163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 615163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey Entry entry = new Entry(); 616163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int i = 0; i < size; i++) { 617163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey entry = getValues(i, entry); 618daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey if (!ArrayUtils.contains(uids, entry.uid)) { 619163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey stats.addValues(entry); 620163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 621163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 622163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 623163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return stats; 624163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 625163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 6269a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public void dump(String prefix, PrintWriter pw) { 6279a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 6289a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); 629fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey for (int i = 0; i < size; i++) { 6309a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 6313359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" ["); pw.print(i); pw.print("]"); 6323359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" iface="); pw.print(iface[i]); 6339a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(" uid="); pw.print(uid[i]); 634b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" set="); pw.print(setToString(set[i])); 635b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" tag="); pw.print(tagToString(tag[i])); 636d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" rxBytes="); pw.print(rxBytes[i]); 637fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey pw.print(" rxPackets="); pw.print(rxPackets[i]); 638d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" txBytes="); pw.print(txBytes[i]); 639a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" txPackets="); pw.print(txPackets[i]); 640a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" operations="); pw.println(operations[i]); 6419a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6429a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6439a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 644b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 645b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #set} value. 646b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 647b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String setToString(int set) { 648b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey switch (set) { 649b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_ALL: 650b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "ALL"; 651b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_DEFAULT: 652b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "DEFAULT"; 653b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_FOREGROUND: 654b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "FOREGROUND"; 655b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey default: 656b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "UNKNOWN"; 657b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 658b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 659b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 660b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 661b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #tag} value. 662b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 663b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String tagToString(int tag) { 664b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "0x" + Integer.toHexString(tag); 665b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 666b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 6679a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey @Override 6689a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public String toString() { 6699a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey final CharArrayWriter writer = new CharArrayWriter(); 6709a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey dump("", new PrintWriter(writer)); 6719a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return writer.toString(); 6729a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6739a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 674bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 675eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey public int describeContents() { 676eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey return 0; 677eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 678eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 6799a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public static final Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { 680bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 6819a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats createFromParcel(Parcel in) { 6829a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats(in); 6839a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6849a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 685bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey @Override 6869a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats[] newArray(int size) { 6879a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats[size]; 6889a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6899a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey }; 690163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 69163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey public interface NonMonotonicObserver<C> { 6925a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey public void foundNonMonotonic( 69363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie); 694163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 6959a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey} 696