NetworkStatsService.java revision b52e3e55098c4a6e3dbfe19885895411cfb38911
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;
29d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkeyimport static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
3061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL;
31b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_ALL;
32b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_DEFAULT;
33b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_FOREGROUND;
341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkStats.TAG_NONE;
3575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.net.NetworkStats.UID_ALL;
3607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateMobileAll;
378fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateWifiWildcard;
38241dde2306202e7655fdf41d5381f2874e47e108Jeff Sharkeyimport static android.net.TrafficStats.MB_IN_BYTES;
3963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_BUCKET_DURATION;
4063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_DELETE_AGE;
4163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_PERSIST_BYTES;
4263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_DEV_ROTATE_AGE;
4363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_GLOBAL_ALERT_BYTES;
4461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_POLL_INTERVAL;
4563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_SAMPLE_ENABLED;
4663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_TIME_CACHE_MAX_AGE;
4739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_BUCKET_DURATION;
4863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_DELETE_AGE;
4963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_PERSIST_BYTES;
5063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport static android.provider.Settings.Secure.NETSTATS_UID_ROTATE_AGE;
51367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
52367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_NONE;
5361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS;
5461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.HOUR_IN_MILLIS;
5561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.MINUTE_IN_MILLIS;
56367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.text.format.DateUtils.SECOND_IN_MILLIS;
57d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull;
588e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
59b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
60b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
6175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
6275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.AlarmManager;
6375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.IAlarmManager;
6475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.PendingIntent;
6575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.BroadcastReceiver;
6639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport android.content.ContentResolver;
6775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Context;
6875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Intent;
6975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.IntentFilter;
70d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.IConnectivityManager;
718e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport android.net.INetworkManagementEventObserver;
7275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService;
73b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkeyimport android.net.INetworkStatsSession;
7463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport android.net.LinkProperties;
751b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkIdentity;
76d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkInfo;
77d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState;
7875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStats;
795a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkeyimport android.net.NetworkStats.NonMonotonicObserver;
8075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStatsHistory;
811b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate;
8263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport android.net.TrafficStats;
83a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport android.os.Binder;
84163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport android.os.DropBoxManager;
853f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport android.os.Environment;
8675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.Handler;
8775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.HandlerThread;
8875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.INetworkManagementService;
89b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.os.Message;
906248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkeyimport android.os.PowerManager;
9175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.RemoteException;
9275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.SystemClock;
9361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.provider.Settings;
94367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport android.telephony.PhoneStateListener;
9575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.telephony.TelephonyManager;
9607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport android.util.EventLog;
97b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkeyimport android.util.Log;
9875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.NtpTrustedTime;
9975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.Slog;
100b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.util.SparseIntArray;
10175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.TrustedTime;
10275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
10363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport com.android.internal.util.FileRotator;
10463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
10507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport com.android.server.EventLogTags;
106cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkeyimport com.android.server.connectivity.Tethering;
10775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport com.google.android.collect.Maps;
10875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1093f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.File;
11075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.FileDescriptor;
1113f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.IOException;
11275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.PrintWriter;
11375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.HashMap;
11461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport java.util.HashSet;
1153f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
11675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/**
11775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collect and persist detailed network statistics, and provide this data to
11875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * other system services.
11975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */
12075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeypublic class NetworkStatsService extends INetworkStatsService.Stub {
12121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static final String TAG = "NetworkStats";
122706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey    private static final boolean LOGV = false;
123b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
124367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private static final int MSG_PERFORM_POLL = 1;
125367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private static final int MSG_UPDATE_IFACES = 2;
12625ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey    private static final int MSG_REGISTER_GLOBAL_ALERT = 3;
127b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
128b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    /** Flags to control detail level of poll event. */
129905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey    private static final int FLAG_PERSIST_NETWORK = 0x1;
130905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey    private static final int FLAG_PERSIST_UID = 0x2;
131b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
1321f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey    private static final int FLAG_PERSIST_FORCE = 0x100;
1333f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
134163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    private static final String TAG_NETSTATS_ERROR = "netstats_error";
135163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
13675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Context mContext;
13775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final INetworkManagementService mNetworkManager;
13875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final IAlarmManager mAlarmManager;
13975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final TrustedTime mTime;
140367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private final TelephonyManager mTeleManager;
14139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    private final NetworkStatsSettings mSettings;
14275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
14363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final File mSystemDir;
14463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final File mBaseDir;
14563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1466248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey    private final PowerManager.WakeLock mWakeLock;
1476248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey
148d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    private IConnectivityManager mConnManager;
149d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
1503f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    // @VisibleForTesting
1513f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    public static final String ACTION_NETWORK_STATS_POLL =
15275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            "com.android.server.action.NETWORK_STATS_POLL";
153497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey    public static final String ACTION_NETWORK_STATS_UPDATED =
154497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey            "com.android.server.action.NETWORK_STATS_UPDATED";
15575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
15675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private PendingIntent mPollIntent;
15775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
15863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_DEV = "dev";
15963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_UID = "uid";
16063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_UID_TAG = "uid_tag";
16163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
16239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    /**
16339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * Settings that can be changed externally.
16439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
16539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    public interface NetworkStatsSettings {
16639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getPollInterval();
16739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getTimeCacheMaxAge();
16863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public long getGlobalAlertBytes();
16963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public boolean getSampleEnabled();
17063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
17163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public static class Config {
17263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long bucketDuration;
17363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long persistBytes;
17463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long rotateAgeMillis;
17563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long deleteAgeMillis;
17663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
17763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public Config(long bucketDuration, long persistBytes, long rotateAgeMillis,
17863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    long deleteAgeMillis) {
17963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.bucketDuration = bucketDuration;
18063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.persistBytes = persistBytes;
18163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.rotateAgeMillis = rotateAgeMillis;
18263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.deleteAgeMillis = deleteAgeMillis;
18363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
18463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        }
18563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
18663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getDevConfig();
18763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidConfig();
18863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidTagConfig();
18939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    }
19075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
19175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Object mStatsLock = new Object();
19275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /** Set of currently active ifaces. */
1941b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
19563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    /** Current default active iface. */
19663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private String mActiveIface;
19763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
19863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
19963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            new DropBoxNonMonotonicObserver();
20063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
20163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mDevRecorder;
20263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mUidRecorder;
20363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mUidTagRecorder;
20463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
20563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    /** Cached {@link #mDevRecorder} stats. */
20663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsCollection mDevStatsCached;
20775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
208b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    /** Current counter sets for each UID. */
209b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
210b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
211a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    /** Data layer operation counters for splicing into other structures. */
21263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats mUidOperations = new NetworkStats(0L, 10);
213a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
21475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final HandlerThread mHandlerThread;
21575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Handler mHandler;
21675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
2176341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey    private boolean mSystemReady;
2186341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
21975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public NetworkStatsService(
22075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
221104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey        this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context),
22263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                getDefaultSystemDir(), new DefaultNetworkStatsSettings(context));
2233f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    }
2243f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
22563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static File getDefaultSystemDir() {
2263f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        return new File(Environment.getDataDirectory(), "system");
22775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
22875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
22975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public NetworkStatsService(Context context, INetworkManagementService networkManager,
23039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            IAlarmManager alarmManager, TrustedTime time, File systemDir,
23139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            NetworkStatsSettings settings) {
23275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mContext = checkNotNull(context, "missing Context");
23375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
23475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
23575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mTime = checkNotNull(time, "missing TrustedTime");
236367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
23739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
23875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
2396248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey        final PowerManager powerManager = (PowerManager) context.getSystemService(
2406248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                Context.POWER_SERVICE);
2416248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
2426248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey
24375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mHandlerThread = new HandlerThread(TAG);
24475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mHandlerThread.start();
245b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
2463f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
24763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mSystemDir = checkNotNull(systemDir);
24863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mBaseDir = new File(systemDir, "netstats");
24963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mBaseDir.mkdirs();
25075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
25175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
25221c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void bindConnectivityManager(IConnectivityManager connManager) {
25321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
25421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
25521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
25675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public void systemReady() {
2576341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        mSystemReady = true;
2586341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
259418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        if (!isBandwidthControlEnabled()) {
260418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
261418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return;
262418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        }
263418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey
26463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // create data recorders along with historical rotators
26563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
26663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
26763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
26863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
2693f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        synchronized (mStatsLock) {
27063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // upgrade any legacy stats, migrating them to rotated files
27163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            maybeUpgradeLegacyStatsLocked();
27263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
27339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            // read historical network stats from disk, since policy service
27463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // might need them right away.
27563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevStatsCached = mDevRecorder.getOrLoadCompleteLocked();
27675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
27763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // bootstrap initial stats to prevent double-counting later
27863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            bootstrapStatsLocked();
27963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        }
2803359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey
28121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // watch for network interfaces to be claimed
282961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE);
283b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
28475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
285cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        // watch for tethering changes
286cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
287cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        mContext.registerReceiver(mTetherReceiver, tetherFilter, CONNECTIVITY_INTERNAL, mHandler);
288cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
28975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // listen for periodic polling events
29075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
29121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
29275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
293b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        // listen for uid removal to clean stats
294b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
295b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
296b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
29775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // persist stats during clean shutdown
298b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
299b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
30075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
30175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        try {
3028e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mNetworkManager.registerObserver(mAlertObserver);
30375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        } catch (RemoteException e) {
304b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
30575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
306b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
307367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        // watch for networkType changes that aren't broadcast through
308367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        // CONNECTIVITY_ACTION_IMMEDIATE above.
309d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (!COMBINE_SUBTYPE_ENABLED) {
310d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE);
311d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
312367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
3138e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        registerPollAlarmLocked();
3148e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        registerGlobalAlert();
31563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    }
3168e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
31763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder buildRecorder(
31863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
31963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        return new NetworkStatsRecorder(
32063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                new FileRotator(mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
32163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mNonMonotonicObserver, prefix, config.bucketDuration, config.persistBytes,
32263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                includeTags);
32375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
32475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
3253f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    private void shutdownLocked() {
326b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.unregisterReceiver(mConnReceiver);
327367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        mContext.unregisterReceiver(mTetherReceiver);
3283f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        mContext.unregisterReceiver(mPollReceiver);
329b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.unregisterReceiver(mRemovedReceiver);
3303f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        mContext.unregisterReceiver(mShutdownReceiver);
3313f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
332d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (!COMBINE_SUBTYPE_ENABLED) {
333d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            mTeleManager.listen(mPhoneListener, LISTEN_NONE);
334d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
335367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
33663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
33763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                : System.currentTimeMillis();
33863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
33963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // persist any pending stats
34063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder.forcePersistLocked(currentTime);
34163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder.forcePersistLocked(currentTime);
34263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder.forcePersistLocked(currentTime);
34363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
34463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder = null;
34563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder = null;
34663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder = null;
34763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
34863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevStatsCached = null;
3496341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
3506341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        mSystemReady = false;
35163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    }
35263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
35363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void maybeUpgradeLegacyStatsLocked() {
35463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        File file;
35563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        try {
35663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats.bin");
35763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
35863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mDevRecorder.importLegacyNetworkLocked(file);
35963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
36063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
36163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
36263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats_xt.bin");
36363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
36463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
36563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
36663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
36763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats_uid.bin");
36863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
36963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.importLegacyUidLocked(file);
37063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.importLegacyUidLocked(file);
37163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
37263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
37363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        } catch (IOException e) {
37463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            Log.wtf(TAG, "problem during legacy upgrade", e);
375af8339374fbf1e2f57b0be918c7fc772f4250f13Jeff Sharkey        }
3763f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    }
3773f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
37875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
37975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
38039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
38175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
3828e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private void registerPollAlarmLocked() {
3838e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
3848e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            if (mPollIntent != null) {
3858e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                mAlarmManager.remove(mPollIntent);
3868e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
38775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
3888e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mPollIntent = PendingIntent.getBroadcast(
3898e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                    mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
39075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
3918e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            final long currentRealtime = SystemClock.elapsedRealtime();
3928e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
3938e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                    mSettings.getPollInterval(), mPollIntent);
3948e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
395b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
3968e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
3978e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
3988e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
3998e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
4008e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Register for a global alert that is delivered through
4018e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * {@link INetworkManagementEventObserver} once a threshold amount of data
4028e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * has been transferred.
4038e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
4048e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private void registerGlobalAlert() {
4058e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
40663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final long alertBytes = mSettings.getGlobalAlertBytes();
4078e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mNetworkManager.setGlobalAlert(alertBytes);
4088e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (IllegalStateException e) {
4098e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.w(TAG, "problem registering for global alert: " + e);
4108e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
411b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
4128e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
41375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
41475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
41575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    @Override
416b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey    public INetworkStatsSession openSession() {
417b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
418d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
419b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        // return an IBinder which holds strong references to any loaded stats
420b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        // for its lifetime; when caller closes only weak references remain.
42175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
422b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        return new INetworkStatsSession.Stub() {
423b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection mUidComplete;
424b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection mUidTagComplete;
425b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
426b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection getUidComplete() {
427b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (mUidComplete == null) {
428b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
429b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
430b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mUidComplete;
431b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
432b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
433b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection getUidTagComplete() {
434b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (mUidTagComplete == null) {
435b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
436b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
437b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mUidTagComplete;
438b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
439b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
440b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
441b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStats getSummaryForNetwork(
442b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, long start, long end) {
443b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mDevStatsCached.getSummary(template, start, end);
444b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
445b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
446b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
447b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
448b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mDevStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
449b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
450b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
451b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
452b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStats getSummaryForAllUid(
453b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, long start, long end, boolean includeTags) {
454b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                final NetworkStats stats = getUidComplete().getSummary(template, start, end);
455b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (includeTags) {
456b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    final NetworkStats tagStats = getUidTagComplete()
457b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                            .getSummary(template, start, end);
458b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    stats.combineAllValues(tagStats);
459b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
460b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return stats;
461b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
462b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
463b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
464b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStatsHistory getHistoryForUid(
465b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, int uid, int set, int tag, int fields) {
466b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (tag == TAG_NONE) {
467b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    return getUidComplete().getHistory(template, uid, set, tag, fields);
468b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                } else {
469b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    return getUidTagComplete().getHistory(template, uid, set, tag, fields);
470b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
471b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
472b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
473b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
474b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public void close() {
475b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                mUidComplete = null;
476b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                mUidTagComplete = null;
477b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
478b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        };
479684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey    }
480684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
48121c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    @Override
482b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey    public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
483b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
484b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        return mDevStatsCached.getSummary(template, start, end).getTotalBytes();
485d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
486d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
487350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    @Override
488a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
489a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        if (Binder.getCallingUid() != uid) {
490a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
491a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
492a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
493a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        // TODO: switch to data layer stats once kernel exports
494a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        // for now, read network layer stats and flatten across all ifaces
4954529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        final long token = Binder.clearCallingIdentity();
4964529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        final NetworkStats networkLayer;
4974529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        try {
4984529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey            networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid);
4994529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        } finally {
5004529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey            Binder.restoreCallingIdentity(token);
5014529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        }
5024529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey
503a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        final NetworkStats dataLayer = new NetworkStats(
504a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey                networkLayer.getElapsedRealtime(), networkLayer.size());
505a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
506a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        NetworkStats.Entry entry = null;
507a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        for (int i = 0; i < networkLayer.size(); i++) {
508a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            entry = networkLayer.getValues(i, entry);
509a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            entry.iface = IFACE_ALL;
510a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            dataLayer.combineValues(entry);
511a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
512a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
513a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        // splice in operation counts
51463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        dataLayer.spliceOperationsFrom(mUidOperations);
515a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        return dataLayer;
516a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    }
517a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
518a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    @Override
519a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    public void incrementOperationCount(int uid, int tag, int operationCount) {
520a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        if (Binder.getCallingUid() != uid) {
521a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
522a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
523a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
524b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        if (operationCount < 0) {
525b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            throw new IllegalArgumentException("operation count can only be incremented");
526b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
527b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        if (tag == TAG_NONE) {
528b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            throw new IllegalArgumentException("operation count must have specific tag");
529b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
530b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
531a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        synchronized (mStatsLock) {
532b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
53363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidOperations.combineValues(
53463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
53563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidOperations.combineValues(
53663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
537b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
538b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    }
539b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
540b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    @Override
541b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    public void setUidForeground(int uid, boolean uidForeground) {
542b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
543b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
544b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        synchronized (mStatsLock) {
545b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
546b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
547b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            if (oldSet != set) {
548b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                mActiveUidCounterSet.put(uid, set);
549b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                setKernelCounterSet(uid, set);
550b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            }
551a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
552a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    }
553a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
554a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    @Override
555350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    public void forceUpdate() {
556350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
557e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey
558e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        final long token = Binder.clearCallingIdentity();
559e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        try {
560e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey            performPoll(FLAG_PERSIST_ALL);
561e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        } finally {
562e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey            Binder.restoreCallingIdentity(token);
563e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        }
564350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    }
565350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
56675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
567d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * Receiver that watches for {@link IConnectivityManager} to claim network
56875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
56975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * with mobile interfaces.
57075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
571b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
57275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
57375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
574d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // on background handler thread, and verified CONNECTIVITY_INTERNAL
575d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // permission above.
576367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            updateIfaces();
57775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
57875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
57975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
580cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    /**
581cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey     * Receiver that watches for {@link Tethering} to claim interface pairs.
582cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey     */
583cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
584cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        @Override
585cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        public void onReceive(Context context, Intent intent) {
586cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey            // on background handler thread, and verified CONNECTIVITY_INTERNAL
587cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey            // permission above.
5881f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey            performPoll(FLAG_PERSIST_NETWORK);
589cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        }
590cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    };
591cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
59275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
59375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
59475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
595d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // on background handler thread, and verified UPDATE_DEVICE_STATS
596d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // permission above.
5971f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey            performPoll(FLAG_PERSIST_ALL);
5988e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
5998e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            // verify that we're watching global alert
6008e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            registerGlobalAlert();
60175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
60275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
60375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
604b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
605b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        @Override
606b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        public void onReceive(Context context, Intent intent) {
607b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // on background handler thread, and UID_REMOVED is protected
608b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // broadcast.
609b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            final int uid = intent.getIntExtra(EXTRA_UID, 0);
610b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            synchronized (mStatsLock) {
6116248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                mWakeLock.acquire();
6126248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                try {
6136248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                    removeUidLocked(uid);
6146248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                } finally {
6156248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                    mWakeLock.release();
6166248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                }
617b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            }
618b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        }
619b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    };
620b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
62175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
62275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
62375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
624b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // SHUTDOWN is protected broadcast.
62575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            synchronized (mStatsLock) {
6263f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                shutdownLocked();
62775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            }
62875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
62975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
63075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
631d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    /**
6328e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Observer that watches for {@link INetworkManagementService} alerts.
6338e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
6348e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() {
6358e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        @Override
6368e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        public void limitReached(String limitName, String iface) {
6378e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            // only someone like NMS should be calling us
6388e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
6398e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
6408e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
6418e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // kick off background poll to collect network stats; UID stats
6428e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // are handled during normal polling interval.
6431f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey                final int flags = FLAG_PERSIST_NETWORK;
644b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget();
6458e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
6468e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // re-arm global alert for next update
64725ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                mHandler.obtainMessage(MSG_REGISTER_GLOBAL_ALERT).sendToTarget();
6488e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
6498e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
6508e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    };
6518e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
652367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN;
653367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
654367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
655367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    /**
656367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     * Receiver that watches for {@link TelephonyManager} changes, such as
657367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     * transitioning between network types.
658367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     */
659367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
660367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        @Override
661367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        public void onDataConnectionStateChanged(int state, int networkType) {
662367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            final boolean stateChanged = state != mLastPhoneState;
663367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            final boolean networkTypeChanged = networkType != mLastPhoneNetworkType;
664367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
665367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            if (networkTypeChanged && !stateChanged) {
666367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // networkType changed without a state change, which means we
667367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // need to roll our own update. delay long enough for
668367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // ConnectivityManager to process.
669367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // TODO: add direct event to ConnectivityService instead of
670367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // relying on this delay.
671367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()");
672367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                mHandler.sendMessageDelayed(
673367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                        mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
674367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            }
675367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
676367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mLastPhoneState = state;
677367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mLastPhoneNetworkType = networkType;
678367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        }
679367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    };
680367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
681367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private void updateIfaces() {
682367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        synchronized (mStatsLock) {
683367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mWakeLock.acquire();
684367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            try {
685367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                updateIfacesLocked();
686367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            } finally {
687367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                mWakeLock.release();
688367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            }
689367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        }
690367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    }
691367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
6928e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
693d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * Inspect all current {@link NetworkState} to derive mapping from {@code
694d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
695d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * are active on a single {@code iface}, they are combined under a single
6961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     * {@link NetworkIdentitySet}.
697d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     */
698d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    private void updateIfacesLocked() {
6996341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        if (!mSystemReady) return;
70039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
701d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
702d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // take one last stats snapshot before updating iface mapping. this
703d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // isn't perfect, since the kernel may already be counting traffic from
704d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // the updated network.
705b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
7061f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        // poll, but only persist network stats to keep codepath fast. UID stats
7071f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        // will be persisted during next alarm poll event.
7081f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        performPollLocked(FLAG_PERSIST_NETWORK);
709d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
710d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final NetworkState[] states;
71163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final LinkProperties activeLink;
712d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        try {
713d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            states = mConnManager.getAllNetworkState();
71463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            activeLink = mConnManager.getActiveLinkProperties();
715d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        } catch (RemoteException e) {
716b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
717d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            return;
718d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
719d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
72063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
72163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
722d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // rebuild active interfaces based on connected networks
7231b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mActiveIfaces.clear();
724d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
725d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        for (NetworkState state : states) {
726d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            if (state.networkInfo.isConnected()) {
727d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                // collect networks under their parent interfaces
728d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                final String iface = state.linkProperties.getInterfaceName();
7291b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
7301b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                NetworkIdentitySet ident = mActiveIfaces.get(iface);
7311b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                if (ident == null) {
7321b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    ident = new NetworkIdentitySet();
7331b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    mActiveIfaces.put(iface, ident);
7341b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                }
7351b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
736d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state));
737d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            }
738d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
739d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
740d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
74139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    /**
7428e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
7438e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * so we have baseline values without double-counting.
7448e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
74563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void bootstrapStatsLocked() {
74663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
74763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                : System.currentTimeMillis();
74863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
7498e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
75063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // snapshot and record current counters; read UID stats first to
75163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // avoid overcounting dev stats.
75263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
75363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats devSnapshot = getNetworkStatsSummary();
75463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
75563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
75663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
75763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
75863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
7598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (IllegalStateException e) {
7608e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.w(TAG, "problem reading network stats: " + e);
7618e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
762b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
7638e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
7648e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
7658e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
766b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private void performPoll(int flags) {
7678e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        synchronized (mStatsLock) {
7688e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mWakeLock.acquire();
769684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
770684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            // try refreshing time source when stale
771684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
772684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey                mTime.forceRefresh();
773684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            }
774684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
7758e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            try {
776b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                performPollLocked(flags);
7778e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            } finally {
7788e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                mWakeLock.release();
7798e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
7808e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
7818e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
7828e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
7838e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
78439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * Periodic poll operation, reading current statistics and recording into
78539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * {@link NetworkStatsHistory}.
78639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
787b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private void performPollLocked(int flags) {
7886341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        if (!mSystemReady) return;
789b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
7906341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
7918e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        final long startRealtime = SystemClock.elapsedRealtime();
79275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
793b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
794b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
7951f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
796b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
79775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // TODO: consider marking "untrusted" times in historical stats
79875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
79975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey                : System.currentTimeMillis();
80075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
80175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        try {
80263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // snapshot and record current counters; read UID stats first to
80363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // avoid overcounting dev stats.
80463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
80563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats devSnapshot = getNetworkStatsSummary();
8061f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey
80763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
80863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
80963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
810367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
811b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        } catch (IllegalStateException e) {
812b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            Log.wtf(TAG, "problem reading network stats", e);
813905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            return;
814b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        } catch (RemoteException e) {
815b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
816905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            return;
817905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        }
818905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey
81963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // persist any pending data depending on requested flags
82063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        if (persistForce) {
82163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.forcePersistLocked(currentTime);
82263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.forcePersistLocked(currentTime);
82363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.forcePersistLocked(currentTime);
82463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        } else {
82563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (persistNetwork) {
82663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mDevRecorder.maybePersistLocked(currentTime);
82763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
82863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (persistUid) {
82963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.maybePersistLocked(currentTime);
83063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.maybePersistLocked(currentTime);
83163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
83261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        }
833497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey
8348e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        if (LOGV) {
8358e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            final long duration = SystemClock.elapsedRealtime() - startRealtime;
8368e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.v(TAG, "performPollLocked() took " + duration + "ms");
8378e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
8388e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
83963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        if (mSettings.getSampleEnabled()) {
840905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            // sample stats after each full poll
84163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            performSampleLocked();
842905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        }
84307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
844497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        // finally, dispatch updated event to any listeners
845497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
846497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
847497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        mContext.sendBroadcast(updatedIntent, READ_NETWORK_USAGE_HISTORY);
84861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    }
84961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
85061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    /**
85107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey     * Sample recent statistics summary into {@link EventLog}.
85207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey     */
85363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void performSampleLocked() {
85463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // TODO: migrate trustedtime fixes to separate binary log events
855905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
856905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey
85763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkTemplate template;
85863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry devTotal;
85963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry xtTotal;
86063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry uidTotal;
86107b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
86207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        // collect mobile sample
86307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        template = buildTemplateMobileAll(getActiveSubscriberId(mContext));
86463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
86563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        xtTotal = new NetworkStats.Entry();
86663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
867684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
868905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        EventLogTags.writeNetstatsMobileSample(
869905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
870905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
871905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
87263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                trustedTime);
87307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
87407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        // collect wifi sample
8758fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        template = buildTemplateWifiWildcard();
87663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
87763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        xtTotal = new NetworkStats.Entry();
87863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
87963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
880905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        EventLogTags.writeNetstatsWifiSample(
881905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
882905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
883905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
88463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                trustedTime);
88507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    }
88607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
88707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    /**
88863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * Clean up {@link #mUidRecorder} after UID is removed.
889b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey     */
890b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private void removeUidLocked(int uid) {
891163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        // perform one last poll before removing
892163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        performPollLocked(FLAG_PERSIST_ALL);
893163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
89463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder.removeUidLocked(uid);
89563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder.removeUidLocked(uid);
896163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
897b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        // clear kernel stats associated with UID
898b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        resetKernelUidStats(uid);
89975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
90075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
90175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    @Override
90263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
90375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mContext.enforceCallingOrSelfPermission(DUMP, TAG);
90475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
90561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        final HashSet<String> argSet = new HashSet<String>();
90661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        for (String arg : args) {
90761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            argSet.add(arg);
90861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        }
90961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
910706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey        // usage: dumpsys netstats --full --uid --tag --poll --checkin
91163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
912706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey        final boolean checkin = argSet.contains("--checkin");
91363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
91463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
91563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
916350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
91763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
91861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
91963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        synchronized (mStatsLock) {
92063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (poll) {
9211f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey                performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
9223f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                pw.println("Forced poll");
9233f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                return;
9243f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey            }
9253f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
926706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey            if (checkin) {
927706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                // list current stats files to verify rotation
928706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.println("Current files:");
929706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.increaseIndent();
930706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                for (String file : mBaseDir.list()) {
931706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                    pw.println(file);
932706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                }
933706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.decreaseIndent();
934706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                return;
935706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey            }
936706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey
93761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            pw.println("Active interfaces:");
93863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.increaseIndent();
9391b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            for (String iface : mActiveIfaces.keySet()) {
9401b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                final NetworkIdentitySet ident = mActiveIfaces.get(iface);
94163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.print("iface="); pw.print(iface);
94261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey                pw.print(" ident="); pw.println(ident.toString());
94361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
94463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.decreaseIndent();
94563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
94663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.println("Dev stats:");
94763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.increaseIndent();
94863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.dumpLocked(pw, fullHistory);
94963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.decreaseIndent();
95063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
95163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (includeUid) {
95263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.println("UID stats:");
95363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.increaseIndent();
95463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.dumpLocked(pw, fullHistory);
95563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.decreaseIndent();
95661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
95761ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
95863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (includeTag) {
95963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.println("UID tag stats:");
96063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.increaseIndent();
96163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.dumpLocked(pw, fullHistory);
96263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.decreaseIndent();
96361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
96475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
96561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    }
96675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
96763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats getNetworkStatsSummary() throws RemoteException {
96863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        return mNetworkManager.getNetworkStatsSummary();
9695a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey    }
9705a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkey
97175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
97263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * Return snapshot of current UID statistics, including any
97363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values.
97475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
97563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats getNetworkStatsUidDetail() throws RemoteException {
97663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
97763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
97863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // fold tethering stats and operations into uid snapshot
97963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final NetworkStats tetherSnapshot = getNetworkStatsTethering();
98063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidSnapshot.combineAllValues(tetherSnapshot);
98163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidSnapshot.combineAllValues(mUidOperations);
98263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
98363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        return uidSnapshot;
98475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
98575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
986d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    /**
987d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     * Return snapshot of current tethering statistics. Will return empty
988d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     * {@link NetworkStats} if any problems are encountered.
989d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     */
990d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    private NetworkStats getNetworkStatsTethering() throws RemoteException {
991d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        try {
992d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
993d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            return mNetworkManager.getNetworkStatsTethering(tetheredIfacePairs);
994d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        } catch (IllegalStateException e) {
995d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            Log.wtf(TAG, "problem reading network stats", e);
996d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            return new NetworkStats(0L, 10);
997d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        }
998d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    }
999d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey
1000b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    private Handler.Callback mHandlerCallback = new Handler.Callback() {
1001b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        /** {@inheritDoc} */
1002b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        public boolean handleMessage(Message msg) {
1003b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            switch (msg.what) {
10048e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                case MSG_PERFORM_POLL: {
1005b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                    final int flags = msg.arg1;
1006b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                    performPoll(flags);
1007b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                    return true;
1008b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                }
1009367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                case MSG_UPDATE_IFACES: {
1010367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                    updateIfaces();
1011367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                    return true;
1012367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                }
101325ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                case MSG_REGISTER_GLOBAL_ALERT: {
101425ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                    registerGlobalAlert();
101525ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                    return true;
101625ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                }
1017b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                default: {
1018b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                    return false;
1019b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                }
1020b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            }
1021b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
1022b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    };
1023b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
102407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    private static String getActiveSubscriberId(Context context) {
102507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        final TelephonyManager telephony = (TelephonyManager) context.getSystemService(
102607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey                Context.TELEPHONY_SERVICE);
102707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        return telephony.getSubscriberId();
102807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    }
102907b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
1030418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey    private boolean isBandwidthControlEnabled() {
1031418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        try {
1032418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return mNetworkManager.isBandwidthControlEnabled();
1033418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        } catch (RemoteException e) {
1034418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            // ignored; service lives in system_server
1035418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return false;
1036418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        }
1037418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey    }
1038418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey
103963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
104063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        /** {@inheritDoc} */
104163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
104263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                int rightIndex, String cookie) {
104363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            Log.w(TAG, "found non-monotonic values; saving to dropbox");
1044b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
104563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // record error for debugging
104663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final StringBuilder builder = new StringBuilder();
104763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
104863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    + "] - right[" + rightIndex + "]\n");
104963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("left=").append(left).append('\n');
105063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("right=").append(right).append('\n');
1051b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
105263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
105363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    Context.DROPBOX_SERVICE);
105463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
1055b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
1056b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    }
1057b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
10581b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
105939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * Default external settings that read from {@link Settings.Secure}.
106039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
106139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
106239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        private final ContentResolver mResolver;
106339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
106439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public DefaultNetworkStatsSettings(Context context) {
106539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            mResolver = checkNotNull(context.getContentResolver());
106639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            // TODO: adjust these timings for production builds
106739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
106839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
106939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        private long getSecureLong(String name, long def) {
107039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            return Settings.Secure.getLong(mResolver, name, def);
107139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1072991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey        private boolean getSecureBoolean(String name, boolean def) {
1073991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey            final int defInt = def ? 1 : 0;
1074991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey            return Settings.Secure.getInt(mResolver, name, defInt) != 0;
1075991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey        }
107639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
107739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getPollInterval() {
10788e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            return getSecureLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
107939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
108063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public long getTimeCacheMaxAge() {
108163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return getSecureLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
108239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
108363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public long getGlobalAlertBytes() {
108463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return getSecureLong(NETSTATS_GLOBAL_ALERT_BYTES, 2 * MB_IN_BYTES);
108539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
108663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public boolean getSampleEnabled() {
108763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return getSecureBoolean(NETSTATS_SAMPLE_ENABLED, true);
108839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
108963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
109063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getDevConfig() {
109163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return new Config(getSecureLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
109263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_DEV_PERSIST_BYTES, 2 * MB_IN_BYTES),
109363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
109463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
109539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
109663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
109763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidConfig() {
109863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
109963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
110063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
110163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
1102d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey        }
110363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
110463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidTagConfig() {
110563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            return new Config(getSecureLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
110663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_PERSIST_BYTES, 2 * MB_IN_BYTES),
110763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_ROTATE_AGE, 5 * DAY_IN_MILLIS),
110863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    getSecureLong(NETSTATS_UID_DELETE_AGE, 15 * DAY_IN_MILLIS));
110939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
111039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    }
111175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey}
1112