NetworkStatsService.java revision d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903f
175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/* 2d2a458750e5a3d490af09cecb5c28370baf0a913Jeff 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 com.android.server.net; 1875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 19a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport static android.Manifest.permission.ACCESS_NETWORK_STATE; 2063d27a9233fed934340231f438493746084a681dJeff Sharkeyimport static android.Manifest.permission.CONNECTIVITY_INTERNAL; 2175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.Manifest.permission.DUMP; 2263d27a9233fed934340231f438493746084a681dJeff Sharkeyimport static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING; 2321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; 24b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.ACTION_SHUTDOWN; 25b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.ACTION_UID_REMOVED; 26b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.EXTRA_UID; 27cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkeyimport static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; 28367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE; 2961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL; 30b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_ALL; 31b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_DEFAULT; 32b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_FOREGROUND; 331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkStats.TAG_NONE; 3475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.net.NetworkStats.UID_ALL; 3507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateMobileAll; 3607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateWifi; 37b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.net.TrafficStats.UID_REMOVED; 3839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION; 3939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY; 4061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD; 4161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL; 42d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_TAG_MAX_HISTORY; 4339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION; 4439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_MAX_HISTORY; 45367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE; 46367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_NONE; 4761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS; 4861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.HOUR_IN_MILLIS; 4961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.MINUTE_IN_MILLIS; 50367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.text.format.DateUtils.SECOND_IN_MILLIS; 51d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull; 528e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT; 53b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats; 54b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet; 5575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 5675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.AlarmManager; 5775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.IAlarmManager; 5875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.PendingIntent; 5975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.BroadcastReceiver; 6039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport android.content.ContentResolver; 6175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Context; 6275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Intent; 6375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.IntentFilter; 6461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.content.pm.ApplicationInfo; 65293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkeyimport android.content.pm.PackageManager; 66293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkeyimport android.content.pm.PackageManager.NameNotFoundException; 67d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.IConnectivityManager; 688e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport android.net.INetworkManagementEventObserver; 6975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService; 701b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkIdentity; 71d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkInfo; 72d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState; 7375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStats; 74163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport android.net.NetworkStats.NonMonotonicException; 7575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStatsHistory; 761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate; 77a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport android.os.Binder; 78163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport android.os.DropBoxManager; 793f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport android.os.Environment; 8075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.Handler; 8175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.HandlerThread; 8275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.INetworkManagementService; 83b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.os.Message; 846248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkeyimport android.os.PowerManager; 8575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.RemoteException; 8675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.SystemClock; 8761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.provider.Settings; 88367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport android.telephony.PhoneStateListener; 8975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.telephony.TelephonyManager; 9007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport android.util.EventLog; 91b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkeyimport android.util.Log; 9275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.NtpTrustedTime; 9375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.Slog; 94b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.util.SparseIntArray; 9575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.TrustedTime; 9675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 973f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport com.android.internal.os.AtomicFile; 98b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport com.android.internal.util.Objects; 9907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport com.android.server.EventLogTags; 100cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkeyimport com.android.server.connectivity.Tethering; 101b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport com.google.android.collect.Lists; 10275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport com.google.android.collect.Maps; 1031b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport com.google.android.collect.Sets; 10475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1054e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkeyimport java.io.BufferedInputStream; 1064e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkeyimport java.io.BufferedOutputStream; 1073f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.DataInputStream; 1083f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.DataOutputStream; 1093f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.File; 11075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.FileDescriptor; 1113f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.FileNotFoundException; 1123f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.FileOutputStream; 1133f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.IOException; 11475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.PrintWriter; 1153f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.net.ProtocolException; 116b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport java.util.ArrayList; 117b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport java.util.Collections; 11875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.HashMap; 11961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport java.util.HashSet; 120293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkeyimport java.util.Random; 12175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1223f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport libcore.io.IoUtils; 1233f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 12475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/** 12575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collect and persist detailed network statistics, and provide this data to 12675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * other system services. 12775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 12875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeypublic class NetworkStatsService extends INetworkStatsService.Stub { 12921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG = "NetworkStats"; 130367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private static final boolean LOGD = false; 13139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private static final boolean LOGV = false; 13275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1333f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey /** File header magic number: "ANET" */ 1343f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey private static final int FILE_MAGIC = 0x414E4554; 1351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey private static final int VERSION_NETWORK_INIT = 1; 1361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey private static final int VERSION_UID_INIT = 1; 1371b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey private static final int VERSION_UID_WITH_IDENT = 2; 138d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey private static final int VERSION_UID_WITH_TAG = 3; 139b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private static final int VERSION_UID_WITH_SET = 4; 140b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 141367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private static final int MSG_PERFORM_POLL = 1; 142367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private static final int MSG_UPDATE_IFACES = 2; 143b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey 144b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey /** Flags to control detail level of poll event. */ 145905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private static final int FLAG_PERSIST_NETWORK = 0x1; 146905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private static final int FLAG_PERSIST_UID = 0x2; 147b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID; 1481f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey private static final int FLAG_PERSIST_FORCE = 0x100; 1493f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 150905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** Sample recent usage after each poll event. */ 151905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private static final boolean ENABLE_SAMPLE_AFTER_POLL = true; 152905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 153163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey private static final String TAG_NETSTATS_ERROR = "netstats_error"; 154163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 15575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Context mContext; 15675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final INetworkManagementService mNetworkManager; 15775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IAlarmManager mAlarmManager; 15875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final TrustedTime mTime; 159367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private final TelephonyManager mTeleManager; 16039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private final NetworkStatsSettings mSettings; 16175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1626248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey private final PowerManager.WakeLock mWakeLock; 1636248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey 164d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private IConnectivityManager mConnManager; 165163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey private DropBoxManager mDropBox; 166d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 1673f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // @VisibleForTesting 1683f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey public static final String ACTION_NETWORK_STATS_POLL = 16975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey "com.android.server.action.NETWORK_STATS_POLL"; 170497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey public static final String ACTION_NETWORK_STATS_UPDATED = 171497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey "com.android.server.action.NETWORK_STATS_UPDATED"; 17275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 17375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private PendingIntent mPollIntent; 17475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 175d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey // TODO: trim empty history objects entirely 176d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey 17775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private static final long KB_IN_BYTES = 1024; 17861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey private static final long MB_IN_BYTES = 1024 * KB_IN_BYTES; 17961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey private static final long GB_IN_BYTES = 1024 * MB_IN_BYTES; 18075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 18139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** 18239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Settings that can be changed externally. 18339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey */ 18439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public interface NetworkStatsSettings { 18539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPollInterval(); 18639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPersistThreshold(); 18739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkBucketDuration(); 18839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkMaxHistory(); 18939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidBucketDuration(); 19039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidMaxHistory(); 191d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey public long getTagMaxHistory(); 19239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getTimeCacheMaxAge(); 19339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 19475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 19575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Object mStatsLock = new Object(); 19675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey /** Set of currently active ifaces. */ 1981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap(); 199905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** Set of historical {@code dev} stats for known networks. */ 200905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkDevStats = Maps.newHashMap(); 201905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** Set of historical {@code xtables} stats for known networks. */ 202905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkXtStats = Maps.newHashMap(); 203905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey /** Set of historical {@code xtables} stats for known UIDs. */ 204b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private HashMap<UidStatsKey, NetworkStatsHistory> mUidStats = Maps.newHashMap(); 20539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 20639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** Flag if {@link #mUidStats} have been loaded from disk. */ 20739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private boolean mUidStatsLoaded = false; 20875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 209905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStats mLastPollNetworkDevSnapshot; 210905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStats mLastPollNetworkXtSnapshot; 2118e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey private NetworkStats mLastPollUidSnapshot; 2128e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey private NetworkStats mLastPollOperationsSnapshot; 21361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 214905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStats mLastPersistNetworkDevSnapshot; 215905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStats mLastPersistNetworkXtSnapshot; 2168e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey private NetworkStats mLastPersistUidSnapshot; 21775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 218b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** Current counter sets for each UID. */ 219b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private SparseIntArray mActiveUidCounterSet = new SparseIntArray(); 220b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 221a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey /** Data layer operation counters for splicing into other structures. */ 222a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey private NetworkStats mOperations = new NetworkStats(0L, 10); 223a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 22475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final HandlerThread mHandlerThread; 22575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Handler mHandler; 22675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 227905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private final AtomicFile mNetworkDevFile; 228905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private final AtomicFile mNetworkXtFile; 22939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private final AtomicFile mUidFile; 2303f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 23175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsService( 23275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) { 233104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context), 234104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey getSystemDir(), new DefaultNetworkStatsSettings(context)); 2353f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 2363f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 2373f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey private static File getSystemDir() { 2383f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey return new File(Environment.getDataDirectory(), "system"); 23975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 24075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 24175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsService(Context context, INetworkManagementService networkManager, 24239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey IAlarmManager alarmManager, TrustedTime time, File systemDir, 24339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey NetworkStatsSettings settings) { 24475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext = checkNotNull(context, "missing Context"); 24575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService"); 24675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager"); 24775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mTime = checkNotNull(time, "missing TrustedTime"); 248367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager"); 24939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mSettings = checkNotNull(settings, "missing NetworkStatsSettings"); 25075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 2516248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey final PowerManager powerManager = (PowerManager) context.getSystemService( 2526248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey Context.POWER_SERVICE); 2536248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 2546248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey 25575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mHandlerThread = new HandlerThread(TAG); 25675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mHandlerThread.start(); 257b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback); 2583f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 259905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mNetworkDevFile = new AtomicFile(new File(systemDir, "netstats.bin")); 260905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mNetworkXtFile = new AtomicFile(new File(systemDir, "netstats_xt.bin")); 26139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidFile = new AtomicFile(new File(systemDir, "netstats_uid.bin")); 26275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 26375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 26421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void bindConnectivityManager(IConnectivityManager connManager) { 26521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 26621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 26721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 26875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void systemReady() { 2693f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey synchronized (mStatsLock) { 27039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // read historical network stats from disk, since policy service 27139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // might need them right away. we delay loading detailed UID stats 27239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // until actually needed. 273905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey readNetworkDevStatsLocked(); 274905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey readNetworkXtStatsLocked(); 2753f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 27675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 2773359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey // bootstrap initial stats to prevent double-counting later 2783359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey bootstrapStats(); 2793359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey 28021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // watch for network interfaces to be claimed 281961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE); 282b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler); 28375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 284cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey // watch for tethering changes 285cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED); 286cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey mContext.registerReceiver(mTetherReceiver, tetherFilter, CONNECTIVITY_INTERNAL, mHandler); 287cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey 28875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // listen for periodic polling events 28975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL); 29021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 29175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 292b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey // listen for uid removal to clean stats 293b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED); 294b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler); 295b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 29675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // persist stats during clean shutdown 297b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN); 298b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey mContext.registerReceiver(mShutdownReceiver, shutdownFilter); 29975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 30075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey try { 3018e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mNetworkManager.registerObserver(mAlertObserver); 30275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } catch (RemoteException e) { 303b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 30475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 305b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 306367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey // watch for networkType changes that aren't broadcast through 307367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey // CONNECTIVITY_ACTION_IMMEDIATE above. 308367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE); 309367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 3108e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey registerPollAlarmLocked(); 3118e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey registerGlobalAlert(); 3128e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 313163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey mDropBox = (DropBoxManager) mContext.getSystemService(Context.DROPBOX_SERVICE); 31475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 31575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 3163f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey private void shutdownLocked() { 317b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey mContext.unregisterReceiver(mConnReceiver); 318367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mContext.unregisterReceiver(mTetherReceiver); 3193f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey mContext.unregisterReceiver(mPollReceiver); 320b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey mContext.unregisterReceiver(mRemovedReceiver); 3213f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey mContext.unregisterReceiver(mShutdownReceiver); 3223f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 323367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mTeleManager.listen(mPhoneListener, LISTEN_NONE); 324367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 325905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey writeNetworkDevStatsLocked(); 326905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey writeNetworkXtStatsLocked(); 327af8339374fbf1e2f57b0be918c7fc772f4250f13Jeff Sharkey if (mUidStatsLoaded) { 328af8339374fbf1e2f57b0be918c7fc772f4250f13Jeff Sharkey writeUidStatsLocked(); 329af8339374fbf1e2f57b0be918c7fc772f4250f13Jeff Sharkey } 330905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mNetworkDevStats.clear(); 331905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mNetworkXtStats.clear(); 33239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.clear(); 33339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStatsLoaded = false; 3343f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 3353f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 33675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 33775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and 33839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}. 33975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 3408e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey private void registerPollAlarmLocked() { 3418e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey try { 3428e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey if (mPollIntent != null) { 3438e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mAlarmManager.remove(mPollIntent); 3448e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 34575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 3468e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mPollIntent = PendingIntent.getBroadcast( 3478e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0); 34875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 3498e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey final long currentRealtime = SystemClock.elapsedRealtime(); 3508e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, 3518e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mSettings.getPollInterval(), mPollIntent); 3528e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } catch (RemoteException e) { 353b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 3548e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 3558e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 3568e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 3578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey /** 3588e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * Register for a global alert that is delivered through 3598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * {@link INetworkManagementEventObserver} once a threshold amount of data 3608e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * has been transferred. 3618e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey */ 3628e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey private void registerGlobalAlert() { 3638e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey try { 3648e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey final long alertBytes = mSettings.getPersistThreshold(); 3658e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mNetworkManager.setGlobalAlert(alertBytes); 3668e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } catch (IllegalStateException e) { 3678e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey Slog.w(TAG, "problem registering for global alert: " + e); 3688e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } catch (RemoteException e) { 369b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 3708e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 37175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 37275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 37375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 37463d27a9233fed934340231f438493746084a681dJeff Sharkey public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) { 37521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 376905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return getHistoryForNetworkDev(template, fields); 377905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 378905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 379905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStatsHistory getHistoryForNetworkDev(NetworkTemplate template, int fields) { 380905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return getHistoryForNetwork(template, fields, mNetworkDevStats); 381905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 382905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 383905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStatsHistory getHistoryForNetworkXt(NetworkTemplate template, int fields) { 384905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return getHistoryForNetwork(template, fields, mNetworkXtStats); 385905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 386d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 387905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields, 388905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey HashMap<NetworkIdentitySet, NetworkStatsHistory> source) { 389d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey synchronized (mStatsLock) { 390d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // combine all interfaces that match template 39161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final NetworkStatsHistory combined = new NetworkStatsHistory( 39263d27a9233fed934340231f438493746084a681dJeff Sharkey mSettings.getNetworkBucketDuration(), estimateNetworkBuckets(), fields); 393905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (NetworkIdentitySet ident : source.keySet()) { 3941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (templateMatches(template, ident)) { 395905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory history = source.get(ident); 396d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey if (history != null) { 397d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey combined.recordEntireHistory(history); 398d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey } 399d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 400d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 401d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey return combined; 402d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 40375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 40475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 40575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 40663d27a9233fed934340231f438493746084a681dJeff Sharkey public NetworkStatsHistory getHistoryForUid( 407b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey NetworkTemplate template, int uid, int set, int tag, int fields) { 40821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 409d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 41039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey synchronized (mStatsLock) { 41139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey ensureUidStatsLoadedLocked(); 4121b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 4131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // combine all interfaces that match template 4141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkStatsHistory combined = new NetworkStatsHistory( 41563d27a9233fed934340231f438493746084a681dJeff Sharkey mSettings.getUidBucketDuration(), estimateUidBuckets(), fields); 416b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (UidStatsKey key : mUidStats.keySet()) { 417b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final boolean setMatches = set == SET_ALL || key.set == set; 418b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (templateMatches(template, key.ident) && key.uid == uid && setMatches 419b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey && key.tag == tag) { 420b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final NetworkStatsHistory history = mUidStats.get(key); 421b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey combined.recordEntireHistory(history); 4221b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 4231b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 424b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 4251b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return combined; 42639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 42775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 42875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 429d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey @Override 4301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey public NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end) { 43121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 432905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return getSummaryForNetworkDev(template, start, end); 433905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 434905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 435905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStats getSummaryForNetworkDev(NetworkTemplate template, long start, long end) { 436905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return getSummaryForNetwork(template, start, end, mNetworkDevStats); 437905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 438905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 439905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStats getSummaryForNetworkXt(NetworkTemplate template, long start, long end) { 440905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return getSummaryForNetwork(template, start, end, mNetworkXtStats); 441905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 44221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 443905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStats getSummaryForNetwork(NetworkTemplate template, long start, long end, 444905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey HashMap<NetworkIdentitySet, NetworkStatsHistory> source) { 44521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mStatsLock) { 446434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey // use system clock to be externally consistent 447434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey final long now = System.currentTimeMillis(); 448434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey 449d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkStats stats = new NetworkStats(end - start, 1); 450d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkStats.Entry entry = new NetworkStats.Entry(); 451434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey NetworkStatsHistory.Entry historyEntry = null; 45221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 45321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // combine total from all interfaces that match template 454905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (NetworkIdentitySet ident : source.keySet()) { 4551b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (templateMatches(template, ident)) { 456905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory history = source.get(ident); 457434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey historyEntry = history.getValues(start, end, now, historyEntry); 458d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 459d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.iface = IFACE_ALL; 460d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.uid = UID_ALL; 461d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry.tag = TAG_NONE; 462434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey entry.rxBytes = historyEntry.rxBytes; 46307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.rxPackets = historyEntry.rxPackets; 464434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey entry.txBytes = historyEntry.txBytes; 46507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey entry.txPackets = historyEntry.txPackets; 466d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 467d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey stats.combineValues(entry); 46821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 46921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 47021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 4714a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return stats; 47221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 47321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 47421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 47521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 476d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey public NetworkStats getSummaryForAllUid( 477d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey NetworkTemplate template, long start, long end, boolean includeTags) { 47821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 479d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 48019862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey synchronized (mStatsLock) { 48139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey ensureUidStatsLoadedLocked(); 48239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 483434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey // use system clock to be externally consistent 484434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey final long now = System.currentTimeMillis(); 485434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey 4861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkStats stats = new NetworkStats(end - start, 24); 487d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkStats.Entry entry = new NetworkStats.Entry(); 488434962e44ea93b1c4d216c55f636a435bf54aa54Jeff Sharkey NetworkStatsHistory.Entry historyEntry = null; 4891b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 490b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (UidStatsKey key : mUidStats.keySet()) { 491b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (templateMatches(template, key.ident)) { 492b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // always include summary under TAG_NONE, and include 493b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // other tags when requested. 494b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (key.tag == TAG_NONE || includeTags) { 495b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final NetworkStatsHistory history = mUidStats.get(key); 496b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey historyEntry = history.getValues(start, end, now, historyEntry); 497b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 498b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.iface = IFACE_ALL; 499b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.uid = key.uid; 500b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.set = key.set; 501b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.tag = key.tag; 502b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.rxBytes = historyEntry.rxBytes; 503b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.rxPackets = historyEntry.rxPackets; 504b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.txBytes = historyEntry.txBytes; 505b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.txPackets = historyEntry.txPackets; 506b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey entry.operations = historyEntry.operations; 507b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 508b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0 509b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey || entry.txPackets > 0 || entry.operations > 0) { 510b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey stats.combineValues(entry); 511d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey } 5121b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 5131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 51419862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 5151b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 5164a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return stats; 51719862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 518d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 519d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 520350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey @Override 521a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException { 522a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (Binder.getCallingUid() != uid) { 523a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG); 524a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 525a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 526a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey // TODO: switch to data layer stats once kernel exports 527a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey // for now, read network layer stats and flatten across all ifaces 528a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final NetworkStats networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid); 529a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey final NetworkStats dataLayer = new NetworkStats( 530a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey networkLayer.getElapsedRealtime(), networkLayer.size()); 531a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 532a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey NetworkStats.Entry entry = null; 533a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey for (int i = 0; i < networkLayer.size(); i++) { 534a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry = networkLayer.getValues(i, entry); 535a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey entry.iface = IFACE_ALL; 536a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dataLayer.combineValues(entry); 537a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 538a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 539a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey // splice in operation counts 540a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey dataLayer.spliceOperationsFrom(mOperations); 541a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return dataLayer; 542a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 543a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 544a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey @Override 545a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey public void incrementOperationCount(int uid, int tag, int operationCount) { 546a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey if (Binder.getCallingUid() != uid) { 547a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG); 548a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 549a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 550b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (operationCount < 0) { 551b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey throw new IllegalArgumentException("operation count can only be incremented"); 552b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 553b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (tag == TAG_NONE) { 554b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey throw new IllegalArgumentException("operation count must have specific tag"); 555b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 556b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 557a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey synchronized (mStatsLock) { 558b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT); 559b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mOperations.combineValues(IFACE_ALL, uid, set, tag, 0L, 0L, 0L, 0L, operationCount); 560b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mOperations.combineValues(IFACE_ALL, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount); 561b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 562b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 563b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 564b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey @Override 565b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public void setUidForeground(int uid, boolean uidForeground) { 566b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG); 567b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 568b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey synchronized (mStatsLock) { 569b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT; 570b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT); 571b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (oldSet != set) { 572b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mActiveUidCounterSet.put(uid, set); 573b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey setKernelCounterSet(uid, set); 574b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 575a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 576a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey } 577a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey 578a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey @Override 579350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey public void forceUpdate() { 580350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 5811f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey performPoll(FLAG_PERSIST_ALL); 582350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey } 583350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey 58475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 585d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * Receiver that watches for {@link IConnectivityManager} to claim network 58675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()} 58775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * with mobile interfaces. 58875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 589b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey private BroadcastReceiver mConnReceiver = new BroadcastReceiver() { 59075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 59175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void onReceive(Context context, Intent intent) { 592d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 593d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // permission above. 594367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey updateIfaces(); 59575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 59675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey }; 59775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 598cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey /** 599cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey * Receiver that watches for {@link Tethering} to claim interface pairs. 600cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey */ 601cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() { 602cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey @Override 603cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey public void onReceive(Context context, Intent intent) { 604cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 605cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey // permission above. 6061f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey performPoll(FLAG_PERSIST_NETWORK); 607cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey } 608cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey }; 609cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey 61075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private BroadcastReceiver mPollReceiver = new BroadcastReceiver() { 61175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 61275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void onReceive(Context context, Intent intent) { 613d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // on background handler thread, and verified UPDATE_DEVICE_STATS 614d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // permission above. 6151f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey performPoll(FLAG_PERSIST_ALL); 6168e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 6178e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey // verify that we're watching global alert 6188e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey registerGlobalAlert(); 61975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 62075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey }; 62175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 622b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() { 623b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey @Override 624b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey public void onReceive(Context context, Intent intent) { 625b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey // on background handler thread, and UID_REMOVED is protected 626b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey // broadcast. 627b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey final int uid = intent.getIntExtra(EXTRA_UID, 0); 628b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey synchronized (mStatsLock) { 6296248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey mWakeLock.acquire(); 6306248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey try { 6316248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey removeUidLocked(uid); 6326248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey } finally { 6336248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey mWakeLock.release(); 6346248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey } 635b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 636b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 637b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey }; 638b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 63975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() { 64075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 64175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void onReceive(Context context, Intent intent) { 642b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey // SHUTDOWN is protected broadcast. 64375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey synchronized (mStatsLock) { 6443f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey shutdownLocked(); 64575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 64675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 64775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey }; 64875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 649d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey /** 6508e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * Observer that watches for {@link INetworkManagementService} alerts. 6518e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey */ 6528e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() { 6538e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey @Override 6548e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey public void limitReached(String limitName, String iface) { 6558e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey // only someone like NMS should be calling us 6568e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); 6578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 6588e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey if (LIMIT_GLOBAL_ALERT.equals(limitName)) { 6598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey // kick off background poll to collect network stats; UID stats 6608e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey // are handled during normal polling interval. 6611f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final int flags = FLAG_PERSIST_NETWORK; 662b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget(); 6638e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 6648e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey // re-arm global alert for next update 6658e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey registerGlobalAlert(); 6668e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 6678e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 6688e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey }; 6698e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 670367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN; 671367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 672367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 673367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey /** 674367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey * Receiver that watches for {@link TelephonyManager} changes, such as 675367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey * transitioning between network types. 676367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey */ 677367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private PhoneStateListener mPhoneListener = new PhoneStateListener() { 678367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey @Override 679367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey public void onDataConnectionStateChanged(int state, int networkType) { 680367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey final boolean stateChanged = state != mLastPhoneState; 681367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey final boolean networkTypeChanged = networkType != mLastPhoneNetworkType; 682367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 683367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey if (networkTypeChanged && !stateChanged) { 684367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey // networkType changed without a state change, which means we 685367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey // need to roll our own update. delay long enough for 686367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey // ConnectivityManager to process. 687367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey // TODO: add direct event to ConnectivityService instead of 688367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey // relying on this delay. 689367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()"); 690367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mHandler.sendMessageDelayed( 691367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS); 692367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey } 693367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 694367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mLastPhoneState = state; 695367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mLastPhoneNetworkType = networkType; 696367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey } 697367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey }; 698367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 699367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey private void updateIfaces() { 700367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey synchronized (mStatsLock) { 701367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mWakeLock.acquire(); 702367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey try { 703367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey updateIfacesLocked(); 704367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey } finally { 705367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey mWakeLock.release(); 706367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey } 707367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey } 708367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey } 709367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 7108e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey /** 711d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * Inspect all current {@link NetworkState} to derive mapping from {@code 712d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo} 713d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * are active on a single {@code iface}, they are combined under a single 7141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * {@link NetworkIdentitySet}. 715d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey */ 716d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private void updateIfacesLocked() { 71739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); 718d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 719d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // take one last stats snapshot before updating iface mapping. this 720d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // isn't perfect, since the kernel may already be counting traffic from 721d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // the updated network. 722b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey 7231f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey // poll, but only persist network stats to keep codepath fast. UID stats 7241f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey // will be persisted during next alarm poll event. 7251f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey performPollLocked(FLAG_PERSIST_NETWORK); 726d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 727d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final NetworkState[] states; 728d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey try { 729d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey states = mConnManager.getAllNetworkState(); 730d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } catch (RemoteException e) { 731b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 732d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey return; 733d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 734d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 735d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // rebuild active interfaces based on connected networks 7361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey mActiveIfaces.clear(); 737d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 738d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey for (NetworkState state : states) { 739d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (state.networkInfo.isConnected()) { 740d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // collect networks under their parent interfaces 741d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final String iface = state.linkProperties.getInterfaceName(); 7421b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 7431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey NetworkIdentitySet ident = mActiveIfaces.get(iface); 7441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (ident == null) { 7451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey ident = new NetworkIdentitySet(); 7461b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey mActiveIfaces.put(iface, ident); 7471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 7481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 749d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state)); 750d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 751d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 752d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 753d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 75439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** 7558e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * Bootstrap initial stats snapshot, usually during {@link #systemReady()} 7568e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey * so we have baseline values without double-counting. 7578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey */ 7588e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey private void bootstrapStats() { 7598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey try { 7608e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mLastPollUidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL); 761905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPollNetworkDevSnapshot = mNetworkManager.getNetworkStatsSummary(); 762905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPollNetworkXtSnapshot = computeNetworkXtSnapshotFromUid(mLastPollUidSnapshot); 7638e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mLastPollOperationsSnapshot = new NetworkStats(0L, 0); 7648e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } catch (IllegalStateException e) { 7658e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey Slog.w(TAG, "problem reading network stats: " + e); 7668e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } catch (RemoteException e) { 767b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 7688e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 7698e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 7708e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 771b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey private void performPoll(int flags) { 7728e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey synchronized (mStatsLock) { 7738e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mWakeLock.acquire(); 7748e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey try { 775b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey performPollLocked(flags); 7768e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } finally { 7778e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey mWakeLock.release(); 7788e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 7798e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 7808e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 7818e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 7828e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey /** 78339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Periodic poll operation, reading current statistics and recording into 78439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * {@link NetworkStatsHistory}. 78539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey */ 786b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey private void performPollLocked(int flags) { 787b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")"); 7888e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey final long startRealtime = SystemClock.elapsedRealtime(); 78975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 790b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0; 791b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0; 7921f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0; 793b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey 79475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // try refreshing time source when stale 79539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) { 79675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mTime.forceRefresh(); 79775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 79875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 79975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // TODO: consider marking "untrusted" times in historical stats 80075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() 80175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey : System.currentTimeMillis(); 802b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey final long threshold = mSettings.getPersistThreshold(); 80375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 804905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats uidSnapshot; 805905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats networkXtSnapshot; 806905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats networkDevSnapshot; 80775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey try { 808905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // collect any tethering stats 809d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey final NetworkStats tetherSnapshot = getNetworkStatsTethering(); 8101f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey 811905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // record uid stats, folding in tethering stats 812905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL); 813905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey uidSnapshot.combineAllValues(tetherSnapshot); 8141f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey performUidPollLocked(uidSnapshot, currentTime); 8151f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey 816905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // record dev network stats 817905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey networkDevSnapshot = mNetworkManager.getNetworkStatsSummary(); 818905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey performNetworkDevPollLocked(networkDevSnapshot, currentTime); 819905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 820905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // record xt network stats 821905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey networkXtSnapshot = computeNetworkXtSnapshotFromUid(uidSnapshot); 822905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey performNetworkXtPollLocked(networkXtSnapshot, currentTime); 823367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey 824b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey } catch (IllegalStateException e) { 825b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem reading network stats", e); 826905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return; 827b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey } catch (RemoteException e) { 828b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey // ignored; service lives in system_server 829905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return; 830905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 831905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 832905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // persist when enough network data has occurred 833905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final long persistNetworkDevDelta = computeStatsDelta( 8343359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey mLastPersistNetworkDevSnapshot, networkDevSnapshot, true, "devp").getTotalBytes(); 835905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final long persistNetworkXtDelta = computeStatsDelta( 8363359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey mLastPersistNetworkXtSnapshot, networkXtSnapshot, true, "xtp").getTotalBytes(); 837905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final boolean networkOverThreshold = persistNetworkDevDelta > threshold 838905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey || persistNetworkXtDelta > threshold; 839905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (persistForce || (persistNetwork && networkOverThreshold)) { 840905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey writeNetworkDevStatsLocked(); 841905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey writeNetworkXtStatsLocked(); 842905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPersistNetworkDevSnapshot = networkDevSnapshot; 843905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPersistNetworkXtSnapshot = networkXtSnapshot; 844905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 845905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 846905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // persist when enough uid data has occurred 847163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final long persistUidDelta = computeStatsDelta( 8483359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey mLastPersistUidSnapshot, uidSnapshot, true, "uidp").getTotalBytes(); 849905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (persistForce || (persistUid && persistUidDelta > threshold)) { 850905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey writeUidStatsLocked(); 851905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPersistUidSnapshot = uidSnapshot; 85261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 853497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey 8548e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey if (LOGV) { 8558e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey final long duration = SystemClock.elapsedRealtime() - startRealtime; 8568e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey Slog.v(TAG, "performPollLocked() took " + duration + "ms"); 8578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey } 8588e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey 859905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (ENABLE_SAMPLE_AFTER_POLL) { 860905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // sample stats after each full poll 861905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey performSample(); 862905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 86307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 864497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey // finally, dispatch updated event to any listeners 865497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED); 866497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 867497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey mContext.sendBroadcast(updatedIntent, READ_NETWORK_USAGE_HISTORY); 86861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 86961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 87061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 871905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Update {@link #mNetworkDevStats} historical usage. 87261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 873905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void performNetworkDevPollLocked(NetworkStats networkDevSnapshot, long currentTime) { 8741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final HashSet<String> unknownIface = Sets.newHashSet(); 875d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 876905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats delta = computeStatsDelta( 8773359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey mLastPollNetworkDevSnapshot, networkDevSnapshot, false, "dev"); 878d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final long timeStart = currentTime - delta.getElapsedRealtime(); 879d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey 880d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey NetworkStats.Entry entry = null; 881d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey for (int i = 0; i < delta.size(); i++) { 882d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry = delta.getValues(i, entry); 883d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface); 884d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (ident == null) { 885d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey unknownIface.add(entry.iface); 88675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey continue; 88775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 88875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 889905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory history = findOrCreateNetworkDevStatsLocked(ident); 890a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey history.recordData(timeStart, currentTime, entry); 891d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey } 892d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey 893905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPollNetworkDevSnapshot = networkDevSnapshot; 89475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 895d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (LOGD && unknownIface.size() > 0) { 896905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey Slog.w(TAG, "unknown dev interfaces " + unknownIface + ", ignoring those stats"); 897d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 89861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 899d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 90061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 901905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Update {@link #mNetworkXtStats} historical usage. 90261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 903905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void performNetworkXtPollLocked(NetworkStats networkXtSnapshot, long currentTime) { 904905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final HashSet<String> unknownIface = Sets.newHashSet(); 90539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 906905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats delta = computeStatsDelta( 9073359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey mLastPollNetworkXtSnapshot, networkXtSnapshot, false, "xt"); 908d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final long timeStart = currentTime - delta.getElapsedRealtime(); 9091b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 910d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey NetworkStats.Entry entry = null; 911d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey for (int i = 0; i < delta.size(); i++) { 912d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey entry = delta.getValues(i, entry); 913d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface); 9141b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (ident == null) { 915905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey unknownIface.add(entry.iface); 9161b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey continue; 91739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 9181b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 919905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory history = findOrCreateNetworkXtStatsLocked(ident); 920a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey history.recordData(timeStart, currentTime, entry); 92161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 9221b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 923905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPollNetworkXtSnapshot = networkXtSnapshot; 924905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 925905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (LOGD && unknownIface.size() > 0) { 926905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey Slog.w(TAG, "unknown xt interfaces " + unknownIface + ", ignoring those stats"); 927905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 92861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 92975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 930b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey /** 931905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey * Update {@link #mUidStats} historical usage. 932cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey */ 933905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void performUidPollLocked(NetworkStats uidSnapshot, long currentTime) { 934cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey ensureUidStatsLoadedLocked(); 935cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey 936163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final NetworkStats delta = computeStatsDelta( 9373359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey mLastPollUidSnapshot, uidSnapshot, false, "uid"); 938905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStats operationsDelta = computeStatsDelta( 9393359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey mLastPollOperationsSnapshot, mOperations, false, "uidop"); 940cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey final long timeStart = currentTime - delta.getElapsedRealtime(); 941cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey 942cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey NetworkStats.Entry entry = null; 943905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkStats.Entry operationsEntry = null; 944cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey for (int i = 0; i < delta.size(); i++) { 945cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey entry = delta.getValues(i, entry); 946cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface); 947cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey if (ident == null) { 948cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0 949cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey || entry.txPackets > 0) { 950905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey Log.w(TAG, "dropping UID delta from unknown iface: " + entry); 951cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey } 952cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey continue; 953cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey } 954cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey 955905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey // splice in operation counts since last poll 956905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.set, entry.tag); 957905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (j != -1) { 958905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey operationsEntry = operationsDelta.getValues(j, operationsEntry); 959905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey entry.operations = operationsEntry.operations; 960905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 961905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 962cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey final NetworkStatsHistory history = findOrCreateUidStatsLocked( 963905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey ident, entry.uid, entry.set, entry.tag); 964cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey history.recordData(timeStart, currentTime, entry); 965cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey } 966cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey 967905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mLastPollUidSnapshot = uidSnapshot; 9684abb1b8ef64dc4cd71966b59dc5d72a15055bf13Jeff Sharkey mLastPollOperationsSnapshot = mOperations.clone(); 969cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey } 970cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey 971cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey /** 97207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey * Sample recent statistics summary into {@link EventLog}. 97307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey */ 97407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey private void performSample() { 9751f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long largestBucketSize = Math.max( 9761f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey mSettings.getNetworkBucketDuration(), mSettings.getUidBucketDuration()); 9771f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey 9781f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey // take sample as atomic buckets 9791f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long now = mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis(); 9801f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long end = now - (now % largestBucketSize) + largestBucketSize; 9811f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long start = end - largestBucketSize; 98207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 983905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1; 984905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 98507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey NetworkTemplate template = null; 986905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkStats.Entry devTotal = null; 987905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkStats.Entry xtTotal = null; 98807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey NetworkStats.Entry uidTotal = null; 98907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 99007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey // collect mobile sample 99107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey template = buildTemplateMobileAll(getActiveSubscriberId(mContext)); 992905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal); 993905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal); 99407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal); 995905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey EventLogTags.writeNetstatsMobileSample( 996905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets, 997905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets, 998905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets, 999905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey trustedTime); 100007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 100107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey // collect wifi sample 100207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey template = buildTemplateWifi(); 1003905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal); 1004905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal); 100507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal); 1006905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey EventLogTags.writeNetstatsWifiSample( 1007905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets, 1008905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets, 1009905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets, 1010905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey trustedTime); 101107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey } 101207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 101307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey /** 1014b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey * Clean up {@link #mUidStats} after UID is removed. 1015b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey */ 1016b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey private void removeUidLocked(int uid) { 1017b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey ensureUidStatsLoadedLocked(); 1018b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 1019163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // perform one last poll before removing 1020163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey performPollLocked(FLAG_PERSIST_ALL); 1021163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 1022b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final ArrayList<UidStatsKey> knownKeys = Lists.newArrayList(); 1023b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey knownKeys.addAll(mUidStats.keySet()); 1024b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 1025b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey // migrate all UID stats into special "removed" bucket 1026b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (UidStatsKey key : knownKeys) { 1027b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (key.uid == uid) { 1028b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // only migrate combined TAG_NONE history 1029b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (key.tag == TAG_NONE) { 1030b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final NetworkStatsHistory uidHistory = mUidStats.get(key); 1031b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final NetworkStatsHistory removedHistory = findOrCreateUidStatsLocked( 1032b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey key.ident, UID_REMOVED, SET_DEFAULT, TAG_NONE); 1033b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey removedHistory.recordEntireHistory(uidHistory); 1034d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey } 1035b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mUidStats.remove(key); 1036b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 1037b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 1038b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 1039163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // clear UID from current stats snapshot 1040163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey mLastPollUidSnapshot = mLastPollUidSnapshot.withoutUid(uid); 1041163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey mLastPollNetworkXtSnapshot = computeNetworkXtSnapshotFromUid(mLastPollUidSnapshot); 1042163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 1043b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // clear kernel stats associated with UID 1044b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey resetKernelUidStats(uid); 1045b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 1046b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey // since this was radical rewrite, push to disk 1047b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey writeUidStatsLocked(); 1048b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 1049b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 1050905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStatsHistory findOrCreateNetworkXtStatsLocked(NetworkIdentitySet ident) { 1051905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return findOrCreateNetworkStatsLocked(ident, mNetworkXtStats); 1052905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 1053905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 1054905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStatsHistory findOrCreateNetworkDevStatsLocked(NetworkIdentitySet ident) { 1055905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return findOrCreateNetworkStatsLocked(ident, mNetworkDevStats); 1056905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 1057905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 1058905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private NetworkStatsHistory findOrCreateNetworkStatsLocked( 1059905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey NetworkIdentitySet ident, HashMap<NetworkIdentitySet, NetworkStatsHistory> source) { 1060905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory existing = source.get(ident); 106139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 106239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // update when no existing, or when bucket duration changed 1063d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey final long bucketDuration = mSettings.getNetworkBucketDuration(); 106439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey NetworkStatsHistory updated = null; 106539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (existing == null) { 10664a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey updated = new NetworkStatsHistory(bucketDuration, 10); 1067d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } else if (existing.getBucketDuration() != bucketDuration) { 10684a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey updated = new NetworkStatsHistory( 10694a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey bucketDuration, estimateResizeBuckets(existing, bucketDuration)); 107039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated.recordEntireHistory(existing); 107139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 107239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 107339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (updated != null) { 1074905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey source.put(ident, updated); 107539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return updated; 107639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } else { 107739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return existing; 107875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 107975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 108075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1081d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey private NetworkStatsHistory findOrCreateUidStatsLocked( 1082b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey NetworkIdentitySet ident, int uid, int set, int tag) { 1083b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey ensureUidStatsLoadedLocked(); 1084b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 1085b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final UidStatsKey key = new UidStatsKey(ident, uid, set, tag); 1086b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final NetworkStatsHistory existing = mUidStats.get(key); 108739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 108839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // update when no existing, or when bucket duration changed 1089d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey final long bucketDuration = mSettings.getUidBucketDuration(); 109039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey NetworkStatsHistory updated = null; 109139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (existing == null) { 10924a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey updated = new NetworkStatsHistory(bucketDuration, 10); 1093d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey } else if (existing.getBucketDuration() != bucketDuration) { 10944a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey updated = new NetworkStatsHistory( 10954a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey bucketDuration, estimateResizeBuckets(existing, bucketDuration)); 109639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated.recordEntireHistory(existing); 109739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 109839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 109939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (updated != null) { 1100b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mUidStats.put(key, updated); 110139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return updated; 110239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } else { 110339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return existing; 110475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 110575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 110675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1107905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void readNetworkDevStatsLocked() { 1108905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (LOGV) Slog.v(TAG, "readNetworkDevStatsLocked()"); 1109905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey readNetworkStats(mNetworkDevFile, mNetworkDevStats); 1110905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 1111905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 1112905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void readNetworkXtStatsLocked() { 1113905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (LOGV) Slog.v(TAG, "readNetworkXtStatsLocked()"); 1114905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey readNetworkStats(mNetworkXtFile, mNetworkXtStats); 1115905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 11163f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 1117905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private static void readNetworkStats( 1118905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey AtomicFile inputFile, HashMap<NetworkIdentitySet, NetworkStatsHistory> output) { 11193f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // clear any existing stats and read from disk 1120905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey output.clear(); 11213f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 11224e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey DataInputStream in = null; 11233f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey try { 1124905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey in = new DataInputStream(new BufferedInputStream(inputFile.openRead())); 11253f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 11263f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // verify file magic header intact 11273f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final int magic = in.readInt(); 11283f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey if (magic != FILE_MAGIC) { 11293f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey throw new ProtocolException("unexpected magic: " + magic); 11303f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 11313f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 11323f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final int version = in.readInt(); 11333f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey switch (version) { 11341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case VERSION_NETWORK_INIT: { 11351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // network := size *(NetworkIdentitySet NetworkStatsHistory) 11363f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final int size = in.readInt(); 11373f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey for (int i = 0; i < size; i++) { 11381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkIdentitySet ident = new NetworkIdentitySet(in); 11393f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final NetworkStatsHistory history = new NetworkStatsHistory(in); 1140905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey output.put(ident, history); 11413f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 11423f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey break; 11433f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 11443f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey default: { 11453f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey throw new ProtocolException("unexpected version: " + version); 11463f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 11473f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 11483f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } catch (FileNotFoundException e) { 11493f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // missing stats is okay, probably first boot 11503f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } catch (IOException e) { 1151b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem reading network stats", e); 11523f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } finally { 11534e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey IoUtils.closeQuietly(in); 11543f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 115575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 115675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 115739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void ensureUidStatsLoadedLocked() { 115839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (!mUidStatsLoaded) { 115939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey readUidStatsLocked(); 116039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStatsLoaded = true; 116139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 116239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 116339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 116439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void readUidStatsLocked() { 116539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "readUidStatsLocked()"); 116639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 116739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // clear any existing stats and read from disk 116839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.clear(); 116939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 11704e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey DataInputStream in = null; 117139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey try { 11724e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey in = new DataInputStream(new BufferedInputStream(mUidFile.openRead())); 117339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 117439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // verify file magic header intact 117539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int magic = in.readInt(); 117639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (magic != FILE_MAGIC) { 117739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey throw new ProtocolException("unexpected magic: " + magic); 117839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 117939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 118039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int version = in.readInt(); 118139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey switch (version) { 11821b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case VERSION_UID_INIT: { 118339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // uid := size *(UID NetworkStatsHistory) 118439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 11851b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // drop this data version, since we don't have a good 11861b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // mapping into NetworkIdentitySet. 11871b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey break; 11881b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 11891b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey case VERSION_UID_WITH_IDENT: { 11901b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey // uid := size *(NetworkIdentitySet size *(UID NetworkStatsHistory)) 1191d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey 1192d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey // drop this data version, since this version only existed 1193d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey // for a short time. 1194d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey break; 1195d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey } 1196b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case VERSION_UID_WITH_TAG: 1197b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey case VERSION_UID_WITH_SET: { 1198b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // uid := size *(NetworkIdentitySet size *(uid set tag NetworkStatsHistory)) 1199b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int identSize = in.readInt(); 1200b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (int i = 0; i < identSize; i++) { 12011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkIdentitySet ident = new NetworkIdentitySet(in); 12021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 1203b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int size = in.readInt(); 1204b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (int j = 0; j < size; j++) { 12051b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final int uid = in.readInt(); 1206b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final int set = (version >= VERSION_UID_WITH_SET) ? in.readInt() 1207b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey : SET_DEFAULT; 1208d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey final int tag = in.readInt(); 1209d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey 1210b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final UidStatsKey key = new UidStatsKey(ident, uid, set, tag); 12111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkStatsHistory history = new NetworkStatsHistory(in); 1212b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey mUidStats.put(key, history); 12131b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 121439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 121539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey break; 121639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 121739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey default: { 121839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey throw new ProtocolException("unexpected version: " + version); 121939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 122039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 122139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } catch (FileNotFoundException e) { 122239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // missing stats is okay, probably first boot 122339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } catch (IOException e) { 1224b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem reading uid stats", e); 122539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } finally { 12264e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey IoUtils.closeQuietly(in); 122739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 122839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 122939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 1230905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void writeNetworkDevStatsLocked() { 1231905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (LOGV) Slog.v(TAG, "writeNetworkDevStatsLocked()"); 1232905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey writeNetworkStats(mNetworkDevStats, mNetworkDevFile); 1233905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 1234905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 1235905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void writeNetworkXtStatsLocked() { 1236905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey if (LOGV) Slog.v(TAG, "writeNetworkXtStatsLocked()"); 1237905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey writeNetworkStats(mNetworkXtStats, mNetworkXtFile); 1238905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 12393f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 1240905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private void writeNetworkStats( 1241905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey HashMap<NetworkIdentitySet, NetworkStatsHistory> input, AtomicFile outputFile) { 1242d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // TODO: consider duplicating stats and releasing lock while writing 12433f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 12441f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey // trim any history beyond max 12451f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey if (mTime.hasCache()) { 12461f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long currentTime = mTime.currentTimeMillis(); 12471f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long maxHistory = mSettings.getNetworkMaxHistory(); 1248905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (NetworkStatsHistory history : input.values()) { 12491f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey history.removeBucketsBefore(currentTime - maxHistory); 12501f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey } 12511f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey } 12521f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey 12533f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey FileOutputStream fos = null; 12543f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey try { 1255905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey fos = outputFile.startWrite(); 12564e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos)); 12573f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 12583f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey out.writeInt(FILE_MAGIC); 12591b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey out.writeInt(VERSION_NETWORK_INIT); 12603f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 1261905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey out.writeInt(input.size()); 1262905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (NetworkIdentitySet ident : input.keySet()) { 1263905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory history = input.get(ident); 12643f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey ident.writeToStream(out); 12653f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey history.writeToStream(out); 12663f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 12673f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 12684e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey out.flush(); 1269905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey outputFile.finishWrite(fos); 127039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } catch (IOException e) { 1271b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem writing stats", e); 127239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (fos != null) { 1273905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey outputFile.failWrite(fos); 127439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 127539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 127639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 127739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 127839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void writeUidStatsLocked() { 127939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "writeUidStatsLocked()"); 128039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 1281b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey if (!mUidStatsLoaded) { 1282b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey Slog.w(TAG, "asked to write UID stats when not loaded; skipping"); 1283b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey return; 1284b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey } 1285b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey 128639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // TODO: consider duplicating stats and releasing lock while writing 128739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 12881f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey // trim any history beyond max 12891f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey if (mTime.hasCache()) { 12901f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long currentTime = mTime.currentTimeMillis(); 12911f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long maxUidHistory = mSettings.getUidMaxHistory(); 12921f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final long maxTagHistory = mSettings.getTagMaxHistory(); 12931f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey for (UidStatsKey key : mUidStats.keySet()) { 12941f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey final NetworkStatsHistory history = mUidStats.get(key); 12951f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey 12961f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey // detailed tags are trimmed sooner than summary in TAG_NONE 12971f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey if (key.tag == TAG_NONE) { 12981f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey history.removeBucketsBefore(currentTime - maxUidHistory); 12991f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey } else { 13001f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey history.removeBucketsBefore(currentTime - maxTagHistory); 13011f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey } 13021f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey } 13031f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey } 13041f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey 1305b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey // build UidStatsKey lists grouped by ident 1306b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final HashMap<NetworkIdentitySet, ArrayList<UidStatsKey>> keysByIdent = Maps.newHashMap(); 1307b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (UidStatsKey key : mUidStats.keySet()) { 1308b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey ArrayList<UidStatsKey> keys = keysByIdent.get(key.ident); 1309b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (keys == null) { 1310b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey keys = Lists.newArrayList(); 1311b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey keysByIdent.put(key.ident, keys); 1312b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1313b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey keys.add(key); 1314b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1315b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 131639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey FileOutputStream fos = null; 131739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey try { 131839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey fos = mUidFile.startWrite(); 13194e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos)); 132039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 132139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey out.writeInt(FILE_MAGIC); 1322b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey out.writeInt(VERSION_UID_WITH_SET); 132339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 1324b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey out.writeInt(keysByIdent.size()); 1325b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (NetworkIdentitySet ident : keysByIdent.keySet()) { 1326b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final ArrayList<UidStatsKey> keys = keysByIdent.get(ident); 13271b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey ident.writeToStream(out); 132839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 1329b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey out.writeInt(keys.size()); 1330b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (UidStatsKey key : keys) { 1331b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final NetworkStatsHistory history = mUidStats.get(key); 1332b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey out.writeInt(key.uid); 1333b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey out.writeInt(key.set); 1334b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey out.writeInt(key.tag); 13351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey history.writeToStream(out); 13361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 133739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 133839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 13394e814c348ce205fcc1a273427f95ef1d100ed60cJeff Sharkey out.flush(); 134039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidFile.finishWrite(fos); 13413f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } catch (IOException e) { 1342b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey Log.wtf(TAG, "problem writing stats", e); 13433f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey if (fos != null) { 134439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidFile.failWrite(fos); 13453f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 13463f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 134775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 134875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 134975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 135075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 135175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(DUMP, TAG); 135275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 135361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final HashSet<String> argSet = new HashSet<String>(); 135461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (String arg : args) { 135561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey argSet.add(arg); 135661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 135761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 1358350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey final boolean fullHistory = argSet.contains("full"); 1359350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey 136061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey synchronized (mStatsLock) { 136161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey // TODO: remove this testing code, since it corrupts stats 136261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey if (argSet.contains("generate")) { 1363293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey generateRandomLocked(args); 136461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.println("Generated stub stats"); 136561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey return; 136661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 136761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 13683f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey if (argSet.contains("poll")) { 13691f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE); 13703f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey pw.println("Forced poll"); 13713f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey return; 13723f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 13733f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 137461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.println("Active interfaces:"); 13751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey for (String iface : mActiveIfaces.keySet()) { 13761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey final NetworkIdentitySet ident = mActiveIfaces.get(iface); 137761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" iface="); pw.print(iface); 137861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" ident="); pw.println(ident.toString()); 137961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 138061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 1381905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey pw.println("Known historical dev stats:"); 1382905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (NetworkIdentitySet ident : mNetworkDevStats.keySet()) { 1383905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory history = mNetworkDevStats.get(ident); 1384905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey pw.print(" ident="); pw.println(ident.toString()); 1385905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey history.dump(" ", pw, fullHistory); 1386905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 1387905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 1388905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey pw.println("Known historical xt stats:"); 1389905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey for (NetworkIdentitySet ident : mNetworkXtStats.keySet()) { 1390905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey final NetworkStatsHistory history = mNetworkXtStats.get(ident); 139161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" ident="); pw.println(ident.toString()); 1392350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey history.dump(" ", pw, fullHistory); 139361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 139461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 139561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey if (argSet.contains("detail")) { 139639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // since explicitly requested with argument, we're okay to load 139739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // from disk if not already in memory. 139839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey ensureUidStatsLoadedLocked(); 13991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 1400b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final ArrayList<UidStatsKey> keys = Lists.newArrayList(); 1401b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey keys.addAll(mUidStats.keySet()); 1402b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey Collections.sort(keys); 1403b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 14041b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey pw.println("Detailed UID stats:"); 1405b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey for (UidStatsKey key : keys) { 1406b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" ident="); pw.print(key.ident.toString()); 1407b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" uid="); pw.print(key.uid); 1408b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" set="); pw.print(NetworkStats.setToString(key.set)); 1409b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey pw.print(" tag="); pw.println(NetworkStats.tagToString(key.tag)); 1410b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 1411b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final NetworkStatsHistory history = mUidStats.get(key); 1412b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey history.dump(" ", pw, fullHistory); 141361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 141461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 141575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 141661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 141775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 141861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 141961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey * @deprecated only for temporary testing 142061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 142161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey @Deprecated 1422293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey private void generateRandomLocked(String[] args) { 1423293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long totalBytes = Long.parseLong(args[1]); 1424293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long totalTime = Long.parseLong(args[2]); 1425293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1426293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final PackageManager pm = mContext.getPackageManager(); 1427293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final ArrayList<Integer> specialUidList = Lists.newArrayList(); 1428293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey for (int i = 3; i < args.length; i++) { 1429293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey try { 1430293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey specialUidList.add(pm.getApplicationInfo(args[i], 0).uid); 1431293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey } catch (NameNotFoundException e) { 1432293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey throw new RuntimeException(e); 1433293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey } 1434293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey } 1435293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1436293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final HashSet<Integer> otherUidSet = Sets.newHashSet(); 1437293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey for (ApplicationInfo info : pm.getInstalledApplications(0)) { 1438293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey if (pm.checkPermission(android.Manifest.permission.INTERNET, info.packageName) 1439293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey == PackageManager.PERMISSION_GRANTED && !specialUidList.contains(info.uid)) { 1440293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey otherUidSet.add(info.uid); 1441293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey } 1442293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey } 1443293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1444293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final ArrayList<Integer> otherUidList = new ArrayList<Integer>(otherUidSet); 1445293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1446293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long end = System.currentTimeMillis(); 1447293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long start = end - totalTime; 144861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 1449905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mNetworkDevStats.clear(); 1450905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey mNetworkXtStats.clear(); 145139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.clear(); 1452293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1453293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final Random r = new Random(); 14541b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey for (NetworkIdentitySet ident : mActiveIfaces.values()) { 1455293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final NetworkStatsHistory devHistory = findOrCreateNetworkDevStatsLocked(ident); 1456293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final NetworkStatsHistory xtHistory = findOrCreateNetworkXtStatsLocked(ident); 1457293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1458293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final ArrayList<Integer> uidList = new ArrayList<Integer>(); 1459293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey uidList.addAll(specialUidList); 1460293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1461293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey if (uidList.size() == 0) { 1462293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey Collections.shuffle(otherUidList); 1463293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey uidList.addAll(otherUidList); 1464293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey } 1465293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1466293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey boolean first = true; 1467293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey long remainingBytes = totalBytes; 1468293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey for (int uid : uidList) { 1469293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final NetworkStatsHistory defaultHistory = findOrCreateUidStatsLocked( 1470293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey ident, uid, SET_DEFAULT, TAG_NONE); 1471293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final NetworkStatsHistory foregroundHistory = findOrCreateUidStatsLocked( 1472293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey ident, uid, SET_FOREGROUND, TAG_NONE); 1473293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1474293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long uidBytes = totalBytes / uidList.size(); 1475293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1476293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final float fractionDefault = r.nextFloat(); 1477293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long defaultBytes = (long) (uidBytes * fractionDefault); 1478293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long foregroundBytes = (long) (uidBytes * (1 - fractionDefault)); 1479293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1480293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey defaultHistory.generateRandom(start, end, defaultBytes); 1481293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey foregroundHistory.generateRandom(start, end, foregroundBytes); 1482293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1483293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey if (first) { 1484293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey final long bumpTime = (start + end) / 2; 1485293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey defaultHistory.recordData( 1486293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey bumpTime, bumpTime + DAY_IN_MILLIS, 200 * MB_IN_BYTES, 0); 1487293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey first = false; 1488293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey } 1489293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey 1490293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey devHistory.recordEntireHistory(defaultHistory); 1491293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey devHistory.recordEntireHistory(foregroundHistory); 1492293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey xtHistory.recordEntireHistory(defaultHistory); 1493293779f9c63cbae0dde564449f0270b595593b0dJeff Sharkey xtHistory.recordEntireHistory(foregroundHistory); 14941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 149561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 149661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 149761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 149875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 149975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Return the delta between two {@link NetworkStats} snapshots, where {@code 150075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * before} can be {@code null}. 150175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 1502163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey private NetworkStats computeStatsDelta( 1503163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey NetworkStats before, NetworkStats current, boolean collectStale, String type) { 150475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (before != null) { 1505163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey try { 1506d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey return current.subtract(before, false); 1507163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } catch (NonMonotonicException e) { 1508163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey Log.w(TAG, "found non-monotonic values; saving to dropbox"); 1509163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 1510163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey // record error for debugging 1511163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey final StringBuilder builder = new StringBuilder(); 15123359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey builder.append("found non-monotonic " + type + " values at left[" + e.leftIndex 1513163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey + "] - right[" + e.rightIndex + "]\n"); 1514163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey builder.append("left=").append(e.left).append('\n'); 1515163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey builder.append("right=").append(e.right).append('\n'); 1516163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString()); 1517163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey 1518d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey try { 1519d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey // return clamped delta to help recover 1520d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey return current.subtract(before, true); 1521d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } catch (NonMonotonicException e1) { 1522d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey Log.wtf(TAG, "found non-monotonic values; returning empty delta", e1); 1523d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey return new NetworkStats(0L, 10); 1524d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 1525163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey } 152663d27a9233fed934340231f438493746084a681dJeff Sharkey } else if (collectStale) { 152763d27a9233fed934340231f438493746084a681dJeff Sharkey // caller is okay collecting stale stats for first call. 152863d27a9233fed934340231f438493746084a681dJeff Sharkey return current; 152975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } else { 1530a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey // this is first snapshot; to prevent from double-counting we only 1531a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey // observe traffic occuring between known snapshots. 1532a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey return new NetworkStats(0L, 10); 153375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 153475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 153575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 1536d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey /** 1537d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * Return snapshot of current tethering statistics. Will return empty 1538d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey * {@link NetworkStats} if any problems are encountered. 1539d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey */ 1540d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey private NetworkStats getNetworkStatsTethering() throws RemoteException { 1541d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey try { 1542d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs(); 1543d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey return mNetworkManager.getNetworkStatsTethering(tetheredIfacePairs); 1544d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } catch (IllegalStateException e) { 1545d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey Log.wtf(TAG, "problem reading network stats", e); 1546d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey return new NetworkStats(0L, 10); 1547d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 1548d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey } 1549d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey 1550905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey private static NetworkStats computeNetworkXtSnapshotFromUid(NetworkStats uidSnapshot) { 1551905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey return uidSnapshot.groupedByIface(); 1552905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey } 1553905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey 15544a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey private int estimateNetworkBuckets() { 15554a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return (int) (mSettings.getNetworkMaxHistory() / mSettings.getNetworkBucketDuration()); 15564a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey } 15574a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey 15584a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey private int estimateUidBuckets() { 15594a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey return (int) (mSettings.getUidMaxHistory() / mSettings.getUidBucketDuration()); 15604a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey } 15614a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey 15624a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey private static int estimateResizeBuckets(NetworkStatsHistory existing, long newBucketDuration) { 1563d37948f6ed1667d077e0e3a38808f42f981ddcc2Jeff Sharkey return (int) (existing.size() * existing.getBucketDuration() / newBucketDuration); 15644a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey } 15654a97122ebf4d92a3f94402041729d77905e6c0c0Jeff Sharkey 156639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** 15671b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * Test if given {@link NetworkTemplate} matches any {@link NetworkIdentity} 15681b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey * in the given {@link NetworkIdentitySet}. 15691b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey */ 15701b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey private static boolean templateMatches(NetworkTemplate template, NetworkIdentitySet identSet) { 15711b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey for (NetworkIdentity ident : identSet) { 15721b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey if (template.matches(ident)) { 15731b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return true; 15741b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 15751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 15761b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey return false; 15771b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey } 15781b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey 1579b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private Handler.Callback mHandlerCallback = new Handler.Callback() { 1580b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@inheritDoc} */ 1581b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public boolean handleMessage(Message msg) { 1582b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey switch (msg.what) { 15838e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey case MSG_PERFORM_POLL: { 1584b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey final int flags = msg.arg1; 1585b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey performPoll(flags); 1586b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return true; 1587b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1588367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey case MSG_UPDATE_IFACES: { 1589367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey updateIfaces(); 1590367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey return true; 1591367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey } 1592b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey default: { 1593b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return false; 1594b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1595b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1596b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1597b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey }; 1598b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 159907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey private static String getActiveSubscriberId(Context context) { 160007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey final TelephonyManager telephony = (TelephonyManager) context.getSystemService( 160107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey Context.TELEPHONY_SERVICE); 160207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey return telephony.getSubscriberId(); 160307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey } 160407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey 1605b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** 1606b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey * Key uniquely identifying a {@link NetworkStatsHistory} for a UID. 1607b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey */ 1608b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey private static class UidStatsKey implements Comparable<UidStatsKey> { 1609b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public final NetworkIdentitySet ident; 1610b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public final int uid; 1611b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public final int set; 1612b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public final int tag; 1613b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 1614b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public UidStatsKey(NetworkIdentitySet ident, int uid, int set, int tag) { 1615b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.ident = ident; 1616b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.uid = uid; 1617b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.set = set; 1618b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey this.tag = tag; 1619b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1620b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 1621b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey @Override 1622b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int hashCode() { 1623b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return Objects.hashCode(ident, uid, set, tag); 1624b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1625b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 1626b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey @Override 1627b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public boolean equals(Object obj) { 1628b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey if (obj instanceof UidStatsKey) { 1629b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey final UidStatsKey key = (UidStatsKey) obj; 1630b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return Objects.equal(ident, key.ident) && uid == key.uid && set == key.set 1631b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey && tag == key.tag; 1632b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1633b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return false; 1634b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1635b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 1636b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey /** {@inheritDoc} */ 1637b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey public int compareTo(UidStatsKey another) { 1638b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey return Integer.compare(uid, another.uid); 1639b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1640b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey } 1641b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey 16421b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey /** 164339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Default external settings that read from {@link Settings.Secure}. 164439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey */ 164539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private static class DefaultNetworkStatsSettings implements NetworkStatsSettings { 164639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private final ContentResolver mResolver; 164739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 164839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public DefaultNetworkStatsSettings(Context context) { 164939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mResolver = checkNotNull(context.getContentResolver()); 165039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // TODO: adjust these timings for production builds 165139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 165239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 165339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private long getSecureLong(String name, long def) { 165439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return Settings.Secure.getLong(mResolver, name, def); 165539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 1656991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey private boolean getSecureBoolean(String name, boolean def) { 1657991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey final int defInt = def ? 1 : 0; 1658991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey return Settings.Secure.getInt(mResolver, name, defInt) != 0; 1659991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey } 166039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 166139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPollInterval() { 16628e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS); 166339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 166439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPersistThreshold() { 1665b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 2 * MB_IN_BYTES); 166639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 166739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkBucketDuration() { 166839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS); 166939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 167039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkMaxHistory() { 167139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_NETWORK_MAX_HISTORY, 90 * DAY_IN_MILLIS); 167239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 167339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidBucketDuration() { 167439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS); 167539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 167639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidMaxHistory() { 167739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_UID_MAX_HISTORY, 90 * DAY_IN_MILLIS); 167839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 1679d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey public long getTagMaxHistory() { 1680d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey return getSecureLong(NETSTATS_TAG_MAX_HISTORY, 30 * DAY_IN_MILLIS); 1681d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey } 168239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getTimeCacheMaxAge() { 168339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return DAY_IN_MILLIS; 168439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 168539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 168675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey} 1687