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;
26daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport static android.content.Intent.ACTION_USER_REMOVED;
27b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkeyimport static android.content.Intent.EXTRA_UID;
28cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkeyimport static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
29367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
30234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static android.net.ConnectivityManager.isNetworkTypeMobile;
31d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkeyimport static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED;
3261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.net.NetworkStats.IFACE_ALL;
33b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_ALL;
34b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_DEFAULT;
35b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static android.net.NetworkStats.SET_FOREGROUND;
361b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport static android.net.NetworkStats.TAG_NONE;
3775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport static android.net.NetworkStats.UID_ALL;
38234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateMobileWildcard;
398fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkeyimport static android.net.NetworkTemplate.buildTemplateWifiWildcard;
40ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkeyimport static android.net.TrafficStats.KB_IN_BYTES;
41241dde2306202e7655fdf41d5381f2874e47e108Jeff Sharkeyimport static android.net.TrafficStats.MB_IN_BYTES;
42023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
43023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
44023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
45023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
46023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
47023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
48023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_REPORT_XT_OVER_DEV;
49023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
50023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE;
51023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
52023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
53023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
54023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
55023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
56023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
57023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
58023c05a341b87d0899c89bf355b6ae27d138bb03Jeff Sharkeyimport static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
59367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_DATA_CONNECTION_STATE;
60367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.telephony.PhoneStateListener.LISTEN_NONE;
6161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.DAY_IN_MILLIS;
6261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.HOUR_IN_MILLIS;
6361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport static android.text.format.DateUtils.MINUTE_IN_MILLIS;
64367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport static android.text.format.DateUtils.SECOND_IN_MILLIS;
65234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static com.android.internal.util.ArrayUtils.appendElement;
66234766a36af6214644fa8205202287084ca9cf93Jeff Sharkeyimport static com.android.internal.util.ArrayUtils.contains;
67d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport static com.android.internal.util.Preconditions.checkNotNull;
688e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
69b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
70b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
7175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
7275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.AlarmManager;
7375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.IAlarmManager;
7475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.app.PendingIntent;
7575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.BroadcastReceiver;
7639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkeyimport android.content.ContentResolver;
7775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Context;
7875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.Intent;
7975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.content.IntentFilter;
80daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport android.content.pm.ApplicationInfo;
81daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport android.content.pm.PackageManager;
82d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.IConnectivityManager;
838e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkeyimport android.net.INetworkManagementEventObserver;
8475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.INetworkStatsService;
85b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkeyimport android.net.INetworkStatsSession;
8663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport android.net.LinkProperties;
871b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkIdentity;
88d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkInfo;
89d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkeyimport android.net.NetworkState;
9075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStats;
915a7bcf31a44d9875ca5fc010dc213aa2bd5b1168Jeff Sharkeyimport android.net.NetworkStats.NonMonotonicObserver;
9275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.net.NetworkStatsHistory;
931b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkeyimport android.net.NetworkTemplate;
9463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport android.net.TrafficStats;
95a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkeyimport android.os.Binder;
96163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkeyimport android.os.DropBoxManager;
973f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport android.os.Environment;
9875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.Handler;
9975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.HandlerThread;
10075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.INetworkManagementService;
101b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.os.Message;
1026248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkeyimport android.os.PowerManager;
10375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.RemoteException;
10475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.os.SystemClock;
1055ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
10661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport android.provider.Settings;
107625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkeyimport android.provider.Settings.Global;
108367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkeyimport android.telephony.PhoneStateListener;
10975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.telephony.TelephonyManager;
11007b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport android.util.EventLog;
111b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkeyimport android.util.Log;
112ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkeyimport android.util.MathUtils;
11375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.NtpTrustedTime;
11475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.Slog;
115b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkeyimport android.util.SparseIntArray;
11675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport android.util.TrustedTime;
11775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1188b2c3a14603d163d7564e6f60286995079687690Jeff Sharkeyimport com.android.internal.annotations.VisibleForTesting;
119daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport com.android.internal.util.ArrayUtils;
12063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport com.android.internal.util.FileRotator;
12163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkeyimport com.android.internal.util.IndentingPrintWriter;
12207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkeyimport com.android.server.EventLogTags;
123cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkeyimport com.android.server.connectivity.Tethering;
12475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport com.google.android.collect.Maps;
12575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1263f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.File;
12775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.FileDescriptor;
1283f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkeyimport java.io.IOException;
12975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.io.PrintWriter;
130daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport java.util.Arrays;
13175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeyimport java.util.HashMap;
13261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkeyimport java.util.HashSet;
133daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkeyimport java.util.List;
1343f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
13575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey/**
13675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * Collect and persist detailed network statistics, and provide this data to
13775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey * other system services.
13875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey */
13975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkeypublic class NetworkStatsService extends INetworkStatsService.Stub {
14021c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    private static final String TAG = "NetworkStats";
141706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey    private static final boolean LOGV = false;
142b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
143367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private static final int MSG_PERFORM_POLL = 1;
144367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private static final int MSG_UPDATE_IFACES = 2;
14525ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey    private static final int MSG_REGISTER_GLOBAL_ALERT = 3;
146b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
147b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    /** Flags to control detail level of poll event. */
148905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey    private static final int FLAG_PERSIST_NETWORK = 0x1;
149905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey    private static final int FLAG_PERSIST_UID = 0x2;
150b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
1511f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey    private static final int FLAG_PERSIST_FORCE = 0x100;
1523f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
153163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey    private static final String TAG_NETSTATS_ERROR = "netstats_error";
154163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
15575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Context mContext;
15675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final INetworkManagementService mNetworkManager;
15775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final IAlarmManager mAlarmManager;
15875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final TrustedTime mTime;
159367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private final TelephonyManager mTeleManager;
16039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    private final NetworkStatsSettings mSettings;
16175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
16263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final File mSystemDir;
16363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final File mBaseDir;
16463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1656248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey    private final PowerManager.WakeLock mWakeLock;
1666248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey
167d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    private IConnectivityManager mConnManager;
168d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
1698b2c3a14603d163d7564e6f60286995079687690Jeff Sharkey    @VisibleForTesting
1703f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    public static final String ACTION_NETWORK_STATS_POLL =
17175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            "com.android.server.action.NETWORK_STATS_POLL";
172497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey    public static final String ACTION_NETWORK_STATS_UPDATED =
173497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey            "com.android.server.action.NETWORK_STATS_UPDATED";
17475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
17575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private PendingIntent mPollIntent;
17675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
17763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_DEV = "dev";
178e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    private static final String PREFIX_XT = "xt";
17963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_UID = "uid";
18063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static final String PREFIX_UID_TAG = "uid_tag";
18163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
18239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    /**
18339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * Settings that can be changed externally.
18439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
18539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    public interface NetworkStatsSettings {
18639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getPollInterval();
18739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getTimeCacheMaxAge();
18863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public boolean getSampleEnabled();
18970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        public boolean getReportXtOverDev();
19063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
19163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public static class Config {
19263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long bucketDuration;
19363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long rotateAgeMillis;
19463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            public final long deleteAgeMillis;
19563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
196ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey            public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
19763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.bucketDuration = bucketDuration;
19863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.rotateAgeMillis = rotateAgeMillis;
19963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                this.deleteAgeMillis = deleteAgeMillis;
20063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
20163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        }
20263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
20363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getDevConfig();
204e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        public Config getXtConfig();
20563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidConfig();
20663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidTagConfig();
207ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
208ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getGlobalAlertBytes(long def);
209ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getDevPersistBytes(long def);
210ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getXtPersistBytes(long def);
211ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getUidPersistBytes(long def);
212ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getUidTagPersistBytes(long def);
21339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    }
21475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
21575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Object mStatsLock = new Object();
21675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
2171b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /** Set of currently active ifaces. */
2181b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
21963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    /** Current default active iface. */
22063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private String mActiveIface;
221234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    /** Set of any ifaces associated with mobile networks since boot. */
222234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    private String[] mMobileIfaces = new String[0];
22363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
22463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
22563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            new DropBoxNonMonotonicObserver();
22663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
22763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mDevRecorder;
228e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey    private NetworkStatsRecorder mXtRecorder;
22963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mUidRecorder;
23063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder mUidTagRecorder;
23163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
23263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    /** Cached {@link #mDevRecorder} stats. */
23363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsCollection mDevStatsCached;
23470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    /** Cached {@link #mXtRecorder} stats. */
23570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    private NetworkStatsCollection mXtStatsCached;
23675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
237b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    /** Current counter sets for each UID. */
238b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
239b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
240a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    /** Data layer operation counters for splicing into other structures. */
24163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats mUidOperations = new NetworkStats(0L, 10);
242a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
24375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final HandlerThread mHandlerThread;
24475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private final Handler mHandler;
24575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
2466341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey    private boolean mSystemReady;
247ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    private long mPersistThreshold = 2 * MB_IN_BYTES;
248ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    private long mGlobalAlertBytes;
2496341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
25075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public NetworkStatsService(
25175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            Context context, INetworkManagementService networkManager, IAlarmManager alarmManager) {
252104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey        this(context, networkManager, alarmManager, NtpTrustedTime.getInstance(context),
25363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                getDefaultSystemDir(), new DefaultNetworkStatsSettings(context));
2543f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    }
2553f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
25663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private static File getDefaultSystemDir() {
2573f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        return new File(Environment.getDataDirectory(), "system");
25875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
25975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
26075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public NetworkStatsService(Context context, INetworkManagementService networkManager,
26139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            IAlarmManager alarmManager, TrustedTime time, File systemDir,
26239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            NetworkStatsSettings settings) {
26375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mContext = checkNotNull(context, "missing Context");
26475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
26575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mAlarmManager = checkNotNull(alarmManager, "missing IAlarmManager");
26675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mTime = checkNotNull(time, "missing TrustedTime");
267367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        mTeleManager = checkNotNull(TelephonyManager.getDefault(), "missing TelephonyManager");
26839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
26975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
2706248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey        final PowerManager powerManager = (PowerManager) context.getSystemService(
2716248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                Context.POWER_SERVICE);
2726248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
2736248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey
27475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mHandlerThread = new HandlerThread(TAG);
27575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mHandlerThread.start();
276b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        mHandler = new Handler(mHandlerThread.getLooper(), mHandlerCallback);
2773f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
27863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mSystemDir = checkNotNull(systemDir);
27963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mBaseDir = new File(systemDir, "netstats");
28063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mBaseDir.mkdirs();
28175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
28275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
28321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    public void bindConnectivityManager(IConnectivityManager connManager) {
28421c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
28521c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    }
28621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey
28775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    public void systemReady() {
2886341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        mSystemReady = true;
2896341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
290418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        if (!isBandwidthControlEnabled()) {
291418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
292418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return;
293418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        }
294418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey
29563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // create data recorders along with historical rotators
29663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
297e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
29863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
29963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
30063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
301ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        updatePersistThresholds();
302ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
3033f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        synchronized (mStatsLock) {
30463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // upgrade any legacy stats, migrating them to rotated files
30563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            maybeUpgradeLegacyStatsLocked();
30663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
30739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            // read historical network stats from disk, since policy service
30863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // might need them right away.
30963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevStatsCached = mDevRecorder.getOrLoadCompleteLocked();
31070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
31175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
31263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // bootstrap initial stats to prevent double-counting later
31363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            bootstrapStatsLocked();
31463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        }
3153359aca7655a7d18615c1ada6cbabeff403947d1Jeff Sharkey
31621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        // watch for network interfaces to be claimed
317961e30458319cfd50e1892ba7dd14a1d0ebe4cc7Jeff Sharkey        final IntentFilter connFilter = new IntentFilter(CONNECTIVITY_ACTION_IMMEDIATE);
318b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mConnReceiver, connFilter, CONNECTIVITY_INTERNAL, mHandler);
31975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
320cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        // watch for tethering changes
321cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
322cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        mContext.registerReceiver(mTetherReceiver, tetherFilter, CONNECTIVITY_INTERNAL, mHandler);
323cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
32475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // listen for periodic polling events
32575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
32621c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey        mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
32775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
328b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        // listen for uid removal to clean stats
329b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
330b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
331b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
332daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        // listen for user changes to clean stats
333daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
334daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
335daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
33675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // persist stats during clean shutdown
337b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
338b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
33975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
34075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        try {
3418e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mNetworkManager.registerObserver(mAlertObserver);
34275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        } catch (RemoteException e) {
343b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
34475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
345b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
346367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        // watch for networkType changes that aren't broadcast through
347367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        // CONNECTIVITY_ACTION_IMMEDIATE above.
348d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (!COMBINE_SUBTYPE_ENABLED) {
349d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            mTeleManager.listen(mPhoneListener, LISTEN_DATA_CONNECTION_STATE);
350d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
351367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
3528e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        registerPollAlarmLocked();
3538e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        registerGlobalAlert();
35463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    }
3558e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
35663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStatsRecorder buildRecorder(
35763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
3586de357e4d10fa5977ab9a6c665dc858765e95d34Jeff Sharkey        final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
3596de357e4d10fa5977ab9a6c665dc858765e95d34Jeff Sharkey                Context.DROPBOX_SERVICE);
360ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        return new NetworkStatsRecorder(new FileRotator(
361ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
3626de357e4d10fa5977ab9a6c665dc858765e95d34Jeff Sharkey                mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
36375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
36475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
3653f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    private void shutdownLocked() {
366b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.unregisterReceiver(mConnReceiver);
367367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        mContext.unregisterReceiver(mTetherReceiver);
3683f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        mContext.unregisterReceiver(mPollReceiver);
369b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        mContext.unregisterReceiver(mRemovedReceiver);
3703f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey        mContext.unregisterReceiver(mShutdownReceiver);
3713f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
372d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        if (!COMBINE_SUBTYPE_ENABLED) {
373d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey            mTeleManager.listen(mPhoneListener, LISTEN_NONE);
374d4dd7716fb825f29a609c5c4cb31204eea78183aJeff Sharkey        }
375367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
37663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
37763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                : System.currentTimeMillis();
37863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
37963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // persist any pending stats
38063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder.forcePersistLocked(currentTime);
381e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        mXtRecorder.forcePersistLocked(currentTime);
38263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder.forcePersistLocked(currentTime);
38363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder.forcePersistLocked(currentTime);
38463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
38563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevRecorder = null;
386e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        mXtRecorder = null;
38763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidRecorder = null;
38863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mUidTagRecorder = null;
38963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
39063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mDevStatsCached = null;
39170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        mXtStatsCached = null;
3926341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
3936341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        mSystemReady = false;
39463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    }
39563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
39663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void maybeUpgradeLegacyStatsLocked() {
39763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        File file;
39863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        try {
39963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats.bin");
40063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
40163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mDevRecorder.importLegacyNetworkLocked(file);
40263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
40363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
40463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
40563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats_xt.bin");
40663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
40763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
40863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
40963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
41063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            file = new File(mSystemDir, "netstats_uid.bin");
41163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (file.exists()) {
41263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.importLegacyUidLocked(file);
41363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.importLegacyUidLocked(file);
41463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                file.delete();
41563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
41663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        } catch (IOException e) {
41763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            Log.wtf(TAG, "problem during legacy upgrade", e);
418af8339374fbf1e2f57b0be918c7fc772f4250f13Jeff Sharkey        }
4193f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey    }
4203f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
42175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
42275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
42339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
42475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
4258e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private void registerPollAlarmLocked() {
4268e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
4278e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            if (mPollIntent != null) {
4288e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                mAlarmManager.remove(mPollIntent);
4298e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
43075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
4318e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mPollIntent = PendingIntent.getBroadcast(
4328e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                    mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
43375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
4348e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            final long currentRealtime = SystemClock.elapsedRealtime();
4358e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
4368e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                    mSettings.getPollInterval(), mPollIntent);
4378e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
438b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
4398e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
4408e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
4418e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
4428e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
4438e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Register for a global alert that is delivered through
4448e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * {@link INetworkManagementEventObserver} once a threshold amount of data
4458e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * has been transferred.
4468e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
4478e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    private void registerGlobalAlert() {
4488e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
449ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey            mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
4508e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (IllegalStateException e) {
4518e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.w(TAG, "problem registering for global alert: " + e);
4528e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
453b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
4548e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
45575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
45675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
45775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    @Override
458b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey    public INetworkStatsSession openSession() {
459b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
4604190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
461d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
462b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        // return an IBinder which holds strong references to any loaded stats
463b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        // for its lifetime; when caller closes only weak references remain.
46475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
465b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        return new INetworkStatsSession.Stub() {
466b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection mUidComplete;
467b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection mUidTagComplete;
468b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
469b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection getUidComplete() {
470b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (mUidComplete == null) {
471ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                    synchronized (mStatsLock) {
472ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                        mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
473ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                    }
474b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
475b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mUidComplete;
476b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
477b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
478b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            private NetworkStatsCollection getUidTagComplete() {
479b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (mUidTagComplete == null) {
480ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                    synchronized (mStatsLock) {
481ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                        mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
482ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                    }
483b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
484b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return mUidTagComplete;
485b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
486b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
487b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
488b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStats getSummaryForNetwork(
489b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, long start, long end) {
49070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey                return internalGetSummaryForNetwork(template, start, end);
491b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
492b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
493b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
494b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
49570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey                return internalGetHistoryForNetwork(template, fields);
496b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
497b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
498b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
499b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStats getSummaryForAllUid(
500b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, long start, long end, boolean includeTags) {
501b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                final NetworkStats stats = getUidComplete().getSummary(template, start, end);
502b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (includeTags) {
503b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    final NetworkStats tagStats = getUidTagComplete()
504b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                            .getSummary(template, start, end);
505b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    stats.combineAllValues(tagStats);
506b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
507b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                return stats;
508b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
509b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
510b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
511b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public NetworkStatsHistory getHistoryForUid(
512b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    NetworkTemplate template, int uid, int set, int tag, int fields) {
513b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                if (tag == TAG_NONE) {
514b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    return getUidComplete().getHistory(template, uid, set, tag, fields);
515b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                } else {
516b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                    return getUidTagComplete().getHistory(template, uid, set, tag, fields);
517b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                }
518b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
519b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey
520b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            @Override
521b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            public void close() {
522b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                mUidComplete = null;
523b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey                mUidTagComplete = null;
524b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey            }
525b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        };
526684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey    }
527684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
52870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    /**
52970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey     * Return network summary, splicing between {@link #mDevStatsCached}
53070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey     * and {@link #mXtStatsCached} when appropriate.
53170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey     */
53270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    private NetworkStats internalGetSummaryForNetwork(
53370c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            NetworkTemplate template, long start, long end) {
53470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        if (!mSettings.getReportXtOverDev()) {
53570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            // shortcut when XT reporting disabled
53670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            return mDevStatsCached.getSummary(template, start, end);
53770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        }
53870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
53970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        // splice stats between DEV and XT, switching over from DEV to XT at
54070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        // first atomic bucket.
54170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        final long firstAtomicBucket = mXtStatsCached.getFirstAtomicBucketMillis();
54270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        final NetworkStats dev = mDevStatsCached.getSummary(
54370c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey                template, Math.min(start, firstAtomicBucket), Math.min(end, firstAtomicBucket));
54470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        final NetworkStats xt = mXtStatsCached.getSummary(
54570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey                template, Math.max(start, firstAtomicBucket), Math.max(end, firstAtomicBucket));
54670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
54770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        xt.combineAllValues(dev);
54870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        return xt;
54970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    }
55070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
55170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    /**
55270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey     * Return network history, splicing between {@link #mDevStatsCached}
55370c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey     * and {@link #mXtStatsCached} when appropriate.
55470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey     */
55570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template, int fields) {
55670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        if (!mSettings.getReportXtOverDev()) {
55770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            // shortcut when XT reporting disabled
55870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey            return mDevStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields);
55970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        }
56070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
56170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        // splice stats between DEV and XT, switching over from DEV to XT at
56270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        // first atomic bucket.
56370c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        final long firstAtomicBucket = mXtStatsCached.getFirstAtomicBucketMillis();
56470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        final NetworkStatsHistory dev = mDevStatsCached.getHistory(
56570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey                template, UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, firstAtomicBucket);
56670c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        final NetworkStatsHistory xt = mXtStatsCached.getHistory(
56770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey                template, UID_ALL, SET_ALL, TAG_NONE, fields, firstAtomicBucket, Long.MAX_VALUE);
56870c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
56970c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        xt.recordEntireHistory(dev);
57070c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        return xt;
57170c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey    }
57270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey
57321c9c45e5caf62b935354b74392fb40c4bf18529Jeff Sharkey    @Override
574b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey    public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
575b52e3e55098c4a6e3dbfe19885895411cfb38911Jeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
5764190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
57770c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        return internalGetSummaryForNetwork(template, start, end).getTotalBytes();
578d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
579d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
580350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    @Override
581a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
582a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        if (Binder.getCallingUid() != uid) {
583a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
584a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
5854190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
586a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
587a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        // TODO: switch to data layer stats once kernel exports
588a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        // for now, read network layer stats and flatten across all ifaces
5894529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        final long token = Binder.clearCallingIdentity();
5904529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        final NetworkStats networkLayer;
5914529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        try {
5924529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey            networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid);
5934529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        } finally {
5944529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey            Binder.restoreCallingIdentity(token);
5954529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey        }
5964529bb66c47fd02b990ecb0810031157b4f36c2fJeff Sharkey
59721a547823de52806de48f70b8360353344a5ad88Jeff Sharkey        // splice in operation counts
59821a547823de52806de48f70b8360353344a5ad88Jeff Sharkey        networkLayer.spliceOperationsFrom(mUidOperations);
59921a547823de52806de48f70b8360353344a5ad88Jeff Sharkey
600a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        final NetworkStats dataLayer = new NetworkStats(
601a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey                networkLayer.getElapsedRealtime(), networkLayer.size());
602a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
603a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        NetworkStats.Entry entry = null;
604a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        for (int i = 0; i < networkLayer.size(); i++) {
605a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            entry = networkLayer.getValues(i, entry);
606a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            entry.iface = IFACE_ALL;
607a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            dataLayer.combineValues(entry);
608a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
609a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
610a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        return dataLayer;
611a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    }
612a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
613a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    @Override
614234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    public String[] getMobileIfaces() {
615234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        return mMobileIfaces;
616234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    }
617234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
618234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey    @Override
619a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    public void incrementOperationCount(int uid, int tag, int operationCount) {
620a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        if (Binder.getCallingUid() != uid) {
621a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey            mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
622a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
623a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
624b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        if (operationCount < 0) {
625b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            throw new IllegalArgumentException("operation count can only be incremented");
626b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
627b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        if (tag == TAG_NONE) {
628b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            throw new IllegalArgumentException("operation count must have specific tag");
629b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
630b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
631a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        synchronized (mStatsLock) {
632b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
63363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidOperations.combineValues(
63463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
63563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidOperations.combineValues(
63663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
637b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
638b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    }
639b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
640b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    @Override
641b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    public void setUidForeground(int uid, boolean uidForeground) {
642b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
643b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
644b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        synchronized (mStatsLock) {
645b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
646b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
647b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            if (oldSet != set) {
648b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                mActiveUidCounterSet.put(uid, set);
649b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                setKernelCounterSet(uid, set);
650b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            }
651a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey        }
652a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    }
653a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey
654a63ba59260cd1bb3f5c16e395ace45a61f1d4461Jeff Sharkey    @Override
655350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    public void forceUpdate() {
656350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey        mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
6574190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        assertBandwidthControlEnabled();
658e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey
659e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        final long token = Binder.clearCallingIdentity();
660e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        try {
661e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey            performPoll(FLAG_PERSIST_ALL);
662e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        } finally {
663e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey            Binder.restoreCallingIdentity(token);
664e630f7b31bb1e77a2eb4ef3102a25f2927cfd5c3Jeff Sharkey        }
665350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey    }
666350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
667ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    @Override
668ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    public void advisePersistThreshold(long thresholdBytes) {
669ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
670ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        assertBandwidthControlEnabled();
671ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
672ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        // clamp threshold into safe range
673ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
674ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        if (LOGV) {
675ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey            Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
676ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                    + mPersistThreshold);
677ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        }
678ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
67920f5c3d4135809ca0b72c23e0c8daf2a8e4e84b2Jeff Sharkey        // update and persist if beyond new thresholds
680ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
681ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey                : System.currentTimeMillis();
6825801597a90949240e99c3980c0bb889deeec2e5cJeff Sharkey        synchronized (mStatsLock) {
68320f5c3d4135809ca0b72c23e0c8daf2a8e4e84b2Jeff Sharkey            if (!mSystemReady) return;
68420f5c3d4135809ca0b72c23e0c8daf2a8e4e84b2Jeff Sharkey
68520f5c3d4135809ca0b72c23e0c8daf2a8e4e84b2Jeff Sharkey            updatePersistThresholds();
68620f5c3d4135809ca0b72c23e0c8daf2a8e4e84b2Jeff Sharkey
6875801597a90949240e99c3980c0bb889deeec2e5cJeff Sharkey            mDevRecorder.maybePersistLocked(currentTime);
6885801597a90949240e99c3980c0bb889deeec2e5cJeff Sharkey            mXtRecorder.maybePersistLocked(currentTime);
6895801597a90949240e99c3980c0bb889deeec2e5cJeff Sharkey            mUidRecorder.maybePersistLocked(currentTime);
6905801597a90949240e99c3980c0bb889deeec2e5cJeff Sharkey            mUidTagRecorder.maybePersistLocked(currentTime);
6915801597a90949240e99c3980c0bb889deeec2e5cJeff Sharkey        }
692ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
693ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        // re-arm global alert
694ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        registerGlobalAlert();
695ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    }
696ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
697ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    /**
698ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey     * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
699ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey     * reflect current {@link #mPersistThreshold} value. Always defers to
700625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey     * {@link Global} values when defined.
701ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey     */
702ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    private void updatePersistThresholds() {
703ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
704ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
705ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
706ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
707ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
708ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey    }
709ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey
71075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
711d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * Receiver that watches for {@link IConnectivityManager} to claim network
71275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * interfaces. Used to associate {@link TelephonyManager#getSubscriberId()}
71375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     * with mobile interfaces.
71475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
715b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
71675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
71775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
718d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // on background handler thread, and verified CONNECTIVITY_INTERNAL
719d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // permission above.
720367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            updateIfaces();
72175279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
72275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
72375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
724cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    /**
725cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey     * Receiver that watches for {@link Tethering} to claim interface pairs.
726cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey     */
727cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
728cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        @Override
729cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        public void onReceive(Context context, Intent intent) {
730cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey            // on background handler thread, and verified CONNECTIVITY_INTERNAL
731cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey            // permission above.
7321f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey            performPoll(FLAG_PERSIST_NETWORK);
733cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey        }
734cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey    };
735cdd02c5d76d3dd4e21b5bb922d7fcfb86efec85fJeff Sharkey
73675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
73775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
73875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
739d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // on background handler thread, and verified UPDATE_DEVICE_STATS
740d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            // permission above.
7411f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey            performPoll(FLAG_PERSIST_ALL);
7428e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
7438e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            // verify that we're watching global alert
7448e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            registerGlobalAlert();
74575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
74675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
74775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
748b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
749b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        @Override
750b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        public void onReceive(Context context, Intent intent) {
751b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // on background handler thread, and UID_REMOVED is protected
752b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // broadcast.
753daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
754daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            final int uid = intent.getIntExtra(EXTRA_UID, -1);
755daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            if (uid == -1) return;
756daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
757daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            synchronized (mStatsLock) {
758daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                mWakeLock.acquire();
759daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                try {
760daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                    removeUidsLocked(uid);
761daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                } finally {
762daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                    mWakeLock.release();
763daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                }
764daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            }
765daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        }
766daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey    };
767daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
768daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey    private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
769daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        @Override
770daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        public void onReceive(Context context, Intent intent) {
771daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            // On background handler thread, and USER_REMOVED is protected
772daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            // broadcast.
773daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
774daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
775daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            if (userId == -1) return;
776daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
777b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            synchronized (mStatsLock) {
7786248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                mWakeLock.acquire();
7796248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                try {
780daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                    removeUserLocked(userId);
7816248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                } finally {
7826248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                    mWakeLock.release();
7836248926e199dca9bde3c76c5f82c486c293cdcddJeff Sharkey                }
784b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            }
785b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey        }
786b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey    };
787b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey
78875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
78975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        @Override
79075279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        public void onReceive(Context context, Intent intent) {
791b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey            // SHUTDOWN is protected broadcast.
79275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            synchronized (mStatsLock) {
7933f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                shutdownLocked();
79475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey            }
79575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
79675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    };
79775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
798d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    /**
7998e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Observer that watches for {@link INetworkManagementService} alerts.
8008e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
801216c181e76ee11a47a0b2a180f9af96740ab38adJeff Sharkey    private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
8028e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        @Override
8038e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        public void limitReached(String limitName, String iface) {
8048e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            // only someone like NMS should be calling us
8058e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
8068e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
8078e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
8088e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // kick off background poll to collect network stats; UID stats
8098e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // are handled during normal polling interval.
8101f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey                final int flags = FLAG_PERSIST_NETWORK;
811b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget();
8128e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
8138e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                // re-arm global alert for next update
81425ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                mHandler.obtainMessage(MSG_REGISTER_GLOBAL_ALERT).sendToTarget();
8158e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
8168e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
8178e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    };
8188e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
819367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private int mLastPhoneState = TelephonyManager.DATA_UNKNOWN;
820367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private int mLastPhoneNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
821367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
822367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    /**
823367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     * Receiver that watches for {@link TelephonyManager} changes, such as
824367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     * transitioning between network types.
825367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey     */
826367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private PhoneStateListener mPhoneListener = new PhoneStateListener() {
827367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        @Override
828367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        public void onDataConnectionStateChanged(int state, int networkType) {
829367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            final boolean stateChanged = state != mLastPhoneState;
830367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            final boolean networkTypeChanged = networkType != mLastPhoneNetworkType;
831367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
832367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            if (networkTypeChanged && !stateChanged) {
833367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // networkType changed without a state change, which means we
834367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // need to roll our own update. delay long enough for
835367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // ConnectivityManager to process.
836367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // TODO: add direct event to ConnectivityService instead of
837367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                // relying on this delay.
838367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                if (LOGV) Slog.v(TAG, "triggering delayed updateIfaces()");
839367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                mHandler.sendMessageDelayed(
840367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                        mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS);
841367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            }
842367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
843367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mLastPhoneState = state;
844367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mLastPhoneNetworkType = networkType;
845367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        }
846367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    };
847367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
848367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    private void updateIfaces() {
849367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        synchronized (mStatsLock) {
850367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            mWakeLock.acquire();
851367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            try {
852367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                updateIfacesLocked();
853367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            } finally {
854367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                mWakeLock.release();
855367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey            }
856367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey        }
857367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey    }
858367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
8598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
860d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * Inspect all current {@link NetworkState} to derive mapping from {@code
861d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
862d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     * are active on a single {@code iface}, they are combined under a single
8631b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey     * {@link NetworkIdentitySet}.
864d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey     */
865d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    private void updateIfacesLocked() {
8666341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        if (!mSystemReady) return;
86739ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
868d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
869d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // take one last stats snapshot before updating iface mapping. this
870d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // isn't perfect, since the kernel may already be counting traffic from
871d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // the updated network.
872b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
8731f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        // poll, but only persist network stats to keep codepath fast. UID stats
8741f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        // will be persisted during next alarm poll event.
8751f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        performPollLocked(FLAG_PERSIST_NETWORK);
876d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
877d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        final NetworkState[] states;
87863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final LinkProperties activeLink;
879d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        try {
880d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            states = mConnManager.getAllNetworkState();
88163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            activeLink = mConnManager.getActiveLinkProperties();
882d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        } catch (RemoteException e) {
883b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
884d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            return;
885d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
886d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
88763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
88863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
889d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        // rebuild active interfaces based on connected networks
8901b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey        mActiveIfaces.clear();
891d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
892d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        for (NetworkState state : states) {
893d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            if (state.networkInfo.isConnected()) {
894d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                // collect networks under their parent interfaces
895d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                final String iface = state.linkProperties.getInterfaceName();
8961b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
8971b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                NetworkIdentitySet ident = mActiveIfaces.get(iface);
8981b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                if (ident == null) {
8991b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    ident = new NetworkIdentitySet();
9001b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                    mActiveIfaces.put(iface, ident);
9011b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                }
9021b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey
903d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey                ident.add(NetworkIdentity.buildNetworkIdentity(mContext, state));
904234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey
905234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                // remember any ifaces associated with mobile networks
9066a328afbab37981f34d8578972dbb2bf1abb7c41Jeff Sharkey                if (isNetworkTypeMobile(state.networkInfo.getType()) && iface != null) {
907234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                    if (!contains(mMobileIfaces, iface)) {
908234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                        mMobileIfaces = appendElement(String.class, mMobileIfaces, iface);
909234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                    }
910234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey                }
911d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey            }
912d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey        }
913d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey    }
914d2a458750e5a3d490af09cecb5c28370baf0a913Jeff Sharkey
91539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    /**
9168e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
9178e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     * so we have baseline values without double-counting.
9188e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey     */
91963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void bootstrapStatsLocked() {
92063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
92163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                : System.currentTimeMillis();
92263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
9238e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        try {
92463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // snapshot and record current counters; read UID stats first to
92563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // avoid overcounting dev stats.
92663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
927e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
928e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
92963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
93063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
931e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
93263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
93363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
93463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
9358e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (IllegalStateException e) {
9368e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.w(TAG, "problem reading network stats: " + e);
9378e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        } catch (RemoteException e) {
938b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
9398e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
9408e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
9418e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
942b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private void performPoll(int flags) {
9438e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        synchronized (mStatsLock) {
9448e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            mWakeLock.acquire();
945684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
946684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            // try refreshing time source when stale
947684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
948684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey                mTime.forceRefresh();
949684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey            }
950684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
9518e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            try {
952b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                performPollLocked(flags);
9538e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            } finally {
9548e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                mWakeLock.release();
9558e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            }
9568e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
9578e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    }
9588e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
9598e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey    /**
96039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * Periodic poll operation, reading current statistics and recording into
96139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     * {@link NetworkStatsHistory}.
96239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
963b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey    private void performPollLocked(int flags) {
9646341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey        if (!mSystemReady) return;
965b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
9666341fcecc8826924a4bb24169aaf80fec9a20894Jeff Sharkey
9678e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        final long startRealtime = SystemClock.elapsedRealtime();
96875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
969b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
970b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
9711f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey        final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
972b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey
97375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        // TODO: consider marking "untrusted" times in historical stats
97475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
97575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey                : System.currentTimeMillis();
97675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
97775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        try {
97863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // snapshot and record current counters; read UID stats first to
97963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // avoid overcounting dev stats.
98063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
981e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
982e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
9831f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey
98463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
985e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
98663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
98763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveIfaces, currentTime);
988367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey
989b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        } catch (IllegalStateException e) {
990b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            Log.wtf(TAG, "problem reading network stats", e);
991905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            return;
992b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey        } catch (RemoteException e) {
993b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey            // ignored; service lives in system_server
994905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            return;
995905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        }
996905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey
99763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // persist any pending data depending on requested flags
99863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        if (persistForce) {
99963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.forcePersistLocked(currentTime);
1000e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            mXtRecorder.forcePersistLocked(currentTime);
100163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidRecorder.forcePersistLocked(currentTime);
100263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mUidTagRecorder.forcePersistLocked(currentTime);
100363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        } else {
100463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (persistNetwork) {
100563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mDevRecorder.maybePersistLocked(currentTime);
1006e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey                mXtRecorder.maybePersistLocked(currentTime);
100763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
100863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (persistUid) {
100963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.maybePersistLocked(currentTime);
101063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.maybePersistLocked(currentTime);
101163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            }
101261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        }
1013497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey
10148e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        if (LOGV) {
10158e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            final long duration = SystemClock.elapsedRealtime() - startRealtime;
10168e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey            Slog.v(TAG, "performPollLocked() took " + duration + "ms");
10178e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey        }
10188e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey
101963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        if (mSettings.getSampleEnabled()) {
1020905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey            // sample stats after each full poll
102163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            performSampleLocked();
1022905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        }
102307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
1024497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        // finally, dispatch updated event to any listeners
1025497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
1026497e4437af386930dff3bd55296d128bd4520959Jeff Sharkey        updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10275ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn        mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
10285ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn                READ_NETWORK_USAGE_HISTORY);
102961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    }
103061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
103161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    /**
103207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey     * Sample recent statistics summary into {@link EventLog}.
103307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey     */
103463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private void performSampleLocked() {
103563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // TODO: migrate trustedtime fixes to separate binary log events
1036905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
1037905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey
103863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkTemplate template;
103963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry devTotal;
104063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry xtTotal;
104163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        NetworkStats.Entry uidTotal;
104207b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
104307b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        // collect mobile sample
1044234766a36af6214644fa8205202287084ca9cf93Jeff Sharkey        template = buildTemplateMobileWildcard();
104563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
1046e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
104763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1048684c54a2eb860062f1960f4eba6bc71aa1cfa71dJeff Sharkey
1049905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        EventLogTags.writeNetstatsMobileSample(
1050905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1051905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1052905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
105363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                trustedTime);
105407b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
105507b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey        // collect wifi sample
10568fc27e8b87bd1def854a03d84009143b315d4176Jeff Sharkey        template = buildTemplateWifiWildcard();
105763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        devTotal = mDevRecorder.getTotalSinceBootLocked(template);
1058e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
105963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
106063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1061905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey        EventLogTags.writeNetstatsWifiSample(
1062905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1063905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1064905b5891d2aa802f447ac2ce5d77b6c5ba06277aJeff Sharkey                uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
106563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                trustedTime);
106607b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    }
106707b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey
106807b0dd9a092273f0451cd9881312cb9b22a7af3fJeff Sharkey    /**
106963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * Clean up {@link #mUidRecorder} after UID is removed.
1070b09540f33a6cabe50edec0ef32d0b1d0b0d96fffJeff Sharkey     */
1071daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey    private void removeUidsLocked(int... uids) {
1072daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1073daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
1074daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        // Perform one last poll before removing
1075163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey        performPollLocked(FLAG_PERSIST_ALL);
1076163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
1077daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        mUidRecorder.removeUidsLocked(uids);
1078daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        mUidTagRecorder.removeUidsLocked(uids);
1079daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
1080daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        // Clear kernel stats associated with UID
1081daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        for (int uid : uids) {
1082daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            resetKernelUidStats(uid);
1083daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        }
1084daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey    }
1085daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
1086daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey    /**
1087daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey     * Clean up {@link #mUidRecorder} after user is removed.
1088daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey     */
1089daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey    private void removeUserLocked(int userId) {
1090daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1091daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey
1092daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        // Build list of UIDs that we should clean up
1093daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        int[] uids = new int[0];
1094daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
1095daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey                PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS);
1096daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        for (ApplicationInfo app : apps) {
1097daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            final int uid = UserHandle.getUid(userId, app.uid);
1098daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey            uids = ArrayUtils.appendInt(uids, uid);
1099daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        }
1100163e6443f27884a9bfcb9a48ef606dc635852c23Jeff Sharkey
1101daa57e8d1866fe4579c280c41604f3660db7cd01Jeff Sharkey        removeUidsLocked(uids);
110275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
110375279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
110475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    @Override
110563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
110675279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        mContext.enforceCallingOrSelfPermission(DUMP, TAG);
110775279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
110861ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        final HashSet<String> argSet = new HashSet<String>();
110961ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        for (String arg : args) {
111061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            argSet.add(arg);
111161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey        }
111261ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
1113706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey        // usage: dumpsys netstats --full --uid --tag --poll --checkin
111463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
1115706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey        final boolean checkin = argSet.contains("--checkin");
111663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
111763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
111863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1119350083e36b9db6062e165954403ef921ff3dfdadJeff Sharkey
112063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
112161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
112263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        synchronized (mStatsLock) {
112363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (poll) {
11241f0b13b9d64085dd8342ba942f39b6063b6d534dJeff Sharkey                performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
11253f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                pw.println("Forced poll");
11263f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey                return;
11273f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey            }
11283f3913550c10792edb8aecf66cc83c3db5c8b311Jeff Sharkey
1129706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey            if (checkin) {
1130706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                // list current stats files to verify rotation
1131706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.println("Current files:");
1132706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.increaseIndent();
1133706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                for (String file : mBaseDir.list()) {
1134706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                    pw.println(file);
1135706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                }
1136706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                pw.decreaseIndent();
1137706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey                return;
1138706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey            }
1139706498d387eaceb574cf4aa982fee3c288819dadJeff Sharkey
114061ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            pw.println("Active interfaces:");
114163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.increaseIndent();
11421b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey            for (String iface : mActiveIfaces.keySet()) {
11431b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey                final NetworkIdentitySet ident = mActiveIfaces.get(iface);
114463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.print("iface="); pw.print(iface);
114561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey                pw.print(" ident="); pw.println(ident.toString());
114661ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
114763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.decreaseIndent();
114863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
114963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.println("Dev stats:");
115063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.increaseIndent();
115163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            mDevRecorder.dumpLocked(pw, fullHistory);
115263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            pw.decreaseIndent();
115363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
1154e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            pw.println("Xt stats:");
1155e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            pw.increaseIndent();
1156e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            mXtRecorder.dumpLocked(pw, fullHistory);
1157e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            pw.decreaseIndent();
1158e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey
115963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (includeUid) {
116063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.println("UID stats:");
116163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.increaseIndent();
116263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidRecorder.dumpLocked(pw, fullHistory);
116363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.decreaseIndent();
116461ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
116561ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey
116663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            if (includeTag) {
116763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.println("UID tag stats:");
116863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.increaseIndent();
116963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                mUidTagRecorder.dumpLocked(pw, fullHistory);
117063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                pw.decreaseIndent();
117161ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey            }
117275279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey        }
117361ee0bbb5b87fb5c4c3dc219868d52743def3d2bJeff Sharkey    }
117475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
117575279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    /**
117663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * Return snapshot of current UID statistics, including any
117763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey     * {@link TrafficStats#UID_TETHERING} and {@link #mUidOperations} values.
117875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey     */
117963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private NetworkStats getNetworkStatsUidDetail() throws RemoteException {
118063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
118163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
118263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        // fold tethering stats and operations into uid snapshot
118363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        final NetworkStats tetherSnapshot = getNetworkStatsTethering();
118463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidSnapshot.combineAllValues(tetherSnapshot);
118563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        uidSnapshot.combineAllValues(mUidOperations);
118663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey
118763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        return uidSnapshot;
118875279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey    }
118975279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey
1190d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    /**
1191d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     * Return snapshot of current tethering statistics. Will return empty
1192d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     * {@link NetworkStats} if any problems are encountered.
1193d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey     */
1194d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    private NetworkStats getNetworkStatsTethering() throws RemoteException {
1195d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        try {
1196d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            final String[] tetheredIfacePairs = mConnManager.getTetheredIfacePairs();
1197d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            return mNetworkManager.getNetworkStatsTethering(tetheredIfacePairs);
1198d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        } catch (IllegalStateException e) {
1199d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            Log.wtf(TAG, "problem reading network stats", e);
1200d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey            return new NetworkStats(0L, 10);
1201d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey        }
1202d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey    }
1203d4ef8c8fc9ea70448e5d8138bf8bc96f4e69903fJeff Sharkey
1204b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    private Handler.Callback mHandlerCallback = new Handler.Callback() {
1205bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
1206b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        public boolean handleMessage(Message msg) {
1207b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            switch (msg.what) {
12088e9992ae5053a3ac52d28a5a892aed0a0798c7abJeff Sharkey                case MSG_PERFORM_POLL: {
1209b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                    final int flags = msg.arg1;
1210b3d5957604f8fcaafe72bd76052bc76b682bf443Jeff Sharkey                    performPoll(flags);
1211b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                    return true;
1212b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                }
1213367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                case MSG_UPDATE_IFACES: {
1214367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                    updateIfaces();
1215367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                    return true;
1216367d15ab1a33b6159447fa8542d4fa8ff148371cJeff Sharkey                }
121725ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                case MSG_REGISTER_GLOBAL_ALERT: {
121825ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                    registerGlobalAlert();
121925ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                    return true;
122025ce9ed57f137dc0b21045ab90fe595640ebf926Jeff Sharkey                }
1221b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                default: {
1222b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                    return false;
1223b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey                }
1224b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey            }
1225b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
1226b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    };
1227b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
12284190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey    private void assertBandwidthControlEnabled() {
12294190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        if (!isBandwidthControlEnabled()) {
12304190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey            throw new IllegalStateException("Bandwidth module disabled");
12314190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey        }
12324190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey    }
12334190a047ca1c5eb19a1f7e5d599ef1d532da71c7Jeff Sharkey
1234418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey    private boolean isBandwidthControlEnabled() {
123549c1d1764bce02cf12a68e9312f3aa9dfa2e25ceJeff Sharkey        final long token = Binder.clearCallingIdentity();
1236418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        try {
1237418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return mNetworkManager.isBandwidthControlEnabled();
1238418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        } catch (RemoteException e) {
1239418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            // ignored; service lives in system_server
1240418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey            return false;
124149c1d1764bce02cf12a68e9312f3aa9dfa2e25ceJeff Sharkey        } finally {
124249c1d1764bce02cf12a68e9312f3aa9dfa2e25ceJeff Sharkey            Binder.restoreCallingIdentity(token);
1243418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey        }
1244418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey    }
1245418d12dc8f2c518b673ebc522de4af6f7dbf0bf3Jeff Sharkey
124663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey    private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
1247bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
124863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
124963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                int rightIndex, String cookie) {
125063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            Log.w(TAG, "found non-monotonic values; saving to dropbox");
1251b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
125263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            // record error for debugging
125363abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final StringBuilder builder = new StringBuilder();
125463abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
125563abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    + "] - right[" + rightIndex + "]\n");
125663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("left=").append(left).append('\n');
125763abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            builder.append("right=").append(right).append('\n');
1258b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
125963abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
126063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey                    Context.DROPBOX_SERVICE);
126163abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey            dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
1262b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey        }
1263b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey    }
1264b5d55e302d2253e4bfb233ea705caf258cdc4cb9Jeff Sharkey
12651b5a2a96f793211bfbd39aa29cc41031dfa23950Jeff Sharkey    /**
1266bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey     * Default external settings that read from
1267625239a05401bbf18b04d9874cea3f82da7c29a1Jeff Sharkey     * {@link android.provider.Settings.Global}.
126839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey     */
126939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
127039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        private final ContentResolver mResolver;
127139ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
127239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public DefaultNetworkStatsSettings(Context context) {
127339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            mResolver = checkNotNull(context.getContentResolver());
127439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey            // TODO: adjust these timings for production builds
127539ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
127639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
1277e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        private long getGlobalLong(String name, long def) {
1278e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return Settings.Global.getLong(mResolver, name, def);
127939ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1280e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey        private boolean getGlobalBoolean(String name, boolean def) {
1281991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey            final int defInt = def ? 1 : 0;
1282e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return Settings.Global.getInt(mResolver, name, defInt) != 0;
1283991d1b1b3f303ad247a959881b1d5b57766f678bJeff Sharkey        }
128439ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey
1285bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
128639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        public long getPollInterval() {
1287e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
128839ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1289bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
129063abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public long getTimeCacheMaxAge() {
1291e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
129239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1293bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
1294ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getGlobalAlertBytes(long def) {
1295e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
129639ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1297bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
129863abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public boolean getSampleEnabled() {
1299e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
130039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1301bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
130270c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        public boolean getReportXtOverDev() {
1303e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalBoolean(NETSTATS_REPORT_XT_OVER_DEV, true);
130470c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        }
130570c70530bd6793869736ec894498e4ebf5dc9b20Jeff Sharkey        @Override
130663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getDevConfig() {
1307e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
1308e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                    getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1309e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                    getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
131039ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
1311bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
1312e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        public Config getXtConfig() {
1313e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey            return getDevConfig();
1314e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        }
1315e8914c36276710de50b347c1e6aecfa45d6a56cdJeff Sharkey        @Override
131663abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidConfig() {
1317e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1318e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                    getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1319e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                    getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
1320d03fd3f004e3ba8aaa1692ee0e92e8ae171d2a04Jeff Sharkey        }
1321bfdd680ab44da173a4a39fcd6feccdebb9d1f855Jeff Sharkey        @Override
132263abc37356728c0575d6a62a203102ae6d97953bJeff Sharkey        public Config getUidTagConfig() {
1323e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1324e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                    getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
1325e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey                    getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
1326ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        }
1327ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        @Override
1328ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getDevPersistBytes(long def) {
1329e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
1330ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        }
1331ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        @Override
1332ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getXtPersistBytes(long def) {
1333ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey            return getDevPersistBytes(def);
1334ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        }
1335ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        @Override
1336ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getUidPersistBytes(long def) {
1337e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
1338ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        }
1339ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        @Override
1340ac3fcb1590e1da21324c13ce237ec48f2bf488bfJeff Sharkey        public long getUidTagPersistBytes(long def) {
1341e6e6197d7c2eb5c29224bcddb0131a302267f6deJeff Sharkey            return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
134239ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey        }
134339ebc2195ed16b9e955dd57f5c95212bb7b934b6Jeff Sharkey    }
134475279904202357565cf5a1cb11148d01f42b4569Jeff Sharkey}
1345