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 19163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull; 20163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 219a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.os.Parcel; 229a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.os.Parcelable; 239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkeyimport android.os.SystemClock; 2461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.util.SparseBooleanArray; 259a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 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 { 4347eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey private static final String TAG = "NetworkStats"; 4447eb102b40cd1324d89816a7fb0fecd14fd7a408Jeff Sharkey 4575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@link #iface} value when interface details unavailable. */ 469a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public static final String IFACE_ALL = null; 4775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@link #uid} value when UID details unavailable. */ 4875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public static final int UID_ALL = -1; 49b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value when all sets combined. */ 50b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_ALL = -1; 51b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value where background data is accounted. */ 52b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_DEFAULT = 0; 53b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #set} value where foreground data is accounted. */ 54b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static final int SET_FOREGROUND = 1; 55b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@link #tag} value for total data across all tags. */ 561b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey public static final int TAG_NONE = 0; 57eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 58163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // TODO: move fields to "mVariable" notation 59163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 609a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** 619a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * {@link SystemClock#elapsedRealtime()} timestamp when this data was 629a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * generated. 639a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 64d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private final long elapsedRealtime; 65d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int size; 66d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private String[] iface; 67d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int[] uid; 68b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private int[] set; 69d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int[] tag; 70d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] rxBytes; 71d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] rxPackets; 72d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] txBytes; 73d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] txPackets; 7463d27a9233fed934340231f438493746084a681dJeff Sharkey private long[] operations; 75fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 76fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public static class Entry { 77fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public String iface; 78fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int uid; 79b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int set; 80fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int tag; 81fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long rxBytes; 82fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long rxPackets; 83fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long txBytes; 84fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long txPackets; 8563d27a9233fed934340231f438493746084a681dJeff Sharkey public long operations; 86d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 87d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public Entry() { 88b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); 8963d27a9233fed934340231f438493746084a681dJeff Sharkey } 9063d27a9233fed934340231f438493746084a681dJeff Sharkey 9163d27a9233fed934340231f438493746084a681dJeff Sharkey public Entry(long rxBytes, long rxPackets, long txBytes, long txPackets, long operations) { 92b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 93b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey operations); 94d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 95d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 96b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public Entry(String iface, int uid, int set, int tag, long rxBytes, long rxPackets, 97b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long txBytes, long txPackets, long operations) { 98d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.iface = iface; 99d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.uid = uid; 100b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.set = set; 101d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.tag = tag; 102d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxBytes = rxBytes; 103d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxPackets = rxPackets; 104d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txBytes = txBytes; 105d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txPackets = txPackets; 106a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey this.operations = operations; 107d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 108b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey 109b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey @Override 110b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey public String toString() { 111b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey final StringBuilder builder = new StringBuilder(); 112b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append("iface=").append(iface); 113b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" uid=").append(uid); 114b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" set=").append(setToString(set)); 115b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" tag=").append(tagToString(tag)); 116b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" rxBytes=").append(rxBytes); 117b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" rxPackets=").append(rxPackets); 118b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" txBytes=").append(txBytes); 119b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" txPackets=").append(txPackets); 120b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey builder.append(" operations=").append(operations); 121b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey return builder.toString(); 122b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey } 123fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 1249a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1254a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey public NetworkStats(long elapsedRealtime, int initialSize) { 1269a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey this.elapsedRealtime = elapsedRealtime; 1274a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.size = 0; 1284a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.iface = new String[initialSize]; 1294a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey this.uid = new int[initialSize]; 130b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.set = new int[initialSize]; 1311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey this.tag = new int[initialSize]; 132d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.rxBytes = new long[initialSize]; 133fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey this.rxPackets = new long[initialSize]; 134d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey this.txBytes = new long[initialSize]; 135fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey this.txPackets = new long[initialSize]; 13663d27a9233fed934340231f438493746084a681dJeff Sharkey this.operations = new long[initialSize]; 1379a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 1389a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1399a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats(Parcel parcel) { 1409a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey elapsedRealtime = parcel.readLong(); 1414a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey size = parcel.readInt(); 1429a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey iface = parcel.createStringArray(); 1439a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey uid = parcel.createIntArray(); 144b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set = parcel.createIntArray(); 1451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey tag = parcel.createIntArray(); 146d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes = parcel.createLongArray(); 147fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets = parcel.createLongArray(); 148d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes = parcel.createLongArray(); 149fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets = parcel.createLongArray(); 15063d27a9233fed934340231f438493746084a681dJeff Sharkey operations = parcel.createLongArray(); 151a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 152a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 153a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** {@inheritDoc} */ 154a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void writeToParcel(Parcel dest, int flags) { 155a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLong(elapsedRealtime); 156a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeInt(size); 157a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeStringArray(iface); 158a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeIntArray(uid); 159b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey dest.writeIntArray(set); 160a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeIntArray(tag); 161a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(rxBytes); 162a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(rxPackets); 163a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(txBytes); 164a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dest.writeLongArray(txPackets); 16563d27a9233fed934340231f438493746084a681dJeff Sharkey dest.writeLongArray(operations); 1669a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 1679a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 1684abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey @Override 1694abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey public NetworkStats clone() { 1704abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey final NetworkStats clone = new NetworkStats(elapsedRealtime, size); 1714abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey NetworkStats.Entry entry = null; 1724abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey for (int i = 0; i < size; i++) { 1734abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey entry = getValues(i, entry); 1744abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey clone.addValues(entry); 1754abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey } 1764abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey return clone; 1774abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey } 1784abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey 179b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // @VisibleForTesting 180b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addIfaceValues( 181b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { 182b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues( 183b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L); 184a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 185a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 186b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // @VisibleForTesting 187b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addValues(String iface, int uid, int set, int tag, long rxBytes, 188b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 189b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues(new Entry( 190b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 191fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 192fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 193fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 194fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Add new stats entry, copying from given {@link Entry}. The {@link Entry} 195fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * object can be recycled across multiple calls. 196fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 197fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public NetworkStats addValues(Entry entry) { 1984a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey if (size >= this.iface.length) { 199fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final int newLength = Math.max(iface.length, 10) * 3 / 2; 200fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface = Arrays.copyOf(iface, newLength); 201fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid = Arrays.copyOf(uid, newLength); 202b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set = Arrays.copyOf(set, newLength); 203fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag = Arrays.copyOf(tag, newLength); 204d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes = Arrays.copyOf(rxBytes, newLength); 205fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets = Arrays.copyOf(rxPackets, newLength); 206d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes = Arrays.copyOf(txBytes, newLength); 207fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets = Arrays.copyOf(txPackets, newLength); 208a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations = Arrays.copyOf(operations, newLength); 2099a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 2109a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 211fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface[size] = entry.iface; 212fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid[size] = entry.uid; 213b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set[size] = entry.set; 214fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag[size] = entry.tag; 215d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[size] = entry.rxBytes; 216fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets[size] = entry.rxPackets; 217d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[size] = entry.txBytes; 218fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets[size] = entry.txPackets; 219a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[size] = entry.operations; 2204a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey size++; 2219a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2224a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return this; 2239a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 2249a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey /** 226fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Return specific stats entry. 227fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 228fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public Entry getValues(int i, Entry recycle) { 229fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 230fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.iface = iface[i]; 231fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.uid = uid[i]; 232b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.set = set[i]; 233fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.tag = tag[i]; 234d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i]; 235fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i]; 236d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i]; 237fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i]; 238a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i]; 239fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return entry; 240fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 241fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 242fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long getElapsedRealtime() { 243fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return elapsedRealtime; 244fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 245fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 2461059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 2471059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return age of this {@link NetworkStats} object with respect to 2481059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * {@link SystemClock#elapsedRealtime()}. 2491059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 2501059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public long getElapsedRealtimeAge() { 2511059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return SystemClock.elapsedRealtime() - elapsedRealtime; 2521059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 2531059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 254fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int size() { 255fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return size; 256fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 257fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 258d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey // @VisibleForTesting 259d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public int internalSize() { 260d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return iface.length; 261d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 262d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 263b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey @Deprecated 264d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, 26563d27a9233fed934340231f438493746084a681dJeff Sharkey long txBytes, long txPackets, long operations) { 266a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return combineValues( 267b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes, txPackets, operations); 268b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 269b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 270b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes, 271b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 272b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return combineValues(new Entry( 273b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 274d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 275d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 276fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 2771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Combine given values with an existing row, or create a new row if 278b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * {@link #findIndex(String, int, int, int)} is unable to find match. Can 279b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * also be used to subtract values from existing rows. 2801b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */ 281d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(Entry entry) { 282b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag); 2831b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (i == -1) { 2841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // only create new entry when positive contribution 285d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey addValues(entry); 2861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } else { 287d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[i] += entry.rxBytes; 288d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxPackets[i] += entry.rxPackets; 289d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[i] += entry.txBytes; 290d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txPackets[i] += entry.txPackets; 291a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] += entry.operations; 2921b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 2931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return this; 294eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 295eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 2969a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** 297905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Combine all values from another {@link NetworkStats} into this object. 298905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 299905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public void combineAllValues(NetworkStats another) { 300905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkStats.Entry entry = null; 301905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < another.size; i++) { 302905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry = another.getValues(i, entry); 303905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey combineValues(entry); 304905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 305905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 306905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 307905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 3089a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * Find first stats index that matches the requested parameters. 3099a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 310b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int findIndex(String iface, int uid, int set, int tag) { 3114a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey for (int i = 0; i < size; i++) { 312163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 313163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 314163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return i; 315163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 316163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 317163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return -1; 318163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 319163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 320163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 321163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Find first stats index that matches the requested parameters, starting 322163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * search around the hinted index as an optimization. 323163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 324163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // @VisibleForTesting 325163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public int findIndexHinted(String iface, int uid, int set, int tag, int hintIndex) { 326163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int offset = 0; offset < size; offset++) { 327163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int halfOffset = offset / 2; 328163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 329163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // search outwards from hint index, alternating forward and backward 330163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int i; 331163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (offset % 2 == 0) { 332163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (hintIndex + halfOffset) % size; 333163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } else { 334163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (size + hintIndex - halfOffset - 1) % size; 335163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 336163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 337163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 338163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 3399a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return i; 3409a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3419a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3429a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return -1; 3439a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3449a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 345eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey /** 346a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * Splice in {@link #operations} from the given {@link NetworkStats} based 347a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface}, 348a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * since operation counts are at data layer. 349a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey */ 350a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void spliceOperationsFrom(NetworkStats stats) { 351a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < size; i++) { 352b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int j = stats.findIndex(IFACE_ALL, uid[i], set[i], tag[i]); 353a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (j == -1) { 354a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = 0; 355a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } else { 356a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = stats.operations[j]; 357a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 358a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 359a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 360a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 361a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** 36275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Return list of unique interfaces known by this data structure. 36375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 36461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public String[] getUniqueIfaces() { 36575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final HashSet<String> ifaces = new HashSet<String>(); 36675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey for (String iface : this.iface) { 36775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (iface != IFACE_ALL) { 36875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey ifaces.add(iface); 36975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 37075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 37175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return ifaces.toArray(new String[ifaces.size()]); 37275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 37375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 37475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 37561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey * Return list of unique UIDs known by this data structure. 37661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 37761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public int[] getUniqueUids() { 37861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final SparseBooleanArray uids = new SparseBooleanArray(); 37961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int uid : this.uid) { 38061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey uids.put(uid, true); 38161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 38261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 38361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int size = uids.size(); 38461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int[] result = new int[size]; 38561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int i = 0; i < size; i++) { 38661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey result[i] = uids.keyAt(i); 38761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 38861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey return result; 38961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 39061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 39161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 3928e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * Return total bytes represented by this snapshot object, usually used when 3938e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * checking if a {@link #subtract(NetworkStats)} delta passes a threshold. 3948e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey */ 3958e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey public long getTotalBytes() { 39607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = getTotal(null); 39707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry.rxBytes + entry.txBytes; 39807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey } 39907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 40007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey /** 40107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey * Return total of all fields represented by this snapshot object. 40207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey */ 40307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey public Entry getTotal(Entry recycle) { 4041059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return getTotal(recycle, null, UID_ALL); 4051059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4061059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4071059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4081059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4091059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #uid}. 4101059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4111059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, int limitUid) { 4121059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return getTotal(recycle, null, limitUid); 4131059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4141059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4151059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4161059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4171059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface}. 4181059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4191059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, HashSet<String> limitIface) { 4201059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return getTotal(recycle, limitIface, UID_ALL); 4211059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4221059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4231059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4241059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4251059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface} and {@link #uid}. 4261059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * 4271059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * @param limitIface Set of {@link #iface} to include in total; or {@code 4281059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * null} to include all ifaces. 4291059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4301059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey private Entry getTotal(Entry recycle, HashSet<String> limitIface, int limitUid) { 43107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 43207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 43307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.iface = IFACE_ALL; 4341059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = limitUid; 43507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.set = SET_ALL; 43607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.tag = TAG_NONE; 43707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxBytes = 0; 43807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxPackets = 0; 43907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txBytes = 0; 44007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txPackets = 0; 4411059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = 0; 44207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 4438e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey for (int i = 0; i < size; i++) { 4441059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesUid = (limitUid == UID_ALL) || (limitUid == uid[i]); 4451059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesIface = (limitIface == null) || (limitIface.contains(iface[i])); 4461059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4471059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (matchesUid && matchesIface) { 4481059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 4491059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (tag[i] != TAG_NONE) continue; 4501059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4511059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes += rxBytes[i]; 4521059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets += rxPackets[i]; 4531059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes += txBytes[i]; 4541059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets += txPackets[i]; 4551059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations += operations[i]; 4561059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 45807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry; 4598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 4608e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 4618e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey /** 462eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * Subtract the given {@link NetworkStats}, effectively leaving the delta 463eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * between two snapshots in time. Assumes that statistics rows collect over 464eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * time, and that none of them have disappeared. 465eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey */ 466163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public NetworkStats subtract(NetworkStats value) throws NonMonotonicException { 467d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey return subtract(value, false); 468d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 469d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey 470d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey /** 471d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * Subtract the given {@link NetworkStats}, effectively leaving the delta 472d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * between two snapshots in time. Assumes that statistics rows collect over 473d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * time, and that none of them have disappeared. 474d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * 475d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * @param clampNonMonotonic When non-monotonic stats are found, just clamp 476d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * to 0 instead of throwing {@link NonMonotonicException}. 477d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey */ 478d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey public NetworkStats subtract(NetworkStats value, boolean clampNonMonotonic) 479d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey throws NonMonotonicException { 48075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long deltaRealtime = this.elapsedRealtime - value.elapsedRealtime; 481163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (deltaRealtime < 0) { 4823359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey throw new NonMonotonicException(this, value); 48375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 484eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 48575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // result will have our rows, and elapsed time between snapshots 486fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = new Entry(); 4874a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey final NetworkStats result = new NetworkStats(deltaRealtime, size); 4884a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey for (int i = 0; i < size; i++) { 489fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.iface = iface[i]; 490fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.uid = uid[i]; 491b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.set = set[i]; 492fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.tag = tag[i]; 493eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 494eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // find remote row that matches, and subtract 495163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int j = value.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i); 496eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey if (j == -1) { 497eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // newly appearing row, return entire value 498d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i]; 499fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i]; 500d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i]; 501fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i]; 502a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i]; 503eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } else { 504eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // existing row, subtract remote value 505d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i] - value.rxBytes[j]; 506fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i] - value.rxPackets[j]; 507d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i] - value.txBytes[j]; 508fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i] - value.txPackets[j]; 509a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i] - value.operations[j]; 510163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 511163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 512163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey || entry.txPackets < 0 || entry.operations < 0) { 513d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey if (clampNonMonotonic) { 514d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey entry.rxBytes = Math.max(entry.rxBytes, 0); 515d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey entry.rxPackets = Math.max(entry.rxPackets, 0); 516d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey entry.txBytes = Math.max(entry.txBytes, 0); 517d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey entry.txPackets = Math.max(entry.txPackets, 0); 518d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey entry.operations = Math.max(entry.operations, 0); 519d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } else { 520d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey throw new NonMonotonicException(this, i, value, j); 521d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 5223f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 523eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 524fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 525fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey result.addValues(entry); 526eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 527eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 5284a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return result; 5299a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 5309a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 531905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 532905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Return total statistics grouped by {@link #iface}; doesn't mutate the 533905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * original structure. 534905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 535905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public NetworkStats groupedByIface() { 536905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 537905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 538905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final Entry entry = new Entry(); 539905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.uid = UID_ALL; 540905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.set = SET_ALL; 541905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.tag = TAG_NONE; 542905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.operations = 0L; 543905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 544905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < size; i++) { 545905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // skip specific tags, since already counted in TAG_NONE 546905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (tag[i] != TAG_NONE) continue; 547905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 548905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.iface = iface[i]; 549905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxBytes = rxBytes[i]; 550905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxPackets = rxPackets[i]; 551905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txBytes = txBytes[i]; 552905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txPackets = txPackets[i]; 553905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey stats.combineValues(entry); 554905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 555905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 556905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return stats; 557905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 558905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 5591059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 5601059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total statistics grouped by {@link #uid}; doesn't mutate the 5611059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * original structure. 5621059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 5631059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public NetworkStats groupedByUid() { 5641059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 5651059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5661059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final Entry entry = new Entry(); 5671059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.iface = IFACE_ALL; 5681059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.set = SET_ALL; 5691059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.tag = TAG_NONE; 5701059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5711059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey for (int i = 0; i < size; i++) { 5721059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 5731059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (tag[i] != TAG_NONE) continue; 5741059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5751059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = uid[i]; 5761059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes = rxBytes[i]; 5771059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets = rxPackets[i]; 5781059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes = txBytes[i]; 5791059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets = txPackets[i]; 5801059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = operations[i]; 5811059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey stats.combineValues(entry); 5821059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 5831059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5841059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return stats; 5851059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 5861059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 587163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 588163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Return all rows except those attributed to the requested UID; doesn't 589163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * mutate the original structure. 590163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 591163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public NetworkStats withoutUid(int uid) { 592163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 593163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 594163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey Entry entry = new Entry(); 595163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int i = 0; i < size; i++) { 596163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey entry = getValues(i, entry); 597163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (entry.uid != uid) { 598163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey stats.addValues(entry); 599163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 600163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 601163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 602163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return stats; 603163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 604163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 6059a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public void dump(String prefix, PrintWriter pw) { 6069a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 6079a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); 608fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey for (int i = 0; i < size; i++) { 6099a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 6103359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" ["); pw.print(i); pw.print("]"); 6113359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" iface="); pw.print(iface[i]); 6129a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(" uid="); pw.print(uid[i]); 613b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" set="); pw.print(setToString(set[i])); 614b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" tag="); pw.print(tagToString(tag[i])); 615d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" rxBytes="); pw.print(rxBytes[i]); 616fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey pw.print(" rxPackets="); pw.print(rxPackets[i]); 617d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" txBytes="); pw.print(txBytes[i]); 618a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" txPackets="); pw.print(txPackets[i]); 619a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" operations="); pw.println(operations[i]); 6209a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6219a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6229a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 623b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 624b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #set} value. 625b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 626b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String setToString(int set) { 627b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey switch (set) { 628b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_ALL: 629b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "ALL"; 630b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_DEFAULT: 631b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "DEFAULT"; 632b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_FOREGROUND: 633b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "FOREGROUND"; 634b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey default: 635b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "UNKNOWN"; 636b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 637b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 638b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 639b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 640b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #tag} value. 641b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 642b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String tagToString(int tag) { 643b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "0x" + Integer.toHexString(tag); 644b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 645b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 6469a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey @Override 6479a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public String toString() { 6489a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey final CharArrayWriter writer = new CharArrayWriter(); 6499a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey dump("", new PrintWriter(writer)); 6509a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return writer.toString(); 6519a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6529a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 6539a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** {@inheritDoc} */ 654eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey public int describeContents() { 655eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey return 0; 656eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 657eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 6589a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public static final Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { 6599a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats createFromParcel(Parcel in) { 6609a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats(in); 6619a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6629a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 6639a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats[] newArray(int size) { 6649a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats[size]; 6659a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6669a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey }; 667163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 668163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public static class NonMonotonicException extends Exception { 669163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final NetworkStats left; 670163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final NetworkStats right; 671163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final int leftIndex; 672163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final int rightIndex; 673163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 6743359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey public NonMonotonicException(NetworkStats left, NetworkStats right) { 6753359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey this(left, -1, right, -1); 6763359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey } 6773359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey 678163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public NonMonotonicException( 679163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey NetworkStats left, int leftIndex, NetworkStats right, int rightIndex) { 680163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.left = checkNotNull(left, "missing left"); 681163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.right = checkNotNull(right, "missing right"); 682163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.leftIndex = leftIndex; 683163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.rightIndex = rightIndex; 684163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 685163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 6869a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey} 687