NetworkStatsHistory.java revision 558a23200697d306b75750cf4612cf0717e73537
175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/* 275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Copyright (C) 2011 The Android Open Source Project 375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * 475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * you may not use this file except in compliance with the License. 675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * You may obtain a copy of the License at 775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * 875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * 1075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 1175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 1275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * See the License for the specific language governing permissions and 1475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * limitations under the License. 1575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 1675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeypackage android.net; 1875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 19a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL; 20b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_DEFAULT; 21a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport static android.net.NetworkStats.TAG_NONE; 22a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport static android.net.NetworkStats.UID_ALL; 2363d27a9233fed934340231f438493746084a681dJeff Sharkeyimport static android.net.NetworkStatsHistory.DataStreamUtils.readFullLongArray; 2463d27a9233fed934340231f438493746084a681dJeff Sharkeyimport static android.net.NetworkStatsHistory.DataStreamUtils.readVarLongArray; 2563d27a9233fed934340231f438493746084a681dJeff Sharkeyimport static android.net.NetworkStatsHistory.DataStreamUtils.writeVarLongArray; 2663d27a9233fed934340231f438493746084a681dJeff Sharkeyimport static android.net.NetworkStatsHistory.Entry.UNKNOWN; 27a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport static android.net.NetworkStatsHistory.ParcelUtils.readLongArray; 28a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport static android.net.NetworkStatsHistory.ParcelUtils.writeLongArray; 29a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 3075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.Parcel; 3175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.Parcelable; 3275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 3375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.CharArrayWriter; 3475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.DataInputStream; 3575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.DataOutputStream; 3675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.IOException; 3775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.PrintWriter; 3861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport java.net.ProtocolException; 3975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.Arrays; 4061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport java.util.Random; 4175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 4275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/** 4375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collection of historical network statistics, recorded into equally-sized 4475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * "buckets" in time. Internally it stores data in {@code long} series for more 4575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * efficient persistence. 4675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * <p> 4775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Each bucket is defined by a {@link #bucketStart} timestamp, and lasts for 4875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * {@link #bucketDuration}. Internally assumes that {@link #bucketStart} is 4975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * sorted at all times. 5075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * 5175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * @hide 5275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 5375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeypublic class NetworkStatsHistory implements Parcelable { 541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey private static final int VERSION_INIT = 1; 5563d27a9233fed934340231f438493746084a681dJeff Sharkey private static final int VERSION_ADD_PACKETS = 2; 56558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey private static final int VERSION_ADD_ACTIVE = 3; 5775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 58558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public static final int FIELD_ACTIVE_TIME = 0x01; 59558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public static final int FIELD_RX_BYTES = 0x02; 60558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public static final int FIELD_RX_PACKETS = 0x04; 61558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public static final int FIELD_TX_BYTES = 0x08; 62558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public static final int FIELD_TX_PACKETS = 0x10; 63558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public static final int FIELD_OPERATIONS = 0x20; 64d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 6563d27a9233fed934340231f438493746084a681dJeff Sharkey public static final int FIELD_ALL = 0xFFFFFFFF; 6663d27a9233fed934340231f438493746084a681dJeff Sharkey 6763d27a9233fed934340231f438493746084a681dJeff Sharkey private long bucketDuration; 68d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private int bucketCount; 69d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] bucketStart; 70558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey private long[] activeTime; 71d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] rxBytes; 72a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey private long[] rxPackets; 73d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey private long[] txBytes; 74a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey private long[] txPackets; 7563d27a9233fed934340231f438493746084a681dJeff Sharkey private long[] operations; 76d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 77d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public static class Entry { 7863d27a9233fed934340231f438493746084a681dJeff Sharkey public static final long UNKNOWN = -1; 7963d27a9233fed934340231f438493746084a681dJeff Sharkey 80d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public long bucketDuration; 81558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public long bucketStart; 82558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey public long activeTime; 83d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public long rxBytes; 84a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public long rxPackets; 85d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public long txBytes; 86a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public long txPackets; 8763d27a9233fed934340231f438493746084a681dJeff Sharkey public long operations; 88d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 8975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 90d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey public NetworkStatsHistory(long bucketDuration) { 9163d27a9233fed934340231f438493746084a681dJeff Sharkey this(bucketDuration, 10, FIELD_ALL); 924a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey } 934a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey 944a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey public NetworkStatsHistory(long bucketDuration, int initialSize) { 9563d27a9233fed934340231f438493746084a681dJeff Sharkey this(bucketDuration, initialSize, FIELD_ALL); 9663d27a9233fed934340231f438493746084a681dJeff Sharkey } 9763d27a9233fed934340231f438493746084a681dJeff Sharkey 9863d27a9233fed934340231f438493746084a681dJeff Sharkey public NetworkStatsHistory(long bucketDuration, int initialSize, int fields) { 9975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey this.bucketDuration = bucketDuration; 1004a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey bucketStart = new long[initialSize]; 101558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey if ((fields & FIELD_ACTIVE_TIME) != 0) activeTime = new long[initialSize]; 10263d27a9233fed934340231f438493746084a681dJeff Sharkey if ((fields & FIELD_RX_BYTES) != 0) rxBytes = new long[initialSize]; 10363d27a9233fed934340231f438493746084a681dJeff Sharkey if ((fields & FIELD_RX_PACKETS) != 0) rxPackets = new long[initialSize]; 10463d27a9233fed934340231f438493746084a681dJeff Sharkey if ((fields & FIELD_TX_BYTES) != 0) txBytes = new long[initialSize]; 10563d27a9233fed934340231f438493746084a681dJeff Sharkey if ((fields & FIELD_TX_PACKETS) != 0) txPackets = new long[initialSize]; 10663d27a9233fed934340231f438493746084a681dJeff Sharkey if ((fields & FIELD_OPERATIONS) != 0) operations = new long[initialSize]; 1074a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey bucketCount = 0; 10875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 10975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 11075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsHistory(Parcel in) { 11175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketDuration = in.readLong(); 11275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketStart = readLongArray(in); 113558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey activeTime = readLongArray(in); 114a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey rxBytes = readLongArray(in); 115a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey rxPackets = readLongArray(in); 116a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey txBytes = readLongArray(in); 117a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey txPackets = readLongArray(in); 11863d27a9233fed934340231f438493746084a681dJeff Sharkey operations = readLongArray(in); 11975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketCount = bucketStart.length; 12075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 12175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 12275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@inheritDoc} */ 12375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void writeToParcel(Parcel out, int flags) { 12475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey out.writeLong(bucketDuration); 12575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey writeLongArray(out, bucketStart, bucketCount); 126558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey writeLongArray(out, activeTime, bucketCount); 127d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey writeLongArray(out, rxBytes, bucketCount); 128a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey writeLongArray(out, rxPackets, bucketCount); 129d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey writeLongArray(out, txBytes, bucketCount); 130a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey writeLongArray(out, txPackets, bucketCount); 13163d27a9233fed934340231f438493746084a681dJeff Sharkey writeLongArray(out, operations, bucketCount); 13275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 13375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 13475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsHistory(DataInputStream in) throws IOException { 13575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final int version = in.readInt(); 13661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey switch (version) { 1371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case VERSION_INIT: { 13861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey bucketDuration = in.readLong(); 13963d27a9233fed934340231f438493746084a681dJeff Sharkey bucketStart = readFullLongArray(in); 14063d27a9233fed934340231f438493746084a681dJeff Sharkey rxBytes = readFullLongArray(in); 141a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey rxPackets = new long[bucketStart.length]; 14263d27a9233fed934340231f438493746084a681dJeff Sharkey txBytes = readFullLongArray(in); 143a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey txPackets = new long[bucketStart.length]; 14463d27a9233fed934340231f438493746084a681dJeff Sharkey operations = new long[bucketStart.length]; 14563d27a9233fed934340231f438493746084a681dJeff Sharkey bucketCount = bucketStart.length; 14663d27a9233fed934340231f438493746084a681dJeff Sharkey break; 14763d27a9233fed934340231f438493746084a681dJeff Sharkey } 148558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey case VERSION_ADD_PACKETS: 149558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey case VERSION_ADD_ACTIVE: { 15063d27a9233fed934340231f438493746084a681dJeff Sharkey bucketDuration = in.readLong(); 15163d27a9233fed934340231f438493746084a681dJeff Sharkey bucketStart = readVarLongArray(in); 152558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey activeTime = (version >= VERSION_ADD_ACTIVE) ? readVarLongArray(in) 153558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey : new long[bucketStart.length]; 15463d27a9233fed934340231f438493746084a681dJeff Sharkey rxBytes = readVarLongArray(in); 15563d27a9233fed934340231f438493746084a681dJeff Sharkey rxPackets = readVarLongArray(in); 15663d27a9233fed934340231f438493746084a681dJeff Sharkey txBytes = readVarLongArray(in); 15763d27a9233fed934340231f438493746084a681dJeff Sharkey txPackets = readVarLongArray(in); 15863d27a9233fed934340231f438493746084a681dJeff Sharkey operations = readVarLongArray(in); 15961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey bucketCount = bucketStart.length; 16061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey break; 16161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 16261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey default: { 16361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey throw new ProtocolException("unexpected version: " + version); 16461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 16561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 16675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 16775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 16875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void writeToStream(DataOutputStream out) throws IOException { 169558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey out.writeInt(VERSION_ADD_ACTIVE); 17075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey out.writeLong(bucketDuration); 17163d27a9233fed934340231f438493746084a681dJeff Sharkey writeVarLongArray(out, bucketStart, bucketCount); 172558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey writeVarLongArray(out, activeTime, bucketCount); 17363d27a9233fed934340231f438493746084a681dJeff Sharkey writeVarLongArray(out, rxBytes, bucketCount); 17463d27a9233fed934340231f438493746084a681dJeff Sharkey writeVarLongArray(out, rxPackets, bucketCount); 17563d27a9233fed934340231f438493746084a681dJeff Sharkey writeVarLongArray(out, txBytes, bucketCount); 17663d27a9233fed934340231f438493746084a681dJeff Sharkey writeVarLongArray(out, txPackets, bucketCount); 17763d27a9233fed934340231f438493746084a681dJeff Sharkey writeVarLongArray(out, operations, bucketCount); 17875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 17975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 18075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** {@inheritDoc} */ 18175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public int describeContents() { 18275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return 0; 18375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 18475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 185d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public int size() { 186d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return bucketCount; 187d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 188d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 189d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public long getBucketDuration() { 190d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return bucketDuration; 191d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 192d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 193434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey public long getStart() { 194434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey if (bucketCount > 0) { 195434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey return bucketStart[0]; 196434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey } else { 197434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey return Long.MAX_VALUE; 198434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey } 199434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey } 200434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey 201434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey public long getEnd() { 202434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey if (bucketCount > 0) { 203434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey return bucketStart[bucketCount - 1] + bucketDuration; 204434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey } else { 205434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey return Long.MIN_VALUE; 206434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey } 207434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey } 208434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey 209d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey /** 210d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey * Return specific stats entry. 211d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey */ 212d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey public Entry getValues(int i, Entry recycle) { 213d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 214d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.bucketStart = bucketStart[i]; 215d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.bucketDuration = bucketDuration; 216558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey entry.activeTime = getLong(activeTime, i, UNKNOWN); 21763d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxBytes = getLong(rxBytes, i, UNKNOWN); 21863d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxPackets = getLong(rxPackets, i, UNKNOWN); 21963d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txBytes = getLong(txBytes, i, UNKNOWN); 22063d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txPackets = getLong(txPackets, i, UNKNOWN); 22163d27a9233fed934340231f438493746084a681dJeff Sharkey entry.operations = getLong(operations, i, UNKNOWN); 222d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return entry; 223d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } 224d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 22575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 22675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Record that data traffic occurred in the given time range. Will 22775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * distribute across internal buckets, creating new buckets as needed. 22875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 229a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey @Deprecated 230a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void recordData(long start, long end, long rxBytes, long txBytes) { 231b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey recordData(start, end, new NetworkStats.Entry( 232b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, rxBytes, 0L, txBytes, 0L, 0L)); 233a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 234a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 235a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** 236a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * Record that data traffic occurred in the given time range. Will 237a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * distribute across internal buckets, creating new buckets as needed. 238a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey */ 239a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void recordData(long start, long end, NetworkStats.Entry entry) { 240a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (entry.rxBytes < 0 || entry.rxPackets < 0 || entry.txBytes < 0 || entry.txPackets < 0 241a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey || entry.operations < 0) { 242a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey throw new IllegalArgumentException("tried recording negative data"); 2431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 2441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 24575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // create any buckets needed by this range 24675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey ensureBuckets(start, end); 24775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 24875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // distribute data usage into buckets 249a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey long duration = end - start; 25075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey for (int i = bucketCount - 1; i >= 0; i--) { 25175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long curStart = bucketStart[i]; 25275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long curEnd = curStart + bucketDuration; 25375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 25475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // bucket is older than record; we're finished 25575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (curEnd < start) break; 25675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // bucket is newer than record; keep looking 25775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (curStart > end) continue; 25875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 25975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long overlap = Math.min(curEnd, end) - Math.max(curStart, start); 260a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (overlap <= 0) continue; 261a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 262a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey // integer math each time is faster than floating point 263a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final long fracRxBytes = entry.rxBytes * overlap / duration; 264a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final long fracRxPackets = entry.rxPackets * overlap / duration; 265a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final long fracTxBytes = entry.txBytes * overlap / duration; 266a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final long fracTxPackets = entry.txPackets * overlap / duration; 267558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey final long fracOperations = entry.operations * overlap / duration; 268a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 269558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey addLong(activeTime, i, overlap); 27063d27a9233fed934340231f438493746084a681dJeff Sharkey addLong(rxBytes, i, fracRxBytes); entry.rxBytes -= fracRxBytes; 27163d27a9233fed934340231f438493746084a681dJeff Sharkey addLong(rxPackets, i, fracRxPackets); entry.rxPackets -= fracRxPackets; 27263d27a9233fed934340231f438493746084a681dJeff Sharkey addLong(txBytes, i, fracTxBytes); entry.txBytes -= fracTxBytes; 27363d27a9233fed934340231f438493746084a681dJeff Sharkey addLong(txPackets, i, fracTxPackets); entry.txPackets -= fracTxPackets; 27463d27a9233fed934340231f438493746084a681dJeff Sharkey addLong(operations, i, fracOperations); entry.operations -= fracOperations; 275a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 276a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey duration -= overlap; 27775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 27875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 27975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 28075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 28119862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey * Record an entire {@link NetworkStatsHistory} into this history. Usually 28219862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey * for combining together stats for external reporting. 28319862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey */ 28419862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey public void recordEntireHistory(NetworkStatsHistory input) { 285a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final NetworkStats.Entry entry = new NetworkStats.Entry( 286b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); 28719862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey for (int i = 0; i < input.bucketCount; i++) { 28819862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey final long start = input.bucketStart[i]; 28919862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey final long end = start + input.bucketDuration; 290a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 29163d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxBytes = getLong(input.rxBytes, i, 0L); 29263d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxPackets = getLong(input.rxPackets, i, 0L); 29363d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txBytes = getLong(input.txBytes, i, 0L); 29463d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txPackets = getLong(input.txPackets, i, 0L); 29563d27a9233fed934340231f438493746084a681dJeff Sharkey entry.operations = getLong(input.operations, i, 0L); 296a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 297a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey recordData(start, end, entry); 29819862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 29919862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 30019862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 30119862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey /** 30275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Ensure that buckets exist for given time range, creating as needed. 30375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 30475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private void ensureBuckets(long start, long end) { 30575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // normalize incoming range to bucket boundaries 30675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey start -= start % bucketDuration; 30775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey end += (bucketDuration - (end % bucketDuration)) % bucketDuration; 30875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 30975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey for (long now = start; now < end; now += bucketDuration) { 31075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // try finding existing bucket 31175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final int index = Arrays.binarySearch(bucketStart, 0, bucketCount, now); 31275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (index < 0) { 31375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // bucket missing, create and insert 31475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey insertBucket(~index, now); 31575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 31675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 31775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 31875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 31975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 32075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Insert new bucket at requested index and starting time. 32175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 32275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private void insertBucket(int index, long start) { 32375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // create more buckets when needed 3244a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey if (bucketCount >= bucketStart.length) { 3254a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey final int newLength = Math.max(bucketStart.length, 10) * 3 / 2; 32675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketStart = Arrays.copyOf(bucketStart, newLength); 327558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey if (activeTime != null) activeTime = Arrays.copyOf(activeTime, newLength); 32863d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxBytes != null) rxBytes = Arrays.copyOf(rxBytes, newLength); 32963d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxPackets != null) rxPackets = Arrays.copyOf(rxPackets, newLength); 33063d27a9233fed934340231f438493746084a681dJeff Sharkey if (txBytes != null) txBytes = Arrays.copyOf(txBytes, newLength); 33163d27a9233fed934340231f438493746084a681dJeff Sharkey if (txPackets != null) txPackets = Arrays.copyOf(txPackets, newLength); 33263d27a9233fed934340231f438493746084a681dJeff Sharkey if (operations != null) operations = Arrays.copyOf(operations, newLength); 33375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 33475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 33575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // create gap when inserting bucket in middle 33675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (index < bucketCount) { 33775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final int dstPos = index + 1; 33875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final int length = bucketCount - index; 33975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 34075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey System.arraycopy(bucketStart, index, bucketStart, dstPos, length); 341558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey if (activeTime != null) System.arraycopy(activeTime, index, activeTime, dstPos, length); 34263d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxBytes != null) System.arraycopy(rxBytes, index, rxBytes, dstPos, length); 34363d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxPackets != null) System.arraycopy(rxPackets, index, rxPackets, dstPos, length); 34463d27a9233fed934340231f438493746084a681dJeff Sharkey if (txBytes != null) System.arraycopy(txBytes, index, txBytes, dstPos, length); 34563d27a9233fed934340231f438493746084a681dJeff Sharkey if (txPackets != null) System.arraycopy(txPackets, index, txPackets, dstPos, length); 34663d27a9233fed934340231f438493746084a681dJeff Sharkey if (operations != null) System.arraycopy(operations, index, operations, dstPos, length); 34775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 34875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 34975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketStart[index] = start; 350558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey setLong(activeTime, index, 0L); 35163d27a9233fed934340231f438493746084a681dJeff Sharkey setLong(rxBytes, index, 0L); 35263d27a9233fed934340231f438493746084a681dJeff Sharkey setLong(rxPackets, index, 0L); 35363d27a9233fed934340231f438493746084a681dJeff Sharkey setLong(txBytes, index, 0L); 35463d27a9233fed934340231f438493746084a681dJeff Sharkey setLong(txPackets, index, 0L); 35563d27a9233fed934340231f438493746084a681dJeff Sharkey setLong(operations, index, 0L); 35675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketCount++; 35775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 35875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 35975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 36075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Remove buckets older than requested cutoff. 36175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 36275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void removeBucketsBefore(long cutoff) { 36375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey int i; 36475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey for (i = 0; i < bucketCount; i++) { 36575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long curStart = bucketStart[i]; 36675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long curEnd = curStart + bucketDuration; 36775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 36875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // cutoff happens before or during this bucket; everything before 36975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // this bucket should be removed. 37075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (curEnd > cutoff) break; 37175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 37275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 37375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (i > 0) { 37475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final int length = bucketStart.length; 37575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketStart = Arrays.copyOfRange(bucketStart, i, length); 376558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey if (activeTime != null) activeTime = Arrays.copyOfRange(activeTime, i, length); 37763d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxBytes != null) rxBytes = Arrays.copyOfRange(rxBytes, i, length); 37863d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxPackets != null) rxPackets = Arrays.copyOfRange(rxPackets, i, length); 37963d27a9233fed934340231f438493746084a681dJeff Sharkey if (txBytes != null) txBytes = Arrays.copyOfRange(txBytes, i, length); 38063d27a9233fed934340231f438493746084a681dJeff Sharkey if (txPackets != null) txPackets = Arrays.copyOfRange(txPackets, i, length); 38163d27a9233fed934340231f438493746084a681dJeff Sharkey if (operations != null) operations = Arrays.copyOfRange(operations, i, length); 38275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey bucketCount -= i; 38375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 38475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 38575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 38661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 38719862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey * Return interpolated data usage across the requested range. Interpolates 38819862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey * across buckets, so values may be rounded slightly. 38919862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey */ 390434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey public Entry getValues(long start, long end, Entry recycle) { 391434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey return getValues(start, end, Long.MAX_VALUE, recycle); 392434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey } 393434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey 394434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey /** 395434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey * Return interpolated data usage across the requested range. Interpolates 396434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey * across buckets, so values may be rounded slightly. 397434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey */ 398434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey public Entry getValues(long start, long end, long now, Entry recycle) { 399434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey final Entry entry = recycle != null ? recycle : new Entry(); 400434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey entry.bucketDuration = end - start; 401558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey entry.bucketStart = start; 402558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey entry.activeTime = activeTime != null ? 0 : UNKNOWN; 40363d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxBytes = rxBytes != null ? 0 : UNKNOWN; 40463d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxPackets = rxPackets != null ? 0 : UNKNOWN; 40563d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txBytes = txBytes != null ? 0 : UNKNOWN; 40663d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txPackets = txPackets != null ? 0 : UNKNOWN; 40763d27a9233fed934340231f438493746084a681dJeff Sharkey entry.operations = operations != null ? 0 : UNKNOWN; 40819862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 40919862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey for (int i = bucketCount - 1; i >= 0; i--) { 41019862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey final long curStart = bucketStart[i]; 41119862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey final long curEnd = curStart + bucketDuration; 41219862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 41319862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey // bucket is older than record; we're finished 41419862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey if (curEnd < start) break; 41519862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey // bucket is newer than record; keep looking 41619862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey if (curStart > end) continue; 41719862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 418434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey // include full value for active buckets, otherwise only fractional 419434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey final boolean activeBucket = curStart < now && curEnd > now; 420a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final long overlap = activeBucket ? bucketDuration 421a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey : Math.min(curEnd, end) - Math.max(curStart, start); 422a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (overlap <= 0) continue; 423a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 424a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey // integer math each time is faster than floating point 425558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey if (activeTime != null) entry.activeTime += activeTime[i] * overlap / bucketDuration; 42663d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxBytes != null) entry.rxBytes += rxBytes[i] * overlap / bucketDuration; 42763d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxPackets != null) entry.rxPackets += rxPackets[i] * overlap / bucketDuration; 42863d27a9233fed934340231f438493746084a681dJeff Sharkey if (txBytes != null) entry.txBytes += txBytes[i] * overlap / bucketDuration; 42963d27a9233fed934340231f438493746084a681dJeff Sharkey if (txPackets != null) entry.txPackets += txPackets[i] * overlap / bucketDuration; 43063d27a9233fed934340231f438493746084a681dJeff Sharkey if (operations != null) entry.operations += operations[i] * overlap / bucketDuration; 43119862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 43219862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 433434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey return entry; 43419862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 43519862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 43619862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey /** 43761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey * @deprecated only for temporary testing 43861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 43961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey @Deprecated 44063d27a9233fed934340231f438493746084a681dJeff Sharkey public void generateRandom(long start, long end, long rxBytes, long rxPackets, long txBytes, 44163d27a9233fed934340231f438493746084a681dJeff Sharkey long txPackets, long operations) { 44261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey ensureBuckets(start, end); 44361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 444a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final NetworkStats.Entry entry = new NetworkStats.Entry( 445b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); 44661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final Random r = new Random(); 44704cd0e47dbc1e9769ac6f258c923d5b17fa57986Jeff Sharkey while (rxBytes > 1024 || rxPackets > 128 || txBytes > 1024 || txPackets > 128 44804cd0e47dbc1e9769ac6f258c923d5b17fa57986Jeff Sharkey || operations > 32) { 44961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final long curStart = randomLong(r, start, end); 45061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final long curEnd = randomLong(r, curStart, end); 45163d27a9233fed934340231f438493746084a681dJeff Sharkey 45263d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxBytes = randomLong(r, 0, rxBytes); 45363d27a9233fed934340231f438493746084a681dJeff Sharkey entry.rxPackets = randomLong(r, 0, rxPackets); 45463d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txBytes = randomLong(r, 0, txBytes); 45563d27a9233fed934340231f438493746084a681dJeff Sharkey entry.txPackets = randomLong(r, 0, txPackets); 45663d27a9233fed934340231f438493746084a681dJeff Sharkey entry.operations = randomLong(r, 0, operations); 45763d27a9233fed934340231f438493746084a681dJeff Sharkey 45863d27a9233fed934340231f438493746084a681dJeff Sharkey rxBytes -= entry.rxBytes; 45963d27a9233fed934340231f438493746084a681dJeff Sharkey rxPackets -= entry.rxPackets; 46063d27a9233fed934340231f438493746084a681dJeff Sharkey txBytes -= entry.txBytes; 46163d27a9233fed934340231f438493746084a681dJeff Sharkey txPackets -= entry.txPackets; 46263d27a9233fed934340231f438493746084a681dJeff Sharkey operations -= entry.operations; 463f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey 464f0ceede8fff5df24e5c98701d81c2b71eb138aa9Jeff Sharkey recordData(curStart, curEnd, entry); 46561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 46661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 46761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 46861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey private static long randomLong(Random r, long start, long end) { 46961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey return (long) (start + (r.nextFloat() * (end - start))); 47061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 47161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 472350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey public void dump(String prefix, PrintWriter pw, boolean fullHistory) { 47375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey pw.print(prefix); 47461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print("NetworkStatsHistory: bucketDuration="); pw.println(bucketDuration); 475350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey 476350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey final int start = fullHistory ? 0 : Math.max(0, bucketCount - 32); 477350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey if (start > 0) { 478350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey pw.print(prefix); 479350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey pw.print(" (omitting "); pw.print(start); pw.println(" buckets)"); 480350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey } 481350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey 482350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey for (int i = start; i < bucketCount; i++) { 48375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey pw.print(prefix); 48461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" bucketStart="); pw.print(bucketStart[i]); 485558a23200697d306b75750cf4612cf0717e73537Jeff Sharkey if (activeTime != null) pw.print(" activeTime="); pw.print(activeTime[i]); 48663d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxBytes != null) pw.print(" rxBytes="); pw.print(rxBytes[i]); 48763d27a9233fed934340231f438493746084a681dJeff Sharkey if (rxPackets != null) pw.print(" rxPackets="); pw.print(rxPackets[i]); 48863d27a9233fed934340231f438493746084a681dJeff Sharkey if (txBytes != null) pw.print(" txBytes="); pw.print(txBytes[i]); 48963d27a9233fed934340231f438493746084a681dJeff Sharkey if (txPackets != null) pw.print(" txPackets="); pw.print(txPackets[i]); 49063d27a9233fed934340231f438493746084a681dJeff Sharkey if (operations != null) pw.print(" operations="); pw.print(operations[i]); 49163d27a9233fed934340231f438493746084a681dJeff Sharkey pw.println(); 49275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 49375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 49475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 49575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 49675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public String toString() { 49775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final CharArrayWriter writer = new CharArrayWriter(); 498350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey dump("", new PrintWriter(writer), false); 49975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return writer.toString(); 50075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 50175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 50275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public static final Creator<NetworkStatsHistory> CREATOR = new Creator<NetworkStatsHistory>() { 50375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsHistory createFromParcel(Parcel in) { 50475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return new NetworkStatsHistory(in); 50575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 50675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 50775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsHistory[] newArray(int size) { 50875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return new NetworkStatsHistory[size]; 50975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 51075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey }; 51175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 51263d27a9233fed934340231f438493746084a681dJeff Sharkey private static long getLong(long[] array, int i, long value) { 51363d27a9233fed934340231f438493746084a681dJeff Sharkey return array != null ? array[i] : value; 51463d27a9233fed934340231f438493746084a681dJeff Sharkey } 51563d27a9233fed934340231f438493746084a681dJeff Sharkey 51663d27a9233fed934340231f438493746084a681dJeff Sharkey private static void setLong(long[] array, int i, long value) { 51763d27a9233fed934340231f438493746084a681dJeff Sharkey if (array != null) array[i] = value; 51863d27a9233fed934340231f438493746084a681dJeff Sharkey } 51963d27a9233fed934340231f438493746084a681dJeff Sharkey 52063d27a9233fed934340231f438493746084a681dJeff Sharkey private static void addLong(long[] array, int i, long value) { 52163d27a9233fed934340231f438493746084a681dJeff Sharkey if (array != null) array[i] += value; 52263d27a9233fed934340231f438493746084a681dJeff Sharkey } 52363d27a9233fed934340231f438493746084a681dJeff Sharkey 524a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** 525a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * Utility methods for interacting with {@link DataInputStream} and 526a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * {@link DataOutputStream}, mostly dealing with writing partial arrays. 527a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey */ 528a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public static class DataStreamUtils { 52963d27a9233fed934340231f438493746084a681dJeff Sharkey @Deprecated 53063d27a9233fed934340231f438493746084a681dJeff Sharkey public static long[] readFullLongArray(DataInputStream in) throws IOException { 531a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final int size = in.readInt(); 532a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final long[] values = new long[size]; 533a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < values.length; i++) { 534a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey values[i] = in.readLong(); 535a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 536a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return values; 537a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 538a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 53963d27a9233fed934340231f438493746084a681dJeff Sharkey /** 54063d27a9233fed934340231f438493746084a681dJeff Sharkey * Read variable-length {@link Long} using protobuf-style approach. 54163d27a9233fed934340231f438493746084a681dJeff Sharkey */ 54263d27a9233fed934340231f438493746084a681dJeff Sharkey public static long readVarLong(DataInputStream in) throws IOException { 54363d27a9233fed934340231f438493746084a681dJeff Sharkey int shift = 0; 54463d27a9233fed934340231f438493746084a681dJeff Sharkey long result = 0; 54563d27a9233fed934340231f438493746084a681dJeff Sharkey while (shift < 64) { 54663d27a9233fed934340231f438493746084a681dJeff Sharkey byte b = in.readByte(); 54763d27a9233fed934340231f438493746084a681dJeff Sharkey result |= (long) (b & 0x7F) << shift; 54863d27a9233fed934340231f438493746084a681dJeff Sharkey if ((b & 0x80) == 0) 54963d27a9233fed934340231f438493746084a681dJeff Sharkey return result; 55063d27a9233fed934340231f438493746084a681dJeff Sharkey shift += 7; 55163d27a9233fed934340231f438493746084a681dJeff Sharkey } 55263d27a9233fed934340231f438493746084a681dJeff Sharkey throw new ProtocolException("malformed long"); 55363d27a9233fed934340231f438493746084a681dJeff Sharkey } 55463d27a9233fed934340231f438493746084a681dJeff Sharkey 55563d27a9233fed934340231f438493746084a681dJeff Sharkey /** 55663d27a9233fed934340231f438493746084a681dJeff Sharkey * Write variable-length {@link Long} using protobuf-style approach. 55763d27a9233fed934340231f438493746084a681dJeff Sharkey */ 55863d27a9233fed934340231f438493746084a681dJeff Sharkey public static void writeVarLong(DataOutputStream out, long value) throws IOException { 55963d27a9233fed934340231f438493746084a681dJeff Sharkey while (true) { 56063d27a9233fed934340231f438493746084a681dJeff Sharkey if ((value & ~0x7FL) == 0) { 56163d27a9233fed934340231f438493746084a681dJeff Sharkey out.writeByte((int) value); 56263d27a9233fed934340231f438493746084a681dJeff Sharkey return; 56363d27a9233fed934340231f438493746084a681dJeff Sharkey } else { 56463d27a9233fed934340231f438493746084a681dJeff Sharkey out.writeByte(((int) value & 0x7F) | 0x80); 56563d27a9233fed934340231f438493746084a681dJeff Sharkey value >>>= 7; 56663d27a9233fed934340231f438493746084a681dJeff Sharkey } 56763d27a9233fed934340231f438493746084a681dJeff Sharkey } 56863d27a9233fed934340231f438493746084a681dJeff Sharkey } 56963d27a9233fed934340231f438493746084a681dJeff Sharkey 57063d27a9233fed934340231f438493746084a681dJeff Sharkey public static long[] readVarLongArray(DataInputStream in) throws IOException { 57163d27a9233fed934340231f438493746084a681dJeff Sharkey final int size = in.readInt(); 57263d27a9233fed934340231f438493746084a681dJeff Sharkey if (size == -1) return null; 57363d27a9233fed934340231f438493746084a681dJeff Sharkey final long[] values = new long[size]; 57463d27a9233fed934340231f438493746084a681dJeff Sharkey for (int i = 0; i < values.length; i++) { 57563d27a9233fed934340231f438493746084a681dJeff Sharkey values[i] = readVarLong(in); 57663d27a9233fed934340231f438493746084a681dJeff Sharkey } 57763d27a9233fed934340231f438493746084a681dJeff Sharkey return values; 57863d27a9233fed934340231f438493746084a681dJeff Sharkey } 57963d27a9233fed934340231f438493746084a681dJeff Sharkey 58063d27a9233fed934340231f438493746084a681dJeff Sharkey public static void writeVarLongArray(DataOutputStream out, long[] values, int size) 581a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey throws IOException { 58263d27a9233fed934340231f438493746084a681dJeff Sharkey if (values == null) { 58363d27a9233fed934340231f438493746084a681dJeff Sharkey out.writeInt(-1); 58463d27a9233fed934340231f438493746084a681dJeff Sharkey return; 58563d27a9233fed934340231f438493746084a681dJeff Sharkey } 586a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (size > values.length) { 587a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey throw new IllegalArgumentException("size larger than length"); 588a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 589a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey out.writeInt(size); 590a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < size; i++) { 59163d27a9233fed934340231f438493746084a681dJeff Sharkey writeVarLong(out, values[i]); 592a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 59375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 59475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 59575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 596a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** 597a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * Utility methods for interacting with {@link Parcel} structures, mostly 598a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey * dealing with writing partial arrays. 599a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey */ 600a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public static class ParcelUtils { 601a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public static long[] readLongArray(Parcel in) { 602a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final int size = in.readInt(); 60363d27a9233fed934340231f438493746084a681dJeff Sharkey if (size == -1) return null; 604a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final long[] values = new long[size]; 605a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < values.length; i++) { 606a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey values[i] = in.readLong(); 607a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 608a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return values; 60975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 61075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 611a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public static void writeLongArray(Parcel out, long[] values, int size) { 61263d27a9233fed934340231f438493746084a681dJeff Sharkey if (values == null) { 61363d27a9233fed934340231f438493746084a681dJeff Sharkey out.writeInt(-1); 61463d27a9233fed934340231f438493746084a681dJeff Sharkey return; 615a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 616a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (size > values.length) { 617a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey throw new IllegalArgumentException("size larger than length"); 618a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 619a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey out.writeInt(size); 620a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < size; i++) { 62163d27a9233fed934340231f438493746084a681dJeff Sharkey out.writeLong(values[i]); 622a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 62375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 62475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 62575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 62675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey} 627