NetworkStats.java revision 3359aca7655a7d18615c1ada6cbabeff403947d1
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 168b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // @VisibleForTesting 169b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addIfaceValues( 170b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey String iface, long rxBytes, long rxPackets, long txBytes, long txPackets) { 171b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues( 172b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, rxPackets, txBytes, txPackets, 0L); 173a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 174a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 175b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // @VisibleForTesting 176b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats addValues(String iface, int uid, int set, int tag, long rxBytes, 177b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 178b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return addValues(new Entry( 179b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 180fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 181fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 182fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 183fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Add new stats entry, copying from given {@link Entry}. The {@link Entry} 184fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * object can be recycled across multiple calls. 185fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 186fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public NetworkStats addValues(Entry entry) { 1874a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey if (size >= this.iface.length) { 188fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final int newLength = Math.max(iface.length, 10) * 3 / 2; 189fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface = Arrays.copyOf(iface, newLength); 190fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid = Arrays.copyOf(uid, newLength); 191b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set = Arrays.copyOf(set, newLength); 192fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag = Arrays.copyOf(tag, newLength); 193d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes = Arrays.copyOf(rxBytes, newLength); 194fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets = Arrays.copyOf(rxPackets, newLength); 195d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes = Arrays.copyOf(txBytes, newLength); 196fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets = Arrays.copyOf(txPackets, newLength); 197a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations = Arrays.copyOf(operations, newLength); 1989a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 1999a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 200fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey iface[size] = entry.iface; 201fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey uid[size] = entry.uid; 202b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey set[size] = entry.set; 203fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey tag[size] = entry.tag; 204d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[size] = entry.rxBytes; 205fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey rxPackets[size] = entry.rxPackets; 206d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[size] = entry.txBytes; 207fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey txPackets[size] = entry.txPackets; 208a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[size] = entry.operations; 2094a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey size++; 2109a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2114a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return this; 2129a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 2139a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 2141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey /** 215fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey * Return specific stats entry. 216fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey */ 217fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public Entry getValues(int i, Entry recycle) { 218fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 219fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.iface = iface[i]; 220fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.uid = uid[i]; 221b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.set = set[i]; 222fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.tag = tag[i]; 223d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i]; 224fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i]; 225d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i]; 226fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i]; 227a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i]; 228fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return entry; 229fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 230fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 231fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public long getElapsedRealtime() { 232fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return elapsedRealtime; 233fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 234fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 2351059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 2361059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return age of this {@link NetworkStats} object with respect to 2371059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * {@link SystemClock#elapsedRealtime()}. 2381059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 2391059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public long getElapsedRealtimeAge() { 2401059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return SystemClock.elapsedRealtime() - elapsedRealtime; 2411059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 2421059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 243fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey public int size() { 244fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey return size; 245fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey } 246fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 247d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey // @VisibleForTesting 248d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public int internalSize() { 249d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return iface.length; 250d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 251d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 252b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey @Deprecated 253d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int tag, long rxBytes, long rxPackets, 25463d27a9233fed934340231f438493746084a681dJeff Sharkey long txBytes, long txPackets, long operations) { 255a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return combineValues( 256b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, SET_DEFAULT, tag, rxBytes, rxPackets, txBytes, txPackets, operations); 257b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 258b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 259b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public NetworkStats combineValues(String iface, int uid, int set, int tag, long rxBytes, 260b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey long rxPackets, long txBytes, long txPackets, long operations) { 261b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return combineValues(new Entry( 262b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey iface, uid, set, tag, rxBytes, rxPackets, txBytes, txPackets, operations)); 263d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 264d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 265fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey /** 2661b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Combine given values with an existing row, or create a new row if 267b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * {@link #findIndex(String, int, int, int)} is unable to find match. Can 268b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * also be used to subtract values from existing rows. 2691b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */ 270d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public NetworkStats combineValues(Entry entry) { 271b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int i = findIndex(entry.iface, entry.uid, entry.set, entry.tag); 2721b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (i == -1) { 2731b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // only create new entry when positive contribution 274d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey addValues(entry); 2751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } else { 276d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxBytes[i] += entry.rxBytes; 277d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey rxPackets[i] += entry.rxPackets; 278d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txBytes[i] += entry.txBytes; 279d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey txPackets[i] += entry.txPackets; 280a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] += entry.operations; 2811b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 2821b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return this; 283eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 284eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 2859a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** 286905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Combine all values from another {@link NetworkStats} into this object. 287905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 288905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public void combineAllValues(NetworkStats another) { 289905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkStats.Entry entry = null; 290905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < another.size; i++) { 291905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry = another.getValues(i, entry); 292905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey combineValues(entry); 293905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 294905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 295905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 296905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 2979a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey * Find first stats index that matches the requested parameters. 2989a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey */ 299b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int findIndex(String iface, int uid, int set, int tag) { 3004a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey for (int i = 0; i < size; i++) { 301163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 302163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 303163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return i; 304163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 305163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 306163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return -1; 307163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 308163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 309163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 310163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Find first stats index that matches the requested parameters, starting 311163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * search around the hinted index as an optimization. 312163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 313163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // @VisibleForTesting 314163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public int findIndexHinted(String iface, int uid, int set, int tag, int hintIndex) { 315163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int offset = 0; offset < size; offset++) { 316163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int halfOffset = offset / 2; 317163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 318163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // search outwards from hint index, alternating forward and backward 319163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int i; 320163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (offset % 2 == 0) { 321163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (hintIndex + halfOffset) % size; 322163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } else { 323163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey i = (size + hintIndex - halfOffset - 1) % size; 324163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 325163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 326163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] 327163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey && Objects.equal(iface, this.iface[i])) { 3289a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return i; 3299a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3309a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3319a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return -1; 3329a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 3339a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 334eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey /** 335a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * Splice in {@link #operations} from the given {@link NetworkStats} based 336a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * on matching {@link #uid} and {@link #tag} rows. Ignores {@link #iface}, 337a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * since operation counts are at data layer. 338a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey */ 339a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void spliceOperationsFrom(NetworkStats stats) { 340a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < size; i++) { 341b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int j = stats.findIndex(IFACE_ALL, uid[i], set[i], tag[i]); 342a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (j == -1) { 343a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = 0; 344a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } else { 345a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey operations[i] = stats.operations[j]; 346a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 347a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 348a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 349a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 350a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** 35175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Return list of unique interfaces known by this data structure. 35275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 35361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public String[] getUniqueIfaces() { 35475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final HashSet<String> ifaces = new HashSet<String>(); 35575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey for (String iface : this.iface) { 35675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (iface != IFACE_ALL) { 35775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey ifaces.add(iface); 35875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 35975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 36075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return ifaces.toArray(new String[ifaces.size()]); 36175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 36275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 36375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 36461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey * Return list of unique UIDs known by this data structure. 36561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 36661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey public int[] getUniqueUids() { 36761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final SparseBooleanArray uids = new SparseBooleanArray(); 36861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int uid : this.uid) { 36961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey uids.put(uid, true); 37061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 37161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 37261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int size = uids.size(); 37361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int[] result = new int[size]; 37461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int i = 0; i < size; i++) { 37561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey result[i] = uids.keyAt(i); 37661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 37761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey return result; 37861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 37961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 38061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 3818e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * Return total bytes represented by this snapshot object, usually used when 3828e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * checking if a {@link #subtract(NetworkStats)} delta passes a threshold. 3838e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey */ 3848e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey public long getTotalBytes() { 38507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = getTotal(null); 38607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry.rxBytes + entry.txBytes; 38707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey } 38807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 38907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey /** 39007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey * Return total of all fields represented by this snapshot object. 39107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey */ 39207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey public Entry getTotal(Entry recycle) { 3931059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return getTotal(recycle, null, UID_ALL); 3941059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 3951059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 3961059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 3971059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 3981059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #uid}. 3991059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4001059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, int limitUid) { 4011059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return getTotal(recycle, null, limitUid); 4021059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4031059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4041059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4051059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4061059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface}. 4071059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4081059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public Entry getTotal(Entry recycle, HashSet<String> limitIface) { 4091059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return getTotal(recycle, limitIface, UID_ALL); 4101059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4111059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4121059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 4131059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total of all fields represented by this snapshot object matching 4141059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * the requested {@link #iface} and {@link #uid}. 4151059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * 4161059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * @param limitIface Set of {@link #iface} to include in total; or {@code 4171059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * null} to include all ifaces. 4181059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 4191059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey private Entry getTotal(Entry recycle, HashSet<String> limitIface, int limitUid) { 42007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 42107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 42207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.iface = IFACE_ALL; 4231059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = limitUid; 42407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.set = SET_ALL; 42507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.tag = TAG_NONE; 42607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxBytes = 0; 42707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxPackets = 0; 42807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txBytes = 0; 42907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txPackets = 0; 4301059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = 0; 43107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 4328e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey for (int i = 0; i < size; i++) { 4331059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesUid = (limitUid == UID_ALL) || (limitUid == uid[i]); 4341059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final boolean matchesIface = (limitIface == null) || (limitIface.contains(iface[i])); 4351059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4361059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (matchesUid && matchesIface) { 4371059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 4381059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (tag[i] != TAG_NONE) continue; 4391059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 4401059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes += rxBytes[i]; 4411059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets += rxPackets[i]; 4421059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes += txBytes[i]; 4431059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets += txPackets[i]; 4441059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations += operations[i]; 4451059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 4468e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 44707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return entry; 4488e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 4498e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 4508e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey /** 451eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * Subtract the given {@link NetworkStats}, effectively leaving the delta 452eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * between two snapshots in time. Assumes that statistics rows collect over 453eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey * time, and that none of them have disappeared. 454eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey */ 455163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public NetworkStats subtract(NetworkStats value) throws NonMonotonicException { 45675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long deltaRealtime = this.elapsedRealtime - value.elapsedRealtime; 457163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (deltaRealtime < 0) { 4583359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey throw new NonMonotonicException(this, value); 45975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 460eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 46175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // result will have our rows, and elapsed time between snapshots 462fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey final Entry entry = new Entry(); 4634a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey final NetworkStats result = new NetworkStats(deltaRealtime, size); 4644a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey for (int i = 0; i < size; i++) { 465fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.iface = iface[i]; 466fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.uid = uid[i]; 467b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.set = set[i]; 468fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.tag = tag[i]; 469eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 470eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // find remote row that matches, and subtract 471163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final int j = value.findIndexHinted(entry.iface, entry.uid, entry.set, entry.tag, i); 472eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey if (j == -1) { 473eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // newly appearing row, return entire value 474d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i]; 475fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i]; 476d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i]; 477fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i]; 478a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i]; 479eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } else { 480eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey // existing row, subtract remote value 481d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.rxBytes = rxBytes[i] - value.rxBytes[j]; 482fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.rxPackets = rxPackets[i] - value.rxPackets[j]; 483d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.txBytes = txBytes[i] - value.txBytes[j]; 484fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey entry.txPackets = txPackets[i] - value.txPackets[j]; 485a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.operations = operations[i] - value.operations[j]; 486163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 487163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 488163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey || entry.txPackets < 0 || entry.operations < 0) { 489163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey throw new NonMonotonicException(this, i, value, j); 4903f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 491eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 492fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey 493fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey result.addValues(entry); 494eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 495eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 4964a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return result; 4979a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 4989a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 499905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** 500905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Return total statistics grouped by {@link #iface}; doesn't mutate the 501905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * original structure. 502905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey */ 503905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey public NetworkStats groupedByIface() { 504905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 505905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 506905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final Entry entry = new Entry(); 507905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.uid = UID_ALL; 508905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.set = SET_ALL; 509905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.tag = TAG_NONE; 510905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.operations = 0L; 511905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 512905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (int i = 0; i < size; i++) { 513905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // skip specific tags, since already counted in TAG_NONE 514905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (tag[i] != TAG_NONE) continue; 515905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 516905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.iface = iface[i]; 517905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxBytes = rxBytes[i]; 518905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.rxPackets = rxPackets[i]; 519905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txBytes = txBytes[i]; 520905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.txPackets = txPackets[i]; 521905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey stats.combineValues(entry); 522905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 523905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 524905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return stats; 525905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 526905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 5271059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey /** 5281059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * Return total statistics grouped by {@link #uid}; doesn't mutate the 5291059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey * original structure. 5301059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey */ 5311059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey public NetworkStats groupedByUid() { 5321059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 5331059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5341059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey final Entry entry = new Entry(); 5351059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.iface = IFACE_ALL; 5361059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.set = SET_ALL; 5371059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.tag = TAG_NONE; 5381059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5391059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey for (int i = 0; i < size; i++) { 5401059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey // skip specific tags, since already counted in TAG_NONE 5411059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey if (tag[i] != TAG_NONE) continue; 5421059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5431059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.uid = uid[i]; 5441059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxBytes = rxBytes[i]; 5451059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.rxPackets = rxPackets[i]; 5461059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txBytes = txBytes[i]; 5471059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.txPackets = txPackets[i]; 5481059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey entry.operations = operations[i]; 5491059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey stats.combineValues(entry); 5501059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 5511059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 5521059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey return stats; 5531059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey } 5541059c3c30ad96a15695c1a92ae8896e078a6309fJeff Sharkey 555163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey /** 556163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * Return all rows except those attributed to the requested UID; doesn't 557163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey * mutate the original structure. 558163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey */ 559163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public NetworkStats withoutUid(int uid) { 560163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final NetworkStats stats = new NetworkStats(elapsedRealtime, 10); 561163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 562163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey Entry entry = new Entry(); 563163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey for (int i = 0; i < size; i++) { 564163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey entry = getValues(i, entry); 565163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey if (entry.uid != uid) { 566163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey stats.addValues(entry); 567163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 568163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 569163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 570163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey return stats; 571163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 572163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 5739a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public void dump(String prefix, PrintWriter pw) { 5749a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 5759a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print("NetworkStats: elapsedRealtime="); pw.println(elapsedRealtime); 576fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey for (int i = 0; i < size; i++) { 5779a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(prefix); 5783359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" ["); pw.print(i); pw.print("]"); 5793359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey pw.print(" iface="); pw.print(iface[i]); 5809a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey pw.print(" uid="); pw.print(uid[i]); 581b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" set="); pw.print(setToString(set[i])); 582b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" tag="); pw.print(tagToString(tag[i])); 583d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" rxBytes="); pw.print(rxBytes[i]); 584fd8be3e5e7420f3cca591daeec8a44487f5f65aaJeff Sharkey pw.print(" rxPackets="); pw.print(rxPackets[i]); 585d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey pw.print(" txBytes="); pw.print(txBytes[i]); 586a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" txPackets="); pw.print(txPackets[i]); 587a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey pw.print(" operations="); pw.println(operations[i]); 5889a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 5899a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 5909a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 591b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 592b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #set} value. 593b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 594b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String setToString(int set) { 595b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey switch (set) { 596b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_ALL: 597b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "ALL"; 598b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_DEFAULT: 599b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "DEFAULT"; 600b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case SET_FOREGROUND: 601b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "FOREGROUND"; 602b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey default: 603b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "UNKNOWN"; 604b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 605b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 606b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 607b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 608b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Return text description of {@link #tag} value. 609b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 610b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public static String tagToString(int tag) { 611b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return "0x" + Integer.toHexString(tag); 612b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 613b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 6149a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey @Override 6159a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public String toString() { 6169a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey final CharArrayWriter writer = new CharArrayWriter(); 6179a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey dump("", new PrintWriter(writer)); 6189a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return writer.toString(); 6199a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6209a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 6219a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey /** {@inheritDoc} */ 622eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey public int describeContents() { 623eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey return 0; 624eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey } 625eedcb9525ba5befee2ba6ebb7a9ee3f13395c2a3Jeff Sharkey 6269a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public static final Creator<NetworkStats> CREATOR = new Creator<NetworkStats>() { 6279a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats createFromParcel(Parcel in) { 6289a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats(in); 6299a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6309a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey 6319a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey public NetworkStats[] newArray(int size) { 6329a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey return new NetworkStats[size]; 6339a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey } 6349a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey }; 635163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 636163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public static class NonMonotonicException extends Exception { 637163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final NetworkStats left; 638163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final NetworkStats right; 639163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final int leftIndex; 640163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public final int rightIndex; 641163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 6423359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey public NonMonotonicException(NetworkStats left, NetworkStats right) { 6433359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey this(left, -1, right, -1); 6443359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey } 6453359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey 646163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey public NonMonotonicException( 647163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey NetworkStats left, int leftIndex, NetworkStats right, int rightIndex) { 648163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.left = checkNotNull(left, "missing left"); 649163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.right = checkNotNull(right, "missing right"); 650163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.leftIndex = leftIndex; 651163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey this.rightIndex = rightIndex; 652163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 653163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 6549a13f36cddaad01350bdb5f000167811a1d753c9Jeff Sharkey} 655