blob: 08c94267e969777e11333329248c3712ac6b516d [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;
Chiachang Wange05d9d82019-04-09 19:42:52 +080028import static android.net.NetworkStack.checkNetworkStackPermission;
Lorenzo Colittiada23ed2018-01-19 01:05:20 +090029import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070030import static android.net.NetworkStats.IFACE_ALL;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090031import static android.net.NetworkStats.INTERFACES_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060032import static android.net.NetworkStats.METERED_ALL;
33import static android.net.NetworkStats.ROAMING_ALL;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070034import static android.net.NetworkStats.SET_ALL;
35import static android.net.NetworkStats.SET_DEFAULT;
36import static android.net.NetworkStats.SET_FOREGROUND;
Lorenzo Colitti5356a352017-08-17 19:23:08 +090037import static android.net.NetworkStats.STATS_PER_IFACE;
38import static android.net.NetworkStats.STATS_PER_UID;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090039import static android.net.NetworkStats.TAG_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070040import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey75279902011-05-24 18:39:45 -070041import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060042import static android.net.NetworkStatsHistory.FIELD_ALL;
Jeff Sharkey234766a2012-04-10 19:48:07 -070043import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070044import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -070045import static android.net.TrafficStats.KB_IN_BYTES;
Jeff Sharkey241dde22012-02-03 14:50:07 -080046import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey00072392018-04-12 14:26:32 -060047import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060048import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070049import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
50import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
51import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
52import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
53import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
54import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070055import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070056import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
57import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
58import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
59import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
60import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
61import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
62import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
63import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070064import static android.text.format.DateUtils.DAY_IN_MILLIS;
65import static android.text.format.DateUtils.HOUR_IN_MILLIS;
66import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070067import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jack Yuf9d559c2017-05-26 16:08:22 -070068
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070069import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070070import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070071import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
72import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
Jeff Sharkey75279902011-05-24 18:39:45 -070073
Jeff Sharkey9911a282018-02-14 22:29:11 -070074import android.annotation.NonNull;
Jeff Sharkey75279902011-05-24 18:39:45 -070075import android.app.AlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070076import android.app.PendingIntent;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060077import android.app.usage.NetworkStatsManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070078import android.content.BroadcastReceiver;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070079import android.content.ContentResolver;
Jeff Sharkey75279902011-05-24 18:39:45 -070080import android.content.Context;
81import android.content.Intent;
82import android.content.IntentFilter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070083import android.content.pm.ApplicationInfo;
84import android.content.pm.PackageManager;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080085import android.net.DataUsageRequest;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070086import android.net.INetworkManagementEventObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070087import android.net.INetworkStatsService;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -070088import android.net.INetworkStatsSession;
Jeff Sharkey63abc372012-01-11 18:38:16 -080089import android.net.LinkProperties;
Lorenzo Colittic78da292018-01-19 00:50:48 +090090import android.net.Network;
Jack Yub6587ea2016-06-22 11:35:10 -070091import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070092import android.net.NetworkIdentity;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070093import android.net.NetworkInfo;
94import android.net.NetworkState;
Jeff Sharkey75279902011-05-24 18:39:45 -070095import android.net.NetworkStats;
Jeff Sharkey5a7bcf32012-01-10 17:24:44 -080096import android.net.NetworkStats.NonMonotonicObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070097import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070098import android.net.NetworkTemplate;
Jeff Sharkey63abc372012-01-11 18:38:16 -080099import android.net.TrafficStats;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700100import android.os.BestClock;
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700101import android.os.Binder;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700102import android.os.DropBoxManager;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700103import android.os.Environment;
Jeff Sharkey75279902011-05-24 18:39:45 -0700104import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700105import android.os.HandlerThread;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800106import android.os.IBinder;
Jeff Sharkey75279902011-05-24 18:39:45 -0700107import android.os.INetworkManagementService;
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100108import android.os.Looper;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700109import android.os.Message;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800110import android.os.Messenger;
Jeff Sharkey62489262011-07-17 12:53:28 -0700111import android.os.PowerManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700112import android.os.RemoteException;
113import android.os.SystemClock;
Jeff Sharkey00072392018-04-12 14:26:32 -0600114import android.os.Trace;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700115import android.os.UserHandle;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700116import android.provider.Settings;
Jeff Sharkey625239a2012-09-26 22:03:49 -0700117import android.provider.Settings.Global;
Makoto Onukida65a522017-01-13 10:23:30 -0800118import android.service.NetworkInterfaceProto;
119import android.service.NetworkStatsServiceDumpProto;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600120import android.telephony.SubscriptionPlan;
Jeff Sharkey75279902011-05-24 18:39:45 -0700121import android.telephony.TelephonyManager;
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800122import android.text.format.DateUtils;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700123import android.util.ArrayMap;
124import android.util.ArraySet;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700125import android.util.EventLog;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700126import android.util.Log;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700127import android.util.MathUtils;
Jeff Sharkey75279902011-05-24 18:39:45 -0700128import android.util.Slog;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700129import android.util.SparseIntArray;
Makoto Onukida65a522017-01-13 10:23:30 -0800130import android.util.proto.ProtoOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -0700131
Jeff Sharkey4635f102017-09-01 11:27:13 -0600132import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800133import com.android.internal.annotations.VisibleForTesting;
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900134import com.android.internal.net.VpnInfo;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700135import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600136import com.android.internal.util.DumpUtils;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800137import com.android.internal.util.FileRotator;
138import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700139import com.android.server.EventLogTags;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700140import com.android.server.LocalServices;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700141import com.android.server.connectivity.Tethering;
Jeff Sharkey75279902011-05-24 18:39:45 -0700142
Jeff Sharkey3f391352011-06-05 17:42:53 -0700143import java.io.File;
Jeff Sharkey75279902011-05-24 18:39:45 -0700144import java.io.FileDescriptor;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700145import java.io.IOException;
Jeff Sharkey75279902011-05-24 18:39:45 -0700146import java.io.PrintWriter;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700147import java.time.Clock;
148import java.time.ZoneOffset;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700149import java.util.Arrays;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700150import java.util.HashSet;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700151import java.util.List;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700152
Jeff Sharkey75279902011-05-24 18:39:45 -0700153/**
154 * Collect and persist detailed network statistics, and provide this data to
155 * other system services.
156 */
157public class NetworkStatsService extends INetworkStatsService.Stub {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600158 static final String TAG = "NetworkStats";
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700159 static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
160 static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700161
Chalard Jeand7c6e122018-08-22 10:21:26 +0900162 // Perform polling and persist all (FLAG_PERSIST_ALL).
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700163 private static final int MSG_PERFORM_POLL = 1;
Chalard Jeand7c6e122018-08-22 10:21:26 +0900164 // Perform polling, persist network, and register the global alert again.
165 private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700166
167 /** Flags to control detail level of poll event. */
Jeff Sharkey905b5892011-09-30 15:19:49 -0700168 private static final int FLAG_PERSIST_NETWORK = 0x1;
169 private static final int FLAG_PERSIST_UID = 0x2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700170 private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700171 private static final int FLAG_PERSIST_FORCE = 0x100;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700172
Chalard Jeand7c6e122018-08-22 10:21:26 +0900173 /**
174 * When global alert quota is high, wait for this delay before processing each polling,
175 * and do not schedule further polls once there is already one queued.
176 * This avoids firing the global alert too often on devices with high transfer speeds and
177 * high quota.
178 */
179 private static final int PERFORM_POLL_DELAY_MS = 1000;
180
Jeff Sharkey163e6442011-10-31 16:37:52 -0700181 private static final String TAG_NETSTATS_ERROR = "netstats_error";
182
Jeff Sharkey75279902011-05-24 18:39:45 -0700183 private final Context mContext;
184 private final INetworkManagementService mNetworkManager;
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900185 private final NetworkStatsFactory mStatsFactory;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700186 private final AlarmManager mAlarmManager;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700187 private final Clock mClock;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700188 private final TelephonyManager mTeleManager;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700189 private final NetworkStatsSettings mSettings;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800190 private final NetworkStatsObservers mStatsObservers;
Jeff Sharkey75279902011-05-24 18:39:45 -0700191
Jeff Sharkey63abc372012-01-11 18:38:16 -0800192 private final File mSystemDir;
193 private final File mBaseDir;
194
Jeff Sharkey62489262011-07-17 12:53:28 -0700195 private final PowerManager.WakeLock mWakeLock;
196
Chenbo Feng00499822018-05-18 17:10:07 -0700197 private final boolean mUseBpfTrafficStats;
198
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800199 @VisibleForTesting
Jeff Sharkey3f391352011-06-05 17:42:53 -0700200 public static final String ACTION_NETWORK_STATS_POLL =
Jeff Sharkey75279902011-05-24 18:39:45 -0700201 "com.android.server.action.NETWORK_STATS_POLL";
Jeff Sharkey497e4432011-06-14 17:27:29 -0700202 public static final String ACTION_NETWORK_STATS_UPDATED =
203 "com.android.server.action.NETWORK_STATS_UPDATED";
Jeff Sharkey75279902011-05-24 18:39:45 -0700204
205 private PendingIntent mPollIntent;
206
Jeff Sharkey63abc372012-01-11 18:38:16 -0800207 private static final String PREFIX_DEV = "dev";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700208 private static final String PREFIX_XT = "xt";
Jeff Sharkey63abc372012-01-11 18:38:16 -0800209 private static final String PREFIX_UID = "uid";
210 private static final String PREFIX_UID_TAG = "uid_tag";
211
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700212 /**
Jack Yub6587ea2016-06-22 11:35:10 -0700213 * Virtual network interface for video telephony. This is for VT data usage counting purpose.
214 */
215 public static final String VT_INTERFACE = "vt_data0";
216
217 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700218 * Settings that can be changed externally.
219 */
220 public interface NetworkStatsSettings {
221 public long getPollInterval();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800222 public boolean getSampleEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600223 public boolean getAugmentEnabled();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800224
225 public static class Config {
226 public final long bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800227 public final long rotateAgeMillis;
228 public final long deleteAgeMillis;
229
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700230 public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800231 this.bucketDuration = bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800232 this.rotateAgeMillis = rotateAgeMillis;
233 this.deleteAgeMillis = deleteAgeMillis;
234 }
235 }
236
237 public Config getDevConfig();
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700238 public Config getXtConfig();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800239 public Config getUidConfig();
240 public Config getUidTagConfig();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700241
242 public long getGlobalAlertBytes(long def);
243 public long getDevPersistBytes(long def);
244 public long getXtPersistBytes(long def);
245 public long getUidPersistBytes(long def);
246 public long getUidTagPersistBytes(long def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700247 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700248
249 private final Object mStatsLock = new Object();
250
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700251 /** Set of currently active ifaces. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900252 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700253 private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900254
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700255 /** Set of currently active ifaces for UID stats. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900256 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700257 private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900258
Jeff Sharkey63abc372012-01-11 18:38:16 -0800259 /** Current default active iface. */
Varun Anandd33cbc62019-02-07 14:13:13 -0800260 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800261 private String mActiveIface;
Lorenzo Colittic78da292018-01-19 00:50:48 +0900262
Jeff Sharkey234766a2012-04-10 19:48:07 -0700263 /** Set of any ifaces associated with mobile networks since boot. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900264 @GuardedBy("mStatsLock")
Jeff Sharkey234766a2012-04-10 19:48:07 -0700265 private String[] mMobileIfaces = new String[0];
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700266
Lorenzo Colittic78da292018-01-19 00:50:48 +0900267 /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
268 @GuardedBy("mStatsLock")
269 private Network[] mDefaultNetworks = new Network[0];
270
Jeff Sharkey63abc372012-01-11 18:38:16 -0800271 private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
272 new DropBoxNonMonotonicObserver();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700273
Jeff Sharkey4635f102017-09-01 11:27:13 -0600274 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800275 private NetworkStatsRecorder mDevRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600276 @GuardedBy("mStatsLock")
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700277 private NetworkStatsRecorder mXtRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600278 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800279 private NetworkStatsRecorder mUidRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600280 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800281 private NetworkStatsRecorder mUidTagRecorder;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700282
Jeff Sharkey70c70532012-05-16 14:51:19 -0700283 /** Cached {@link #mXtRecorder} stats. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600284 @GuardedBy("mStatsLock")
Jeff Sharkey70c70532012-05-16 14:51:19 -0700285 private NetworkStatsCollection mXtStatsCached;
Jeff Sharkey75279902011-05-24 18:39:45 -0700286
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700287 /** Current counter sets for each UID. */
288 private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
289
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700290 /** Data layer operation counters for splicing into other structures. */
Jeff Sharkey63abc372012-01-11 18:38:16 -0800291 private NetworkStats mUidOperations = new NetworkStats(0L, 10);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700292
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800293 /** Must be set in factory by calling #setHandler. */
294 private Handler mHandler;
295 private Handler.Callback mHandlerCallback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700296
Jeff Sharkey050151e2018-04-13 14:28:30 -0600297 private volatile boolean mSystemReady;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700298 private long mPersistThreshold = 2 * MB_IN_BYTES;
299 private long mGlobalAlertBytes;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800300
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900301 private static final long POLL_RATE_LIMIT_MS = 15_000;
302
303 private long mLastStatsSessionPoll;
304
305 /** Map from UID to number of opened sessions */
306 @GuardedBy("mOpenSessionCallsPerUid")
307 private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
308
309 private final static int DUMP_STATS_SESSION_COUNT = 20;
310
Jeff Sharkey9911a282018-02-14 22:29:11 -0700311 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700312 return new File(Environment.getDataDirectory(), "system");
Jeff Sharkey75279902011-05-24 18:39:45 -0700313 }
314
Jeff Sharkey9911a282018-02-14 22:29:11 -0700315 private static @NonNull File getDefaultBaseDir() {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800316 File baseDir = new File(getDefaultSystemDir(), "netstats");
317 baseDir.mkdirs();
318 return baseDir;
319 }
320
Jeff Sharkey9911a282018-02-14 22:29:11 -0700321 private static @NonNull Clock getDefaultClock() {
322 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
323 Clock.systemUTC());
324 }
325
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100326 private static final class NetworkStatsHandler extends Handler {
327 NetworkStatsHandler(Looper looper, Handler.Callback callback) {
328 super(looper, callback);
329 }
330 }
331
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800332 public static NetworkStatsService create(Context context,
333 INetworkManagementService networkManager) {
334 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
335 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
336 PowerManager.WakeLock wakeLock =
337 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
338
339 NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
Jayachandran C43fa1be2019-11-15 09:58:04 -0800340 wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900341 new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
342 new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir());
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900343 service.registerLocalService();
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800344
345 HandlerThread handlerThread = new HandlerThread(TAG);
346 Handler.Callback callback = new HandlerCallback(service);
347 handlerThread.start();
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100348 Handler handler = new NetworkStatsHandler(handlerThread.getLooper(), callback);
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800349 service.setHandler(handler, callback);
350 return service;
351 }
352
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900353 // This must not be called outside of tests, even within the same package, as this constructor
354 // does not register the local service. Use the create() helper above.
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800355 @VisibleForTesting
356 NetworkStatsService(Context context, INetworkManagementService networkManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700357 AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800358 TelephonyManager teleManager, NetworkStatsSettings settings,
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900359 NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
360 File baseDir) {
Jeff Sharkey75279902011-05-24 18:39:45 -0700361 mContext = checkNotNull(context, "missing Context");
362 mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800363 mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
Jeff Sharkey9911a282018-02-14 22:29:11 -0700364 mClock = checkNotNull(clock, "missing Clock");
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700365 mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800366 mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
367 mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900368 mStatsFactory = checkNotNull(factory, "missing factory");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800369 mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
370 mSystemDir = checkNotNull(systemDir, "missing systemDir");
371 mBaseDir = checkNotNull(baseDir, "missing baseDir");
Chenbo Feng6880d632018-12-22 13:20:31 -0800372 mUseBpfTrafficStats = new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists();
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900373 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700374
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900375 private void registerLocalService() {
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700376 LocalServices.addService(NetworkStatsManagerInternal.class,
377 new NetworkStatsManagerInternalImpl());
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800378 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700379
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800380 @VisibleForTesting
381 void setHandler(Handler handler, Handler.Callback callback) {
382 mHandler = handler;
383 mHandlerCallback = callback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700384 }
385
386 public void systemReady() {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800387 synchronized (mStatsLock) {
Hugo Benichi96dc0c12019-05-15 23:38:43 +0900388 mSystemReady = true;
389
Jeff Sharkey4635f102017-09-01 11:27:13 -0600390 // create data recorders along with historical rotators
391 mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
392 mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
393 mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
394 mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
395
396 updatePersistThresholdsLocked();
397
Jeff Sharkey63abc372012-01-11 18:38:16 -0800398 // upgrade any legacy stats, migrating them to rotated files
399 maybeUpgradeLegacyStatsLocked();
400
401 // read historical network stats from disk, since policy service
402 // might need them right away.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700403 mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800404
405 // bootstrap initial stats to prevent double-counting later
406 bootstrapStatsLocked();
407 }
Jeff Sharkey3359aca2011-11-08 18:08:48 -0800408
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700409 // watch for tethering changes
410 final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
Vinit Deshpande92d141f2014-09-10 18:05:10 -0700411 mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700412
Jeff Sharkey75279902011-05-24 18:39:45 -0700413 // listen for periodic polling events
414 final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700415 mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
Jeff Sharkey75279902011-05-24 18:39:45 -0700416
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700417 // listen for uid removal to clean stats
418 final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
419 mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
420
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700421 // listen for user changes to clean stats
422 final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
423 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
424
Jeff Sharkey75279902011-05-24 18:39:45 -0700425 // persist stats during clean shutdown
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700426 final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
427 mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
Jeff Sharkey75279902011-05-24 18:39:45 -0700428
429 try {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700430 mNetworkManager.registerObserver(mAlertObserver);
Jeff Sharkey75279902011-05-24 18:39:45 -0700431 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700432 // ignored; service lives in system_server
Jeff Sharkey75279902011-05-24 18:39:45 -0700433 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700434
Hugo Benichi96dc0c12019-05-15 23:38:43 +0900435 // schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
436 final PendingIntent pollIntent =
437 PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
438
439 final long currentRealtime = SystemClock.elapsedRealtime();
440 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
441 mSettings.getPollInterval(), pollIntent);
442
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700443 registerGlobalAlert();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800444 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700445
Jeff Sharkey63abc372012-01-11 18:38:16 -0800446 private NetworkStatsRecorder buildRecorder(
447 String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700448 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
449 Context.DROPBOX_SERVICE);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700450 return new NetworkStatsRecorder(new FileRotator(
451 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700452 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
Jeff Sharkey75279902011-05-24 18:39:45 -0700453 }
454
Andreas Gampea36dc622018-02-05 17:19:22 -0800455 @GuardedBy("mStatsLock")
Jeff Sharkey3f391352011-06-05 17:42:53 -0700456 private void shutdownLocked() {
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700457 mContext.unregisterReceiver(mTetherReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700458 mContext.unregisterReceiver(mPollReceiver);
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700459 mContext.unregisterReceiver(mRemovedReceiver);
Ryuki Nakamuraa47b0c92017-03-01 10:40:36 +0900460 mContext.unregisterReceiver(mUserReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700461 mContext.unregisterReceiver(mShutdownReceiver);
462
Jeff Sharkey9911a282018-02-14 22:29:11 -0700463 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800464
465 // persist any pending stats
466 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700467 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800468 mUidRecorder.forcePersistLocked(currentTime);
469 mUidTagRecorder.forcePersistLocked(currentTime);
470
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800471 mSystemReady = false;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800472 }
473
Andreas Gampea36dc622018-02-05 17:19:22 -0800474 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800475 private void maybeUpgradeLegacyStatsLocked() {
476 File file;
477 try {
478 file = new File(mSystemDir, "netstats.bin");
479 if (file.exists()) {
480 mDevRecorder.importLegacyNetworkLocked(file);
481 file.delete();
482 }
483
484 file = new File(mSystemDir, "netstats_xt.bin");
485 if (file.exists()) {
486 file.delete();
487 }
488
489 file = new File(mSystemDir, "netstats_uid.bin");
490 if (file.exists()) {
491 mUidRecorder.importLegacyUidLocked(file);
492 mUidTagRecorder.importLegacyUidLocked(file);
493 file.delete();
494 }
495 } catch (IOException e) {
496 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700497 } catch (OutOfMemoryError e) {
498 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeyc506ff62011-11-17 11:59:29 -0800499 }
Jeff Sharkey3f391352011-06-05 17:42:53 -0700500 }
501
Jeff Sharkey75279902011-05-24 18:39:45 -0700502 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700503 * Register for a global alert that is delivered through
504 * {@link INetworkManagementEventObserver} once a threshold amount of data
505 * has been transferred.
506 */
507 private void registerGlobalAlert() {
508 try {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700509 mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700510 } catch (IllegalStateException e) {
511 Slog.w(TAG, "problem registering for global alert: " + e);
512 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700513 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700514 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700515 }
516
517 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700518 public INetworkStatsSession openSession() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600519 // NOTE: if callers want to get non-augmented data, they should go
520 // through the public API
521 return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000522 }
523
524 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600525 public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
526 return openSessionInternal(flags, callingPackage);
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100527 }
528
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900529 private boolean isRateLimitedForPoll(int callingUid) {
530 if (callingUid == android.os.Process.SYSTEM_UID) {
531 return false;
532 }
533
534 final long lastCallTime;
535 final long now = SystemClock.elapsedRealtime();
536 synchronized (mOpenSessionCallsPerUid) {
537 int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
538 mOpenSessionCallsPerUid.put(callingUid, calls + 1);
539 lastCallTime = mLastStatsSessionPoll;
540 mLastStatsSessionPoll = now;
541 }
542
543 return now - lastCallTime < POLL_RATE_LIMIT_MS;
544 }
545
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600546 private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900547 final int callingUid = Binder.getCallingUid();
548 final int usedFlags = isRateLimitedForPoll(callingUid)
549 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
550 : flags;
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600551 if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
552 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100553 final long ident = Binder.clearCallingIdentity();
554 try {
555 performPoll(FLAG_PERSIST_ALL);
556 } finally {
557 Binder.restoreCallingIdentity(ident);
558 }
559 }
560
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700561 // return an IBinder which holds strong references to any loaded stats
562 // for its lifetime; when caller closes only weak references remain.
563
564 return new INetworkStatsSession.Stub() {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900565 private final int mCallingUid = callingUid;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600566 private final String mCallingPackage = callingPackage;
567 private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
568 callingPackage);
569
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700570 private NetworkStatsCollection mUidComplete;
571 private NetworkStatsCollection mUidTagComplete;
572
573 private NetworkStatsCollection getUidComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700574 synchronized (mStatsLock) {
575 if (mUidComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700576 mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
577 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700578 return mUidComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700579 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700580 }
581
582 private NetworkStatsCollection getUidTagComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700583 synchronized (mStatsLock) {
584 if (mUidTagComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700585 mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
586 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700587 return mUidTagComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700588 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700589 }
590
591 @Override
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000592 public int[] getRelevantUids() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600593 return getUidComplete().getRelevantUids(mAccessLevel);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000594 }
595
596 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600597 public NetworkStats getDeviceSummaryForNetwork(
598 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900599 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600600 mCallingUid);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000601 }
602
603 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700604 public NetworkStats getSummaryForNetwork(
605 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900606 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600607 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700608 }
609
610 @Override
611 public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900612 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600613 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700614 }
615
616 @Override
617 public NetworkStats getSummaryForAllUid(
618 NetworkTemplate template, long start, long end, boolean includeTags) {
Jeff Davidson39583b52016-12-12 11:55:37 -0800619 try {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600620 final NetworkStats stats = getUidComplete()
621 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800622 if (includeTags) {
623 final NetworkStats tagStats = getUidTagComplete()
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600624 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800625 stats.combineAllValues(tagStats);
626 }
627 return stats;
628 } catch (NullPointerException e) {
629 // TODO: Track down and fix the cause of this crash and remove this catch block.
630 Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
631 throw e;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700632 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700633 }
634
635 @Override
636 public NetworkStatsHistory getHistoryForUid(
637 NetworkTemplate template, int uid, int set, int tag, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600638 // NOTE: We don't augment UID-level statistics
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700639 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600640 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
641 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700642 } else {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600643 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
644 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700645 }
646 }
647
648 @Override
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100649 public NetworkStatsHistory getHistoryIntervalForUid(
650 NetworkTemplate template, int uid, int set, int tag, int fields,
651 long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600652 // NOTE: We don't augment UID-level statistics
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100653 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600654 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
655 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700656 } else if (uid == Binder.getCallingUid()) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600657 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
658 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700659 } else {
660 throw new SecurityException("Calling package " + mCallingPackage
661 + " cannot access tag information from a different uid");
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100662 }
663 }
664
665 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700666 public void close() {
667 mUidComplete = null;
668 mUidTagComplete = null;
669 }
670 };
Jeff Sharkey905b5892011-09-30 15:19:49 -0700671 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700672
Jeff Davidson1efb1332015-12-09 18:04:50 -0800673 private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
674 return NetworkStatsAccess.checkAccessLevel(
675 mContext, Binder.getCallingUid(), callingPackage);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000676 }
677
Jeff Sharkey70c70532012-05-16 14:51:19 -0700678 /**
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600679 * Find the most relevant {@link SubscriptionPlan} for the given
680 * {@link NetworkTemplate} and flags. This is typically used to augment
681 * local measurement results to match a known anchor from the carrier.
682 */
683 private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
684 SubscriptionPlan plan = null;
685 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600686 && mSettings.getAugmentEnabled()) {
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700687 if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600688 final long token = Binder.clearCallingIdentity();
689 try {
Jeff Sharkey146bb332018-04-18 15:42:57 -0600690 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
691 .getSubscriptionPlan(template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600692 } finally {
693 Binder.restoreCallingIdentity(token);
694 }
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700695 if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600696 }
697 return plan;
698 }
699
700 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700701 * Return network summary, splicing between DEV and XT stats when
702 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700703 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600704 private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
705 long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700706 // We've been using pure XT stats long enough that we no longer need to
707 // splice DEV and XT together.
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600708 final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
709 accessLevel, callingUid);
710
711 final long now = System.currentTimeMillis();
712 final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
713
714 final NetworkStats stats = new NetworkStats(end - start, 1);
Lorenzo Colittiada23ed2018-01-19 01:05:20 +0900715 stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
716 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
717 entry.txBytes, entry.txPackets, entry.operations));
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600718 return stats;
Jeff Sharkey70c70532012-05-16 14:51:19 -0700719 }
720
721 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700722 * Return network history, splicing between DEV and XT stats when
723 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700724 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600725 private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
726 int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700727 // We've been using pure XT stats long enough that we no longer need to
728 // splice DEV and XT together.
Jeff Sharkey4635f102017-09-01 11:27:13 -0600729 final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
730 synchronized (mStatsLock) {
731 return mXtStatsCached.getHistory(template, augmentPlan,
732 UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
733 accessLevel, callingUid);
734 }
Jeff Sharkey70c70532012-05-16 14:51:19 -0700735 }
736
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700737 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
738 assertSystemReady();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600739
740 // NOTE: if callers want to get non-augmented data, they should go
741 // through the public API
742 return internalGetSummaryForNetwork(template,
743 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
744 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700745 }
746
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700747 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
748 assertSystemReady();
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700749
750 final NetworkStatsCollection uidComplete;
751 synchronized (mStatsLock) {
752 uidComplete = mUidRecorder.getOrLoadCompleteLocked();
753 }
754 return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
755 android.os.Process.SYSTEM_UID);
756 }
757
Jeff Sharkey350083e2011-06-29 10:45:16 -0700758 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700759 public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
760 if (Binder.getCallingUid() != uid) {
761 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
762 }
763
764 // TODO: switch to data layer stats once kernel exports
765 // for now, read network layer stats and flatten across all ifaces
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900766 final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800767
Jeff Sharkey21a54782012-04-09 10:27:55 -0700768 // splice in operation counts
769 networkLayer.spliceOperationsFrom(mUidOperations);
770
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700771 final NetworkStats dataLayer = new NetworkStats(
772 networkLayer.getElapsedRealtime(), networkLayer.size());
773
774 NetworkStats.Entry entry = null;
775 for (int i = 0; i < networkLayer.size(); i++) {
776 entry = networkLayer.getValues(i, entry);
777 entry.iface = IFACE_ALL;
778 dataLayer.combineValues(entry);
779 }
780
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700781 return dataLayer;
782 }
783
784 @Override
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900785 public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
786 try {
787 final String[] ifacesToQuery =
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900788 mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
Varun Anand6a04d492019-06-10 22:43:52 +0000789 return getNetworkStatsUidDetail(ifacesToQuery);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900790 } catch (RemoteException e) {
791 Log.wtf(TAG, "Error compiling UID stats", e);
792 return new NetworkStats(0L, 0);
793 }
794 }
795
796 @Override
Jeff Sharkey234766a2012-04-10 19:48:07 -0700797 public String[] getMobileIfaces() {
798 return mMobileIfaces;
799 }
800
801 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700802 public void incrementOperationCount(int uid, int tag, int operationCount) {
803 if (Binder.getCallingUid() != uid) {
Jeff Sharkey9f09e6a72017-06-26 11:24:47 -0600804 mContext.enforceCallingOrSelfPermission(
805 android.Manifest.permission.UPDATE_DEVICE_STATS, TAG);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700806 }
807
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700808 if (operationCount < 0) {
809 throw new IllegalArgumentException("operation count can only be incremented");
810 }
811 if (tag == TAG_NONE) {
812 throw new IllegalArgumentException("operation count must have specific tag");
813 }
814
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700815 synchronized (mStatsLock) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700816 final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800817 mUidOperations.combineValues(
818 mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
819 mUidOperations.combineValues(
820 mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700821 }
822 }
823
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700824 @VisibleForTesting
825 void setUidForeground(int uid, boolean uidForeground) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700826 synchronized (mStatsLock) {
827 final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
828 final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
829 if (oldSet != set) {
830 mActiveUidCounterSet.put(uid, set);
831 setKernelCounterSet(uid, set);
832 }
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700833 }
834 }
835
836 @Override
Varun Anandd33cbc62019-02-07 14:13:13 -0800837 public void forceUpdateIfaces(
838 Network[] defaultNetworks,
Varun Anandd33cbc62019-02-07 14:13:13 -0800839 NetworkState[] networkStates,
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900840 String activeIface,
841 VpnInfo[] vpnInfos) {
Chiachang Wange05d9d82019-04-09 19:42:52 +0800842 checkNetworkStackPermission(mContext);
Jeff Sharkey69736342014-12-08 14:50:12 -0800843
844 final long token = Binder.clearCallingIdentity();
845 try {
Benedict Wong9fbbdeb2019-06-12 17:46:31 +0000846 updateIfaces(defaultNetworks, networkStates, activeIface);
Jeff Sharkey69736342014-12-08 14:50:12 -0800847 } finally {
848 Binder.restoreCallingIdentity(token);
849 }
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900850
851 // Update the VPN underlying interfaces only after the poll is made and tun data has been
852 // migrated. Otherwise the migration would use the new interfaces instead of the ones that
853 // were current when the polled data was transferred.
854 mStatsFactory.updateVpnInfos(vpnInfos);
Jeff Sharkey69736342014-12-08 14:50:12 -0800855 }
856
857 @Override
Jeff Sharkey350083e2011-06-29 10:45:16 -0700858 public void forceUpdate() {
859 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkeye630f7b2012-01-31 17:12:53 -0800860
861 final long token = Binder.clearCallingIdentity();
862 try {
863 performPoll(FLAG_PERSIST_ALL);
864 } finally {
865 Binder.restoreCallingIdentity(token);
866 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700867 }
868
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700869 private void advisePersistThreshold(long thresholdBytes) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700870 // clamp threshold into safe range
871 mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700872 if (LOGV) {
873 Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
874 + mPersistThreshold);
875 }
876
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700877 // update and persist if beyond new thresholds
Jeff Sharkey9911a282018-02-14 22:29:11 -0700878 final long currentTime = mClock.millis();
Jeff Sharkey58015972012-05-07 11:08:49 -0700879 synchronized (mStatsLock) {
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700880 if (!mSystemReady) return;
881
Jeff Sharkey4635f102017-09-01 11:27:13 -0600882 updatePersistThresholdsLocked();
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700883
Jeff Sharkey58015972012-05-07 11:08:49 -0700884 mDevRecorder.maybePersistLocked(currentTime);
885 mXtRecorder.maybePersistLocked(currentTime);
886 mUidRecorder.maybePersistLocked(currentTime);
887 mUidTagRecorder.maybePersistLocked(currentTime);
888 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700889
890 // re-arm global alert
891 registerGlobalAlert();
892 }
893
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800894 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700895 public DataUsageRequest registerUsageCallback(String callingPackage,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800896 DataUsageRequest request, Messenger messenger, IBinder binder) {
897 checkNotNull(callingPackage, "calling package is null");
898 checkNotNull(request, "DataUsageRequest is null");
Antonio Cansado6965c182016-03-30 11:37:18 -0700899 checkNotNull(request.template, "NetworkTemplate is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800900 checkNotNull(messenger, "messenger is null");
901 checkNotNull(binder, "binder is null");
902
903 int callingUid = Binder.getCallingUid();
904 @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
905 DataUsageRequest normalizedRequest;
906 final long token = Binder.clearCallingIdentity();
907 try {
908 normalizedRequest = mStatsObservers.register(request, messenger, binder,
909 callingUid, accessLevel);
910 } finally {
911 Binder.restoreCallingIdentity(token);
912 }
913
914 // Create baseline stats
Chalard Jeand7c6e122018-08-22 10:21:26 +0900915 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800916
917 return normalizedRequest;
918 }
919
920 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700921 public void unregisterUsageRequest(DataUsageRequest request) {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800922 checkNotNull(request, "DataUsageRequest is null");
923
924 int callingUid = Binder.getCallingUid();
925 final long token = Binder.clearCallingIdentity();
926 try {
927 mStatsObservers.unregister(request, callingUid);
928 } finally {
929 Binder.restoreCallingIdentity(token);
930 }
931 }
932
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800933 @Override
934 public long getUidStats(int uid, int type) {
Chenbo Fengaedd6a32017-11-20 18:23:46 -0800935 return nativeGetUidStat(uid, type, checkBpfStatsEnable());
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800936 }
937
938 @Override
939 public long getIfaceStats(String iface, int type) {
Mike SUce756752018-11-26 15:05:13 +0800940 long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
941 if (nativeIfaceStats == -1) {
942 return nativeIfaceStats;
943 } else {
944 // When tethering offload is in use, nativeIfaceStats does not contain usage from
945 // offload, add it back here.
946 // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
947 // this does not cause double-counting of tethering traffic, because
948 // NetdTetheringStatsProvider returns zero NetworkStats
949 // when called with STATS_PER_IFACE.
950 return nativeIfaceStats + getTetherStats(iface, type);
951 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800952 }
953
954 @Override
955 public long getTotalStats(int type) {
Mike SUce756752018-11-26 15:05:13 +0800956 long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
957 if (nativeTotalStats == -1) {
958 return nativeTotalStats;
959 } else {
960 // Refer to comment in getIfaceStats
961 return nativeTotalStats + getTetherStats(IFACE_ALL, type);
962 }
963 }
964
965 private long getTetherStats(String iface, int type) {
966 final NetworkStats tetherSnapshot;
967 final long token = Binder.clearCallingIdentity();
968 try {
969 tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
970 } catch (RemoteException e) {
971 Slog.w(TAG, "Error get TetherStats: " + e);
972 return 0;
973 } finally {
974 Binder.restoreCallingIdentity(token);
975 }
976 HashSet<String> limitIfaces;
977 if (iface == IFACE_ALL) {
978 limitIfaces = null;
979 } else {
980 limitIfaces = new HashSet<String>();
981 limitIfaces.add(iface);
982 }
983 NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
984 if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
985 " entry=" + entry);
986 switch (type) {
987 case 0: // TYPE_RX_BYTES
988 return entry.rxBytes;
989 case 1: // TYPE_RX_PACKETS
990 return entry.rxPackets;
991 case 2: // TYPE_TX_BYTES
992 return entry.txBytes;
993 case 3: // TYPE_TX_PACKETS
994 return entry.txPackets;
995 default:
996 return 0;
997 }
Chenbo Fengaedd6a32017-11-20 18:23:46 -0800998 }
999
1000 private boolean checkBpfStatsEnable() {
Chenbo Feng00499822018-05-18 17:10:07 -07001001 return mUseBpfTrafficStats;
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001002 }
1003
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001004 /**
1005 * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
1006 * reflect current {@link #mPersistThreshold} value. Always defers to
Jeff Sharkey625239a2012-09-26 22:03:49 -07001007 * {@link Global} values when defined.
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001008 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001009 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001010 private void updatePersistThresholdsLocked() {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001011 mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
1012 mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
1013 mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
1014 mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
1015 mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
1016 }
1017
Jeff Sharkey75279902011-05-24 18:39:45 -07001018 /**
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001019 * Receiver that watches for {@link Tethering} to claim interface pairs.
1020 */
1021 private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
1022 @Override
1023 public void onReceive(Context context, Intent intent) {
1024 // on background handler thread, and verified CONNECTIVITY_INTERNAL
1025 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001026 performPoll(FLAG_PERSIST_NETWORK);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001027 }
1028 };
1029
Jeff Sharkey75279902011-05-24 18:39:45 -07001030 private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
1031 @Override
1032 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001033 // on background handler thread, and verified UPDATE_DEVICE_STATS
1034 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001035 performPoll(FLAG_PERSIST_ALL);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001036
1037 // verify that we're watching global alert
1038 registerGlobalAlert();
Jeff Sharkey75279902011-05-24 18:39:45 -07001039 }
1040 };
1041
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001042 private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
1043 @Override
1044 public void onReceive(Context context, Intent intent) {
1045 // on background handler thread, and UID_REMOVED is protected
1046 // broadcast.
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001047
1048 final int uid = intent.getIntExtra(EXTRA_UID, -1);
1049 if (uid == -1) return;
1050
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001051 synchronized (mStatsLock) {
Jeff Sharkey62489262011-07-17 12:53:28 -07001052 mWakeLock.acquire();
1053 try {
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001054 removeUidsLocked(uid);
1055 } finally {
1056 mWakeLock.release();
1057 }
1058 }
1059 }
1060 };
1061
1062 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1063 @Override
1064 public void onReceive(Context context, Intent intent) {
1065 // On background handler thread, and USER_REMOVED is protected
1066 // broadcast.
1067
1068 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1069 if (userId == -1) return;
1070
1071 synchronized (mStatsLock) {
1072 mWakeLock.acquire();
1073 try {
1074 removeUserLocked(userId);
Jeff Sharkey62489262011-07-17 12:53:28 -07001075 } finally {
1076 mWakeLock.release();
1077 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001078 }
1079 }
1080 };
1081
Jeff Sharkey75279902011-05-24 18:39:45 -07001082 private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
1083 @Override
1084 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001085 // SHUTDOWN is protected broadcast.
Jeff Sharkey75279902011-05-24 18:39:45 -07001086 synchronized (mStatsLock) {
Jeff Sharkey3f391352011-06-05 17:42:53 -07001087 shutdownLocked();
Jeff Sharkey75279902011-05-24 18:39:45 -07001088 }
1089 }
1090 };
1091
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001092 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001093 * Observer that watches for {@link INetworkManagementService} alerts.
1094 */
Jeff Sharkey216c1812012-08-05 14:29:23 -07001095 private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001096 @Override
1097 public void limitReached(String limitName, String iface) {
1098 // only someone like NMS should be calling us
1099 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1100
1101 if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001102 // kick off background poll to collect network stats unless there is already
1103 // such a call pending; UID stats are handled during normal polling interval.
1104 if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
1105 mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
1106 PERFORM_POLL_DELAY_MS);
1107 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001108 }
1109 }
1110 };
1111
Varun Anandd33cbc62019-02-07 14:13:13 -08001112 private void updateIfaces(
1113 Network[] defaultNetworks,
Varun Anandd33cbc62019-02-07 14:13:13 -08001114 NetworkState[] networkStates,
1115 String activeIface) {
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001116 synchronized (mStatsLock) {
1117 mWakeLock.acquire();
1118 try {
Varun Anandd33cbc62019-02-07 14:13:13 -08001119 mActiveIface = activeIface;
1120 updateIfacesLocked(defaultNetworks, networkStates);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001121 } finally {
1122 mWakeLock.release();
1123 }
1124 }
1125 }
1126
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001127 /**
Benedict Wong9fbbdeb2019-06-12 17:46:31 +00001128 * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
1129 * NetworkStatsHistory}. When multiple {@link NetworkInfo} are active on a single {@code iface},
1130 * they are combined under a single {@link NetworkIdentitySet}.
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001131 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001132 @GuardedBy("mStatsLock")
Varun Anandd33cbc62019-02-07 14:13:13 -08001133 private void updateIfacesLocked(Network[] defaultNetworks, NetworkState[] states) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001134 if (!mSystemReady) return;
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001135 if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001136
1137 // take one last stats snapshot before updating iface mapping. this
1138 // isn't perfect, since the kernel may already be counting traffic from
1139 // the updated network.
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001140
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001141 // poll, but only persist network stats to keep codepath fast. UID stats
1142 // will be persisted during next alarm poll event.
1143 performPollLocked(FLAG_PERSIST_NETWORK);
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001144
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001145 // Rebuild active interfaces based on connected networks
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001146 mActiveIfaces.clear();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001147 mActiveUidIfaces.clear();
Lorenzo Colittic78da292018-01-19 00:50:48 +09001148 if (defaultNetworks != null) {
1149 // Caller is ConnectivityService. Update the list of default networks.
1150 mDefaultNetworks = defaultNetworks;
1151 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001152
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001153 final ArraySet<String> mobileIfaces = new ArraySet<>();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001154 for (NetworkState state : states) {
1155 if (state.networkInfo.isConnected()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001156 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001157 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
1158 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1159 isDefault);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001160
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001161 // Traffic occurring on the base interface is always counted for
1162 // both total usage and UID details.
1163 final String baseIface = state.linkProperties.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001164 if (baseIface != null) {
1165 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1166 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
Jack Yub6587ea2016-06-22 11:35:10 -07001167
1168 // Build a separate virtual interface for VT (Video Telephony) data usage.
1169 // Only do this when IMS is not metered, but VT is metered.
1170 // If IMS is metered, then the IMS network usage has already included VT usage.
1171 // VT is considered always metered in framework's layer. If VT is not metered
1172 // per carrier's policy, modem will report 0 usage for VT calls.
1173 if (state.networkCapabilities.hasCapability(
1174 NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1175
1176 // Copy the identify from IMS one but mark it as metered.
1177 NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1178 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001179 ident.getRoaming(), true /* metered */,
1180 true /* onDefaultNetwork */);
Jack Yub6587ea2016-06-22 11:35:10 -07001181 findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent);
1182 findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent);
1183 }
1184
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001185 if (isMobile) {
1186 mobileIfaces.add(baseIface);
1187 }
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001188 }
1189
junyulai669ef462019-06-28 16:47:49 +08001190 // Traffic occurring on stacked interfaces is usually clatd.
1191 // UID stats are always counted on the stacked interface and never
1192 // on the base interface, because the packets on the base interface
1193 // do not actually match application sockets until they are translated.
1194 //
1195 // Interface stats are more complicated. Packets subject to BPF offload
1196 // never appear on the base interface and only appear on the stacked
1197 // interface, so to ensure those packets increment interface stats, interface
1198 // stats from stacked interfaces must be collected.
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001199 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1200 for (LinkProperties stackedLink : stackedLinks) {
1201 final String stackedIface = stackedLink.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001202 if (stackedIface != null) {
junyulai669ef462019-06-28 16:47:49 +08001203 if (mUseBpfTrafficStats) {
1204 findOrCreateNetworkIdentitySet(mActiveIfaces, stackedIface).add(ident);
1205 }
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001206 findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1207 if (isMobile) {
1208 mobileIfaces.add(stackedIface);
1209 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001210
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001211 mStatsFactory.noteStackedIface(stackedIface, baseIface);
Jeff Sharkey234766a2012-04-10 19:48:07 -07001212 }
1213 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001214 }
1215 }
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001216
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001217 mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1218 }
1219
1220 private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1221 ArrayMap<K, NetworkIdentitySet> map, K key) {
1222 NetworkIdentitySet ident = map.get(key);
1223 if (ident == null) {
1224 ident = new NetworkIdentitySet();
1225 map.put(key, ident);
1226 }
1227 return ident;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001228 }
1229
Andreas Gampea36dc622018-02-05 17:19:22 -08001230 @GuardedBy("mStatsLock")
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001231 private void recordSnapshotLocked(long currentTime) throws RemoteException {
1232 // snapshot and record current counters; read UID stats first to
Jack Yub6587ea2016-06-22 11:35:10 -07001233 // avoid over counting dev stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001234 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001235 final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
Jeff Sharkey00072392018-04-12 14:26:32 -06001236 Trace.traceEnd(TRACE_TAG_NETWORK);
1237 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
Jack Yuf9d559c2017-05-26 16:08:22 -07001238 final NetworkStats xtSnapshot = getNetworkStatsXt();
Jeff Sharkey00072392018-04-12 14:26:32 -06001239 Trace.traceEnd(TRACE_TAG_NETWORK);
1240 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001241 final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
Jeff Sharkey00072392018-04-12 14:26:32 -06001242 Trace.traceEnd(TRACE_TAG_NETWORK);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001243
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001244 // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1245 // providers that isn't already counted by dev and XT stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001246 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001247 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
Jeff Sharkey00072392018-04-12 14:26:32 -06001248 Trace.traceEnd(TRACE_TAG_NETWORK);
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001249 xtSnapshot.combineAllValues(tetherSnapshot);
1250 devSnapshot.combineAllValues(tetherSnapshot);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001251
1252 // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1253 // can't be reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001254 Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
Benedict Wong833603c2019-06-13 10:54:38 -07001255 mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001256 Trace.traceEnd(TRACE_TAG_NETWORK);
1257 Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
Benedict Wong833603c2019-06-13 10:54:38 -07001258 mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001259 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001260
1261 // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001262 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
Benedict Wong833603c2019-06-13 10:54:38 -07001263 mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001264 Trace.traceEnd(TRACE_TAG_NETWORK);
1265 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
Benedict Wong833603c2019-06-13 10:54:38 -07001266 mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001267 Trace.traceEnd(TRACE_TAG_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001268
1269 // We need to make copies of member fields that are sent to the observer to avoid
1270 // a race condition between the service handler thread and the observer's
1271 mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
Benedict Wong833603c2019-06-13 10:54:38 -07001272 new ArrayMap<>(mActiveUidIfaces), currentTime);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001273 }
1274
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001275 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001276 * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1277 * so we have baseline values without double-counting.
1278 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001279 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001280 private void bootstrapStatsLocked() {
Jeff Sharkey9911a282018-02-14 22:29:11 -07001281 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001282
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001283 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001284 recordSnapshotLocked(currentTime);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001285 } catch (IllegalStateException e) {
1286 Slog.w(TAG, "problem reading network stats: " + e);
1287 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001288 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001289 }
1290 }
1291
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001292 private void performPoll(int flags) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001293 synchronized (mStatsLock) {
1294 mWakeLock.acquire();
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001295
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001296 try {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001297 performPollLocked(flags);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001298 } finally {
1299 mWakeLock.release();
1300 }
1301 }
1302 }
1303
1304 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001305 * Periodic poll operation, reading current statistics and recording into
1306 * {@link NetworkStatsHistory}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001307 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001308 @GuardedBy("mStatsLock")
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001309 private void performPollLocked(int flags) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001310 if (!mSystemReady) return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001311 if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
Jeff Sharkey00072392018-04-12 14:26:32 -06001312 Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
Jeff Sharkey75279902011-05-24 18:39:45 -07001313
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001314 final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1315 final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001316 final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001317
Jeff Sharkey75279902011-05-24 18:39:45 -07001318 // TODO: consider marking "untrusted" times in historical stats
Jeff Sharkey9911a282018-02-14 22:29:11 -07001319 final long currentTime = mClock.millis();
Jeff Sharkey75279902011-05-24 18:39:45 -07001320
Jeff Sharkey75279902011-05-24 18:39:45 -07001321 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001322 recordSnapshotLocked(currentTime);
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001323 } catch (IllegalStateException e) {
1324 Log.wtf(TAG, "problem reading network stats", e);
Jeff Sharkey905b5892011-09-30 15:19:49 -07001325 return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001326 } catch (RemoteException e) {
1327 // ignored; service lives in system_server
Jeff Sharkey905b5892011-09-30 15:19:49 -07001328 return;
1329 }
1330
Jeff Sharkey63abc372012-01-11 18:38:16 -08001331 // persist any pending data depending on requested flags
Jeff Sharkey00072392018-04-12 14:26:32 -06001332 Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001333 if (persistForce) {
1334 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001335 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001336 mUidRecorder.forcePersistLocked(currentTime);
1337 mUidTagRecorder.forcePersistLocked(currentTime);
1338 } else {
1339 if (persistNetwork) {
1340 mDevRecorder.maybePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001341 mXtRecorder.maybePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001342 }
1343 if (persistUid) {
1344 mUidRecorder.maybePersistLocked(currentTime);
1345 mUidTagRecorder.maybePersistLocked(currentTime);
1346 }
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001347 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001348 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001349
Jeff Sharkey63abc372012-01-11 18:38:16 -08001350 if (mSettings.getSampleEnabled()) {
Jeff Sharkey905b5892011-09-30 15:19:49 -07001351 // sample stats after each full poll
Jeff Sharkey63abc372012-01-11 18:38:16 -08001352 performSampleLocked();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001353 }
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001354
Jeff Sharkey497e4432011-06-14 17:27:29 -07001355 // finally, dispatch updated event to any listeners
1356 final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
1357 updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001358 mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
1359 READ_NETWORK_USAGE_HISTORY);
Jeff Sharkey00072392018-04-12 14:26:32 -06001360
1361 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001362 }
1363
1364 /**
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001365 * Sample recent statistics summary into {@link EventLog}.
1366 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001367 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001368 private void performSampleLocked() {
1369 // TODO: migrate trustedtime fixes to separate binary log events
Jeff Sharkey9911a282018-02-14 22:29:11 -07001370 final long currentTime = mClock.millis();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001371
Jeff Sharkey63abc372012-01-11 18:38:16 -08001372 NetworkTemplate template;
1373 NetworkStats.Entry devTotal;
1374 NetworkStats.Entry xtTotal;
1375 NetworkStats.Entry uidTotal;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001376
1377 // collect mobile sample
Jeff Sharkey234766a2012-04-10 19:48:07 -07001378 template = buildTemplateMobileWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001379 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001380 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001381 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001382
Jeff Sharkey905b5892011-09-30 15:19:49 -07001383 EventLogTags.writeNetstatsMobileSample(
1384 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1385 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1386 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001387 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001388
1389 // collect wifi sample
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001390 template = buildTemplateWifiWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001391 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001392 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001393 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1394
Jeff Sharkey905b5892011-09-30 15:19:49 -07001395 EventLogTags.writeNetstatsWifiSample(
1396 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1397 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1398 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001399 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001400 }
1401
1402 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001403 * Clean up {@link #mUidRecorder} after UID is removed.
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001404 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001405 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001406 private void removeUidsLocked(int... uids) {
1407 if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1408
1409 // Perform one last poll before removing
Jeff Sharkey163e6442011-10-31 16:37:52 -07001410 performPollLocked(FLAG_PERSIST_ALL);
1411
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001412 mUidRecorder.removeUidsLocked(uids);
1413 mUidTagRecorder.removeUidsLocked(uids);
Jeff Sharkey163e6442011-10-31 16:37:52 -07001414
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001415 // Clear kernel stats associated with UID
1416 for (int uid : uids) {
1417 resetKernelUidStats(uid);
1418 }
1419 }
1420
1421 /**
1422 * Clean up {@link #mUidRecorder} after user is removed.
1423 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001424 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001425 private void removeUserLocked(int userId) {
1426 if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1427
1428 // Build list of UIDs that we should clean up
1429 int[] uids = new int[0];
1430 final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001431 PackageManager.MATCH_ANY_USER
1432 | PackageManager.MATCH_DISABLED_COMPONENTS);
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001433 for (ApplicationInfo app : apps) {
1434 final int uid = UserHandle.getUid(userId, app.uid);
1435 uids = ArrayUtils.appendInt(uids, uid);
1436 }
1437
1438 removeUidsLocked(uids);
Jeff Sharkey75279902011-05-24 18:39:45 -07001439 }
1440
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001441 private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
1442 @Override
1443 public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001444 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
1445 try {
1446 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
1447 } finally {
1448 Trace.traceEnd(TRACE_TAG_NETWORK);
1449 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001450 }
1451
1452 @Override
1453 public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001454 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
1455 try {
1456 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
1457 } finally {
1458 Trace.traceEnd(TRACE_TAG_NETWORK);
1459 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001460 }
1461
1462 @Override
1463 public void setUidForeground(int uid, boolean uidForeground) {
1464 NetworkStatsService.this.setUidForeground(uid, uidForeground);
1465 }
1466
1467 @Override
1468 public void advisePersistThreshold(long thresholdBytes) {
1469 NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
1470 }
1471
1472 @Override
1473 public void forceUpdate() {
1474 NetworkStatsService.this.forceUpdate();
1475 }
1476 }
1477
Jeff Sharkey75279902011-05-24 18:39:45 -07001478 @Override
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001479 protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001480 if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
Jeff Sharkey75279902011-05-24 18:39:45 -07001481
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001482 long duration = DateUtils.DAY_IN_MILLIS;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001483 final HashSet<String> argSet = new HashSet<String>();
1484 for (String arg : args) {
1485 argSet.add(arg);
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001486
1487 if (arg.startsWith("--duration=")) {
1488 try {
1489 duration = Long.parseLong(arg.substring(11));
1490 } catch (NumberFormatException ignored) {
1491 }
1492 }
Jeff Sharkey75279902011-05-24 18:39:45 -07001493 }
1494
Jeff Sharkey706498d2012-02-06 17:35:07 -08001495 // usage: dumpsys netstats --full --uid --tag --poll --checkin
Jeff Sharkey63abc372012-01-11 18:38:16 -08001496 final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
Jeff Sharkey706498d2012-02-06 17:35:07 -08001497 final boolean checkin = argSet.contains("--checkin");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001498 final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1499 final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1500 final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1501
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001502 final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
Jeff Sharkey350083e2011-06-29 10:45:16 -07001503
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001504 synchronized (mStatsLock) {
Makoto Onukida65a522017-01-13 10:23:30 -08001505 if (args.length > 0 && "--proto".equals(args[0])) {
1506 // In this case ignore all other arguments.
Jeff Sharkey4635f102017-09-01 11:27:13 -06001507 dumpProtoLocked(fd);
Makoto Onukida65a522017-01-13 10:23:30 -08001508 return;
1509 }
1510
Jeff Sharkey63abc372012-01-11 18:38:16 -08001511 if (poll) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001512 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
Jeff Sharkey3f391352011-06-05 17:42:53 -07001513 pw.println("Forced poll");
1514 return;
1515 }
1516
Jeff Sharkey706498d2012-02-06 17:35:07 -08001517 if (checkin) {
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001518 final long end = System.currentTimeMillis();
1519 final long start = end - duration;
1520
1521 pw.print("v1,");
1522 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1523 pw.print(end / SECOND_IN_MILLIS); pw.println();
1524
1525 pw.println("xt");
1526 mXtRecorder.dumpCheckin(rawWriter, start, end);
1527
1528 if (includeUid) {
1529 pw.println("uid");
1530 mUidRecorder.dumpCheckin(rawWriter, start, end);
Jeff Sharkey706498d2012-02-06 17:35:07 -08001531 }
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001532 if (includeTag) {
1533 pw.println("tag");
1534 mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1535 }
Jeff Sharkey706498d2012-02-06 17:35:07 -08001536 return;
1537 }
1538
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001539 pw.println("Active interfaces:");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001540 pw.increaseIndent();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001541 for (int i = 0; i < mActiveIfaces.size(); i++) {
1542 pw.printPair("iface", mActiveIfaces.keyAt(i));
1543 pw.printPair("ident", mActiveIfaces.valueAt(i));
1544 pw.println();
1545 }
1546 pw.decreaseIndent();
1547
1548 pw.println("Active UID interfaces:");
1549 pw.increaseIndent();
1550 for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1551 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1552 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1553 pw.println();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001554 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001555 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001556
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +09001557 // Get the top openSession callers
1558 final SparseIntArray calls;
1559 synchronized (mOpenSessionCallsPerUid) {
1560 calls = mOpenSessionCallsPerUid.clone();
1561 }
1562
1563 final int N = calls.size();
1564 final long[] values = new long[N];
1565 for (int j = 0; j < N; j++) {
1566 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
1567 }
1568 Arrays.sort(values);
1569
1570 pw.println("Top openSession callers (uid=count):");
1571 pw.increaseIndent();
1572 final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
1573 for (int j = N - 1; j >= end; j--) {
1574 final int uid = (int) (values[j] & 0xffffffff);
1575 final int count = (int) (values[j] >> 32);
1576 pw.print(uid); pw.print("="); pw.println(count);
1577 }
1578 pw.decreaseIndent();
1579 pw.println();
1580
Jeff Sharkey63abc372012-01-11 18:38:16 -08001581 pw.println("Dev stats:");
1582 pw.increaseIndent();
1583 mDevRecorder.dumpLocked(pw, fullHistory);
1584 pw.decreaseIndent();
1585
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001586 pw.println("Xt stats:");
1587 pw.increaseIndent();
1588 mXtRecorder.dumpLocked(pw, fullHistory);
1589 pw.decreaseIndent();
1590
Jeff Sharkey63abc372012-01-11 18:38:16 -08001591 if (includeUid) {
1592 pw.println("UID stats:");
1593 pw.increaseIndent();
1594 mUidRecorder.dumpLocked(pw, fullHistory);
1595 pw.decreaseIndent();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001596 }
1597
Jeff Sharkey63abc372012-01-11 18:38:16 -08001598 if (includeTag) {
1599 pw.println("UID tag stats:");
1600 pw.increaseIndent();
1601 mUidTagRecorder.dumpLocked(pw, fullHistory);
1602 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001603 }
1604 }
1605 }
1606
Andreas Gampea36dc622018-02-05 17:19:22 -08001607 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001608 private void dumpProtoLocked(FileDescriptor fd) {
Makoto Onukida65a522017-01-13 10:23:30 -08001609 final ProtoOutputStream proto = new ProtoOutputStream(fd);
1610
1611 // TODO Right now it writes all history. Should it limit to the "since-boot" log?
1612
1613 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1614 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
1615 mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1616 mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1617 mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1618 mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
1619
1620 proto.flush();
1621 }
1622
1623 private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1624 ArrayMap<String, NetworkIdentitySet> ifaces) {
1625 for (int i = 0; i < ifaces.size(); i++) {
1626 final long start = proto.start(tag);
1627
1628 proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
1629 ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
1630
1631 proto.end(start);
1632 }
1633 }
1634
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001635 private NetworkStats readNetworkStatsSummaryDev() {
1636 try {
1637 return mStatsFactory.readNetworkStatsSummaryDev();
1638 } catch (IOException e) {
1639 throw new IllegalStateException(e);
1640 }
1641 }
1642
1643 private NetworkStats readNetworkStatsSummaryXt() {
1644 try {
1645 return mStatsFactory.readNetworkStatsSummaryXt();
1646 } catch (IOException e) {
1647 throw new IllegalStateException(e);
1648 }
1649 }
1650
1651 private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
1652 try {
1653 return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
1654 } catch (IOException e) {
1655 throw new IllegalStateException(e);
1656 }
1657 }
1658
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001659 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001660 * Return snapshot of current UID statistics, including any
Jack Yuf9d559c2017-05-26 16:08:22 -07001661 * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1662 * values.
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001663 *
1664 * @param ifaces A list of interfaces the stats should be restricted to, or
1665 * {@link NetworkStats#INTERFACES_ALL}.
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001666 */
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001667 private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
1668 throws RemoteException {
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001669 final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL, ifaces, TAG_ALL);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001670
Jeff Sharkey63abc372012-01-11 18:38:16 -08001671 // fold tethering stats and operations into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001672 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001673 tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
Lorenzo Colitti4aa87602019-06-24 13:50:45 +09001674 mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
junyulaic33ac0d2018-10-19 21:14:30 +08001675 mUseBpfTrafficStats);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001676 uidSnapshot.combineAllValues(tetherSnapshot);
Jack Yuf9d559c2017-05-26 16:08:22 -07001677
1678 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
1679 Context.TELEPHONY_SERVICE);
1680
1681 // fold video calling data usage stats into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001682 final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
Jack Yuf9d559c2017-05-26 16:08:22 -07001683 if (vtStats != null) {
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001684 vtStats.filter(UID_ALL, ifaces, TAG_ALL);
Lorenzo Colitti4aa87602019-06-24 13:50:45 +09001685 mStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
junyulaic33ac0d2018-10-19 21:14:30 +08001686 mUseBpfTrafficStats);
Jack Yuf9d559c2017-05-26 16:08:22 -07001687 uidSnapshot.combineAllValues(vtStats);
1688 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001689
Jeff Sharkey63abc372012-01-11 18:38:16 -08001690 uidSnapshot.combineAllValues(mUidOperations);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001691
Jeff Sharkey63abc372012-01-11 18:38:16 -08001692 return uidSnapshot;
Jeff Sharkey75279902011-05-24 18:39:45 -07001693 }
1694
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001695 /**
Jack Yuf9d559c2017-05-26 16:08:22 -07001696 * Return snapshot of current XT statistics with video calling data usage statistics.
Jack Yub6587ea2016-06-22 11:35:10 -07001697 */
Jack Yuf9d559c2017-05-26 16:08:22 -07001698 private NetworkStats getNetworkStatsXt() throws RemoteException {
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001699 final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
Jack Yub6587ea2016-06-22 11:35:10 -07001700
Jack Yuf9d559c2017-05-26 16:08:22 -07001701 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Jack Yub6587ea2016-06-22 11:35:10 -07001702 Context.TELEPHONY_SERVICE);
1703
Jack Yuf9d559c2017-05-26 16:08:22 -07001704 // Merge video calling data usage into XT
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001705 final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
Jack Yuf9d559c2017-05-26 16:08:22 -07001706 if (vtSnapshot != null) {
1707 xtSnapshot.combineAllValues(vtSnapshot);
1708 }
Jack Yub6587ea2016-06-22 11:35:10 -07001709
1710 return xtSnapshot;
1711 }
1712
1713 /**
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001714 * Return snapshot of current tethering statistics. Will return empty
1715 * {@link NetworkStats} if any problems are encountered.
1716 */
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001717 private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001718 try {
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001719 return mNetworkManager.getNetworkStatsTethering(how);
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001720 } catch (IllegalStateException e) {
1721 Log.wtf(TAG, "problem reading network stats", e);
1722 return new NetworkStats(0L, 10);
1723 }
1724 }
1725
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001726 @VisibleForTesting
1727 static class HandlerCallback implements Handler.Callback {
1728 private final NetworkStatsService mService;
1729
1730 HandlerCallback(NetworkStatsService service) {
1731 this.mService = service;
1732 }
1733
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001734 @Override
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001735 public boolean handleMessage(Message msg) {
1736 switch (msg.what) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001737 case MSG_PERFORM_POLL: {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001738 mService.performPoll(FLAG_PERSIST_ALL);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001739 return true;
1740 }
Chalard Jeand7c6e122018-08-22 10:21:26 +09001741 case MSG_PERFORM_POLL_REGISTER_ALERT: {
1742 mService.performPoll(FLAG_PERSIST_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001743 mService.registerGlobalAlert();
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -08001744 return true;
1745 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001746 default: {
1747 return false;
1748 }
1749 }
1750 }
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001751 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001752
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001753 private void assertSystemReady() {
1754 if (!mSystemReady) {
1755 throw new IllegalStateException("System not ready");
1756 }
1757 }
1758
Jeff Sharkey63abc372012-01-11 18:38:16 -08001759 private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001760 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001761 public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
1762 int rightIndex, String cookie) {
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001763 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001764
1765 // record error for debugging
1766 final StringBuilder builder = new StringBuilder();
1767 builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
1768 + "] - right[" + rightIndex + "]\n");
1769 builder.append("left=").append(left).append('\n');
1770 builder.append("right=").append(right).append('\n');
1771
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001772 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1773 builder.toString());
1774 }
1775
1776 @Override
1777 public void foundNonMonotonic(
1778 NetworkStats stats, int statsIndex, String cookie) {
1779 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
1780
1781 final StringBuilder builder = new StringBuilder();
1782 builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
1783 builder.append("stats=").append(stats).append('\n');
1784
1785 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1786 builder.toString());
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001787 }
1788 }
1789
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001790 /**
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001791 * Default external settings that read from
Jeff Sharkey625239a2012-09-26 22:03:49 -07001792 * {@link android.provider.Settings.Global}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001793 */
1794 private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
1795 private final ContentResolver mResolver;
1796
1797 public DefaultNetworkStatsSettings(Context context) {
1798 mResolver = checkNotNull(context.getContentResolver());
1799 // TODO: adjust these timings for production builds
1800 }
1801
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001802 private long getGlobalLong(String name, long def) {
1803 return Settings.Global.getLong(mResolver, name, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001804 }
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001805 private boolean getGlobalBoolean(String name, boolean def) {
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001806 final int defInt = def ? 1 : 0;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001807 return Settings.Global.getInt(mResolver, name, defInt) != 0;
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001808 }
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001809
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001810 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001811 public long getPollInterval() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001812 return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001813 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001814 @Override
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001815 public long getGlobalAlertBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001816 return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001817 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001818 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001819 public boolean getSampleEnabled() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001820 return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001821 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001822 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -06001823 public boolean getAugmentEnabled() {
1824 return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
1825 }
1826 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001827 public Config getDevConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001828 return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
1829 getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1830 getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001831 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001832 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001833 public Config getXtConfig() {
1834 return getDevConfig();
1835 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001836 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001837 public Config getUidConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001838 return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1839 getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1840 getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001841 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001842 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001843 public Config getUidTagConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001844 return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1845 getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
1846 getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001847 }
1848 @Override
1849 public long getDevPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001850 return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001851 }
1852 @Override
1853 public long getXtPersistBytes(long def) {
1854 return getDevPersistBytes(def);
1855 }
1856 @Override
1857 public long getUidPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001858 return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001859 }
1860 @Override
1861 public long getUidTagPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001862 return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001863 }
1864 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001865
1866 private static int TYPE_RX_BYTES;
1867 private static int TYPE_RX_PACKETS;
1868 private static int TYPE_TX_BYTES;
1869 private static int TYPE_TX_PACKETS;
1870 private static int TYPE_TCP_RX_PACKETS;
1871 private static int TYPE_TCP_TX_PACKETS;
1872
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001873 private static native long nativeGetTotalStat(int type, boolean useBpfStats);
1874 private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
1875 private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
Jeff Sharkey75279902011-05-24 18:39:45 -07001876}