NetworkStatsService.java revision 49c1d1764bce02cf12a68e9312f3aa9dfa2e25ce
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;
29234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static android.net.ConnectivityManager.isNetworkTypeMobile;
30d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkeyimport static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
3161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL;
32b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_ALL;
33b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_DEFAULT;
34b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_FOREGROUND;
351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkStats.TAG_NONE;
3675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.net.NetworkStats.UID_ALL;
37234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateMobileWildcard;
388fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateWifiWildcard;
39241dde2306202e7655fdf41d5381f2874e47e108Jeff Sharkeyimport static android.net.TrafficStats.MB_IN_BYTES;
4063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION;
4163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE;
4263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_PERSIST_BYTES;
4363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_ROTATE_AGE;
4463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_GLOBAL_ALERT_BYTES;
4561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL;
4663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_SAMPLE_ENABLED;
4763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_TIME_CACHE_MAX_AGE;
4839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
4963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_DELETE_AGE;
5063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_PERSIST_BYTES;
5163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_ROTATE_AGE;
52367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
53367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_NONE;
5461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS;
5561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.HOUR_IN_MILLIS;
5661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.MINUTE_IN_MILLIS;
57367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.text.format.DateUtils.SECOND_IN_MILLIS;
58234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static com.android.internal.util.ArrayUtils.appendElement;
59234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static com.android.internal.util.ArrayUtils.contains;
60d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull;
618e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
62b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
63b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
6475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
6575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.AlarmManager;
6675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.IAlarmManager;
6775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.PendingIntent;
6875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.BroadcastReceiver;
6939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport android.content.ContentResolver;
7075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Context;
7175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Intent;
7275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.IntentFilter;
73d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.IConnectivityManager;
748e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport android.net.INetworkManagementEventObserver;
7575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService;
76b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkeyimport android.net.INetworkStatsSession;
7763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport android.net.LinkProperties;
781b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkIdentity;
79d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkInfo;
80d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState;
8175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStats;
825a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkeyimport android.net.NetworkStats.NonMonotonicObserver;
8375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStatsHistory;
841b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate;
8563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport android.net.TrafficStats;
86a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport android.os.Binder;
87163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport android.os.DropBoxManager;
883f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport android.os.Environment;
8975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.Handler;
9075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.HandlerThread;
9175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.INetworkManagementService;
92b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.os.Message;
936248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkeyimport android.os.PowerManager;
9475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.RemoteException;
9575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.SystemClock;
9661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.provider.Settings;
97367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport android.telephony.PhoneStateListener;
9875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.telephony.TelephonyManager;
9907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport android.util.EventLog;
100b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkeyimport android.util.Log;
10175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.NtpTrustedTime;
10275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.Slog;
103b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.util.SparseIntArray;
10475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.TrustedTime;
10575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
10663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport com.android.internal.util.FileRotator;
10763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
10807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport com.android.server.EventLogTags;
109cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkeyimport com.android.server.connectivity.Tethering;
11075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport com.google.android.collect.Maps;
11175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1123f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.File;
11375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.FileDescriptor;
1143f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.IOException;
11575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.PrintWriter;
11675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.HashMap;
11761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport java.util.HashSet;
1183f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
11975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/**
12075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collect and persist detailed network statistics, and provide this data to
12175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * other system services.
12275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */
12375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeypublic class NetworkStatsService extends INetworkStatsService.Stub {
12421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static final String TAG = "NetworkStats";
125706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey    private static final boolean LOGV = false;
126b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
127367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private static final int MSG_PERFORM_POLL = 1;
128367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private static final int MSG_UPDATE_IFACES = 2;
12925ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey    private static final int MSG_REGISTER_GLOBAL_ALERT = 3;
130b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
131b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    /** Flags to control detail level of poll event. */
132905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey    private static final int FLAG_PERSIST_NETWORK = 0x1;
133905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey    private static final int FLAG_PERSIST_UID = 0x2;
134b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
1351f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey    private static final int FLAG_PERSIST_FORCE = 0x100;
1363f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
137163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    private static final String TAG_NETSTATS_ERROR = "netstats_error";
138163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
13975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Context mContext;
14075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final INetworkManagementService mNetworkManager;
14175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final IAlarmManager mAlarmManager;
14275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final TrustedTime mTime;
143367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private final TelephonyManager mTeleManager;
14439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    private final NetworkStatsSettings mSettings;
14575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
14663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final File mSystemDir;
14763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final File mBaseDir;
14863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1496248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey    private final PowerManager.WakeLock mWakeLock;
1506248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey
151d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    private IConnectivityManager mConnManager;
152d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
1533f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    // @VisibleForTesting
1543f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    public static final String ACTION_NETWORK_STATS_POLL =
15575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            "com.android.server.action.NETWORK_STATS_POLL";
156497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey    public static final String ACTION_NETWORK_STATS_UPDATED =
157497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey            "com.android.server.action.NETWORK_STATS_UPDATED";
15875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
15975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private PendingIntent mPollIntent;
16075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
16163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_DEV = "dev";
16263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_UID = "uid";
16363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_UID_TAG = "uid_tag";
16463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
16539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    /**
16639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * Settings that can be changed externally.
16739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
16839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    public interface NetworkStatsSettings {
16939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getPollInterval();
17039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getTimeCacheMaxAge();
17163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public long getGlobalAlertBytes();
17263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public boolean getSampleEnabled();
17363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
17463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public static class Config {
17563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long bucketDuration;
17663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long persistBytes;
17763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long rotateAgeMillis;
17863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long deleteAgeMillis;
17963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
18063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public Config(long bucketDuration, long persistBytes, long rotateAgeMillis,
18163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    long deleteAgeMillis) {
18263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.bucketDuration = bucketDuration;
18363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.persistBytes = persistBytes;
18463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.rotateAgeMillis = rotateAgeMillis;
18563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.deleteAgeMillis = deleteAgeMillis;
18663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
18763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        }
18863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
18963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getDevConfig();
19063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidConfig();
19163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidTagConfig();
19239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    }
19375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
19475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Object mStatsLock = new Object();
19575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /** Set of currently active ifaces. */
1971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
19863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    /** Current default active iface. */
19963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private String mActiveIface;
200234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    /** Set of any ifaces associated with mobile networks since boot. */
201234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private String[] mMobileIfaces = new String[0];
20263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
20363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
20463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            new DropBoxNonMonotonicObserver();
20563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
20663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mDevRecorder;
20763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mUidRecorder;
20863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mUidTagRecorder;
20963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
21063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    /** Cached {@link #mDevRecorder} stats. */
21163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsCollection mDevStatsCached;
21275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
213b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    /** Current counter sets for each UID. */
214b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
215b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
216a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    /** Data layer operation counters for splicing into other structures. */
21763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats mUidOperations = new NetworkStats(0L, 10);
218a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
21975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final HandlerThread mHandlerThread;
22075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Handler mHandler;
22175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
2226341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey    private boolean mSystemReady;
2236341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
22475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public NetworkStatsService(
22575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
226104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey        this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context),
22763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                getDefaultSystemDir(), new DefaultNetworkStatsSettings(context));
2283f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    }
2293f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
23063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static File getDefaultSystemDir() {
2313f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        return new File(Environment.getDataDirectory(), "system");
23275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
23375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
23475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public NetworkStatsService(Context context, INetworkManagementService networkManager,
23539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            IAlarmManager alarmManager, TrustedTime time, File systemDir,
23639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            NetworkStatsSettings settings) {
23775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mContext = checkNotNull(context, "missing Context");
23875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
23975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
24075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mTime = checkNotNull(time, "missing TrustedTime");
241367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
24239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
24375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
2446248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey        final PowerManager powerManager = (PowerManager) context.getSystemService(
2456248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                Context.POWER_SERVICE);
2466248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
2476248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey
24875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mHandlerThread = new HandlerThread(TAG);
24975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mHandlerThread.start();
250b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
2513f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
25263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mSystemDir = checkNotNull(systemDir);
25363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mBaseDir = new File(systemDir, "netstats");
25463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mBaseDir.mkdirs();
25575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
25675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
25721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void bindConnectivityManager(IConnectivityManager connManager) {
25821c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
25921c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
26021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
26175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public void systemReady() {
2626341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        mSystemReady = true;
2636341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
264418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        if (!isBandwidthControlEnabled()) {
265418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
266418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return;
267418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        }
268418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey
26963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // create data recorders along with historical rotators
27063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
27163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
27263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
27363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
2743f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        synchronized (mStatsLock) {
27563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // upgrade any legacy stats, migrating them to rotated files
27663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            maybeUpgradeLegacyStatsLocked();
27763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
27839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            // read historical network stats from disk, since policy service
27963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // might need them right away.
28063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevStatsCached = mDevRecorder.getOrLoadCompleteLocked();
28175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
28263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // bootstrap initial stats to prevent double-counting later
28363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            bootstrapStatsLocked();
28463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        }
2853359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey
28621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // watch for network interfaces to be claimed
287961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE);
288b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
28975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
290cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        // watch for tethering changes
291cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
292cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        mContext.registerReceiver(mTetherReceiver, tetherFilter, CONNECTIVITY_INTERNAL, mHandler);
293cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
29475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // listen for periodic polling events
29575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
29621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
29775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
298b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        // listen for uid removal to clean stats
299b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
300b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
301b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
30275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // persist stats during clean shutdown
303b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
304b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
30575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
30675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        try {
3078e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mNetworkManager.registerObserver(mAlertObserver);
30875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        } catch (RemoteException e) {
309b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
31075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
311b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
312367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        // watch for networkType changes that aren't broadcast through
313367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        // CONNECTIVITY_ACTION_IMMEDIATE above.
314d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (!COMBINE_SUBTYPE_ENABLED) {
315d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE);
316d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
317367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
3188e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        registerPollAlarmLocked();
3198e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        registerGlobalAlert();
32063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    }
3218e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
32263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder buildRecorder(
32363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
32463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        return new NetworkStatsRecorder(
32563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                new FileRotator(mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
32663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mNonMonotonicObserver, prefix, config.bucketDuration, config.persistBytes,
32763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                includeTags);
32875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
32975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
3303f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    private void shutdownLocked() {
331b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.unregisterReceiver(mConnReceiver);
332367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        mContext.unregisterReceiver(mTetherReceiver);
3333f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        mContext.unregisterReceiver(mPollReceiver);
334b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.unregisterReceiver(mRemovedReceiver);
3353f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        mContext.unregisterReceiver(mShutdownReceiver);
3363f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
337d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (!COMBINE_SUBTYPE_ENABLED) {
338d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            mTeleManager.listen(mPhoneListener, LISTEN_NONE);
339d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
340367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
34163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
34263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                : System.currentTimeMillis();
34363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
34463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // persist any pending stats
34563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder.forcePersistLocked(currentTime);
34663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder.forcePersistLocked(currentTime);
34763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder.forcePersistLocked(currentTime);
34863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
34963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder = null;
35063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder = null;
35163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder = null;
35263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
35363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevStatsCached = null;
3546341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
3556341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        mSystemReady = false;
35663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    }
35763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
35863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void maybeUpgradeLegacyStatsLocked() {
35963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        File file;
36063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        try {
36163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats.bin");
36263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
36363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mDevRecorder.importLegacyNetworkLocked(file);
36463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
36563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
36663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
36763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats_xt.bin");
36863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
36963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
37063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
37163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
37263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats_uid.bin");
37363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
37463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.importLegacyUidLocked(file);
37563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.importLegacyUidLocked(file);
37663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
37763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
37863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        } catch (IOException e) {
37963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            Log.wtf(TAG, "problem during legacy upgrade", e);
380af8339374fbf1e2f57b0be918c7fc772f4250f13Jeff Sharkey        }
3813f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    }
3823f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
38375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
38475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
38539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
38675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
3878e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private void registerPollAlarmLocked() {
3888e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
3898e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            if (mPollIntent != null) {
3908e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                mAlarmManager.remove(mPollIntent);
3918e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
39275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
3938e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mPollIntent = PendingIntent.getBroadcast(
3948e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                    mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
39575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
3968e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            final long currentRealtime = SystemClock.elapsedRealtime();
3978e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
3988e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                    mSettings.getPollInterval(), mPollIntent);
3998e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
400b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
4018e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
4028e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
4038e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
4048e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
4058e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Register for a global alert that is delivered through
4068e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * {@link INetworkManagementEventObserver} once a threshold amount of data
4078e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * has been transferred.
4088e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
4098e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private void registerGlobalAlert() {
4108e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
41163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final long alertBytes = mSettings.getGlobalAlertBytes();
4128e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mNetworkManager.setGlobalAlert(alertBytes);
4138e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (IllegalStateException e) {
4148e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.w(TAG, "problem registering for global alert: " + e);
4158e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
416b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
4178e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
41875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
41975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
42075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    @Override
421b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey    public INetworkStatsSession openSession() {
422b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
4234190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
424d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
425b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        // return an IBinder which holds strong references to any loaded stats
426b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        // for its lifetime; when caller closes only weak references remain.
42775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
428b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        return new INetworkStatsSession.Stub() {
429b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection mUidComplete;
430b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection mUidTagComplete;
431b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
432b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection getUidComplete() {
433b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (mUidComplete == null) {
434b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
435b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
436b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mUidComplete;
437b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
438b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
439b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection getUidTagComplete() {
440b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (mUidTagComplete == null) {
441b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
442b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
443b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mUidTagComplete;
444b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
445b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
446b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
447b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStats getSummaryForNetwork(
448b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, long start, long end) {
449b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mDevStatsCached.getSummary(template, start, end);
450b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
451b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
452b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
453b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
454b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mDevStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
455b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
456b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
457b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
458b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStats getSummaryForAllUid(
459b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, long start, long end, boolean includeTags) {
460b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                final NetworkStats stats = getUidComplete().getSummary(template, start, end);
461b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (includeTags) {
462b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    final NetworkStats tagStats = getUidTagComplete()
463b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                            .getSummary(template, start, end);
464b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    stats.combineAllValues(tagStats);
465b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
466b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return stats;
467b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
468b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
469b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
470b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStatsHistory getHistoryForUid(
471b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, int uid, int set, int tag, int fields) {
472b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (tag == TAG_NONE) {
473b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    return getUidComplete().getHistory(template, uid, set, tag, fields);
474b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                } else {
475b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    return getUidTagComplete().getHistory(template, uid, set, tag, fields);
476b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
477b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
478b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
479b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
480b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public void close() {
481b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                mUidComplete = null;
482b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                mUidTagComplete = null;
483b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
484b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        };
485684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey    }
486684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
48721c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    @Override
488b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey    public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
489b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
4904190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
491b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        return mDevStatsCached.getSummary(template, start, end).getTotalBytes();
492d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
493d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
494350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    @Override
495a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
496a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        if (Binder.getCallingUid() != uid) {
497a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
498a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
4994190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
500a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
501a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        // TODO: switch to data layer stats once kernel exports
502a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        // for now, read network layer stats and flatten across all ifaces
5034529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        final long token = Binder.clearCallingIdentity();
5044529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        final NetworkStats networkLayer;
5054529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        try {
5064529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey            networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid);
5074529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        } finally {
5084529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey            Binder.restoreCallingIdentity(token);
5094529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        }
5104529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey
51121a547823de52806de48f70b8360353344a5ad88Jeff Sharkey        // splice in operation counts
51221a547823de52806de48f70b8360353344a5ad88Jeff Sharkey        networkLayer.spliceOperationsFrom(mUidOperations);
51321a547823de52806de48f70b8360353344a5ad88Jeff Sharkey
514a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        final NetworkStats dataLayer = new NetworkStats(
515a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey                networkLayer.getElapsedRealtime(), networkLayer.size());
516a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
517a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        NetworkStats.Entry entry = null;
518a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        for (int i = 0; i < networkLayer.size(); i++) {
519a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            entry = networkLayer.getValues(i, entry);
520a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            entry.iface = IFACE_ALL;
521a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            dataLayer.combineValues(entry);
522a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
523a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
524a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        return dataLayer;
525a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    }
526a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
527a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    @Override
528234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public String[] getMobileIfaces() {
529234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return mMobileIfaces;
530234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
531234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
532234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    @Override
533a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    public void incrementOperationCount(int uid, int tag, int operationCount) {
534a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        if (Binder.getCallingUid() != uid) {
535a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
536a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
537a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
538b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        if (operationCount < 0) {
539b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            throw new IllegalArgumentException("operation count can only be incremented");
540b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
541b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        if (tag == TAG_NONE) {
542b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            throw new IllegalArgumentException("operation count must have specific tag");
543b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
544b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
545a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        synchronized (mStatsLock) {
546b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
54763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidOperations.combineValues(
54863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
54963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidOperations.combineValues(
55063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
551b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
552b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    }
553b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
554b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    @Override
555b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    public void setUidForeground(int uid, boolean uidForeground) {
556b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
557b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
558b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        synchronized (mStatsLock) {
559b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
560b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
561b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            if (oldSet != set) {
562b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                mActiveUidCounterSet.put(uid, set);
563b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                setKernelCounterSet(uid, set);
564b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            }
565a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
566a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    }
567a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
568a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    @Override
569350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    public void forceUpdate() {
570350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
5714190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
572e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey
573e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        final long token = Binder.clearCallingIdentity();
574e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        try {
575e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey            performPoll(FLAG_PERSIST_ALL);
576e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        } finally {
577e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey            Binder.restoreCallingIdentity(token);
578e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        }
579350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    }
580350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
58175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
582d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * Receiver that watches for {@link IConnectivityManager} to claim network
58375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
58475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * with mobile interfaces.
58575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
586b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
58775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
58875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
589d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // on background handler thread, and verified CONNECTIVITY_INTERNAL
590d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // permission above.
591367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            updateIfaces();
59275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
59375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
59475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
595cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    /**
596cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey     * Receiver that watches for {@link Tethering} to claim interface pairs.
597cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey     */
598cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
599cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        @Override
600cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        public void onReceive(Context context, Intent intent) {
601cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey            // on background handler thread, and verified CONNECTIVITY_INTERNAL
602cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey            // permission above.
6031f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey            performPoll(FLAG_PERSIST_NETWORK);
604cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        }
605cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    };
606cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
60775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
60875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
60975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
610d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // on background handler thread, and verified UPDATE_DEVICE_STATS
611d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // permission above.
6121f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey            performPoll(FLAG_PERSIST_ALL);
6138e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
6148e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            // verify that we're watching global alert
6158e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            registerGlobalAlert();
61675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
61775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
61875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
619b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
620b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        @Override
621b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        public void onReceive(Context context, Intent intent) {
622b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // on background handler thread, and UID_REMOVED is protected
623b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // broadcast.
624b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            final int uid = intent.getIntExtra(EXTRA_UID, 0);
625b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            synchronized (mStatsLock) {
6266248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                mWakeLock.acquire();
6276248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                try {
6286248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                    removeUidLocked(uid);
6296248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                } finally {
6306248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                    mWakeLock.release();
6316248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                }
632b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            }
633b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        }
634b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    };
635b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
63675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
63775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
63875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
639b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // SHUTDOWN is protected broadcast.
64075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            synchronized (mStatsLock) {
6413f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                shutdownLocked();
64275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            }
64375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
64475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
64575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
646d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    /**
6478e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Observer that watches for {@link INetworkManagementService} alerts.
6488e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
6498e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() {
6508e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        @Override
6518e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        public void limitReached(String limitName, String iface) {
6528e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            // only someone like NMS should be calling us
6538e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
6548e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
6558e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
6568e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // kick off background poll to collect network stats; UID stats
6578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // are handled during normal polling interval.
6581f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey                final int flags = FLAG_PERSIST_NETWORK;
659b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget();
6608e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
6618e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // re-arm global alert for next update
66225ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                mHandler.obtainMessage(MSG_REGISTER_GLOBAL_ALERT).sendToTarget();
6638e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
6648e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
6658e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    };
6668e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
667367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN;
668367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
669367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
670367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    /**
671367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     * Receiver that watches for {@link TelephonyManager} changes, such as
672367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     * transitioning between network types.
673367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     */
674367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
675367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        @Override
676367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        public void onDataConnectionStateChanged(int state, int networkType) {
677367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            final boolean stateChanged = state != mLastPhoneState;
678367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            final boolean networkTypeChanged = networkType != mLastPhoneNetworkType;
679367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
680367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            if (networkTypeChanged && !stateChanged) {
681367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // networkType changed without a state change, which means we
682367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // need to roll our own update. delay long enough for
683367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // ConnectivityManager to process.
684367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // TODO: add direct event to ConnectivityService instead of
685367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // relying on this delay.
686367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()");
687367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                mHandler.sendMessageDelayed(
688367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                        mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
689367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            }
690367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
691367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mLastPhoneState = state;
692367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mLastPhoneNetworkType = networkType;
693367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        }
694367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    };
695367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
696367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private void updateIfaces() {
697367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        synchronized (mStatsLock) {
698367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mWakeLock.acquire();
699367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            try {
700367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                updateIfacesLocked();
701367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            } finally {
702367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                mWakeLock.release();
703367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            }
704367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        }
705367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    }
706367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
7078e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
708d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * Inspect all current {@link NetworkState} to derive mapping from {@code
709d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
710d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * are active on a single {@code iface}, they are combined under a single
7111b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     * {@link NetworkIdentitySet}.
712d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     */
713d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    private void updateIfacesLocked() {
7146341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        if (!mSystemReady) return;
71539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
716d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
717d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // take one last stats snapshot before updating iface mapping. this
718d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // isn't perfect, since the kernel may already be counting traffic from
719d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // the updated network.
720b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
7211f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        // poll, but only persist network stats to keep codepath fast. UID stats
7221f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        // will be persisted during next alarm poll event.
7231f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        performPollLocked(FLAG_PERSIST_NETWORK);
724d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
725d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final NetworkState[] states;
72663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final LinkProperties activeLink;
727d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        try {
728d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            states = mConnManager.getAllNetworkState();
72963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            activeLink = mConnManager.getActiveLinkProperties();
730d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        } catch (RemoteException e) {
731b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
732d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            return;
733d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
734d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
73563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
73663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
737d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // rebuild active interfaces based on connected networks
7381b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mActiveIfaces.clear();
739d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
740d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        for (NetworkState state : states) {
741d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            if (state.networkInfo.isConnected()) {
742d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                // collect networks under their parent interfaces
743d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                final String iface = state.linkProperties.getInterfaceName();
7441b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
7451b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                NetworkIdentitySet ident = mActiveIfaces.get(iface);
7461b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                if (ident == null) {
7471b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    ident = new NetworkIdentitySet();
7481b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    mActiveIfaces.put(iface, ident);
7491b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                }
7501b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
751d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state));
752234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
753234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                // remember any ifaces associated with mobile networks
754234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                if (isNetworkTypeMobile(state.networkInfo.getType())) {
755234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                    if (!contains(mMobileIfaces, iface)) {
756234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                        mMobileIfaces = appendElement(String.class, mMobileIfaces, iface);
757234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                    }
758234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                }
759d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            }
760d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
761d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
762d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
76339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    /**
7648e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
7658e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * so we have baseline values without double-counting.
7668e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
76763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void bootstrapStatsLocked() {
76863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
76963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                : System.currentTimeMillis();
77063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
7718e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
77263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // snapshot and record current counters; read UID stats first to
77363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // avoid overcounting dev stats.
77463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
77563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats devSnapshot = getNetworkStatsSummary();
77663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
77763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
77863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
77963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
78063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
7818e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (IllegalStateException e) {
7828e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.w(TAG, "problem reading network stats: " + e);
7838e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
784b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
7858e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
7868e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
7878e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
788b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private void performPoll(int flags) {
7898e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        synchronized (mStatsLock) {
7908e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mWakeLock.acquire();
791684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
792684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            // try refreshing time source when stale
793684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
794684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey                mTime.forceRefresh();
795684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            }
796684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
7978e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            try {
798b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                performPollLocked(flags);
7998e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            } finally {
8008e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                mWakeLock.release();
8018e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
8028e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
8038e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
8048e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
8058e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
80639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * Periodic poll operation, reading current statistics and recording into
80739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * {@link NetworkStatsHistory}.
80839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
809b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private void performPollLocked(int flags) {
8106341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        if (!mSystemReady) return;
811b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
8126341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
8138e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        final long startRealtime = SystemClock.elapsedRealtime();
81475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
815b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
816b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
8171f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
818b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
81975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // TODO: consider marking "untrusted" times in historical stats
82075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
82175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey                : System.currentTimeMillis();
82275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
82375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        try {
82463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // snapshot and record current counters; read UID stats first to
82563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // avoid overcounting dev stats.
82663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
82763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats devSnapshot = getNetworkStatsSummary();
8281f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey
82963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
83063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
83163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
832367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
833b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        } catch (IllegalStateException e) {
834b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            Log.wtf(TAG, "problem reading network stats", e);
835905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            return;
836b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        } catch (RemoteException e) {
837b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
838905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            return;
839905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        }
840905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey
84163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // persist any pending data depending on requested flags
84263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        if (persistForce) {
84363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.forcePersistLocked(currentTime);
84463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.forcePersistLocked(currentTime);
84563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.forcePersistLocked(currentTime);
84663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        } else {
84763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (persistNetwork) {
84863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mDevRecorder.maybePersistLocked(currentTime);
84963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
85063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (persistUid) {
85163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.maybePersistLocked(currentTime);
85263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.maybePersistLocked(currentTime);
85363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
85461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        }
855497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey
8568e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        if (LOGV) {
8578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            final long duration = SystemClock.elapsedRealtime() - startRealtime;
8588e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.v(TAG, "performPollLocked() took " + duration + "ms");
8598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
8608e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
86163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        if (mSettings.getSampleEnabled()) {
862905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            // sample stats after each full poll
86363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            performSampleLocked();
864905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        }
86507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
866497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        // finally, dispatch updated event to any listeners
867497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
868497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
869497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        mContext.sendBroadcast(updatedIntent, READ_NETWORK_USAGE_HISTORY);
87061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    }
87161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
87261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    /**
87307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey     * Sample recent statistics summary into {@link EventLog}.
87407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey     */
87563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void performSampleLocked() {
87663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // TODO: migrate trustedtime fixes to separate binary log events
877905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
878905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey
87963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkTemplate template;
88063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry devTotal;
88163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry xtTotal;
88263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry uidTotal;
88307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
88407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        // collect mobile sample
885234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        template = buildTemplateMobileWildcard();
88663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
88763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        xtTotal = new NetworkStats.Entry();
88863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
889684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
890905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        EventLogTags.writeNetstatsMobileSample(
891905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
892905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
893905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
89463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                trustedTime);
89507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
89607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        // collect wifi sample
8978fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        template = buildTemplateWifiWildcard();
89863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
89963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        xtTotal = new NetworkStats.Entry();
90063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
90163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
902905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        EventLogTags.writeNetstatsWifiSample(
903905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
904905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
905905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
90663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                trustedTime);
90707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    }
90807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
90907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    /**
91063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * Clean up {@link #mUidRecorder} after UID is removed.
911b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey     */
912b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private void removeUidLocked(int uid) {
913163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        // perform one last poll before removing
914163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        performPollLocked(FLAG_PERSIST_ALL);
915163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
91663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder.removeUidLocked(uid);
91763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder.removeUidLocked(uid);
918163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
919b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        // clear kernel stats associated with UID
920b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        resetKernelUidStats(uid);
92175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
92275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
92375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    @Override
92463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
92575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mContext.enforceCallingOrSelfPermission(DUMP, TAG);
92675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
92761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        final HashSet<String> argSet = new HashSet<String>();
92861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        for (String arg : args) {
92961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            argSet.add(arg);
93061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        }
93161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
932706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey        // usage: dumpsys netstats --full --uid --tag --poll --checkin
93363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
934706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey        final boolean checkin = argSet.contains("--checkin");
93563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
93663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
93763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
938350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
93963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
94061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
94163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        synchronized (mStatsLock) {
94263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (poll) {
9431f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey                performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
9443f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                pw.println("Forced poll");
9453f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                return;
9463f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey            }
9473f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
948706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey            if (checkin) {
949706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                // list current stats files to verify rotation
950706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.println("Current files:");
951706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.increaseIndent();
952706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                for (String file : mBaseDir.list()) {
953706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                    pw.println(file);
954706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                }
955706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.decreaseIndent();
956706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                return;
957706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey            }
958706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey
95961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            pw.println("Active interfaces:");
96063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.increaseIndent();
9611b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            for (String iface : mActiveIfaces.keySet()) {
9621b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                final NetworkIdentitySet ident = mActiveIfaces.get(iface);
96363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.print("iface="); pw.print(iface);
96461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey                pw.print(" ident="); pw.println(ident.toString());
96561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
96663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.decreaseIndent();
96763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
96863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.println("Dev stats:");
96963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.increaseIndent();
97063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.dumpLocked(pw, fullHistory);
97163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.decreaseIndent();
97263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
97363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (includeUid) {
97463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.println("UID stats:");
97563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.increaseIndent();
97663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.dumpLocked(pw, fullHistory);
97763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.decreaseIndent();
97861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
97961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
98063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (includeTag) {
98163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.println("UID tag stats:");
98263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.increaseIndent();
98363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.dumpLocked(pw, fullHistory);
98463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.decreaseIndent();
98561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
98675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
98761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    }
98875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
98963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats getNetworkStatsSummary() throws RemoteException {
99063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        return mNetworkManager.getNetworkStatsSummary();
9915a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey    }
9925a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey
99375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
99463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * Return snapshot of current UID statistics, including any
99563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values.
99675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
99763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats getNetworkStatsUidDetail() throws RemoteException {
99863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
99963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
100063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // fold tethering stats and operations into uid snapshot
100163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final NetworkStats tetherSnapshot = getNetworkStatsTethering();
100263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidSnapshot.combineAllValues(tetherSnapshot);
100363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidSnapshot.combineAllValues(mUidOperations);
100463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
100563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        return uidSnapshot;
100675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
100775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1008d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    /**
1009d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     * Return snapshot of current tethering statistics. Will return empty
1010d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     * {@link NetworkStats} if any problems are encountered.
1011d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     */
1012d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    private NetworkStats getNetworkStatsTethering() throws RemoteException {
1013d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        try {
1014d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
1015d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            return mNetworkManager.getNetworkStatsTethering(tetheredIfacePairs);
1016d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        } catch (IllegalStateException e) {
1017d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            Log.wtf(TAG, "problem reading network stats", e);
1018d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            return new NetworkStats(0L, 10);
1019d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        }
1020d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    }
1021d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey
1022b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    private Handler.Callback mHandlerCallback = new Handler.Callback() {
1023bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
1024b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        public boolean handleMessage(Message msg) {
1025b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            switch (msg.what) {
10268e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                case MSG_PERFORM_POLL: {
1027b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                    final int flags = msg.arg1;
1028b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                    performPoll(flags);
1029b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                    return true;
1030b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                }
1031367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                case MSG_UPDATE_IFACES: {
1032367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                    updateIfaces();
1033367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                    return true;
1034367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                }
103525ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                case MSG_REGISTER_GLOBAL_ALERT: {
103625ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                    registerGlobalAlert();
103725ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                    return true;
103825ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                }
1039b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                default: {
1040b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                    return false;
1041b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                }
1042b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            }
1043b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
1044b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    };
1045b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
10464190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey    private void assertBandwidthControlEnabled() {
10474190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        if (!isBandwidthControlEnabled()) {
10484190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey            throw new IllegalStateException("Bandwidth module disabled");
10494190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        }
10504190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey    }
10514190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey
1052418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey    private boolean isBandwidthControlEnabled() {
105349c1d1764bce02cf12a68e9312f3aa9dfa2e25ceJeff Sharkey        final long token = Binder.clearCallingIdentity();
1054418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        try {
1055418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return mNetworkManager.isBandwidthControlEnabled();
1056418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        } catch (RemoteException e) {
1057418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            // ignored; service lives in system_server
1058418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return false;
105949c1d1764bce02cf12a68e9312f3aa9dfa2e25ceJeff Sharkey        } finally {
106049c1d1764bce02cf12a68e9312f3aa9dfa2e25ceJeff Sharkey            Binder.restoreCallingIdentity(token);
1061418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        }
1062418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey    }
1063418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey
106463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
1065bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
106663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
106763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                int rightIndex, String cookie) {
106863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            Log.w(TAG, "found non-monotonic values; saving to dropbox");
1069b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
107063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // record error for debugging
107163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final StringBuilder builder = new StringBuilder();
107263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
107363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    + "] - right[" + rightIndex + "]\n");
107463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("left=").append(left).append('\n');
107563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("right=").append(right).append('\n');
1076b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
107763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
107863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    Context.DROPBOX_SERVICE);
107963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
1080b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
1081b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    }
1082b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
10831b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
1084bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey     * Default external settings that read from
1085bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey     * {@link android.provider.Settings.Secure}.
108639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
108739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
108839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        private final ContentResolver mResolver;
108939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
109039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public DefaultNetworkStatsSettings(Context context) {
109139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            mResolver = checkNotNull(context.getContentResolver());
109239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            // TODO: adjust these timings for production builds
109339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
109439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
109539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        private long getSecureLong(String name, long def) {
109639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            return Settings.Secure.getLong(mResolver, name, def);
109739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1098991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey        private boolean getSecureBoolean(String name, boolean def) {
1099991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey            final int defInt = def ? 1 : 0;
1100991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey            return Settings.Secure.getInt(mResolver, name, defInt) != 0;
1101991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey        }
110239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
1103bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
110439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getPollInterval() {
11058e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
110639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1107bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
110863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public long getTimeCacheMaxAge() {
110963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return getSecureLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
111039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1111bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
111263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public long getGlobalAlertBytes() {
111363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return getSecureLong(NETSTATS_GLOBAL_ALERT_BYTES, 2 * MB_IN_BYTES);
111439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1115bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
111663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public boolean getSampleEnabled() {
111763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true);
111839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
111963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1120bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
112163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getDevConfig() {
112263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
112363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_DEV_PERSIST_BYTES, 2 * MB_IN_BYTES),
112463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
112563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
112639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
112763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1128bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
112963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidConfig() {
113063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
113163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
113263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
113363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
1134d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey        }
113563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1136bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
113763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidTagConfig() {
113863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
113963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
114063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_ROTATE_AGE, 5 * DAY_IN_MILLIS),
114163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_DELETE_AGE, 15 * DAY_IN_MILLIS));
114239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
114339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    }
114475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey}
1145