blob: 78fd4b49237aa512c2f800127e5ebcbab122947b [file] [log] [blame]
Jeff Sharkey75279902011-05-24 18:39:45 -07001/*
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07002 * Copyright (C) 2011 The Android Open Source Project
Jeff Sharkey75279902011-05-24 18:39:45 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.net;
18
Jeff Sharkeya63ba592011-07-19 23:47:12 -070019import static android.Manifest.permission.ACCESS_NETWORK_STATE;
Jeff Sharkey63d27a92011-08-03 17:04:22 -070020import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070021import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070022import static android.content.Intent.ACTION_SHUTDOWN;
23import static android.content.Intent.ACTION_UID_REMOVED;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070024import static android.content.Intent.ACTION_USER_REMOVED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070025import static android.content.Intent.EXTRA_UID;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -070026import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
Jeff Sharkey234766a2012-04-10 19:48:07 -070027import static android.net.ConnectivityManager.isNetworkTypeMobile;
Lorenzo Colittiada23ed2018-01-19 01:05:20 +090028import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070029import static android.net.NetworkStats.IFACE_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060030import static android.net.NetworkStats.METERED_ALL;
31import static android.net.NetworkStats.ROAMING_ALL;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070032import static android.net.NetworkStats.SET_ALL;
33import static android.net.NetworkStats.SET_DEFAULT;
34import static android.net.NetworkStats.SET_FOREGROUND;
Lorenzo Colitti5356a352017-08-17 19:23:08 +090035import static android.net.NetworkStats.STATS_PER_IFACE;
36import static android.net.NetworkStats.STATS_PER_UID;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070037import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey75279902011-05-24 18:39:45 -070038import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060039import static android.net.NetworkStatsHistory.FIELD_ALL;
Jeff Sharkey234766a2012-04-10 19:48:07 -070040import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070041import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -070042import static android.net.TrafficStats.KB_IN_BYTES;
Jeff Sharkey241dde22012-02-03 14:50:07 -080043import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060044import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070045import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
46import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
47import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
48import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
49import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
50import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070051import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
52import static android.provider.Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE;
53import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
54import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
55import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
56import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
57import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
58import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
59import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
60import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070061import static android.text.format.DateUtils.DAY_IN_MILLIS;
62import static android.text.format.DateUtils.HOUR_IN_MILLIS;
63import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070064import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jack Yuf9d559c2017-05-26 16:08:22 -070065
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070066import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070067import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070068import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
69import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
Jeff Sharkey75279902011-05-24 18:39:45 -070070
71import android.app.AlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070072import android.app.PendingIntent;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060073import android.app.usage.NetworkStatsManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070074import android.content.BroadcastReceiver;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070075import android.content.ContentResolver;
Jeff Sharkey75279902011-05-24 18:39:45 -070076import android.content.Context;
77import android.content.Intent;
78import android.content.IntentFilter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070079import android.content.pm.ApplicationInfo;
80import android.content.pm.PackageManager;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080081import android.net.DataUsageRequest;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070082import android.net.IConnectivityManager;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070083import android.net.INetworkManagementEventObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070084import android.net.INetworkStatsService;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -070085import android.net.INetworkStatsSession;
Jeff Sharkey63abc372012-01-11 18:38:16 -080086import android.net.LinkProperties;
Lorenzo Colittic78da292018-01-19 00:50:48 +090087import android.net.Network;
Jack Yub6587ea2016-06-22 11:35:10 -070088import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070089import android.net.NetworkIdentity;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070090import android.net.NetworkInfo;
91import android.net.NetworkState;
Jeff Sharkey75279902011-05-24 18:39:45 -070092import android.net.NetworkStats;
Jeff Sharkey5a7bcf32012-01-10 17:24:44 -080093import android.net.NetworkStats.NonMonotonicObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070094import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070095import android.net.NetworkTemplate;
Jeff Sharkey63abc372012-01-11 18:38:16 -080096import android.net.TrafficStats;
Jeff Sharkeya63ba592011-07-19 23:47:12 -070097import android.os.Binder;
Jeff Sharkey163e6442011-10-31 16:37:52 -070098import android.os.DropBoxManager;
Jeff Sharkey3f391352011-06-05 17:42:53 -070099import android.os.Environment;
Jeff Sharkey75279902011-05-24 18:39:45 -0700100import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700101import android.os.HandlerThread;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800102import android.os.IBinder;
Jeff Sharkey75279902011-05-24 18:39:45 -0700103import android.os.INetworkManagementService;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700104import android.os.Message;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800105import android.os.Messenger;
Jeff Sharkey62489262011-07-17 12:53:28 -0700106import android.os.PowerManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700107import android.os.RemoteException;
108import android.os.SystemClock;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700109import android.os.UserHandle;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700110import android.provider.Settings;
Jeff Sharkey625239a2012-09-26 22:03:49 -0700111import android.provider.Settings.Global;
Makoto Onukida65a522017-01-13 10:23:30 -0800112import android.service.NetworkInterfaceProto;
113import android.service.NetworkStatsServiceDumpProto;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600114import android.telephony.SubscriptionManager;
115import android.telephony.SubscriptionPlan;
Jeff Sharkey75279902011-05-24 18:39:45 -0700116import android.telephony.TelephonyManager;
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800117import android.text.format.DateUtils;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700118import android.util.ArrayMap;
119import android.util.ArraySet;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700120import android.util.EventLog;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700121import android.util.Log;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700122import android.util.MathUtils;
Jeff Sharkey75279902011-05-24 18:39:45 -0700123import android.util.NtpTrustedTime;
124import android.util.Slog;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700125import android.util.SparseIntArray;
Jeff Sharkey75279902011-05-24 18:39:45 -0700126import android.util.TrustedTime;
Makoto Onukida65a522017-01-13 10:23:30 -0800127import android.util.proto.ProtoOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -0700128
Jeff Sharkey4635f102017-09-01 11:27:13 -0600129import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800130import com.android.internal.annotations.VisibleForTesting;
Wenchao Tongf5ea3402015-03-04 13:26:38 -0800131import com.android.internal.net.VpnInfo;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700132import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600133import com.android.internal.util.DumpUtils;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800134import com.android.internal.util.FileRotator;
135import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700136import com.android.server.EventLogTags;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700137import com.android.server.connectivity.Tethering;
Jeff Sharkey75279902011-05-24 18:39:45 -0700138
Jeff Sharkey3f391352011-06-05 17:42:53 -0700139import java.io.File;
Jeff Sharkey75279902011-05-24 18:39:45 -0700140import java.io.FileDescriptor;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700141import java.io.IOException;
Jeff Sharkey75279902011-05-24 18:39:45 -0700142import java.io.PrintWriter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700143import java.util.Arrays;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700144import java.util.HashSet;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700145import java.util.List;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700146
Jeff Sharkey75279902011-05-24 18:39:45 -0700147/**
148 * Collect and persist detailed network statistics, and provide this data to
149 * other system services.
150 */
151public class NetworkStatsService extends INetworkStatsService.Stub {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600152 static final String TAG = "NetworkStats";
153 static final boolean LOGV = false;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700154
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700155 private static final int MSG_PERFORM_POLL = 1;
156 private static final int MSG_UPDATE_IFACES = 2;
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -0800157 private static final int MSG_REGISTER_GLOBAL_ALERT = 3;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700158
159 /** Flags to control detail level of poll event. */
Jeff Sharkey905b5892011-09-30 15:19:49 -0700160 private static final int FLAG_PERSIST_NETWORK = 0x1;
161 private static final int FLAG_PERSIST_UID = 0x2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700162 private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700163 private static final int FLAG_PERSIST_FORCE = 0x100;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700164
Jeff Sharkey163e6442011-10-31 16:37:52 -0700165 private static final String TAG_NETSTATS_ERROR = "netstats_error";
166
Jeff Sharkey75279902011-05-24 18:39:45 -0700167 private final Context mContext;
168 private final INetworkManagementService mNetworkManager;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700169 private final AlarmManager mAlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700170 private final TrustedTime mTime;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700171 private final TelephonyManager mTeleManager;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700172 private final NetworkStatsSettings mSettings;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800173 private final NetworkStatsObservers mStatsObservers;
Jeff Sharkey75279902011-05-24 18:39:45 -0700174
Jeff Sharkey63abc372012-01-11 18:38:16 -0800175 private final File mSystemDir;
176 private final File mBaseDir;
177
Jeff Sharkey62489262011-07-17 12:53:28 -0700178 private final PowerManager.WakeLock mWakeLock;
179
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700180 private IConnectivityManager mConnManager;
181
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800182 @VisibleForTesting
Jeff Sharkey3f391352011-06-05 17:42:53 -0700183 public static final String ACTION_NETWORK_STATS_POLL =
Jeff Sharkey75279902011-05-24 18:39:45 -0700184 "com.android.server.action.NETWORK_STATS_POLL";
Jeff Sharkey497e4432011-06-14 17:27:29 -0700185 public static final String ACTION_NETWORK_STATS_UPDATED =
186 "com.android.server.action.NETWORK_STATS_UPDATED";
Jeff Sharkey75279902011-05-24 18:39:45 -0700187
188 private PendingIntent mPollIntent;
189
Jeff Sharkey63abc372012-01-11 18:38:16 -0800190 private static final String PREFIX_DEV = "dev";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700191 private static final String PREFIX_XT = "xt";
Jeff Sharkey63abc372012-01-11 18:38:16 -0800192 private static final String PREFIX_UID = "uid";
193 private static final String PREFIX_UID_TAG = "uid_tag";
194
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700195 /**
Jack Yub6587ea2016-06-22 11:35:10 -0700196 * Virtual network interface for video telephony. This is for VT data usage counting purpose.
197 */
198 public static final String VT_INTERFACE = "vt_data0";
199
200 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700201 * Settings that can be changed externally.
202 */
203 public interface NetworkStatsSettings {
204 public long getPollInterval();
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700205 public long getTimeCacheMaxAge();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800206 public boolean getSampleEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600207 public boolean getAugmentEnabled();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800208
209 public static class Config {
210 public final long bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800211 public final long rotateAgeMillis;
212 public final long deleteAgeMillis;
213
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700214 public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800215 this.bucketDuration = bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800216 this.rotateAgeMillis = rotateAgeMillis;
217 this.deleteAgeMillis = deleteAgeMillis;
218 }
219 }
220
221 public Config getDevConfig();
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700222 public Config getXtConfig();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800223 public Config getUidConfig();
224 public Config getUidTagConfig();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700225
226 public long getGlobalAlertBytes(long def);
227 public long getDevPersistBytes(long def);
228 public long getXtPersistBytes(long def);
229 public long getUidPersistBytes(long def);
230 public long getUidTagPersistBytes(long def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700231 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700232
233 private final Object mStatsLock = new Object();
234
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700235 /** Set of currently active ifaces. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900236 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700237 private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900238
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700239 /** Set of currently active ifaces for UID stats. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900240 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700241 private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900242
Jeff Sharkey63abc372012-01-11 18:38:16 -0800243 /** Current default active iface. */
244 private String mActiveIface;
Lorenzo Colittic78da292018-01-19 00:50:48 +0900245
Jeff Sharkey234766a2012-04-10 19:48:07 -0700246 /** Set of any ifaces associated with mobile networks since boot. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900247 @GuardedBy("mStatsLock")
Jeff Sharkey234766a2012-04-10 19:48:07 -0700248 private String[] mMobileIfaces = new String[0];
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700249
Lorenzo Colittic78da292018-01-19 00:50:48 +0900250 /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
251 @GuardedBy("mStatsLock")
252 private Network[] mDefaultNetworks = new Network[0];
253
Jeff Sharkey63abc372012-01-11 18:38:16 -0800254 private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
255 new DropBoxNonMonotonicObserver();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700256
Jeff Sharkey4635f102017-09-01 11:27:13 -0600257 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800258 private NetworkStatsRecorder mDevRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600259 @GuardedBy("mStatsLock")
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700260 private NetworkStatsRecorder mXtRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600261 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800262 private NetworkStatsRecorder mUidRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600263 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800264 private NetworkStatsRecorder mUidTagRecorder;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700265
Jeff Sharkey70c70532012-05-16 14:51:19 -0700266 /** Cached {@link #mXtRecorder} stats. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600267 @GuardedBy("mStatsLock")
Jeff Sharkey70c70532012-05-16 14:51:19 -0700268 private NetworkStatsCollection mXtStatsCached;
Jeff Sharkey75279902011-05-24 18:39:45 -0700269
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700270 /** Current counter sets for each UID. */
271 private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
272
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700273 /** Data layer operation counters for splicing into other structures. */
Jeff Sharkey63abc372012-01-11 18:38:16 -0800274 private NetworkStats mUidOperations = new NetworkStats(0L, 10);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700275
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800276 /** Must be set in factory by calling #setHandler. */
277 private Handler mHandler;
278 private Handler.Callback mHandlerCallback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700279
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800280 private boolean mSystemReady;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700281 private long mPersistThreshold = 2 * MB_IN_BYTES;
282 private long mGlobalAlertBytes;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800283
Jeff Sharkey63abc372012-01-11 18:38:16 -0800284 private static File getDefaultSystemDir() {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700285 return new File(Environment.getDataDirectory(), "system");
Jeff Sharkey75279902011-05-24 18:39:45 -0700286 }
287
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800288 private static File getDefaultBaseDir() {
289 File baseDir = new File(getDefaultSystemDir(), "netstats");
290 baseDir.mkdirs();
291 return baseDir;
292 }
293
294 public static NetworkStatsService create(Context context,
295 INetworkManagementService networkManager) {
296 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
297 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
298 PowerManager.WakeLock wakeLock =
299 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
300
301 NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
302 wakeLock, NtpTrustedTime.getInstance(context), TelephonyManager.getDefault(),
303 new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
304 getDefaultSystemDir(), getDefaultBaseDir());
305
306 HandlerThread handlerThread = new HandlerThread(TAG);
307 Handler.Callback callback = new HandlerCallback(service);
308 handlerThread.start();
309 Handler handler = new Handler(handlerThread.getLooper(), callback);
310 service.setHandler(handler, callback);
311 return service;
312 }
313
314 @VisibleForTesting
315 NetworkStatsService(Context context, INetworkManagementService networkManager,
316 AlarmManager alarmManager, PowerManager.WakeLock wakeLock, TrustedTime time,
317 TelephonyManager teleManager, NetworkStatsSettings settings,
318 NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
Jeff Sharkey75279902011-05-24 18:39:45 -0700319 mContext = checkNotNull(context, "missing Context");
320 mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800321 mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
Jeff Sharkey75279902011-05-24 18:39:45 -0700322 mTime = checkNotNull(time, "missing TrustedTime");
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700323 mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800324 mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
325 mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
326 mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
327 mSystemDir = checkNotNull(systemDir, "missing systemDir");
328 mBaseDir = checkNotNull(baseDir, "missing baseDir");
329 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700330
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800331 @VisibleForTesting
332 void setHandler(Handler handler, Handler.Callback callback) {
333 mHandler = handler;
334 mHandlerCallback = callback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700335 }
336
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700337 public void bindConnectivityManager(IConnectivityManager connManager) {
338 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
339 }
340
Jeff Sharkey75279902011-05-24 18:39:45 -0700341 public void systemReady() {
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800342 mSystemReady = true;
343
Jeff Sharkey418d12d2011-12-13 15:38:03 -0800344 if (!isBandwidthControlEnabled()) {
345 Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
346 return;
347 }
348
Jeff Sharkey63abc372012-01-11 18:38:16 -0800349 synchronized (mStatsLock) {
Jeff Sharkey4635f102017-09-01 11:27:13 -0600350 // create data recorders along with historical rotators
351 mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
352 mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
353 mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
354 mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
355
356 updatePersistThresholdsLocked();
357
Jeff Sharkey63abc372012-01-11 18:38:16 -0800358 // upgrade any legacy stats, migrating them to rotated files
359 maybeUpgradeLegacyStatsLocked();
360
361 // read historical network stats from disk, since policy service
362 // might need them right away.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700363 mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800364
365 // bootstrap initial stats to prevent double-counting later
366 bootstrapStatsLocked();
367 }
Jeff Sharkey3359aca2011-11-08 18:08:48 -0800368
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700369 // watch for tethering changes
370 final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
Vinit Deshpande92d141f2014-09-10 18:05:10 -0700371 mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700372
Jeff Sharkey75279902011-05-24 18:39:45 -0700373 // listen for periodic polling events
374 final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700375 mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
Jeff Sharkey75279902011-05-24 18:39:45 -0700376
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700377 // listen for uid removal to clean stats
378 final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
379 mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
380
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700381 // listen for user changes to clean stats
382 final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
383 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
384
Jeff Sharkey75279902011-05-24 18:39:45 -0700385 // persist stats during clean shutdown
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700386 final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
387 mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
Jeff Sharkey75279902011-05-24 18:39:45 -0700388
389 try {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700390 mNetworkManager.registerObserver(mAlertObserver);
Jeff Sharkey75279902011-05-24 18:39:45 -0700391 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700392 // ignored; service lives in system_server
Jeff Sharkey75279902011-05-24 18:39:45 -0700393 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700394
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700395 registerPollAlarmLocked();
396 registerGlobalAlert();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800397 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700398
Jeff Sharkey63abc372012-01-11 18:38:16 -0800399 private NetworkStatsRecorder buildRecorder(
400 String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700401 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
402 Context.DROPBOX_SERVICE);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700403 return new NetworkStatsRecorder(new FileRotator(
404 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700405 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
Jeff Sharkey75279902011-05-24 18:39:45 -0700406 }
407
Jeff Sharkey3f391352011-06-05 17:42:53 -0700408 private void shutdownLocked() {
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700409 mContext.unregisterReceiver(mTetherReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700410 mContext.unregisterReceiver(mPollReceiver);
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700411 mContext.unregisterReceiver(mRemovedReceiver);
Ryuki Nakamuraa47b0c92017-03-01 10:40:36 +0900412 mContext.unregisterReceiver(mUserReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700413 mContext.unregisterReceiver(mShutdownReceiver);
414
Jeff Sharkey63abc372012-01-11 18:38:16 -0800415 final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
416 : System.currentTimeMillis();
417
418 // persist any pending stats
419 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700420 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800421 mUidRecorder.forcePersistLocked(currentTime);
422 mUidTagRecorder.forcePersistLocked(currentTime);
423
424 mDevRecorder = null;
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700425 mXtRecorder = null;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800426 mUidRecorder = null;
427 mUidTagRecorder = null;
428
Jeff Sharkey70c70532012-05-16 14:51:19 -0700429 mXtStatsCached = null;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800430
431 mSystemReady = false;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800432 }
433
434 private void maybeUpgradeLegacyStatsLocked() {
435 File file;
436 try {
437 file = new File(mSystemDir, "netstats.bin");
438 if (file.exists()) {
439 mDevRecorder.importLegacyNetworkLocked(file);
440 file.delete();
441 }
442
443 file = new File(mSystemDir, "netstats_xt.bin");
444 if (file.exists()) {
445 file.delete();
446 }
447
448 file = new File(mSystemDir, "netstats_uid.bin");
449 if (file.exists()) {
450 mUidRecorder.importLegacyUidLocked(file);
451 mUidTagRecorder.importLegacyUidLocked(file);
452 file.delete();
453 }
454 } catch (IOException e) {
455 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700456 } catch (OutOfMemoryError e) {
457 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeyc506ff62011-11-17 11:59:29 -0800458 }
Jeff Sharkey3f391352011-06-05 17:42:53 -0700459 }
460
Jeff Sharkey75279902011-05-24 18:39:45 -0700461 /**
462 * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700463 * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
Jeff Sharkey75279902011-05-24 18:39:45 -0700464 */
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700465 private void registerPollAlarmLocked() {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700466 if (mPollIntent != null) {
467 mAlarmManager.cancel(mPollIntent);
Jeff Sharkey75279902011-05-24 18:39:45 -0700468 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700469
470 mPollIntent = PendingIntent.getBroadcast(
471 mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
472
473 final long currentRealtime = SystemClock.elapsedRealtime();
474 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
475 mSettings.getPollInterval(), mPollIntent);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700476 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700477
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700478 /**
479 * Register for a global alert that is delivered through
480 * {@link INetworkManagementEventObserver} once a threshold amount of data
481 * has been transferred.
482 */
483 private void registerGlobalAlert() {
484 try {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700485 mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700486 } catch (IllegalStateException e) {
487 Slog.w(TAG, "problem registering for global alert: " + e);
488 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700489 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700490 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700491 }
492
493 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700494 public INetworkStatsSession openSession() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600495 // NOTE: if callers want to get non-augmented data, they should go
496 // through the public API
497 return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000498 }
499
500 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600501 public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
502 return openSessionInternal(flags, callingPackage);
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100503 }
504
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600505 private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
Jeff Sharkey4190a042012-04-21 15:36:48 -0700506 assertBandwidthControlEnabled();
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700507
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600508 if ((flags & NetworkStatsManager.FLAG_POLL_ON_OPEN) != 0) {
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100509 final long ident = Binder.clearCallingIdentity();
510 try {
511 performPoll(FLAG_PERSIST_ALL);
512 } finally {
513 Binder.restoreCallingIdentity(ident);
514 }
515 }
516
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700517 // return an IBinder which holds strong references to any loaded stats
518 // for its lifetime; when caller closes only weak references remain.
519
520 return new INetworkStatsSession.Stub() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600521 private final int mCallingUid = Binder.getCallingUid();
522 private final String mCallingPackage = callingPackage;
523 private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
524 callingPackage);
525
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700526 private NetworkStatsCollection mUidComplete;
527 private NetworkStatsCollection mUidTagComplete;
528
529 private NetworkStatsCollection getUidComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700530 synchronized (mStatsLock) {
531 if (mUidComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700532 mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
533 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700534 return mUidComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700535 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700536 }
537
538 private NetworkStatsCollection getUidTagComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700539 synchronized (mStatsLock) {
540 if (mUidTagComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700541 mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
542 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700543 return mUidTagComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700544 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700545 }
546
547 @Override
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000548 public int[] getRelevantUids() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600549 return getUidComplete().getRelevantUids(mAccessLevel);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000550 }
551
552 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600553 public NetworkStats getDeviceSummaryForNetwork(
554 NetworkTemplate template, long start, long end) {
555 return internalGetSummaryForNetwork(template, flags, start, end, mAccessLevel,
556 mCallingUid);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000557 }
558
559 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700560 public NetworkStats getSummaryForNetwork(
561 NetworkTemplate template, long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600562 return internalGetSummaryForNetwork(template, flags, start, end, mAccessLevel,
563 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700564 }
565
566 @Override
567 public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600568 return internalGetHistoryForNetwork(template, flags, fields, mAccessLevel,
569 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700570 }
571
572 @Override
573 public NetworkStats getSummaryForAllUid(
574 NetworkTemplate template, long start, long end, boolean includeTags) {
Jeff Davidson39583b52016-12-12 11:55:37 -0800575 try {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600576 final NetworkStats stats = getUidComplete()
577 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800578 if (includeTags) {
579 final NetworkStats tagStats = getUidTagComplete()
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600580 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800581 stats.combineAllValues(tagStats);
582 }
583 return stats;
584 } catch (NullPointerException e) {
585 // TODO: Track down and fix the cause of this crash and remove this catch block.
586 Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
587 throw e;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700588 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700589 }
590
591 @Override
592 public NetworkStatsHistory getHistoryForUid(
593 NetworkTemplate template, int uid, int set, int tag, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600594 // NOTE: We don't augment UID-level statistics
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700595 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600596 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
597 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700598 } else {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600599 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
600 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700601 }
602 }
603
604 @Override
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100605 public NetworkStatsHistory getHistoryIntervalForUid(
606 NetworkTemplate template, int uid, int set, int tag, int fields,
607 long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600608 // NOTE: We don't augment UID-level statistics
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100609 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600610 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
611 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700612 } else if (uid == Binder.getCallingUid()) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600613 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
614 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700615 } else {
616 throw new SecurityException("Calling package " + mCallingPackage
617 + " cannot access tag information from a different uid");
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100618 }
619 }
620
621 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700622 public void close() {
623 mUidComplete = null;
624 mUidTagComplete = null;
625 }
626 };
Jeff Sharkey905b5892011-09-30 15:19:49 -0700627 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700628
Jeff Davidson1efb1332015-12-09 18:04:50 -0800629 private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
630 return NetworkStatsAccess.checkAccessLevel(
631 mContext, Binder.getCallingUid(), callingPackage);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000632 }
633
Jeff Sharkey70c70532012-05-16 14:51:19 -0700634 /**
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600635 * Find the most relevant {@link SubscriptionPlan} for the given
636 * {@link NetworkTemplate} and flags. This is typically used to augment
637 * local measurement results to match a known anchor from the carrier.
638 */
639 private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
640 SubscriptionPlan plan = null;
641 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
642 && (template.getMatchRule() == NetworkTemplate.MATCH_MOBILE_ALL)
643 && mSettings.getAugmentEnabled()) {
644 Slog.d(TAG, "Resolving plan for " + template);
645 final long token = Binder.clearCallingIdentity();
646 try {
647 final SubscriptionManager sm = mContext.getSystemService(SubscriptionManager.class);
648 final TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
649 for (int subId : sm.getActiveSubscriptionIdList()) {
650 if (template.matchesSubscriberId(tm.getSubscriberId(subId))) {
651 Slog.d(TAG, "Found active matching subId " + subId);
652 final List<SubscriptionPlan> plans = sm.getSubscriptionPlans(subId);
653 if (!plans.isEmpty()) {
654 plan = plans.get(0);
655 }
656 }
657 }
658 } finally {
659 Binder.restoreCallingIdentity(token);
660 }
661 Slog.d(TAG, "Resolved to plan " + plan);
662 }
663 return plan;
664 }
665
666 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700667 * Return network summary, splicing between DEV and XT stats when
668 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700669 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600670 private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
671 long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700672 // We've been using pure XT stats long enough that we no longer need to
673 // splice DEV and XT together.
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600674 final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
675 accessLevel, callingUid);
676
677 final long now = System.currentTimeMillis();
678 final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
679
680 final NetworkStats stats = new NetworkStats(end - start, 1);
Lorenzo Colittiada23ed2018-01-19 01:05:20 +0900681 stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
682 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
683 entry.txBytes, entry.txPackets, entry.operations));
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600684 return stats;
Jeff Sharkey70c70532012-05-16 14:51:19 -0700685 }
686
687 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700688 * Return network history, splicing between DEV and XT stats when
689 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700690 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600691 private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
692 int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700693 // We've been using pure XT stats long enough that we no longer need to
694 // splice DEV and XT together.
Jeff Sharkey4635f102017-09-01 11:27:13 -0600695 final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
696 synchronized (mStatsLock) {
697 return mXtStatsCached.getHistory(template, augmentPlan,
698 UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
699 accessLevel, callingUid);
700 }
Jeff Sharkey70c70532012-05-16 14:51:19 -0700701 }
702
Jeff Sharkey63abc372012-01-11 18:38:16 -0800703 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700704 public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600705 // Special case - since this is for internal use only, don't worry about
706 // a full access level check and just require the signature/privileged
707 // permission.
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700708 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkey4190a042012-04-21 15:36:48 -0700709 assertBandwidthControlEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600710
711 // NOTE: if callers want to get non-augmented data, they should go
712 // through the public API
713 return internalGetSummaryForNetwork(template,
714 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
715 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700716 }
717
Jeff Sharkey350083e2011-06-29 10:45:16 -0700718 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700719 public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
720 if (Binder.getCallingUid() != uid) {
721 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
722 }
Jeff Sharkey4190a042012-04-21 15:36:48 -0700723 assertBandwidthControlEnabled();
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700724
725 // TODO: switch to data layer stats once kernel exports
726 // for now, read network layer stats and flatten across all ifaces
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800727 final long token = Binder.clearCallingIdentity();
728 final NetworkStats networkLayer;
729 try {
730 networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid);
731 } finally {
732 Binder.restoreCallingIdentity(token);
733 }
734
Jeff Sharkey21a54782012-04-09 10:27:55 -0700735 // splice in operation counts
736 networkLayer.spliceOperationsFrom(mUidOperations);
737
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700738 final NetworkStats dataLayer = new NetworkStats(
739 networkLayer.getElapsedRealtime(), networkLayer.size());
740
741 NetworkStats.Entry entry = null;
742 for (int i = 0; i < networkLayer.size(); i++) {
743 entry = networkLayer.getValues(i, entry);
744 entry.iface = IFACE_ALL;
745 dataLayer.combineValues(entry);
746 }
747
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700748 return dataLayer;
749 }
750
751 @Override
Jeff Sharkey234766a2012-04-10 19:48:07 -0700752 public String[] getMobileIfaces() {
753 return mMobileIfaces;
754 }
755
756 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700757 public void incrementOperationCount(int uid, int tag, int operationCount) {
758 if (Binder.getCallingUid() != uid) {
Jeff Sharkey9f09e6a72017-06-26 11:24:47 -0600759 mContext.enforceCallingOrSelfPermission(
760 android.Manifest.permission.UPDATE_DEVICE_STATS, TAG);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700761 }
762
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700763 if (operationCount < 0) {
764 throw new IllegalArgumentException("operation count can only be incremented");
765 }
766 if (tag == TAG_NONE) {
767 throw new IllegalArgumentException("operation count must have specific tag");
768 }
769
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700770 synchronized (mStatsLock) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700771 final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800772 mUidOperations.combineValues(
773 mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
774 mUidOperations.combineValues(
775 mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700776 }
777 }
778
779 @Override
780 public void setUidForeground(int uid, boolean uidForeground) {
Jeff Sharkey9f09e6a72017-06-26 11:24:47 -0600781 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700782
783 synchronized (mStatsLock) {
784 final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
785 final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
786 if (oldSet != set) {
787 mActiveUidCounterSet.put(uid, set);
788 setKernelCounterSet(uid, set);
789 }
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700790 }
791 }
792
793 @Override
Lorenzo Colittic78da292018-01-19 00:50:48 +0900794 public void forceUpdateIfaces(Network[] defaultNetworks) {
Jeff Sharkey69736342014-12-08 14:50:12 -0800795 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
796 assertBandwidthControlEnabled();
797
798 final long token = Binder.clearCallingIdentity();
799 try {
Lorenzo Colittic78da292018-01-19 00:50:48 +0900800 updateIfaces(defaultNetworks);
Jeff Sharkey69736342014-12-08 14:50:12 -0800801 } finally {
802 Binder.restoreCallingIdentity(token);
803 }
804 }
805
806 @Override
Jeff Sharkey350083e2011-06-29 10:45:16 -0700807 public void forceUpdate() {
808 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkey4190a042012-04-21 15:36:48 -0700809 assertBandwidthControlEnabled();
Jeff Sharkeye630f7b2012-01-31 17:12:53 -0800810
811 final long token = Binder.clearCallingIdentity();
812 try {
813 performPoll(FLAG_PERSIST_ALL);
814 } finally {
815 Binder.restoreCallingIdentity(token);
816 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700817 }
818
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700819 @Override
820 public void advisePersistThreshold(long thresholdBytes) {
Jeff Sharkey9f09e6a72017-06-26 11:24:47 -0600821 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700822 assertBandwidthControlEnabled();
823
824 // clamp threshold into safe range
825 mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700826 if (LOGV) {
827 Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
828 + mPersistThreshold);
829 }
830
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700831 // update and persist if beyond new thresholds
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700832 final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
833 : System.currentTimeMillis();
Jeff Sharkey58015972012-05-07 11:08:49 -0700834 synchronized (mStatsLock) {
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700835 if (!mSystemReady) return;
836
Jeff Sharkey4635f102017-09-01 11:27:13 -0600837 updatePersistThresholdsLocked();
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700838
Jeff Sharkey58015972012-05-07 11:08:49 -0700839 mDevRecorder.maybePersistLocked(currentTime);
840 mXtRecorder.maybePersistLocked(currentTime);
841 mUidRecorder.maybePersistLocked(currentTime);
842 mUidTagRecorder.maybePersistLocked(currentTime);
843 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700844
845 // re-arm global alert
846 registerGlobalAlert();
847 }
848
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800849 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700850 public DataUsageRequest registerUsageCallback(String callingPackage,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800851 DataUsageRequest request, Messenger messenger, IBinder binder) {
852 checkNotNull(callingPackage, "calling package is null");
853 checkNotNull(request, "DataUsageRequest is null");
Antonio Cansado6965c182016-03-30 11:37:18 -0700854 checkNotNull(request.template, "NetworkTemplate is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800855 checkNotNull(messenger, "messenger is null");
856 checkNotNull(binder, "binder is null");
857
858 int callingUid = Binder.getCallingUid();
859 @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
860 DataUsageRequest normalizedRequest;
861 final long token = Binder.clearCallingIdentity();
862 try {
863 normalizedRequest = mStatsObservers.register(request, messenger, binder,
864 callingUid, accessLevel);
865 } finally {
866 Binder.restoreCallingIdentity(token);
867 }
868
869 // Create baseline stats
870 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL, FLAG_PERSIST_ALL));
871
872 return normalizedRequest;
873 }
874
875 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700876 public void unregisterUsageRequest(DataUsageRequest request) {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800877 checkNotNull(request, "DataUsageRequest is null");
878
879 int callingUid = Binder.getCallingUid();
880 final long token = Binder.clearCallingIdentity();
881 try {
882 mStatsObservers.unregister(request, callingUid);
883 } finally {
884 Binder.restoreCallingIdentity(token);
885 }
886 }
887
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800888 @Override
889 public long getUidStats(int uid, int type) {
890 return nativeGetUidStat(uid, type);
891 }
892
893 @Override
894 public long getIfaceStats(String iface, int type) {
895 return nativeGetIfaceStat(iface, type);
896 }
897
898 @Override
899 public long getTotalStats(int type) {
900 return nativeGetTotalStat(type);
901 }
902
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700903 /**
904 * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
905 * reflect current {@link #mPersistThreshold} value. Always defers to
Jeff Sharkey625239a2012-09-26 22:03:49 -0700906 * {@link Global} values when defined.
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700907 */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600908 private void updatePersistThresholdsLocked() {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700909 mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
910 mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
911 mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
912 mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
913 mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
914 }
915
Jeff Sharkey75279902011-05-24 18:39:45 -0700916 /**
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700917 * Receiver that watches for {@link Tethering} to claim interface pairs.
918 */
919 private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
920 @Override
921 public void onReceive(Context context, Intent intent) {
922 // on background handler thread, and verified CONNECTIVITY_INTERNAL
923 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700924 performPoll(FLAG_PERSIST_NETWORK);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700925 }
926 };
927
Jeff Sharkey75279902011-05-24 18:39:45 -0700928 private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
929 @Override
930 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700931 // on background handler thread, and verified UPDATE_DEVICE_STATS
932 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700933 performPoll(FLAG_PERSIST_ALL);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700934
935 // verify that we're watching global alert
936 registerGlobalAlert();
Jeff Sharkey75279902011-05-24 18:39:45 -0700937 }
938 };
939
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700940 private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
941 @Override
942 public void onReceive(Context context, Intent intent) {
943 // on background handler thread, and UID_REMOVED is protected
944 // broadcast.
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700945
946 final int uid = intent.getIntExtra(EXTRA_UID, -1);
947 if (uid == -1) return;
948
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700949 synchronized (mStatsLock) {
Jeff Sharkey62489262011-07-17 12:53:28 -0700950 mWakeLock.acquire();
951 try {
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700952 removeUidsLocked(uid);
953 } finally {
954 mWakeLock.release();
955 }
956 }
957 }
958 };
959
960 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
961 @Override
962 public void onReceive(Context context, Intent intent) {
963 // On background handler thread, and USER_REMOVED is protected
964 // broadcast.
965
966 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
967 if (userId == -1) return;
968
969 synchronized (mStatsLock) {
970 mWakeLock.acquire();
971 try {
972 removeUserLocked(userId);
Jeff Sharkey62489262011-07-17 12:53:28 -0700973 } finally {
974 mWakeLock.release();
975 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700976 }
977 }
978 };
979
Jeff Sharkey75279902011-05-24 18:39:45 -0700980 private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
981 @Override
982 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700983 // SHUTDOWN is protected broadcast.
Jeff Sharkey75279902011-05-24 18:39:45 -0700984 synchronized (mStatsLock) {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700985 shutdownLocked();
Jeff Sharkey75279902011-05-24 18:39:45 -0700986 }
987 }
988 };
989
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700990 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700991 * Observer that watches for {@link INetworkManagementService} alerts.
992 */
Jeff Sharkey216c1812012-08-05 14:29:23 -0700993 private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700994 @Override
995 public void limitReached(String limitName, String iface) {
996 // only someone like NMS should be calling us
997 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
998
999 if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
1000 // kick off background poll to collect network stats; UID stats
1001 // are handled during normal polling interval.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001002 final int flags = FLAG_PERSIST_NETWORK;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001003 mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget();
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001004
1005 // re-arm global alert for next update
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -08001006 mHandler.obtainMessage(MSG_REGISTER_GLOBAL_ALERT).sendToTarget();
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001007 }
1008 }
1009 };
1010
Lorenzo Colittic78da292018-01-19 00:50:48 +09001011 private void updateIfaces(Network[] defaultNetworks) {
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001012 synchronized (mStatsLock) {
1013 mWakeLock.acquire();
1014 try {
Lorenzo Colittic78da292018-01-19 00:50:48 +09001015 updateIfacesLocked(defaultNetworks);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001016 } finally {
1017 mWakeLock.release();
1018 }
1019 }
1020 }
1021
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001022 /**
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001023 * Inspect all current {@link NetworkState} to derive mapping from {@code
1024 * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
1025 * are active on a single {@code iface}, they are combined under a single
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001026 * {@link NetworkIdentitySet}.
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001027 */
Lorenzo Colittic78da292018-01-19 00:50:48 +09001028 private void updateIfacesLocked(Network[] defaultNetworks) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001029 if (!mSystemReady) return;
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001030 if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001031
1032 // take one last stats snapshot before updating iface mapping. this
1033 // isn't perfect, since the kernel may already be counting traffic from
1034 // the updated network.
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001035
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001036 // poll, but only persist network stats to keep codepath fast. UID stats
1037 // will be persisted during next alarm poll event.
1038 performPollLocked(FLAG_PERSIST_NETWORK);
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001039
1040 final NetworkState[] states;
Jeff Sharkey63abc372012-01-11 18:38:16 -08001041 final LinkProperties activeLink;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001042 try {
1043 states = mConnManager.getAllNetworkState();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001044 activeLink = mConnManager.getActiveLinkProperties();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001045 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001046 // ignored; service lives in system_server
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001047 return;
1048 }
1049
Jeff Sharkey63abc372012-01-11 18:38:16 -08001050 mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
1051
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001052 // Rebuild active interfaces based on connected networks
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001053 mActiveIfaces.clear();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001054 mActiveUidIfaces.clear();
Lorenzo Colittic78da292018-01-19 00:50:48 +09001055 if (defaultNetworks != null) {
1056 // Caller is ConnectivityService. Update the list of default networks.
1057 mDefaultNetworks = defaultNetworks;
1058 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001059
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001060 final ArraySet<String> mobileIfaces = new ArraySet<>();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001061 for (NetworkState state : states) {
1062 if (state.networkInfo.isConnected()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001063 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001064 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
1065 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1066 isDefault);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001067
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001068 // Traffic occurring on the base interface is always counted for
1069 // both total usage and UID details.
1070 final String baseIface = state.linkProperties.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001071 if (baseIface != null) {
1072 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1073 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
Jack Yub6587ea2016-06-22 11:35:10 -07001074
1075 // Build a separate virtual interface for VT (Video Telephony) data usage.
1076 // Only do this when IMS is not metered, but VT is metered.
1077 // If IMS is metered, then the IMS network usage has already included VT usage.
1078 // VT is considered always metered in framework's layer. If VT is not metered
1079 // per carrier's policy, modem will report 0 usage for VT calls.
1080 if (state.networkCapabilities.hasCapability(
1081 NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1082
1083 // Copy the identify from IMS one but mark it as metered.
1084 NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1085 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001086 ident.getRoaming(), true /* metered */,
1087 true /* onDefaultNetwork */);
Jack Yub6587ea2016-06-22 11:35:10 -07001088 findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent);
1089 findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent);
1090 }
1091
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001092 if (isMobile) {
1093 mobileIfaces.add(baseIface);
1094 }
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001095 }
1096
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001097 // Traffic occurring on stacked interfaces is usually clatd,
1098 // which is already accounted against its final egress interface
1099 // by the kernel. Thus, we only need to collect stacked
1100 // interface stats at the UID level.
1101 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1102 for (LinkProperties stackedLink : stackedLinks) {
1103 final String stackedIface = stackedLink.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001104 if (stackedIface != null) {
1105 findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1106 if (isMobile) {
1107 mobileIfaces.add(stackedIface);
1108 }
Jeff Sharkey234766a2012-04-10 19:48:07 -07001109 }
1110 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001111 }
1112 }
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001113
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001114 mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1115 }
1116
1117 private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1118 ArrayMap<K, NetworkIdentitySet> map, K key) {
1119 NetworkIdentitySet ident = map.get(key);
1120 if (ident == null) {
1121 ident = new NetworkIdentitySet();
1122 map.put(key, ident);
1123 }
1124 return ident;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001125 }
1126
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001127 private void recordSnapshotLocked(long currentTime) throws RemoteException {
1128 // snapshot and record current counters; read UID stats first to
Jack Yub6587ea2016-06-22 11:35:10 -07001129 // avoid over counting dev stats.
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001130 final NetworkStats uidSnapshot = getNetworkStatsUidDetail();
Jack Yuf9d559c2017-05-26 16:08:22 -07001131 final NetworkStats xtSnapshot = getNetworkStatsXt();
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001132 final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
1133
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001134 // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1135 // providers that isn't already counted by dev and XT stats.
1136 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
1137 xtSnapshot.combineAllValues(tetherSnapshot);
1138 devSnapshot.combineAllValues(tetherSnapshot);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001139
1140 // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1141 // can't be reattributed to responsible apps.
1142 mDevRecorder.recordSnapshotLocked(
1143 devSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
1144 mXtRecorder.recordSnapshotLocked(
1145 xtSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
1146
1147 // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001148 VpnInfo[] vpnArray = mConnManager.getAllVpnInfo();
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001149 mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
1150 mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001151
1152 // We need to make copies of member fields that are sent to the observer to avoid
1153 // a race condition between the service handler thread and the observer's
1154 mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
1155 new ArrayMap<>(mActiveUidIfaces), vpnArray, currentTime);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001156 }
1157
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001158 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001159 * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1160 * so we have baseline values without double-counting.
1161 */
Jeff Sharkey63abc372012-01-11 18:38:16 -08001162 private void bootstrapStatsLocked() {
1163 final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
1164 : System.currentTimeMillis();
1165
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001166 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001167 recordSnapshotLocked(currentTime);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001168 } catch (IllegalStateException e) {
1169 Slog.w(TAG, "problem reading network stats: " + e);
1170 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001171 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001172 }
1173 }
1174
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001175 private void performPoll(int flags) {
Anders 3 Fridlund36bc5b62012-06-07 11:24:10 +02001176 // try refreshing time source when stale
1177 if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
1178 mTime.forceRefresh();
1179 }
1180
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001181 synchronized (mStatsLock) {
1182 mWakeLock.acquire();
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001183
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001184 try {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001185 performPollLocked(flags);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001186 } finally {
1187 mWakeLock.release();
1188 }
1189 }
1190 }
1191
1192 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001193 * Periodic poll operation, reading current statistics and recording into
1194 * {@link NetworkStatsHistory}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001195 */
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001196 private void performPollLocked(int flags) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001197 if (!mSystemReady) return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001198 if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001199
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001200 final long startRealtime = SystemClock.elapsedRealtime();
Jeff Sharkey75279902011-05-24 18:39:45 -07001201
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001202 final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1203 final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001204 final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001205
Jeff Sharkey75279902011-05-24 18:39:45 -07001206 // TODO: consider marking "untrusted" times in historical stats
1207 final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
1208 : System.currentTimeMillis();
1209
Jeff Sharkey75279902011-05-24 18:39:45 -07001210 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001211 recordSnapshotLocked(currentTime);
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001212 } catch (IllegalStateException e) {
1213 Log.wtf(TAG, "problem reading network stats", e);
Jeff Sharkey905b5892011-09-30 15:19:49 -07001214 return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001215 } catch (RemoteException e) {
1216 // ignored; service lives in system_server
Jeff Sharkey905b5892011-09-30 15:19:49 -07001217 return;
1218 }
1219
Jeff Sharkey63abc372012-01-11 18:38:16 -08001220 // persist any pending data depending on requested flags
1221 if (persistForce) {
1222 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001223 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001224 mUidRecorder.forcePersistLocked(currentTime);
1225 mUidTagRecorder.forcePersistLocked(currentTime);
1226 } else {
1227 if (persistNetwork) {
1228 mDevRecorder.maybePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001229 mXtRecorder.maybePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001230 }
1231 if (persistUid) {
1232 mUidRecorder.maybePersistLocked(currentTime);
1233 mUidTagRecorder.maybePersistLocked(currentTime);
1234 }
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001235 }
Jeff Sharkey497e4432011-06-14 17:27:29 -07001236
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001237 if (LOGV) {
1238 final long duration = SystemClock.elapsedRealtime() - startRealtime;
1239 Slog.v(TAG, "performPollLocked() took " + duration + "ms");
1240 }
1241
Jeff Sharkey63abc372012-01-11 18:38:16 -08001242 if (mSettings.getSampleEnabled()) {
Jeff Sharkey905b5892011-09-30 15:19:49 -07001243 // sample stats after each full poll
Jeff Sharkey63abc372012-01-11 18:38:16 -08001244 performSampleLocked();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001245 }
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001246
Jeff Sharkey497e4432011-06-14 17:27:29 -07001247 // finally, dispatch updated event to any listeners
1248 final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
1249 updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001250 mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
1251 READ_NETWORK_USAGE_HISTORY);
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001252 }
1253
1254 /**
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001255 * Sample recent statistics summary into {@link EventLog}.
1256 */
Jeff Sharkey63abc372012-01-11 18:38:16 -08001257 private void performSampleLocked() {
1258 // TODO: migrate trustedtime fixes to separate binary log events
Jeff Sharkey905b5892011-09-30 15:19:49 -07001259 final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
1260
Jeff Sharkey63abc372012-01-11 18:38:16 -08001261 NetworkTemplate template;
1262 NetworkStats.Entry devTotal;
1263 NetworkStats.Entry xtTotal;
1264 NetworkStats.Entry uidTotal;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001265
1266 // collect mobile sample
Jeff Sharkey234766a2012-04-10 19:48:07 -07001267 template = buildTemplateMobileWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001268 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001269 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001270 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001271
Jeff Sharkey905b5892011-09-30 15:19:49 -07001272 EventLogTags.writeNetstatsMobileSample(
1273 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1274 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1275 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey63abc372012-01-11 18:38:16 -08001276 trustedTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001277
1278 // collect wifi sample
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001279 template = buildTemplateWifiWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001280 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001281 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001282 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1283
Jeff Sharkey905b5892011-09-30 15:19:49 -07001284 EventLogTags.writeNetstatsWifiSample(
1285 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1286 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1287 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey63abc372012-01-11 18:38:16 -08001288 trustedTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001289 }
1290
1291 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001292 * Clean up {@link #mUidRecorder} after UID is removed.
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001293 */
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001294 private void removeUidsLocked(int... uids) {
1295 if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1296
1297 // Perform one last poll before removing
Jeff Sharkey163e6442011-10-31 16:37:52 -07001298 performPollLocked(FLAG_PERSIST_ALL);
1299
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001300 mUidRecorder.removeUidsLocked(uids);
1301 mUidTagRecorder.removeUidsLocked(uids);
Jeff Sharkey163e6442011-10-31 16:37:52 -07001302
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001303 // Clear kernel stats associated with UID
1304 for (int uid : uids) {
1305 resetKernelUidStats(uid);
1306 }
1307 }
1308
1309 /**
1310 * Clean up {@link #mUidRecorder} after user is removed.
1311 */
1312 private void removeUserLocked(int userId) {
1313 if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1314
1315 // Build list of UIDs that we should clean up
1316 int[] uids = new int[0];
1317 final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001318 PackageManager.MATCH_ANY_USER
1319 | PackageManager.MATCH_DISABLED_COMPONENTS);
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001320 for (ApplicationInfo app : apps) {
1321 final int uid = UserHandle.getUid(userId, app.uid);
1322 uids = ArrayUtils.appendInt(uids, uid);
1323 }
1324
1325 removeUidsLocked(uids);
Jeff Sharkey75279902011-05-24 18:39:45 -07001326 }
1327
1328 @Override
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001329 protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001330 if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
Jeff Sharkey75279902011-05-24 18:39:45 -07001331
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001332 long duration = DateUtils.DAY_IN_MILLIS;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001333 final HashSet<String> argSet = new HashSet<String>();
1334 for (String arg : args) {
1335 argSet.add(arg);
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001336
1337 if (arg.startsWith("--duration=")) {
1338 try {
1339 duration = Long.parseLong(arg.substring(11));
1340 } catch (NumberFormatException ignored) {
1341 }
1342 }
Jeff Sharkey75279902011-05-24 18:39:45 -07001343 }
1344
Jeff Sharkey706498d2012-02-06 17:35:07 -08001345 // usage: dumpsys netstats --full --uid --tag --poll --checkin
Jeff Sharkey63abc372012-01-11 18:38:16 -08001346 final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
Jeff Sharkey706498d2012-02-06 17:35:07 -08001347 final boolean checkin = argSet.contains("--checkin");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001348 final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1349 final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1350 final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1351
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001352 final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
Jeff Sharkey350083e2011-06-29 10:45:16 -07001353
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001354 synchronized (mStatsLock) {
Makoto Onukida65a522017-01-13 10:23:30 -08001355 if (args.length > 0 && "--proto".equals(args[0])) {
1356 // In this case ignore all other arguments.
Jeff Sharkey4635f102017-09-01 11:27:13 -06001357 dumpProtoLocked(fd);
Makoto Onukida65a522017-01-13 10:23:30 -08001358 return;
1359 }
1360
Jeff Sharkey63abc372012-01-11 18:38:16 -08001361 if (poll) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001362 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
Jeff Sharkey3f391352011-06-05 17:42:53 -07001363 pw.println("Forced poll");
1364 return;
1365 }
1366
Jeff Sharkey706498d2012-02-06 17:35:07 -08001367 if (checkin) {
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001368 final long end = System.currentTimeMillis();
1369 final long start = end - duration;
1370
1371 pw.print("v1,");
1372 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1373 pw.print(end / SECOND_IN_MILLIS); pw.println();
1374
1375 pw.println("xt");
1376 mXtRecorder.dumpCheckin(rawWriter, start, end);
1377
1378 if (includeUid) {
1379 pw.println("uid");
1380 mUidRecorder.dumpCheckin(rawWriter, start, end);
Jeff Sharkey706498d2012-02-06 17:35:07 -08001381 }
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001382 if (includeTag) {
1383 pw.println("tag");
1384 mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1385 }
Jeff Sharkey706498d2012-02-06 17:35:07 -08001386 return;
1387 }
1388
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001389 pw.println("Active interfaces:");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001390 pw.increaseIndent();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001391 for (int i = 0; i < mActiveIfaces.size(); i++) {
1392 pw.printPair("iface", mActiveIfaces.keyAt(i));
1393 pw.printPair("ident", mActiveIfaces.valueAt(i));
1394 pw.println();
1395 }
1396 pw.decreaseIndent();
1397
1398 pw.println("Active UID interfaces:");
1399 pw.increaseIndent();
1400 for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1401 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1402 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1403 pw.println();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001404 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001405 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001406
Jeff Sharkey63abc372012-01-11 18:38:16 -08001407 pw.println("Dev stats:");
1408 pw.increaseIndent();
1409 mDevRecorder.dumpLocked(pw, fullHistory);
1410 pw.decreaseIndent();
1411
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001412 pw.println("Xt stats:");
1413 pw.increaseIndent();
1414 mXtRecorder.dumpLocked(pw, fullHistory);
1415 pw.decreaseIndent();
1416
Jeff Sharkey63abc372012-01-11 18:38:16 -08001417 if (includeUid) {
1418 pw.println("UID stats:");
1419 pw.increaseIndent();
1420 mUidRecorder.dumpLocked(pw, fullHistory);
1421 pw.decreaseIndent();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001422 }
1423
Jeff Sharkey63abc372012-01-11 18:38:16 -08001424 if (includeTag) {
1425 pw.println("UID tag stats:");
1426 pw.increaseIndent();
1427 mUidTagRecorder.dumpLocked(pw, fullHistory);
1428 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001429 }
1430 }
1431 }
1432
Jeff Sharkey4635f102017-09-01 11:27:13 -06001433 private void dumpProtoLocked(FileDescriptor fd) {
Makoto Onukida65a522017-01-13 10:23:30 -08001434 final ProtoOutputStream proto = new ProtoOutputStream(fd);
1435
1436 // TODO Right now it writes all history. Should it limit to the "since-boot" log?
1437
1438 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1439 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
1440 mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1441 mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1442 mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1443 mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
1444
1445 proto.flush();
1446 }
1447
1448 private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1449 ArrayMap<String, NetworkIdentitySet> ifaces) {
1450 for (int i = 0; i < ifaces.size(); i++) {
1451 final long start = proto.start(tag);
1452
1453 proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
1454 ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
1455
1456 proto.end(start);
1457 }
1458 }
1459
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001460 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001461 * Return snapshot of current UID statistics, including any
Jack Yuf9d559c2017-05-26 16:08:22 -07001462 * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1463 * values.
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001464 */
Jeff Sharkey63abc372012-01-11 18:38:16 -08001465 private NetworkStats getNetworkStatsUidDetail() throws RemoteException {
1466 final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001467
Jeff Sharkey63abc372012-01-11 18:38:16 -08001468 // fold tethering stats and operations into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001469 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001470 uidSnapshot.combineAllValues(tetherSnapshot);
Jack Yuf9d559c2017-05-26 16:08:22 -07001471
1472 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
1473 Context.TELEPHONY_SERVICE);
1474
1475 // fold video calling data usage stats into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001476 final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
Jack Yuf9d559c2017-05-26 16:08:22 -07001477 if (vtStats != null) {
1478 uidSnapshot.combineAllValues(vtStats);
1479 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001480 uidSnapshot.combineAllValues(mUidOperations);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001481
Jeff Sharkey63abc372012-01-11 18:38:16 -08001482 return uidSnapshot;
Jeff Sharkey75279902011-05-24 18:39:45 -07001483 }
1484
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001485 /**
Jack Yuf9d559c2017-05-26 16:08:22 -07001486 * Return snapshot of current XT statistics with video calling data usage statistics.
Jack Yub6587ea2016-06-22 11:35:10 -07001487 */
Jack Yuf9d559c2017-05-26 16:08:22 -07001488 private NetworkStats getNetworkStatsXt() throws RemoteException {
Jack Yub6587ea2016-06-22 11:35:10 -07001489 final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
1490
Jack Yuf9d559c2017-05-26 16:08:22 -07001491 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Jack Yub6587ea2016-06-22 11:35:10 -07001492 Context.TELEPHONY_SERVICE);
1493
Jack Yuf9d559c2017-05-26 16:08:22 -07001494 // Merge video calling data usage into XT
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001495 final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
Jack Yuf9d559c2017-05-26 16:08:22 -07001496 if (vtSnapshot != null) {
1497 xtSnapshot.combineAllValues(vtSnapshot);
1498 }
Jack Yub6587ea2016-06-22 11:35:10 -07001499
1500 return xtSnapshot;
1501 }
1502
1503 /**
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001504 * Return snapshot of current tethering statistics. Will return empty
1505 * {@link NetworkStats} if any problems are encountered.
1506 */
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001507 private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001508 try {
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001509 return mNetworkManager.getNetworkStatsTethering(how);
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001510 } catch (IllegalStateException e) {
1511 Log.wtf(TAG, "problem reading network stats", e);
1512 return new NetworkStats(0L, 10);
1513 }
1514 }
1515
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001516 @VisibleForTesting
1517 static class HandlerCallback implements Handler.Callback {
1518 private final NetworkStatsService mService;
1519
1520 HandlerCallback(NetworkStatsService service) {
1521 this.mService = service;
1522 }
1523
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001524 @Override
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001525 public boolean handleMessage(Message msg) {
1526 switch (msg.what) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001527 case MSG_PERFORM_POLL: {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001528 final int flags = msg.arg1;
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001529 mService.performPoll(flags);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001530 return true;
1531 }
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001532 case MSG_UPDATE_IFACES: {
Lorenzo Colittic78da292018-01-19 00:50:48 +09001533 mService.updateIfaces(null);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001534 return true;
1535 }
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -08001536 case MSG_REGISTER_GLOBAL_ALERT: {
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001537 mService.registerGlobalAlert();
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -08001538 return true;
1539 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001540 default: {
1541 return false;
1542 }
1543 }
1544 }
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001545 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001546
Jeff Sharkey4190a042012-04-21 15:36:48 -07001547 private void assertBandwidthControlEnabled() {
1548 if (!isBandwidthControlEnabled()) {
1549 throw new IllegalStateException("Bandwidth module disabled");
1550 }
1551 }
1552
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001553 private boolean isBandwidthControlEnabled() {
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001554 final long token = Binder.clearCallingIdentity();
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001555 try {
1556 return mNetworkManager.isBandwidthControlEnabled();
1557 } catch (RemoteException e) {
1558 // ignored; service lives in system_server
1559 return false;
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001560 } finally {
1561 Binder.restoreCallingIdentity(token);
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001562 }
1563 }
1564
Jeff Sharkey63abc372012-01-11 18:38:16 -08001565 private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001566 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001567 public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
1568 int rightIndex, String cookie) {
1569 Log.w(TAG, "found non-monotonic values; saving to dropbox");
1570
1571 // record error for debugging
1572 final StringBuilder builder = new StringBuilder();
1573 builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
1574 + "] - right[" + rightIndex + "]\n");
1575 builder.append("left=").append(left).append('\n');
1576 builder.append("right=").append(right).append('\n');
1577
1578 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
1579 Context.DROPBOX_SERVICE);
1580 dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001581 }
1582 }
1583
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001584 /**
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001585 * Default external settings that read from
Jeff Sharkey625239a2012-09-26 22:03:49 -07001586 * {@link android.provider.Settings.Global}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001587 */
1588 private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
1589 private final ContentResolver mResolver;
1590
1591 public DefaultNetworkStatsSettings(Context context) {
1592 mResolver = checkNotNull(context.getContentResolver());
1593 // TODO: adjust these timings for production builds
1594 }
1595
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001596 private long getGlobalLong(String name, long def) {
1597 return Settings.Global.getLong(mResolver, name, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001598 }
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001599 private boolean getGlobalBoolean(String name, boolean def) {
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001600 final int defInt = def ? 1 : 0;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001601 return Settings.Global.getInt(mResolver, name, defInt) != 0;
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001602 }
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001603
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001604 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001605 public long getPollInterval() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001606 return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001607 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001608 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001609 public long getTimeCacheMaxAge() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001610 return getGlobalLong(NETSTATS_TIME_CACHE_MAX_AGE, DAY_IN_MILLIS);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001611 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001612 @Override
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001613 public long getGlobalAlertBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001614 return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001615 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001616 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001617 public boolean getSampleEnabled() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001618 return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001619 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001620 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -06001621 public boolean getAugmentEnabled() {
1622 return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
1623 }
1624 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001625 public Config getDevConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001626 return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
1627 getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1628 getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001629 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001630 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001631 public Config getXtConfig() {
1632 return getDevConfig();
1633 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001634 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001635 public Config getUidConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001636 return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1637 getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1638 getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001639 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001640 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001641 public Config getUidTagConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001642 return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1643 getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
1644 getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001645 }
1646 @Override
1647 public long getDevPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001648 return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001649 }
1650 @Override
1651 public long getXtPersistBytes(long def) {
1652 return getDevPersistBytes(def);
1653 }
1654 @Override
1655 public long getUidPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001656 return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001657 }
1658 @Override
1659 public long getUidTagPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001660 return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001661 }
1662 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001663
1664 private static int TYPE_RX_BYTES;
1665 private static int TYPE_RX_PACKETS;
1666 private static int TYPE_TX_BYTES;
1667 private static int TYPE_TX_PACKETS;
1668 private static int TYPE_TCP_RX_PACKETS;
1669 private static int TYPE_TCP_TX_PACKETS;
1670
1671 private static native long nativeGetTotalStat(int type);
1672 private static native long nativeGetIfaceStat(String iface, int type);
1673 private static native long nativeGetUidStat(int uid, int type);
Jeff Sharkey75279902011-05-24 18:39:45 -07001674}