NetworkStatsService.java revision 39ebc2195ed16b9e955dd57f5c95212bb7b934b6
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 19d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport static android.Manifest.permission.CONNECTIVITY_INTERNAL; 2075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.Manifest.permission.DUMP; 2121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkeyimport static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY; 2275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.Manifest.permission.SHUTDOWN; 23d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION; 2461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL; 2575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.net.NetworkStats.UID_ALL; 2639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_NETWORK_BUCKET_DURATION; 2739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_NETWORK_MAX_HISTORY; 2861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_PERSIST_THRESHOLD; 2961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL; 3039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION; 3139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_MAX_HISTORY; 3261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS; 3361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.HOUR_IN_MILLIS; 3461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.MINUTE_IN_MILLIS; 35d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull; 3675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 3775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.AlarmManager; 3875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.IAlarmManager; 3975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.PendingIntent; 4075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.BroadcastReceiver; 4139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport android.content.ContentResolver; 4275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Context; 4375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Intent; 4475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.IntentFilter; 4561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.content.pm.ApplicationInfo; 46d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.IConnectivityManager; 4775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService; 48d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkInfo; 49d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState; 5075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStats; 5175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStatsHistory; 523f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport android.os.Environment; 5375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.Handler; 5475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.HandlerThread; 5575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.INetworkManagementService; 5675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.RemoteException; 5775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.SystemClock; 5861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.provider.Settings; 5975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.telephony.TelephonyManager; 6075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.NtpTrustedTime; 6175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.Slog; 6261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.util.SparseArray; 6375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.TrustedTime; 6475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 653f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport com.android.internal.os.AtomicFile; 66d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport com.google.android.collect.Lists; 6775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport com.google.android.collect.Maps; 6875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 693f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.DataInputStream; 703f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.DataOutputStream; 713f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.File; 7275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.FileDescriptor; 733f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.FileInputStream; 743f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.FileNotFoundException; 753f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.FileOutputStream; 763f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.IOException; 7775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.PrintWriter; 783f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.net.ProtocolException; 79d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport java.util.ArrayList; 8075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.HashMap; 8161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport java.util.HashSet; 8275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 833f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport libcore.io.IoUtils; 843f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 8575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/** 8675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collect and persist detailed network statistics, and provide this data to 8775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * other system services. 8875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 8975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeypublic class NetworkStatsService extends INetworkStatsService.Stub { 9021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey private static final String TAG = "NetworkStats"; 9175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private static final boolean LOGD = true; 9239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private static final boolean LOGV = false; 9375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 943f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey /** File header magic number: "ANET" */ 953f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey private static final int FILE_MAGIC = 0x414E4554; 963f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey private static final int VERSION_CURRENT = 1; 973f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 9875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Context mContext; 9975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final INetworkManagementService mNetworkManager; 10075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final IAlarmManager mAlarmManager; 10175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final TrustedTime mTime; 10239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private final NetworkStatsSettings mSettings; 10375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 104d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private IConnectivityManager mConnManager; 105d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 1063f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // @VisibleForTesting 1073f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey public static final String ACTION_NETWORK_STATS_POLL = 10875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey "com.android.server.action.NETWORK_STATS_POLL"; 10975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 11075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private PendingIntent mPollIntent; 11175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 11275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // TODO: listen for kernel push events through netd instead of polling 11375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 11475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private static final long KB_IN_BYTES = 1024; 11561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey private static final long MB_IN_BYTES = 1024 * KB_IN_BYTES; 11661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey private static final long GB_IN_BYTES = 1024 * MB_IN_BYTES; 11775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 11839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** 11939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Settings that can be changed externally. 12039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey */ 12139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public interface NetworkStatsSettings { 12239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPollInterval(); 12339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPersistThreshold(); 12439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkBucketDuration(); 12539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkMaxHistory(); 12639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidBucketDuration(); 12739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidMaxHistory(); 12839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getTimeCacheMaxAge(); 12939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 13075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 13175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Object mStatsLock = new Object(); 13275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 13375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** Set of active ifaces during this boot. */ 134d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private HashMap<String, InterfaceIdentity> mActiveIface = Maps.newHashMap(); 13561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 13675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** Set of historical stats for known ifaces. */ 13739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private HashMap<InterfaceIdentity, NetworkStatsHistory> mNetworkStats = Maps.newHashMap(); 13861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** Set of historical stats for known UIDs. */ 13939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private SparseArray<NetworkStatsHistory> mUidStats = new SparseArray<NetworkStatsHistory>(); 14039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 14139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** Flag if {@link #mUidStats} have been loaded from disk. */ 14239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private boolean mUidStatsLoaded = false; 14375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 14439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private NetworkStats mLastNetworkPoll; 14539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private NetworkStats mLastNetworkPersist; 14661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 14739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private NetworkStats mLastUidPoll; 14875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 14975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final HandlerThread mHandlerThread; 15075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private final Handler mHandler; 15175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 15239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private final AtomicFile mNetworkFile; 15339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private final AtomicFile mUidFile; 1543f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 15575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // TODO: collect detailed uid stats, storing tag-granularity data until next 15675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // dropbox, and uid summary for a specific bucket count. 15775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 15875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // TODO: periodically compile statistics and send to dropbox. 15975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 16075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsService( 16175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) { 16275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // TODO: move to using cached NtpTrustedTime 16339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey this(context, networkManager, alarmManager, new NtpTrustedTime(), getSystemDir(), 16439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey new DefaultNetworkStatsSettings(context)); 1653f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 1663f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 1673f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey private static File getSystemDir() { 1683f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey return new File(Environment.getDataDirectory(), "system"); 16975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 17075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 17175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public NetworkStatsService(Context context, INetworkManagementService networkManager, 17239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey IAlarmManager alarmManager, TrustedTime time, File systemDir, 17339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey NetworkStatsSettings settings) { 17475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext = checkNotNull(context, "missing Context"); 17575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService"); 17675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager"); 17775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mTime = checkNotNull(time, "missing TrustedTime"); 17839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mSettings = checkNotNull(settings, "missing NetworkStatsSettings"); 17975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 18075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mHandlerThread = new HandlerThread(TAG); 18175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mHandlerThread.start(); 18275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mHandler = new Handler(mHandlerThread.getLooper()); 1833f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 18439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkFile = new AtomicFile(new File(systemDir, "netstats.bin")); 18539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidFile = new AtomicFile(new File(systemDir, "netstats_uid.bin")); 18675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 18775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 18821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public void bindConnectivityManager(IConnectivityManager connManager) { 18921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mConnManager = checkNotNull(connManager, "missing IConnectivityManager"); 19021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 19121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 19275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void systemReady() { 1933f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey synchronized (mStatsLock) { 19439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // read historical network stats from disk, since policy service 19539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // might need them right away. we delay loading detailed UID stats 19639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // until actually needed. 19739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey readNetworkStatsLocked(); 1983f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 19975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 20021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // watch for network interfaces to be claimed 201d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final IntentFilter ifaceFilter = new IntentFilter(); 202d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey ifaceFilter.addAction(CONNECTIVITY_ACTION); 203d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey mContext.registerReceiver(mIfaceReceiver, ifaceFilter, CONNECTIVITY_INTERNAL, mHandler); 20475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 20575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // listen for periodic polling events 20621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // TODO: switch to stronger internal permission 20775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL); 20821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler); 20975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 21075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // persist stats during clean shutdown 21175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final IntentFilter shutdownFilter = new IntentFilter(Intent.ACTION_SHUTDOWN); 21275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.registerReceiver(mShutdownReceiver, shutdownFilter, SHUTDOWN, null); 21375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 21475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey try { 21575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey registerPollAlarmLocked(); 21675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } catch (RemoteException e) { 21775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey Slog.w(TAG, "unable to register poll alarm"); 21875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 21975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 22075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 2213f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey private void shutdownLocked() { 2223f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey mContext.unregisterReceiver(mIfaceReceiver); 2233f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey mContext.unregisterReceiver(mPollReceiver); 2243f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey mContext.unregisterReceiver(mShutdownReceiver); 2253f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 22639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey writeNetworkStatsLocked(); 22739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey writeUidStatsLocked(); 22839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkStats.clear(); 22939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.clear(); 23039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStatsLoaded = false; 2313f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 2323f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 23375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 23475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and 23539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}. 23675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 23775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private void registerPollAlarmLocked() throws RemoteException { 23875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (mPollIntent != null) { 23975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mAlarmManager.remove(mPollIntent); 24075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 24175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 24275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mPollIntent = PendingIntent.getBroadcast( 24375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0); 24475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 24575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long currentRealtime = SystemClock.elapsedRealtime(); 24639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, 24739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mSettings.getPollInterval(), mPollIntent); 24875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 24975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 25075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 251d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey public NetworkStatsHistory getHistoryForNetwork(int networkTemplate) { 25221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 253d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 254d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey synchronized (mStatsLock) { 255d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // combine all interfaces that match template 256d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final String subscriberId = getActiveSubscriberId(); 25761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final NetworkStatsHistory combined = new NetworkStatsHistory( 25839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mSettings.getNetworkBucketDuration()); 25939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey for (InterfaceIdentity ident : mNetworkStats.keySet()) { 26039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = mNetworkStats.get(ident); 261d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (ident.matchesTemplate(networkTemplate, subscriberId)) { 26219862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey combined.recordEntireHistory(history); 263d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 264d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 265d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey return combined; 266d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 26775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 26875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 26975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 270d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey public NetworkStatsHistory getHistoryForUid(int uid, int networkTemplate) { 27121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 272d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 27339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey synchronized (mStatsLock) { 27439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // TODO: combine based on template, if we store that granularity 27539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey ensureUidStatsLoadedLocked(); 27639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return mUidStats.get(uid); 27739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 27875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 27975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 280d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey @Override 28121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey public NetworkStats getSummaryForNetwork( 28221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey long start, long end, int networkTemplate, String subscriberId) { 28321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 28421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 28521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey synchronized (mStatsLock) { 28621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey long rx = 0; 28721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey long tx = 0; 28821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey long[] networkTotal = new long[2]; 28921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 29021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey // combine total from all interfaces that match template 29139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey for (InterfaceIdentity ident : mNetworkStats.keySet()) { 29239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = mNetworkStats.get(ident); 29321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey if (ident.matchesTemplate(networkTemplate, subscriberId)) { 29421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey networkTotal = history.getTotalData(start, end, networkTotal); 29521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey rx += networkTotal[0]; 29621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey tx += networkTotal[1]; 29721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 29821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 29921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 30021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey final NetworkStats.Builder stats = new NetworkStats.Builder(end - start, 1); 30121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey stats.addEntry(IFACE_ALL, UID_ALL, tx, tx); 30221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey return stats.build(); 30321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 30421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey } 30521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey 30621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey @Override 3073f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey public NetworkStats getSummaryForAllUid(long start, long end, int networkTemplate) { 30821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG); 309d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 31019862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey // TODO: apply networktemplate once granular uid stats are stored. 31119862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 31219862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey synchronized (mStatsLock) { 31339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey ensureUidStatsLoadedLocked(); 31439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 31539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int size = mUidStats.size(); 31619862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey final NetworkStats.Builder stats = new NetworkStats.Builder(end - start, size); 31719862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey 31821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey long[] total = new long[2]; 31919862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey for (int i = 0; i < size; i++) { 32039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int uid = mUidStats.keyAt(i); 32139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = mUidStats.valueAt(i); 32221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey total = history.getTotalData(start, end, total); 32319862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey stats.addEntry(IFACE_ALL, uid, total[0], total[1]); 32419862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 32519862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey return stats.build(); 32619862bf5d058b6ab0c2979e7a5e0297dae6b170bJeff Sharkey } 327d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 328d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 32975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 330d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * Receiver that watches for {@link IConnectivityManager} to claim network 33175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()} 33275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * with mobile interfaces. 33375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 334d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private BroadcastReceiver mIfaceReceiver = new BroadcastReceiver() { 33575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 33675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void onReceive(Context context, Intent intent) { 337d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // on background handler thread, and verified CONNECTIVITY_INTERNAL 338d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // permission above. 339d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey synchronized (mStatsLock) { 340d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey updateIfacesLocked(); 34175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 34275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 34375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey }; 34475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 34575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private BroadcastReceiver mPollReceiver = new BroadcastReceiver() { 34675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 34775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void onReceive(Context context, Intent intent) { 348d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // on background handler thread, and verified UPDATE_DEVICE_STATS 349d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // permission above. 35075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey synchronized (mStatsLock) { 35175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // TODO: acquire wakelock while performing poll 35239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey performPollLocked(true); 35375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 35475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 35575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey }; 35675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 35775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() { 35875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 35975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey public void onReceive(Context context, Intent intent) { 360d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // verified SHUTDOWN permission above. 36175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey synchronized (mStatsLock) { 3623f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey shutdownLocked(); 36375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 36475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 36575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey }; 36675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 367d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey /** 368d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * Inspect all current {@link NetworkState} to derive mapping from {@code 369d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo} 370d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * are active on a single {@code iface}, they are combined under a single 371d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey * {@link InterfaceIdentity}. 372d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey */ 373d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private void updateIfacesLocked() { 37439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); 375d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 376d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // take one last stats snapshot before updating iface mapping. this 377d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // isn't perfect, since the kernel may already be counting traffic from 378d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // the updated network. 37939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey performPollLocked(false); 380d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 381d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final NetworkState[] states; 382d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey try { 383d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey states = mConnManager.getAllNetworkState(); 384d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } catch (RemoteException e) { 385d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey Slog.w(TAG, "problem reading network state"); 386d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey return; 387d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 388d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 389d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // rebuild active interfaces based on connected networks 390d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey mActiveIface.clear(); 391d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 392d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey for (NetworkState state : states) { 393d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (state.networkInfo.isConnected()) { 394d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // collect networks under their parent interfaces 395d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final String iface = state.linkProperties.getInterfaceName(); 396d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final InterfaceIdentity ident = findOrCreateInterfaceLocked(iface); 397d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state)); 398d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 399d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 400d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 401d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 40239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** 40339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Periodic poll operation, reading current statistics and recording into 40439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * {@link NetworkStatsHistory}. 40539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * 40639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * @param detailedPoll Indicate if detailed UID stats should be collected 40739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * during this poll operation. 40839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey */ 40939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void performPollLocked(boolean detailedPoll) { 41039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "performPollLocked()"); 41175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 41275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // try refreshing time source when stale 41339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) { 41475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mTime.forceRefresh(); 41575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 41675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 41775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey // TODO: consider marking "untrusted" times in historical stats 41875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis() 41975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey : System.currentTimeMillis(); 42075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 42139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStats networkStats; 42239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStats uidStats; 42375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey try { 42439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey networkStats = mNetworkManager.getNetworkStatsSummary(); 42539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey uidStats = detailedPoll ? mNetworkManager.getNetworkStatsDetail() : null; 42675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } catch (RemoteException e) { 42775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey Slog.w(TAG, "problem reading network stats"); 42875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return; 42975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 43075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 43139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey performNetworkPollLocked(networkStats, currentTime); 43239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (detailedPoll) { 43339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey performUidPollLocked(uidStats, currentTime); 43439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 43561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 43661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey // decide if enough has changed to trigger persist 43739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStats persistDelta = computeStatsDelta(mLastNetworkPersist, networkStats); 43839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final long persistThreshold = mSettings.getPersistThreshold(); 43961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (String iface : persistDelta.getUniqueIfaces()) { 44061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int index = persistDelta.findIndex(iface, UID_ALL); 44161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey if (persistDelta.rx[index] > persistThreshold 44261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey || persistDelta.tx[index] > persistThreshold) { 44339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey writeNetworkStatsLocked(); 44439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey writeUidStatsLocked(); 44539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mLastNetworkPersist = networkStats; 44661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey break; 44761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 44861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 44961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 45061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 45161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 45239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Update {@link #mNetworkStats} historical usage. 45361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 45439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void performNetworkPollLocked(NetworkStats networkStats, long currentTime) { 455d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final ArrayList<String> unknownIface = Lists.newArrayList(); 456d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 45739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStats delta = computeStatsDelta(mLastNetworkPoll, networkStats); 45861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final long timeStart = currentTime - delta.elapsedRealtime; 45939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final long maxHistory = mSettings.getNetworkMaxHistory(); 46061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (String iface : delta.getUniqueIfaces()) { 461d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final InterfaceIdentity ident = mActiveIface.get(iface); 462d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (ident == null) { 463d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey unknownIface.add(iface); 46475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey continue; 46575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 46675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 46761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int index = delta.findIndex(iface, UID_ALL); 46861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final long rx = delta.rx[index]; 46961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final long tx = delta.tx[index]; 47075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 47139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = findOrCreateNetworkLocked(ident); 47275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey history.recordData(timeStart, currentTime, rx, tx); 47361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey history.removeBucketsBefore(currentTime - maxHistory); 47475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 47539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mLastNetworkPoll = networkStats; 47675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 477d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (LOGD && unknownIface.size() > 0) { 478d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey Slog.w(TAG, "unknown interfaces " + unknownIface.toString() + ", ignoring those stats"); 479d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 48061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 481d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 48261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 48339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Update {@link #mUidStats} historical usage. 48461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 48539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void performUidPollLocked(NetworkStats uidStats, long currentTime) { 48639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey ensureUidStatsLoadedLocked(); 48739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 48839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStats delta = computeStatsDelta(mLastUidPoll, uidStats); 48961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final long timeStart = currentTime - delta.elapsedRealtime; 49039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final long maxHistory = mSettings.getUidMaxHistory(); 49161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (int uid : delta.getUniqueUids()) { 49239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // TODO: traverse all ifaces once surfaced in stats 49361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int index = delta.findIndex(IFACE_ALL, uid); 49439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (index != -1) { 49539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final long rx = delta.rx[index]; 49639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final long tx = delta.tx[index]; 49761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 49839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = findOrCreateUidLocked(uid); 49939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey history.recordData(timeStart, currentTime, rx, tx); 50039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey history.removeBucketsBefore(currentTime - maxHistory); 50139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 50261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 50339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mLastUidPoll = uidStats; 50461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 50575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 50639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private NetworkStatsHistory findOrCreateNetworkLocked(InterfaceIdentity ident) { 50739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final long bucketDuration = mSettings.getNetworkBucketDuration(); 50839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory existing = mNetworkStats.get(ident); 50939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 51039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // update when no existing, or when bucket duration changed 51139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey NetworkStatsHistory updated = null; 51239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (existing == null) { 51339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated = new NetworkStatsHistory(bucketDuration); 51439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } else if (existing.bucketDuration != bucketDuration) { 51539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated = new NetworkStatsHistory(bucketDuration); 51639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated.recordEntireHistory(existing); 51739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 51839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 51939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (updated != null) { 52039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkStats.put(ident, updated); 52139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return updated; 52239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } else { 52339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return existing; 52475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 52575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 52675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 52739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private NetworkStatsHistory findOrCreateUidLocked(int uid) { 52839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final long bucketDuration = mSettings.getUidBucketDuration(); 52939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory existing = mUidStats.get(uid); 53039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 53139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // update when no existing, or when bucket duration changed 53239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey NetworkStatsHistory updated = null; 53339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (existing == null) { 53439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated = new NetworkStatsHistory(bucketDuration); 53539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } else if (existing.bucketDuration != bucketDuration) { 53639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated = new NetworkStatsHistory(bucketDuration); 53739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey updated.recordEntireHistory(existing); 53839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 53939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 54039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (updated != null) { 54139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.put(uid, updated); 54239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return updated; 54339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } else { 54439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return existing; 54575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 54675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 54775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 548d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private InterfaceIdentity findOrCreateInterfaceLocked(String iface) { 549d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey InterfaceIdentity ident = mActiveIface.get(iface); 550d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey if (ident == null) { 551d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey ident = new InterfaceIdentity(); 552d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey mActiveIface.put(iface, ident); 553d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 554d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey return ident; 555d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey } 556d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey 55739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void readNetworkStatsLocked() { 55839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "readNetworkStatsLocked()"); 5593f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 5603f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // clear any existing stats and read from disk 56139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkStats.clear(); 5623f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 5633f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey FileInputStream fis = null; 5643f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey try { 56539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey fis = mNetworkFile.openRead(); 5663f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final DataInputStream in = new DataInputStream(fis); 5673f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 5683f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // verify file magic header intact 5693f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final int magic = in.readInt(); 5703f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey if (magic != FILE_MAGIC) { 5713f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey throw new ProtocolException("unexpected magic: " + magic); 5723f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 5733f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 5743f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final int version = in.readInt(); 5753f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey switch (version) { 5763f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey case VERSION_CURRENT: { 5773f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // file format is pairs of interfaces and stats: 57839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // network := size *(InterfaceIdentity NetworkStatsHistory) 5793f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 5803f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final int size = in.readInt(); 5813f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey for (int i = 0; i < size; i++) { 5823f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final InterfaceIdentity ident = new InterfaceIdentity(in); 5833f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final NetworkStatsHistory history = new NetworkStatsHistory(in); 58439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 58539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkStats.put(ident, history); 5863f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 5873f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey break; 5883f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 5893f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey default: { 5903f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey throw new ProtocolException("unexpected version: " + version); 5913f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 5923f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 5933f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } catch (FileNotFoundException e) { 5943f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey // missing stats is okay, probably first boot 5953f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } catch (IOException e) { 5963f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey Slog.e(TAG, "problem reading network stats", e); 5973f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } finally { 5983f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey IoUtils.closeQuietly(fis); 5993f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 60075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 60175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 60239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void ensureUidStatsLoadedLocked() { 60339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (!mUidStatsLoaded) { 60439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey readUidStatsLocked(); 60539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStatsLoaded = true; 60639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 60739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 60839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 60939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void readUidStatsLocked() { 61039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "readUidStatsLocked()"); 61139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 61239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // clear any existing stats and read from disk 61339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.clear(); 61439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 61539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey FileInputStream fis = null; 61639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey try { 61739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey fis = mUidFile.openRead(); 61839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final DataInputStream in = new DataInputStream(fis); 61939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 62039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // verify file magic header intact 62139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int magic = in.readInt(); 62239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (magic != FILE_MAGIC) { 62339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey throw new ProtocolException("unexpected magic: " + magic); 62439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 62539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 62639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int version = in.readInt(); 62739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey switch (version) { 62839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey case VERSION_CURRENT: { 62939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // file format is pairs of UIDs and stats: 63039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // uid := size *(UID NetworkStatsHistory) 63139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 63239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int size = in.readInt(); 63339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey for (int i = 0; i < size; i++) { 63439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int uid = in.readInt(); 63539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = new NetworkStatsHistory(in); 63639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 63739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.put(uid, history); 63839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 63939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey break; 64039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 64139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey default: { 64239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey throw new ProtocolException("unexpected version: " + version); 64339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 64439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 64539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } catch (FileNotFoundException e) { 64639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // missing stats is okay, probably first boot 64739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } catch (IOException e) { 64839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey Slog.e(TAG, "problem reading uid stats", e); 64939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } finally { 65039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey IoUtils.closeQuietly(fis); 65139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 65239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 65339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 65439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void writeNetworkStatsLocked() { 65539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "writeNetworkStatsLocked()"); 6563f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 657d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey // TODO: consider duplicating stats and releasing lock while writing 6583f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 6593f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey FileOutputStream fos = null; 6603f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey try { 66139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey fos = mNetworkFile.startWrite(); 6623f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey final DataOutputStream out = new DataOutputStream(fos); 6633f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 6643f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey out.writeInt(FILE_MAGIC); 6653f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey out.writeInt(VERSION_CURRENT); 6663f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 66739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey out.writeInt(mNetworkStats.size()); 66839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey for (InterfaceIdentity ident : mNetworkStats.keySet()) { 66939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = mNetworkStats.get(ident); 6703f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey ident.writeToStream(out); 6713f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey history.writeToStream(out); 6723f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 6733f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 67439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkFile.finishWrite(fos); 67539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } catch (IOException e) { 67639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (fos != null) { 67739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkFile.failWrite(fos); 67839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 67939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 68039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 68139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 68239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private void writeUidStatsLocked() { 68339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey if (LOGV) Slog.v(TAG, "writeUidStatsLocked()"); 68439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 68539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // TODO: consider duplicating stats and releasing lock while writing 68639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 68739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey FileOutputStream fos = null; 68839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey try { 68939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey fos = mUidFile.startWrite(); 69039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final DataOutputStream out = new DataOutputStream(fos); 69139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 69239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey out.writeInt(FILE_MAGIC); 69339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey out.writeInt(VERSION_CURRENT); 69439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 69539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int size = mUidStats.size(); 69639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 69739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey out.writeInt(size); 69839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey for (int i = 0; i < size; i++) { 69939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int uid = mUidStats.keyAt(i); 70039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory history = mUidStats.valueAt(i); 70139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey out.writeInt(uid); 70239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey history.writeToStream(out); 70339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 70439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 70539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidFile.finishWrite(fos); 7063f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } catch (IOException e) { 7073f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey if (fos != null) { 70839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidFile.failWrite(fos); 7093f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 7103f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 71175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 71275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 71375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey @Override 71475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 71575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey mContext.enforceCallingOrSelfPermission(DUMP, TAG); 71675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 71761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final HashSet<String> argSet = new HashSet<String>(); 71861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (String arg : args) { 71961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey argSet.add(arg); 72061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 72161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 72261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey synchronized (mStatsLock) { 72361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey // TODO: remove this testing code, since it corrupts stats 72461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey if (argSet.contains("generate")) { 72561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey generateRandomLocked(); 72661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.println("Generated stub stats"); 72761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey return; 72861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 72961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 7303f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey if (argSet.contains("poll")) { 73139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey performPollLocked(true); 7323f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey pw.println("Forced poll"); 7333f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey return; 7343f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey } 7353f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey 73661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.println("Active interfaces:"); 73761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (String iface : mActiveIface.keySet()) { 73861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final InterfaceIdentity ident = mActiveIface.get(iface); 73961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" iface="); pw.print(iface); 74061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" ident="); pw.println(ident.toString()); 74161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 74261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 74361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.println("Known historical stats:"); 74439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey for (InterfaceIdentity ident : mNetworkStats.keySet()) { 74539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory stats = mNetworkStats.get(ident); 74661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" ident="); pw.println(ident.toString()); 74761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey stats.dump(" ", pw); 74861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 74961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 75061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey if (argSet.contains("detail")) { 75139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // since explicitly requested with argument, we're okay to load 75239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // from disk if not already in memory. 75339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey ensureUidStatsLoadedLocked(); 75439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey pw.println("Known UID stats:"); 75539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey for (int i = 0; i < mUidStats.size(); i++) { 75639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final int uid = mUidStats.keyAt(i); 75739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory stats = mUidStats.valueAt(i); 75861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey pw.print(" UID="); pw.println(uid); 75961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey stats.dump(" ", pw); 76061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 76161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 76275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 76361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 76475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 76561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey /** 76661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey * @deprecated only for temporary testing 76761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey */ 76861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey @Deprecated 76961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey private void generateRandomLocked() { 77061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey long end = System.currentTimeMillis(); 77139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey long start = end - mSettings.getNetworkMaxHistory(); 77261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey long rx = 3 * GB_IN_BYTES; 77361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey long tx = 2 * GB_IN_BYTES; 77461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 77539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mNetworkStats.clear(); 77661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (InterfaceIdentity ident : mActiveIface.values()) { 77739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory stats = findOrCreateNetworkLocked(ident); 77861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey stats.generateRandom(start, end, rx, tx); 77961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 78061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 78161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey end = System.currentTimeMillis(); 78239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey start = end - mSettings.getUidMaxHistory(); 78361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey rx = 500 * MB_IN_BYTES; 78461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey tx = 100 * MB_IN_BYTES; 78561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 78639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mUidStats.clear(); 78761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey for (ApplicationInfo info : mContext.getPackageManager().getInstalledApplications(0)) { 78861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey final int uid = info.uid; 78939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey final NetworkStatsHistory stats = findOrCreateUidLocked(uid); 79061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey stats.generateRandom(start, end, rx, tx); 79161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 79261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey } 79361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey 79475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey /** 79575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Return the delta between two {@link NetworkStats} snapshots, where {@code 79675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * before} can be {@code null}. 79775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */ 79875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey private static NetworkStats computeStatsDelta(NetworkStats before, NetworkStats current) { 79975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey if (before != null) { 8003f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey return current.subtractClamped(before); 80175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } else { 80275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey return current; 80375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 80475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 80575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 806d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey private String getActiveSubscriberId() { 807d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey final TelephonyManager telephony = (TelephonyManager) mContext.getSystemService( 808d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey Context.TELEPHONY_SERVICE); 809d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey return telephony.getSubscriberId(); 81075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey } 81175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey 81239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey /** 81339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey * Default external settings that read from {@link Settings.Secure}. 81439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey */ 81539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private static class DefaultNetworkStatsSettings implements NetworkStatsSettings { 81639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private final ContentResolver mResolver; 81739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 81839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public DefaultNetworkStatsSettings(Context context) { 81939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey mResolver = checkNotNull(context.getContentResolver()); 82039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey // TODO: adjust these timings for production builds 82139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 82239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 82339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey private long getSecureLong(String name, long def) { 82439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return Settings.Secure.getLong(mResolver, name, def); 82539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 82639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 82739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPollInterval() { 82839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_POLL_INTERVAL, 15 * MINUTE_IN_MILLIS); 82939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 83039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getPersistThreshold() { 83139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_PERSIST_THRESHOLD, 16 * KB_IN_BYTES); 83239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 83339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkBucketDuration() { 83439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_NETWORK_BUCKET_DURATION, HOUR_IN_MILLIS); 83539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 83639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getNetworkMaxHistory() { 83739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_NETWORK_MAX_HISTORY, 90 * DAY_IN_MILLIS); 83839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 83939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidBucketDuration() { 84039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS); 84139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 84239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getUidMaxHistory() { 84339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return getSecureLong(NETSTATS_UID_MAX_HISTORY, 90 * DAY_IN_MILLIS); 84439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 84539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey public long getTimeCacheMaxAge() { 84639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey return DAY_IN_MILLIS; 84739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 84839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey } 84939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey 85075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey} 851