blob: dcbdfdf7a2979f53dcc6dcb85d265e704726069a [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
Automerger Merge Workeraf8d85f2020-03-12 09:46:48 +000019import static android.Manifest.permission.NETWORK_STATS_PROVIDER;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070020import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
junyulai80831d22019-11-21 16:26:27 +080021import static android.Manifest.permission.UPDATE_DEVICE_STATS;
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;
Automerger Merge Worker9b3ff072020-03-12 09:46:43 +000026import static android.content.pm.PackageManager.PERMISSION_GRANTED;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -070027import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
Jeff Sharkey234766a2012-04-10 19:48:07 -070028import static android.net.ConnectivityManager.isNetworkTypeMobile;
junyulaif2d6fd52019-12-12 19:42:59 +080029import static android.net.NetworkIdentity.SUBTYPE_COMBINED;
Chiachang Wange05d9d82019-04-09 19:42:52 +080030import static android.net.NetworkStack.checkNetworkStackPermission;
Lorenzo Colittiada23ed2018-01-19 01:05:20 +090031import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070032import static android.net.NetworkStats.IFACE_ALL;
junyulaid27a1722019-11-15 17:15:01 +080033import static android.net.NetworkStats.IFACE_VT;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090034import static android.net.NetworkStats.INTERFACES_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060035import static android.net.NetworkStats.METERED_ALL;
36import static android.net.NetworkStats.ROAMING_ALL;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070037import static android.net.NetworkStats.SET_ALL;
38import static android.net.NetworkStats.SET_DEFAULT;
39import static android.net.NetworkStats.SET_FOREGROUND;
Lorenzo Colitti5356a352017-08-17 19:23:08 +090040import static android.net.NetworkStats.STATS_PER_IFACE;
41import static android.net.NetworkStats.STATS_PER_UID;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090042import static android.net.NetworkStats.TAG_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070043import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey75279902011-05-24 18:39:45 -070044import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060045import static android.net.NetworkStatsHistory.FIELD_ALL;
Jeff Sharkey234766a2012-04-10 19:48:07 -070046import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070047import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -070048import static android.net.TrafficStats.KB_IN_BYTES;
Jeff Sharkey241dde22012-02-03 14:50:07 -080049import static android.net.TrafficStats.MB_IN_BYTES;
Chenbo Feng78cd3842019-06-17 16:22:28 -070050import static android.net.TrafficStats.UNSUPPORTED;
Jeff Sharkey00072392018-04-12 14:26:32 -060051import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060052import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
junyulai1be2d732020-01-02 19:35:59 +080053import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070054import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
55import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
56import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
57import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
58import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
59import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070060import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070061import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
62import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
63import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
64import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
65import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
66import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
67import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
68import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070069import static android.text.format.DateUtils.DAY_IN_MILLIS;
70import static android.text.format.DateUtils.HOUR_IN_MILLIS;
71import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070072import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jack Yuf9d559c2017-05-26 16:08:22 -070073
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070074import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070075import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
76import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
Jeff Sharkey75279902011-05-24 18:39:45 -070077
Jeff Sharkey9911a282018-02-14 22:29:11 -070078import android.annotation.NonNull;
junyulai80831d22019-11-21 16:26:27 +080079import android.annotation.Nullable;
Jeff Sharkey75279902011-05-24 18:39:45 -070080import android.app.AlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070081import android.app.PendingIntent;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060082import android.app.usage.NetworkStatsManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070083import android.content.BroadcastReceiver;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070084import android.content.ContentResolver;
Jeff Sharkey75279902011-05-24 18:39:45 -070085import android.content.Context;
86import android.content.Intent;
87import android.content.IntentFilter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070088import android.content.pm.ApplicationInfo;
89import android.content.pm.PackageManager;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080090import android.net.DataUsageRequest;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070091import android.net.INetworkManagementEventObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070092import android.net.INetworkStatsService;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -070093import android.net.INetworkStatsSession;
Jeff Sharkey63abc372012-01-11 18:38:16 -080094import android.net.LinkProperties;
Lorenzo Colittic78da292018-01-19 00:50:48 +090095import android.net.Network;
Jack Yub6587ea2016-06-22 11:35:10 -070096import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070097import android.net.NetworkIdentity;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070098import android.net.NetworkInfo;
paulhua6af6b62019-08-12 16:25:11 +080099import android.net.NetworkStack;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700100import android.net.NetworkState;
Jeff Sharkey75279902011-05-24 18:39:45 -0700101import android.net.NetworkStats;
Jeff Sharkey5a7bcf32012-01-10 17:24:44 -0800102import android.net.NetworkStats.NonMonotonicObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -0700103import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700104import android.net.NetworkTemplate;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800105import android.net.TrafficStats;
junyulai80831d22019-11-21 16:26:27 +0800106import android.net.netstats.provider.INetworkStatsProvider;
107import android.net.netstats.provider.INetworkStatsProviderCallback;
junyulaiea8f185b2020-03-06 14:50:48 +0800108import android.net.netstats.provider.NetworkStatsProvider;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700109import android.os.BestClock;
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700110import android.os.Binder;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700111import android.os.DropBoxManager;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700112import android.os.Environment;
Jeff Sharkey75279902011-05-24 18:39:45 -0700113import android.os.Handler;
junyulaif2d6fd52019-12-12 19:42:59 +0800114import android.os.HandlerExecutor;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700115import android.os.HandlerThread;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800116import android.os.IBinder;
Jeff Sharkey75279902011-05-24 18:39:45 -0700117import android.os.INetworkManagementService;
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100118import android.os.Looper;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700119import android.os.Message;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800120import android.os.Messenger;
Jeff Sharkey62489262011-07-17 12:53:28 -0700121import android.os.PowerManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700122import android.os.RemoteException;
123import android.os.SystemClock;
Jeff Sharkey00072392018-04-12 14:26:32 -0600124import android.os.Trace;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700125import android.os.UserHandle;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700126import android.provider.Settings;
Jeff Sharkey625239a2012-09-26 22:03:49 -0700127import android.provider.Settings.Global;
Makoto Onukida65a522017-01-13 10:23:30 -0800128import android.service.NetworkInterfaceProto;
129import android.service.NetworkStatsServiceDumpProto;
junyulaif2d6fd52019-12-12 19:42:59 +0800130import android.telephony.PhoneStateListener;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600131import android.telephony.SubscriptionPlan;
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800132import android.text.format.DateUtils;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700133import android.util.ArrayMap;
134import android.util.ArraySet;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700135import android.util.EventLog;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700136import android.util.Log;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700137import android.util.MathUtils;
Jeff Sharkey75279902011-05-24 18:39:45 -0700138import android.util.Slog;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700139import android.util.SparseIntArray;
Makoto Onukida65a522017-01-13 10:23:30 -0800140import android.util.proto.ProtoOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -0700141
Jeff Sharkey4635f102017-09-01 11:27:13 -0600142import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800143import com.android.internal.annotations.VisibleForTesting;
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900144import com.android.internal.net.VpnInfo;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700145import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600146import com.android.internal.util.DumpUtils;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800147import com.android.internal.util.FileRotator;
148import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700149import com.android.server.EventLogTags;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700150import com.android.server.LocalServices;
Jeff Sharkey75279902011-05-24 18:39:45 -0700151
Jeff Sharkey3f391352011-06-05 17:42:53 -0700152import java.io.File;
Jeff Sharkey75279902011-05-24 18:39:45 -0700153import java.io.FileDescriptor;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700154import java.io.IOException;
Jeff Sharkey75279902011-05-24 18:39:45 -0700155import java.io.PrintWriter;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700156import java.time.Clock;
157import java.time.ZoneOffset;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700158import java.util.Arrays;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700159import java.util.HashSet;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700160import java.util.List;
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000161import java.util.Objects;
Treehugger Robot37ec8672020-05-12 11:06:23 +0000162import java.util.concurrent.CopyOnWriteArrayList;
junyulaif2d6fd52019-12-12 19:42:59 +0800163import java.util.concurrent.Executor;
junyulai05a04c22020-02-12 14:55:54 +0800164import java.util.concurrent.Semaphore;
165import java.util.concurrent.TimeUnit;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700166
Jeff Sharkey75279902011-05-24 18:39:45 -0700167/**
168 * Collect and persist detailed network statistics, and provide this data to
169 * other system services.
170 */
171public class NetworkStatsService extends INetworkStatsService.Stub {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600172 static final String TAG = "NetworkStats";
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700173 static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
174 static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700175
Chalard Jeand7c6e122018-08-22 10:21:26 +0900176 // Perform polling and persist all (FLAG_PERSIST_ALL).
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700177 private static final int MSG_PERFORM_POLL = 1;
Chalard Jeand7c6e122018-08-22 10:21:26 +0900178 // Perform polling, persist network, and register the global alert again.
179 private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
junyulaif2d6fd52019-12-12 19:42:59 +0800180 private static final int MSG_UPDATE_IFACES = 3;
Lucas Lin62ee8f62020-05-07 10:12:30 +0000181 // A message for broadcasting ACTION_NETWORK_STATS_UPDATED in handler thread to prevent
182 // deadlock.
183 private static final int MSG_BROADCAST_NETWORK_STATS_UPDATED = 4;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700184
185 /** Flags to control detail level of poll event. */
Jeff Sharkey905b5892011-09-30 15:19:49 -0700186 private static final int FLAG_PERSIST_NETWORK = 0x1;
187 private static final int FLAG_PERSIST_UID = 0x2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700188 private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700189 private static final int FLAG_PERSIST_FORCE = 0x100;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700190
Chalard Jeand7c6e122018-08-22 10:21:26 +0900191 /**
192 * When global alert quota is high, wait for this delay before processing each polling,
193 * and do not schedule further polls once there is already one queued.
194 * This avoids firing the global alert too often on devices with high transfer speeds and
195 * high quota.
196 */
junyulai9ff7b4e2019-11-22 22:27:21 +0800197 private static final int DEFAULT_PERFORM_POLL_DELAY_MS = 1000;
Chalard Jeand7c6e122018-08-22 10:21:26 +0900198
Jeff Sharkey163e6442011-10-31 16:37:52 -0700199 private static final String TAG_NETSTATS_ERROR = "netstats_error";
200
Jeff Sharkey75279902011-05-24 18:39:45 -0700201 private final Context mContext;
202 private final INetworkManagementService mNetworkManager;
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900203 private final NetworkStatsFactory mStatsFactory;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700204 private final AlarmManager mAlarmManager;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700205 private final Clock mClock;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700206 private final NetworkStatsSettings mSettings;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800207 private final NetworkStatsObservers mStatsObservers;
Jeff Sharkey75279902011-05-24 18:39:45 -0700208
Jeff Sharkey63abc372012-01-11 18:38:16 -0800209 private final File mSystemDir;
210 private final File mBaseDir;
211
Jeff Sharkey62489262011-07-17 12:53:28 -0700212 private final PowerManager.WakeLock mWakeLock;
213
Chenbo Feng00499822018-05-18 17:10:07 -0700214 private final boolean mUseBpfTrafficStats;
215
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800216 @VisibleForTesting
Jeff Sharkey3f391352011-06-05 17:42:53 -0700217 public static final String ACTION_NETWORK_STATS_POLL =
Jeff Sharkey75279902011-05-24 18:39:45 -0700218 "com.android.server.action.NETWORK_STATS_POLL";
Jeff Sharkey497e4432011-06-14 17:27:29 -0700219 public static final String ACTION_NETWORK_STATS_UPDATED =
220 "com.android.server.action.NETWORK_STATS_UPDATED";
Jeff Sharkey75279902011-05-24 18:39:45 -0700221
222 private PendingIntent mPollIntent;
223
Jeff Sharkey63abc372012-01-11 18:38:16 -0800224 private static final String PREFIX_DEV = "dev";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700225 private static final String PREFIX_XT = "xt";
Jeff Sharkey63abc372012-01-11 18:38:16 -0800226 private static final String PREFIX_UID = "uid";
227 private static final String PREFIX_UID_TAG = "uid_tag";
228
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700229 /**
230 * Settings that can be changed externally.
231 */
232 public interface NetworkStatsSettings {
junyulai1be2d732020-01-02 19:35:59 +0800233 long getPollInterval();
234 long getPollDelay();
235 boolean getSampleEnabled();
236 boolean getAugmentEnabled();
237 /**
238 * When enabled, all mobile data is reported under {@link NetworkIdentity#SUBTYPE_COMBINED}.
239 * When disabled, mobile data is broken down by a granular subtype representative of the
240 * actual subtype. {@see NetworkTemplate#getCollapsedRatType}.
241 * Enabling this decreases the level of detail but saves performance, disk space and
242 * amount of data logged.
243 */
244 boolean getCombineSubtypeEnabled();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800245
junyulai1be2d732020-01-02 19:35:59 +0800246 class Config {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800247 public final long bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800248 public final long rotateAgeMillis;
249 public final long deleteAgeMillis;
250
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700251 public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800252 this.bucketDuration = bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800253 this.rotateAgeMillis = rotateAgeMillis;
254 this.deleteAgeMillis = deleteAgeMillis;
255 }
256 }
257
junyulai1be2d732020-01-02 19:35:59 +0800258 Config getDevConfig();
259 Config getXtConfig();
260 Config getUidConfig();
261 Config getUidTagConfig();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700262
junyulai1be2d732020-01-02 19:35:59 +0800263 long getGlobalAlertBytes(long def);
264 long getDevPersistBytes(long def);
265 long getXtPersistBytes(long def);
266 long getUidPersistBytes(long def);
267 long getUidTagPersistBytes(long def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700268 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700269
270 private final Object mStatsLock = new Object();
271
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700272 /** Set of currently active ifaces. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900273 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700274 private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900275
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700276 /** Set of currently active ifaces for UID stats. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900277 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700278 private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900279
Jeff Sharkey63abc372012-01-11 18:38:16 -0800280 /** Current default active iface. */
Varun Anandd33cbc62019-02-07 14:13:13 -0800281 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800282 private String mActiveIface;
Lorenzo Colittic78da292018-01-19 00:50:48 +0900283
Jeff Sharkey234766a2012-04-10 19:48:07 -0700284 /** Set of any ifaces associated with mobile networks since boot. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900285 @GuardedBy("mStatsLock")
Jeff Sharkey234766a2012-04-10 19:48:07 -0700286 private String[] mMobileIfaces = new String[0];
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700287
Lorenzo Colittic78da292018-01-19 00:50:48 +0900288 /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
289 @GuardedBy("mStatsLock")
290 private Network[] mDefaultNetworks = new Network[0];
291
junyulaif2d6fd52019-12-12 19:42:59 +0800292 /** Last states of all networks sent from ConnectivityService. */
293 @GuardedBy("mStatsLock")
294 @Nullable
295 private NetworkState[] mLastNetworkStates = null;
296
Jeff Sharkey63abc372012-01-11 18:38:16 -0800297 private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
298 new DropBoxNonMonotonicObserver();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700299
junyulai05a04c22020-02-12 14:55:54 +0800300 private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
Treehugger Robot37ec8672020-05-12 11:06:23 +0000301 private final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
302 new CopyOnWriteArrayList<>();
junyulai05a04c22020-02-12 14:55:54 +0800303 /** Semaphore used to wait for stats provider to respond to request stats update. */
304 private final Semaphore mStatsProviderSem = new Semaphore(0, true);
junyulai80831d22019-11-21 16:26:27 +0800305
Jeff Sharkey4635f102017-09-01 11:27:13 -0600306 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800307 private NetworkStatsRecorder mDevRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600308 @GuardedBy("mStatsLock")
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700309 private NetworkStatsRecorder mXtRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600310 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800311 private NetworkStatsRecorder mUidRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600312 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800313 private NetworkStatsRecorder mUidTagRecorder;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700314
Jeff Sharkey70c70532012-05-16 14:51:19 -0700315 /** Cached {@link #mXtRecorder} stats. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600316 @GuardedBy("mStatsLock")
Jeff Sharkey70c70532012-05-16 14:51:19 -0700317 private NetworkStatsCollection mXtStatsCached;
Jeff Sharkey75279902011-05-24 18:39:45 -0700318
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700319 /** Current counter sets for each UID. */
320 private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
321
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700322 /** Data layer operation counters for splicing into other structures. */
Jeff Sharkey63abc372012-01-11 18:38:16 -0800323 private NetworkStats mUidOperations = new NetworkStats(0L, 10);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700324
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000325 @NonNull
326 private final Handler mHandler;
Jeff Sharkey75279902011-05-24 18:39:45 -0700327
Jeff Sharkey050151e2018-04-13 14:28:30 -0600328 private volatile boolean mSystemReady;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700329 private long mPersistThreshold = 2 * MB_IN_BYTES;
330 private long mGlobalAlertBytes;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800331
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900332 private static final long POLL_RATE_LIMIT_MS = 15_000;
333
334 private long mLastStatsSessionPoll;
335
336 /** Map from UID to number of opened sessions */
337 @GuardedBy("mOpenSessionCallsPerUid")
338 private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
339
340 private final static int DUMP_STATS_SESSION_COUNT = 20;
341
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000342 @NonNull
343 private final Dependencies mDeps;
344
junyulai95a6a3d2020-03-04 12:58:00 +0800345 @NonNull
346 private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor;
347
Jeff Sharkey9911a282018-02-14 22:29:11 -0700348 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700349 return new File(Environment.getDataDirectory(), "system");
Jeff Sharkey75279902011-05-24 18:39:45 -0700350 }
351
Jeff Sharkey9911a282018-02-14 22:29:11 -0700352 private static @NonNull File getDefaultBaseDir() {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800353 File baseDir = new File(getDefaultSystemDir(), "netstats");
354 baseDir.mkdirs();
355 return baseDir;
356 }
357
Jeff Sharkey9911a282018-02-14 22:29:11 -0700358 private static @NonNull Clock getDefaultClock() {
359 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
360 Clock.systemUTC());
361 }
362
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000363 private final class NetworkStatsHandler extends Handler {
364 NetworkStatsHandler(@NonNull Looper looper) {
365 super(looper);
366 }
367
368 @Override
369 public void handleMessage(Message msg) {
370 switch (msg.what) {
371 case MSG_PERFORM_POLL: {
372 performPoll(FLAG_PERSIST_ALL);
373 break;
374 }
junyulaif2d6fd52019-12-12 19:42:59 +0800375 case MSG_UPDATE_IFACES: {
376 // If no cached states, ignore.
377 if (mLastNetworkStates == null) break;
378 updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface);
379 break;
380 }
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000381 case MSG_PERFORM_POLL_REGISTER_ALERT: {
382 performPoll(FLAG_PERSIST_NETWORK);
383 registerGlobalAlert();
384 break;
385 }
Lucas Lin62ee8f62020-05-07 10:12:30 +0000386 case MSG_BROADCAST_NETWORK_STATS_UPDATED: {
387 final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
388 updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
389 mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
390 READ_NETWORK_USAGE_HISTORY);
391 break;
392 }
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000393 }
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100394 }
395 }
396
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800397 public static NetworkStatsService create(Context context,
398 INetworkManagementService networkManager) {
399 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
400 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
401 PowerManager.WakeLock wakeLock =
402 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
403
junyulai95a6a3d2020-03-04 12:58:00 +0800404 final NetworkStatsService service = new NetworkStatsService(context, networkManager,
405 alarmManager, wakeLock, getDefaultClock(),
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900406 new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000407 new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
408 new Dependencies());
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900409 service.registerLocalService();
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800410
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800411 return service;
412 }
413
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900414 // This must not be called outside of tests, even within the same package, as this constructor
415 // does not register the local service. Use the create() helper above.
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800416 @VisibleForTesting
417 NetworkStatsService(Context context, INetworkManagementService networkManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700418 AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
junyulai95a6a3d2020-03-04 12:58:00 +0800419 NetworkStatsSettings settings, NetworkStatsFactory factory,
420 NetworkStatsObservers statsObservers, File systemDir, File baseDir,
421 @NonNull Dependencies deps) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000422 mContext = Objects.requireNonNull(context, "missing Context");
423 mNetworkManager = Objects.requireNonNull(networkManager,
junyulai95a6a3d2020-03-04 12:58:00 +0800424 "missing INetworkManagementService");
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000425 mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
426 mClock = Objects.requireNonNull(clock, "missing Clock");
427 mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000428 mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
429 mStatsFactory = Objects.requireNonNull(factory, "missing factory");
430 mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
431 mSystemDir = Objects.requireNonNull(systemDir, "missing systemDir");
432 mBaseDir = Objects.requireNonNull(baseDir, "missing baseDir");
Chenbo Feng6880d632018-12-22 13:20:31 -0800433 mUseBpfTrafficStats = new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists();
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000434 mDeps = Objects.requireNonNull(deps, "missing Dependencies");
435
436 final HandlerThread handlerThread = mDeps.makeHandlerThread();
437 handlerThread.start();
438 mHandler = new NetworkStatsHandler(handlerThread.getLooper());
junyulai95a6a3d2020-03-04 12:58:00 +0800439 mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext,
440 new HandlerExecutor(mHandler), this);
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000441 }
442
443 /**
444 * Dependencies of NetworkStatsService, for injection in tests.
445 */
446 // TODO: Move more stuff into dependencies object.
447 @VisibleForTesting
448 public static class Dependencies {
449 /**
450 * Create a HandlerThread to use in NetworkStatsService.
451 */
452 @NonNull
453 public HandlerThread makeHandlerThread() {
454 return new HandlerThread(TAG);
455 }
junyulai95a6a3d2020-03-04 12:58:00 +0800456
457 /**
458 * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change
459 * event in NetworkStatsService.
460 */
461 @NonNull
462 public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context,
463 @NonNull Executor executor, @NonNull NetworkStatsService service) {
464 // TODO: Update RatType passively in NSS, instead of querying into the monitor
465 // when forceUpdateIface.
466 return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) ->
467 service.handleOnCollapsedRatTypeChanged());
468 }
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900469 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700470
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900471 private void registerLocalService() {
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700472 LocalServices.addService(NetworkStatsManagerInternal.class,
473 new NetworkStatsManagerInternalImpl());
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800474 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700475
Jeff Sharkey75279902011-05-24 18:39:45 -0700476 public void systemReady() {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800477 synchronized (mStatsLock) {
Hugo Benichi96dc0c12019-05-15 23:38:43 +0900478 mSystemReady = true;
479
Jeff Sharkey4635f102017-09-01 11:27:13 -0600480 // create data recorders along with historical rotators
481 mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
482 mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
483 mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
484 mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
485
486 updatePersistThresholdsLocked();
487
Jeff Sharkey63abc372012-01-11 18:38:16 -0800488 // upgrade any legacy stats, migrating them to rotated files
489 maybeUpgradeLegacyStatsLocked();
490
491 // read historical network stats from disk, since policy service
492 // might need them right away.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700493 mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800494
495 // bootstrap initial stats to prevent double-counting later
496 bootstrapStatsLocked();
497 }
Jeff Sharkey3359aca2011-11-08 18:08:48 -0800498
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700499 // watch for tethering changes
500 final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
Vinit Deshpande92d141f2014-09-10 18:05:10 -0700501 mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700502
Jeff Sharkey75279902011-05-24 18:39:45 -0700503 // listen for periodic polling events
504 final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700505 mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
Jeff Sharkey75279902011-05-24 18:39:45 -0700506
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700507 // listen for uid removal to clean stats
508 final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
509 mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
510
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700511 // listen for user changes to clean stats
512 final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
513 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
514
Jeff Sharkey75279902011-05-24 18:39:45 -0700515 // persist stats during clean shutdown
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700516 final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
517 mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
Jeff Sharkey75279902011-05-24 18:39:45 -0700518
519 try {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700520 mNetworkManager.registerObserver(mAlertObserver);
Jeff Sharkey75279902011-05-24 18:39:45 -0700521 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700522 // ignored; service lives in system_server
Jeff Sharkey75279902011-05-24 18:39:45 -0700523 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700524
Hugo Benichi96dc0c12019-05-15 23:38:43 +0900525 // schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
526 final PendingIntent pollIntent =
527 PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
528
529 final long currentRealtime = SystemClock.elapsedRealtime();
530 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
531 mSettings.getPollInterval(), pollIntent);
532
junyulai95a6a3d2020-03-04 12:58:00 +0800533 // TODO: listen to settings changed to support dynamically enable/disable.
junyulaif2d6fd52019-12-12 19:42:59 +0800534 // watch for networkType changes
junyulai1be2d732020-01-02 19:35:59 +0800535 if (!mSettings.getCombineSubtypeEnabled()) {
junyulai95a6a3d2020-03-04 12:58:00 +0800536 mNetworkStatsSubscriptionsMonitor.start();
junyulaif2d6fd52019-12-12 19:42:59 +0800537 }
538
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700539 registerGlobalAlert();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800540 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700541
Jeff Sharkey63abc372012-01-11 18:38:16 -0800542 private NetworkStatsRecorder buildRecorder(
543 String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700544 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
545 Context.DROPBOX_SERVICE);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700546 return new NetworkStatsRecorder(new FileRotator(
547 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700548 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
Jeff Sharkey75279902011-05-24 18:39:45 -0700549 }
550
Andreas Gampea36dc622018-02-05 17:19:22 -0800551 @GuardedBy("mStatsLock")
Jeff Sharkey3f391352011-06-05 17:42:53 -0700552 private void shutdownLocked() {
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700553 mContext.unregisterReceiver(mTetherReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700554 mContext.unregisterReceiver(mPollReceiver);
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700555 mContext.unregisterReceiver(mRemovedReceiver);
Ryuki Nakamuraa47b0c92017-03-01 10:40:36 +0900556 mContext.unregisterReceiver(mUserReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700557 mContext.unregisterReceiver(mShutdownReceiver);
558
junyulai95a6a3d2020-03-04 12:58:00 +0800559 if (!mSettings.getCombineSubtypeEnabled()) {
560 mNetworkStatsSubscriptionsMonitor.stop();
561 }
junyulaif2d6fd52019-12-12 19:42:59 +0800562
Jeff Sharkey9911a282018-02-14 22:29:11 -0700563 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800564
565 // persist any pending stats
566 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700567 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800568 mUidRecorder.forcePersistLocked(currentTime);
569 mUidTagRecorder.forcePersistLocked(currentTime);
570
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800571 mSystemReady = false;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800572 }
573
Andreas Gampea36dc622018-02-05 17:19:22 -0800574 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800575 private void maybeUpgradeLegacyStatsLocked() {
576 File file;
577 try {
578 file = new File(mSystemDir, "netstats.bin");
579 if (file.exists()) {
580 mDevRecorder.importLegacyNetworkLocked(file);
581 file.delete();
582 }
583
584 file = new File(mSystemDir, "netstats_xt.bin");
585 if (file.exists()) {
586 file.delete();
587 }
588
589 file = new File(mSystemDir, "netstats_uid.bin");
590 if (file.exists()) {
591 mUidRecorder.importLegacyUidLocked(file);
592 mUidTagRecorder.importLegacyUidLocked(file);
593 file.delete();
594 }
595 } catch (IOException e) {
596 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700597 } catch (OutOfMemoryError e) {
598 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeyc506ff62011-11-17 11:59:29 -0800599 }
Jeff Sharkey3f391352011-06-05 17:42:53 -0700600 }
601
Jeff Sharkey75279902011-05-24 18:39:45 -0700602 /**
junyulai80831d22019-11-21 16:26:27 +0800603 * Register for a global alert that is delivered through {@link INetworkManagementEventObserver}
604 * or {@link NetworkStatsProviderCallback#onAlertReached()} once a threshold amount of data has
605 * been transferred.
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700606 */
607 private void registerGlobalAlert() {
608 try {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700609 mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700610 } catch (IllegalStateException e) {
611 Slog.w(TAG, "problem registering for global alert: " + e);
612 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700613 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700614 }
junyulaiea8f185b2020-03-06 14:50:48 +0800615 invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
Jeff Sharkey75279902011-05-24 18:39:45 -0700616 }
617
618 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700619 public INetworkStatsSession openSession() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600620 // NOTE: if callers want to get non-augmented data, they should go
621 // through the public API
622 return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000623 }
624
625 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600626 public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
627 return openSessionInternal(flags, callingPackage);
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100628 }
629
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900630 private boolean isRateLimitedForPoll(int callingUid) {
631 if (callingUid == android.os.Process.SYSTEM_UID) {
632 return false;
633 }
634
635 final long lastCallTime;
636 final long now = SystemClock.elapsedRealtime();
637 synchronized (mOpenSessionCallsPerUid) {
638 int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
639 mOpenSessionCallsPerUid.put(callingUid, calls + 1);
640 lastCallTime = mLastStatsSessionPoll;
641 mLastStatsSessionPoll = now;
642 }
643
644 return now - lastCallTime < POLL_RATE_LIMIT_MS;
645 }
646
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600647 private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900648 final int callingUid = Binder.getCallingUid();
649 final int usedFlags = isRateLimitedForPoll(callingUid)
650 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
651 : flags;
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600652 if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
653 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100654 final long ident = Binder.clearCallingIdentity();
655 try {
656 performPoll(FLAG_PERSIST_ALL);
657 } finally {
658 Binder.restoreCallingIdentity(ident);
659 }
660 }
661
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700662 // return an IBinder which holds strong references to any loaded stats
663 // for its lifetime; when caller closes only weak references remain.
664
665 return new INetworkStatsSession.Stub() {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900666 private final int mCallingUid = callingUid;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600667 private final String mCallingPackage = callingPackage;
668 private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
669 callingPackage);
670
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700671 private NetworkStatsCollection mUidComplete;
672 private NetworkStatsCollection mUidTagComplete;
673
674 private NetworkStatsCollection getUidComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700675 synchronized (mStatsLock) {
676 if (mUidComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700677 mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
678 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700679 return mUidComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700680 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700681 }
682
683 private NetworkStatsCollection getUidTagComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700684 synchronized (mStatsLock) {
685 if (mUidTagComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700686 mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
687 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700688 return mUidTagComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700689 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700690 }
691
692 @Override
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000693 public int[] getRelevantUids() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600694 return getUidComplete().getRelevantUids(mAccessLevel);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000695 }
696
697 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600698 public NetworkStats getDeviceSummaryForNetwork(
699 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900700 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600701 mCallingUid);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000702 }
703
704 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700705 public NetworkStats getSummaryForNetwork(
706 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900707 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600708 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700709 }
710
711 @Override
712 public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900713 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600714 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700715 }
716
717 @Override
718 public NetworkStats getSummaryForAllUid(
719 NetworkTemplate template, long start, long end, boolean includeTags) {
Jeff Davidson39583b52016-12-12 11:55:37 -0800720 try {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600721 final NetworkStats stats = getUidComplete()
722 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800723 if (includeTags) {
724 final NetworkStats tagStats = getUidTagComplete()
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600725 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800726 stats.combineAllValues(tagStats);
727 }
728 return stats;
729 } catch (NullPointerException e) {
730 // TODO: Track down and fix the cause of this crash and remove this catch block.
731 Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
732 throw e;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700733 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700734 }
735
736 @Override
737 public NetworkStatsHistory getHistoryForUid(
738 NetworkTemplate template, int uid, int set, int tag, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600739 // NOTE: We don't augment UID-level statistics
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700740 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600741 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
742 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700743 } else {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600744 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
745 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700746 }
747 }
748
749 @Override
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100750 public NetworkStatsHistory getHistoryIntervalForUid(
751 NetworkTemplate template, int uid, int set, int tag, int fields,
752 long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600753 // NOTE: We don't augment UID-level statistics
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100754 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600755 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
756 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700757 } else if (uid == Binder.getCallingUid()) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600758 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
759 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700760 } else {
761 throw new SecurityException("Calling package " + mCallingPackage
762 + " cannot access tag information from a different uid");
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100763 }
764 }
765
766 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700767 public void close() {
768 mUidComplete = null;
769 mUidTagComplete = null;
770 }
771 };
Jeff Sharkey905b5892011-09-30 15:19:49 -0700772 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700773
Jeff Davidson1efb1332015-12-09 18:04:50 -0800774 private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
775 return NetworkStatsAccess.checkAccessLevel(
776 mContext, Binder.getCallingUid(), callingPackage);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000777 }
778
Jeff Sharkey70c70532012-05-16 14:51:19 -0700779 /**
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600780 * Find the most relevant {@link SubscriptionPlan} for the given
781 * {@link NetworkTemplate} and flags. This is typically used to augment
782 * local measurement results to match a known anchor from the carrier.
783 */
784 private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
785 SubscriptionPlan plan = null;
786 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600787 && mSettings.getAugmentEnabled()) {
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700788 if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600789 final long token = Binder.clearCallingIdentity();
790 try {
Jeff Sharkey146bb332018-04-18 15:42:57 -0600791 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
792 .getSubscriptionPlan(template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600793 } finally {
794 Binder.restoreCallingIdentity(token);
795 }
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700796 if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600797 }
798 return plan;
799 }
800
801 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700802 * Return network summary, splicing between DEV and XT stats when
803 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700804 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600805 private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
806 long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700807 // We've been using pure XT stats long enough that we no longer need to
808 // splice DEV and XT together.
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600809 final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
810 accessLevel, callingUid);
811
812 final long now = System.currentTimeMillis();
813 final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
814
815 final NetworkStats stats = new NetworkStats(end - start, 1);
junyulai88f89a02020-03-13 19:04:17 +0800816 stats.insertEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
Lorenzo Colittiada23ed2018-01-19 01:05:20 +0900817 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
818 entry.txBytes, entry.txPackets, entry.operations));
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600819 return stats;
Jeff Sharkey70c70532012-05-16 14:51:19 -0700820 }
821
822 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700823 * Return network history, splicing between DEV and XT stats when
824 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700825 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600826 private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
827 int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700828 // We've been using pure XT stats long enough that we no longer need to
829 // splice DEV and XT together.
Jeff Sharkey4635f102017-09-01 11:27:13 -0600830 final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
831 synchronized (mStatsLock) {
832 return mXtStatsCached.getHistory(template, augmentPlan,
833 UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
834 accessLevel, callingUid);
835 }
Jeff Sharkey70c70532012-05-16 14:51:19 -0700836 }
837
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700838 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
839 assertSystemReady();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600840
841 // NOTE: if callers want to get non-augmented data, they should go
842 // through the public API
843 return internalGetSummaryForNetwork(template,
844 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
845 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700846 }
847
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700848 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
849 assertSystemReady();
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700850
851 final NetworkStatsCollection uidComplete;
852 synchronized (mStatsLock) {
853 uidComplete = mUidRecorder.getOrLoadCompleteLocked();
854 }
855 return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
856 android.os.Process.SYSTEM_UID);
857 }
858
Jeff Sharkey350083e2011-06-29 10:45:16 -0700859 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700860 public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
861 if (Binder.getCallingUid() != uid) {
Jeff Sharkey41f7cbc2020-04-10 13:54:43 -0600862 Log.w(TAG, "Snapshots only available for calling UID");
863 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700864 }
865
866 // TODO: switch to data layer stats once kernel exports
867 // for now, read network layer stats and flatten across all ifaces
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900868 final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800869
Jeff Sharkey21a54782012-04-09 10:27:55 -0700870 // splice in operation counts
871 networkLayer.spliceOperationsFrom(mUidOperations);
872
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700873 final NetworkStats dataLayer = new NetworkStats(
874 networkLayer.getElapsedRealtime(), networkLayer.size());
875
876 NetworkStats.Entry entry = null;
877 for (int i = 0; i < networkLayer.size(); i++) {
878 entry = networkLayer.getValues(i, entry);
879 entry.iface = IFACE_ALL;
880 dataLayer.combineValues(entry);
881 }
882
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700883 return dataLayer;
884 }
885
886 @Override
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900887 public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
888 try {
889 final String[] ifacesToQuery =
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900890 mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
Varun Anand6a04d492019-06-10 22:43:52 +0000891 return getNetworkStatsUidDetail(ifacesToQuery);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900892 } catch (RemoteException e) {
893 Log.wtf(TAG, "Error compiling UID stats", e);
894 return new NetworkStats(0L, 0);
895 }
896 }
897
898 @Override
Jeff Sharkey234766a2012-04-10 19:48:07 -0700899 public String[] getMobileIfaces() {
900 return mMobileIfaces;
901 }
902
903 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700904 public void incrementOperationCount(int uid, int tag, int operationCount) {
905 if (Binder.getCallingUid() != uid) {
junyulai80831d22019-11-21 16:26:27 +0800906 mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700907 }
908
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700909 if (operationCount < 0) {
910 throw new IllegalArgumentException("operation count can only be incremented");
911 }
912 if (tag == TAG_NONE) {
913 throw new IllegalArgumentException("operation count must have specific tag");
914 }
915
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700916 synchronized (mStatsLock) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700917 final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800918 mUidOperations.combineValues(
919 mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
920 mUidOperations.combineValues(
921 mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700922 }
923 }
924
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700925 @VisibleForTesting
926 void setUidForeground(int uid, boolean uidForeground) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700927 synchronized (mStatsLock) {
928 final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
929 final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
930 if (oldSet != set) {
931 mActiveUidCounterSet.put(uid, set);
932 setKernelCounterSet(uid, set);
933 }
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700934 }
935 }
936
937 @Override
Varun Anandd33cbc62019-02-07 14:13:13 -0800938 public void forceUpdateIfaces(
939 Network[] defaultNetworks,
Varun Anandd33cbc62019-02-07 14:13:13 -0800940 NetworkState[] networkStates,
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900941 String activeIface,
942 VpnInfo[] vpnInfos) {
Chiachang Wange05d9d82019-04-09 19:42:52 +0800943 checkNetworkStackPermission(mContext);
Jeff Sharkey69736342014-12-08 14:50:12 -0800944
945 final long token = Binder.clearCallingIdentity();
946 try {
Benedict Wong9fbbdeb2019-06-12 17:46:31 +0000947 updateIfaces(defaultNetworks, networkStates, activeIface);
Jeff Sharkey69736342014-12-08 14:50:12 -0800948 } finally {
949 Binder.restoreCallingIdentity(token);
950 }
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900951
952 // Update the VPN underlying interfaces only after the poll is made and tun data has been
953 // migrated. Otherwise the migration would use the new interfaces instead of the ones that
954 // were current when the polled data was transferred.
955 mStatsFactory.updateVpnInfos(vpnInfos);
Jeff Sharkey69736342014-12-08 14:50:12 -0800956 }
957
958 @Override
Jeff Sharkey350083e2011-06-29 10:45:16 -0700959 public void forceUpdate() {
960 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkeye630f7b2012-01-31 17:12:53 -0800961
962 final long token = Binder.clearCallingIdentity();
963 try {
964 performPoll(FLAG_PERSIST_ALL);
965 } finally {
966 Binder.restoreCallingIdentity(token);
967 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700968 }
969
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700970 private void advisePersistThreshold(long thresholdBytes) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700971 // clamp threshold into safe range
972 mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700973 if (LOGV) {
974 Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
975 + mPersistThreshold);
976 }
977
junyulai41c13c92019-12-06 18:50:41 +0800978 final long oldGlobalAlertBytes = mGlobalAlertBytes;
979
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700980 // update and persist if beyond new thresholds
Jeff Sharkey9911a282018-02-14 22:29:11 -0700981 final long currentTime = mClock.millis();
Jeff Sharkey58015972012-05-07 11:08:49 -0700982 synchronized (mStatsLock) {
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700983 if (!mSystemReady) return;
984
Jeff Sharkey4635f102017-09-01 11:27:13 -0600985 updatePersistThresholdsLocked();
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700986
Jeff Sharkey58015972012-05-07 11:08:49 -0700987 mDevRecorder.maybePersistLocked(currentTime);
988 mXtRecorder.maybePersistLocked(currentTime);
989 mUidRecorder.maybePersistLocked(currentTime);
990 mUidTagRecorder.maybePersistLocked(currentTime);
991 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700992
junyulai41c13c92019-12-06 18:50:41 +0800993 if (oldGlobalAlertBytes != mGlobalAlertBytes) {
994 registerGlobalAlert();
995 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700996 }
997
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800998 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700999 public DataUsageRequest registerUsageCallback(String callingPackage,
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001000 DataUsageRequest request, Messenger messenger, IBinder binder) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +00001001 Objects.requireNonNull(callingPackage, "calling package is null");
1002 Objects.requireNonNull(request, "DataUsageRequest is null");
1003 Objects.requireNonNull(request.template, "NetworkTemplate is null");
1004 Objects.requireNonNull(messenger, "messenger is null");
1005 Objects.requireNonNull(binder, "binder is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001006
1007 int callingUid = Binder.getCallingUid();
1008 @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
1009 DataUsageRequest normalizedRequest;
1010 final long token = Binder.clearCallingIdentity();
1011 try {
1012 normalizedRequest = mStatsObservers.register(request, messenger, binder,
1013 callingUid, accessLevel);
1014 } finally {
1015 Binder.restoreCallingIdentity(token);
1016 }
1017
1018 // Create baseline stats
Chalard Jeand7c6e122018-08-22 10:21:26 +09001019 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001020
1021 return normalizedRequest;
1022 }
1023
1024 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -07001025 public void unregisterUsageRequest(DataUsageRequest request) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +00001026 Objects.requireNonNull(request, "DataUsageRequest is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001027
1028 int callingUid = Binder.getCallingUid();
1029 final long token = Binder.clearCallingIdentity();
1030 try {
1031 mStatsObservers.unregister(request, callingUid);
1032 } finally {
1033 Binder.restoreCallingIdentity(token);
1034 }
1035 }
1036
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001037 @Override
1038 public long getUidStats(int uid, int type) {
Chenbo Feng78cd3842019-06-17 16:22:28 -07001039 final int callingUid = Binder.getCallingUid();
1040 if (callingUid != android.os.Process.SYSTEM_UID && callingUid != uid) {
1041 return UNSUPPORTED;
1042 }
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001043 return nativeGetUidStat(uid, type, checkBpfStatsEnable());
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001044 }
1045
1046 @Override
1047 public long getIfaceStats(String iface, int type) {
Mike SUce756752018-11-26 15:05:13 +08001048 long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
1049 if (nativeIfaceStats == -1) {
1050 return nativeIfaceStats;
1051 } else {
1052 // When tethering offload is in use, nativeIfaceStats does not contain usage from
1053 // offload, add it back here.
1054 // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
1055 // this does not cause double-counting of tethering traffic, because
1056 // NetdTetheringStatsProvider returns zero NetworkStats
1057 // when called with STATS_PER_IFACE.
1058 return nativeIfaceStats + getTetherStats(iface, type);
1059 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001060 }
1061
1062 @Override
1063 public long getTotalStats(int type) {
Mike SUce756752018-11-26 15:05:13 +08001064 long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
1065 if (nativeTotalStats == -1) {
1066 return nativeTotalStats;
1067 } else {
1068 // Refer to comment in getIfaceStats
1069 return nativeTotalStats + getTetherStats(IFACE_ALL, type);
1070 }
1071 }
1072
1073 private long getTetherStats(String iface, int type) {
1074 final NetworkStats tetherSnapshot;
1075 final long token = Binder.clearCallingIdentity();
1076 try {
1077 tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
1078 } catch (RemoteException e) {
1079 Slog.w(TAG, "Error get TetherStats: " + e);
1080 return 0;
1081 } finally {
1082 Binder.restoreCallingIdentity(token);
1083 }
1084 HashSet<String> limitIfaces;
1085 if (iface == IFACE_ALL) {
1086 limitIfaces = null;
1087 } else {
1088 limitIfaces = new HashSet<String>();
1089 limitIfaces.add(iface);
1090 }
1091 NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
1092 if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
1093 " entry=" + entry);
1094 switch (type) {
1095 case 0: // TYPE_RX_BYTES
1096 return entry.rxBytes;
1097 case 1: // TYPE_RX_PACKETS
1098 return entry.rxPackets;
1099 case 2: // TYPE_TX_BYTES
1100 return entry.txBytes;
1101 case 3: // TYPE_TX_PACKETS
1102 return entry.txPackets;
1103 default:
1104 return 0;
1105 }
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001106 }
1107
1108 private boolean checkBpfStatsEnable() {
Chenbo Feng00499822018-05-18 17:10:07 -07001109 return mUseBpfTrafficStats;
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001110 }
1111
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001112 /**
1113 * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
1114 * reflect current {@link #mPersistThreshold} value. Always defers to
Jeff Sharkey625239a2012-09-26 22:03:49 -07001115 * {@link Global} values when defined.
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001116 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001117 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001118 private void updatePersistThresholdsLocked() {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001119 mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
1120 mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
1121 mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
1122 mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
1123 mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
1124 }
1125
Jeff Sharkey75279902011-05-24 18:39:45 -07001126 /**
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001127 * Receiver that watches for {@link Tethering} to claim interface pairs.
1128 */
1129 private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
1130 @Override
1131 public void onReceive(Context context, Intent intent) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001132 performPoll(FLAG_PERSIST_NETWORK);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001133 }
1134 };
1135
Jeff Sharkey75279902011-05-24 18:39:45 -07001136 private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
1137 @Override
1138 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001139 // on background handler thread, and verified UPDATE_DEVICE_STATS
1140 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001141 performPoll(FLAG_PERSIST_ALL);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001142
1143 // verify that we're watching global alert
1144 registerGlobalAlert();
Jeff Sharkey75279902011-05-24 18:39:45 -07001145 }
1146 };
1147
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001148 private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
1149 @Override
1150 public void onReceive(Context context, Intent intent) {
1151 // on background handler thread, and UID_REMOVED is protected
1152 // broadcast.
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001153
1154 final int uid = intent.getIntExtra(EXTRA_UID, -1);
1155 if (uid == -1) return;
1156
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001157 synchronized (mStatsLock) {
Jeff Sharkey62489262011-07-17 12:53:28 -07001158 mWakeLock.acquire();
1159 try {
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001160 removeUidsLocked(uid);
1161 } finally {
1162 mWakeLock.release();
1163 }
1164 }
1165 }
1166 };
1167
1168 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1169 @Override
1170 public void onReceive(Context context, Intent intent) {
1171 // On background handler thread, and USER_REMOVED is protected
1172 // broadcast.
1173
1174 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1175 if (userId == -1) return;
1176
1177 synchronized (mStatsLock) {
1178 mWakeLock.acquire();
1179 try {
1180 removeUserLocked(userId);
Jeff Sharkey62489262011-07-17 12:53:28 -07001181 } finally {
1182 mWakeLock.release();
1183 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001184 }
1185 }
1186 };
1187
Jeff Sharkey75279902011-05-24 18:39:45 -07001188 private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
1189 @Override
1190 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001191 // SHUTDOWN is protected broadcast.
Jeff Sharkey75279902011-05-24 18:39:45 -07001192 synchronized (mStatsLock) {
Jeff Sharkey3f391352011-06-05 17:42:53 -07001193 shutdownLocked();
Jeff Sharkey75279902011-05-24 18:39:45 -07001194 }
1195 }
1196 };
1197
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001198 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001199 * Observer that watches for {@link INetworkManagementService} alerts.
1200 */
junyulai80831d22019-11-21 16:26:27 +08001201 private final INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001202 @Override
1203 public void limitReached(String limitName, String iface) {
1204 // only someone like NMS should be calling us
paulhua6af6b62019-08-12 16:25:11 +08001205 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001206
1207 if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001208 // kick off background poll to collect network stats unless there is already
1209 // such a call pending; UID stats are handled during normal polling interval.
1210 if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
1211 mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
junyulai9ff7b4e2019-11-22 22:27:21 +08001212 mSettings.getPollDelay());
Chalard Jeand7c6e122018-08-22 10:21:26 +09001213 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001214 }
1215 }
1216 };
1217
junyulaif2d6fd52019-12-12 19:42:59 +08001218 /**
junyulai95a6a3d2020-03-04 12:58:00 +08001219 * Handle collapsed RAT type changed event.
junyulaif2d6fd52019-12-12 19:42:59 +08001220 */
junyulai95a6a3d2020-03-04 12:58:00 +08001221 @VisibleForTesting
1222 public void handleOnCollapsedRatTypeChanged() {
1223 // Protect service from frequently updating. Remove pending messages if any.
1224 mHandler.removeMessages(MSG_UPDATE_IFACES);
1225 mHandler.sendMessageDelayed(
1226 mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay());
junyulaif2d6fd52019-12-12 19:42:59 +08001227 }
1228
Varun Anandd33cbc62019-02-07 14:13:13 -08001229 private void updateIfaces(
1230 Network[] defaultNetworks,
Varun Anandd33cbc62019-02-07 14:13:13 -08001231 NetworkState[] networkStates,
1232 String activeIface) {
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001233 synchronized (mStatsLock) {
1234 mWakeLock.acquire();
1235 try {
Varun Anandd33cbc62019-02-07 14:13:13 -08001236 mActiveIface = activeIface;
1237 updateIfacesLocked(defaultNetworks, networkStates);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001238 } finally {
1239 mWakeLock.release();
1240 }
1241 }
1242 }
1243
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001244 /**
Benedict Wong9fbbdeb2019-06-12 17:46:31 +00001245 * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
1246 * NetworkStatsHistory}. When multiple {@link NetworkInfo} are active on a single {@code iface},
1247 * they are combined under a single {@link NetworkIdentitySet}.
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001248 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001249 @GuardedBy("mStatsLock")
junyulaif2d6fd52019-12-12 19:42:59 +08001250 private void updateIfacesLocked(@Nullable Network[] defaultNetworks,
1251 @NonNull NetworkState[] states) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001252 if (!mSystemReady) return;
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001253 if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001254
1255 // take one last stats snapshot before updating iface mapping. this
1256 // isn't perfect, since the kernel may already be counting traffic from
1257 // the updated network.
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001258
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001259 // poll, but only persist network stats to keep codepath fast. UID stats
1260 // will be persisted during next alarm poll event.
1261 performPollLocked(FLAG_PERSIST_NETWORK);
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001262
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001263 // Rebuild active interfaces based on connected networks
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001264 mActiveIfaces.clear();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001265 mActiveUidIfaces.clear();
Lorenzo Colittic78da292018-01-19 00:50:48 +09001266 if (defaultNetworks != null) {
1267 // Caller is ConnectivityService. Update the list of default networks.
1268 mDefaultNetworks = defaultNetworks;
1269 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001270
junyulaif2d6fd52019-12-12 19:42:59 +08001271 mLastNetworkStates = states;
1272
junyulai1be2d732020-01-02 19:35:59 +08001273 final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001274 final ArraySet<String> mobileIfaces = new ArraySet<>();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001275 for (NetworkState state : states) {
1276 if (state.networkInfo.isConnected()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001277 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001278 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
junyulai1be2d732020-01-02 19:35:59 +08001279 final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
1280 : getSubTypeForState(state);
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001281 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
junyulaif2d6fd52019-12-12 19:42:59 +08001282 isDefault, subType);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001283
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001284 // Traffic occurring on the base interface is always counted for
1285 // both total usage and UID details.
1286 final String baseIface = state.linkProperties.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001287 if (baseIface != null) {
1288 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1289 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
Jack Yub6587ea2016-06-22 11:35:10 -07001290
1291 // Build a separate virtual interface for VT (Video Telephony) data usage.
1292 // Only do this when IMS is not metered, but VT is metered.
1293 // If IMS is metered, then the IMS network usage has already included VT usage.
1294 // VT is considered always metered in framework's layer. If VT is not metered
1295 // per carrier's policy, modem will report 0 usage for VT calls.
1296 if (state.networkCapabilities.hasCapability(
1297 NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1298
1299 // Copy the identify from IMS one but mark it as metered.
1300 NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1301 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001302 ident.getRoaming(), true /* metered */,
1303 true /* onDefaultNetwork */);
junyulaid27a1722019-11-15 17:15:01 +08001304 findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent);
1305 findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent);
Jack Yub6587ea2016-06-22 11:35:10 -07001306 }
1307
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001308 if (isMobile) {
1309 mobileIfaces.add(baseIface);
1310 }
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001311 }
1312
junyulai669ef462019-06-28 16:47:49 +08001313 // Traffic occurring on stacked interfaces is usually clatd.
1314 // UID stats are always counted on the stacked interface and never
1315 // on the base interface, because the packets on the base interface
1316 // do not actually match application sockets until they are translated.
1317 //
1318 // Interface stats are more complicated. Packets subject to BPF offload
1319 // never appear on the base interface and only appear on the stacked
1320 // interface, so to ensure those packets increment interface stats, interface
1321 // stats from stacked interfaces must be collected.
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001322 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1323 for (LinkProperties stackedLink : stackedLinks) {
1324 final String stackedIface = stackedLink.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001325 if (stackedIface != null) {
junyulai669ef462019-06-28 16:47:49 +08001326 if (mUseBpfTrafficStats) {
1327 findOrCreateNetworkIdentitySet(mActiveIfaces, stackedIface).add(ident);
1328 }
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001329 findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1330 if (isMobile) {
1331 mobileIfaces.add(stackedIface);
1332 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001333
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001334 mStatsFactory.noteStackedIface(stackedIface, baseIface);
Jeff Sharkey234766a2012-04-10 19:48:07 -07001335 }
1336 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001337 }
1338 }
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001339
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001340 mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1341 }
1342
junyulaif2d6fd52019-12-12 19:42:59 +08001343 /**
junyulai1be2d732020-01-02 19:35:59 +08001344 * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through
1345 * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
1346 * transport types do not actually fill this value.
junyulaif2d6fd52019-12-12 19:42:59 +08001347 */
1348 private int getSubTypeForState(@NonNull NetworkState state) {
junyulaif2d6fd52019-12-12 19:42:59 +08001349 if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
1350 return 0;
1351 }
1352
junyulai95a6a3d2020-03-04 12:58:00 +08001353 return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId);
junyulaif2d6fd52019-12-12 19:42:59 +08001354 }
1355
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001356 private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1357 ArrayMap<K, NetworkIdentitySet> map, K key) {
1358 NetworkIdentitySet ident = map.get(key);
1359 if (ident == null) {
1360 ident = new NetworkIdentitySet();
1361 map.put(key, ident);
1362 }
1363 return ident;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001364 }
1365
Andreas Gampea36dc622018-02-05 17:19:22 -08001366 @GuardedBy("mStatsLock")
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001367 private void recordSnapshotLocked(long currentTime) throws RemoteException {
1368 // snapshot and record current counters; read UID stats first to
Jack Yub6587ea2016-06-22 11:35:10 -07001369 // avoid over counting dev stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001370 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001371 final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
Jeff Sharkey00072392018-04-12 14:26:32 -06001372 Trace.traceEnd(TRACE_TAG_NETWORK);
1373 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
junyulai5bbd6262020-01-14 18:41:08 +08001374 final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
Jeff Sharkey00072392018-04-12 14:26:32 -06001375 Trace.traceEnd(TRACE_TAG_NETWORK);
1376 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001377 final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
Jeff Sharkey00072392018-04-12 14:26:32 -06001378 Trace.traceEnd(TRACE_TAG_NETWORK);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001379
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001380 // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1381 // providers that isn't already counted by dev and XT stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001382 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001383 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
Jeff Sharkey00072392018-04-12 14:26:32 -06001384 Trace.traceEnd(TRACE_TAG_NETWORK);
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001385 xtSnapshot.combineAllValues(tetherSnapshot);
1386 devSnapshot.combineAllValues(tetherSnapshot);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001387
junyulai80831d22019-11-21 16:26:27 +08001388 // Snapshot for dev/xt stats from all custom stats providers. Counts per-interface data
1389 // from stats providers that isn't already counted by dev and XT stats.
1390 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotStatsProvider");
1391 final NetworkStats providersnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
1392 Trace.traceEnd(TRACE_TAG_NETWORK);
1393 xtSnapshot.combineAllValues(providersnapshot);
1394 devSnapshot.combineAllValues(providersnapshot);
1395
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001396 // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1397 // can't be reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001398 Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
Benedict Wong833603c2019-06-13 10:54:38 -07001399 mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001400 Trace.traceEnd(TRACE_TAG_NETWORK);
1401 Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
Benedict Wong833603c2019-06-13 10:54:38 -07001402 mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001403 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001404
1405 // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001406 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
Benedict Wong833603c2019-06-13 10:54:38 -07001407 mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001408 Trace.traceEnd(TRACE_TAG_NETWORK);
1409 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
Benedict Wong833603c2019-06-13 10:54:38 -07001410 mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001411 Trace.traceEnd(TRACE_TAG_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001412
1413 // We need to make copies of member fields that are sent to the observer to avoid
1414 // a race condition between the service handler thread and the observer's
1415 mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
Benedict Wong833603c2019-06-13 10:54:38 -07001416 new ArrayMap<>(mActiveUidIfaces), currentTime);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001417 }
1418
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001419 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001420 * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1421 * so we have baseline values without double-counting.
1422 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001423 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001424 private void bootstrapStatsLocked() {
Jeff Sharkey9911a282018-02-14 22:29:11 -07001425 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001426
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001427 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001428 recordSnapshotLocked(currentTime);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001429 } catch (IllegalStateException e) {
1430 Slog.w(TAG, "problem reading network stats: " + e);
1431 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001432 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001433 }
1434 }
1435
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001436 private void performPoll(int flags) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001437 synchronized (mStatsLock) {
1438 mWakeLock.acquire();
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001439
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001440 try {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001441 performPollLocked(flags);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001442 } finally {
1443 mWakeLock.release();
1444 }
1445 }
1446 }
1447
1448 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001449 * Periodic poll operation, reading current statistics and recording into
1450 * {@link NetworkStatsHistory}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001451 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001452 @GuardedBy("mStatsLock")
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001453 private void performPollLocked(int flags) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001454 if (!mSystemReady) return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001455 if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
Jeff Sharkey00072392018-04-12 14:26:32 -06001456 Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
Jeff Sharkey75279902011-05-24 18:39:45 -07001457
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001458 final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1459 final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001460 final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001461
junyulai05a04c22020-02-12 14:55:54 +08001462 // Request asynchronous stats update from all providers for next poll. And wait a bit of
Treehugger Robot37ec8672020-05-12 11:06:23 +00001463 // time to allow providers report-in given that normally binder call should be fast. Note
1464 // that size of list might be changed because addition/removing at the same time. For
1465 // addition, the stats of the missed provider can only be collected in next poll;
1466 // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
1467 // once that happened.
junyulai05a04c22020-02-12 14:55:54 +08001468 // TODO: request with a valid token.
1469 Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
Treehugger Robot37ec8672020-05-12 11:06:23 +00001470 final int registeredCallbackCount = mStatsProviderCbList.size();
junyulai05a04c22020-02-12 14:55:54 +08001471 mStatsProviderSem.drainPermits();
junyulaiea8f185b2020-03-06 14:50:48 +08001472 invokeForAllStatsProviderCallbacks(
1473 (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
junyulai05a04c22020-02-12 14:55:54 +08001474 try {
1475 mStatsProviderSem.tryAcquire(registeredCallbackCount,
1476 MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
1477 } catch (InterruptedException e) {
1478 // Strictly speaking it's possible a provider happened to deliver between the timeout
1479 // and the log, and that doesn't matter too much as this is just a debug log.
1480 Log.d(TAG, "requestStatsUpdate - providers responded "
1481 + mStatsProviderSem.availablePermits()
1482 + "/" + registeredCallbackCount + " : " + e);
1483 }
1484 Trace.traceEnd(TRACE_TAG_NETWORK);
1485
Jeff Sharkey75279902011-05-24 18:39:45 -07001486 // TODO: consider marking "untrusted" times in historical stats
Jeff Sharkey9911a282018-02-14 22:29:11 -07001487 final long currentTime = mClock.millis();
Jeff Sharkey75279902011-05-24 18:39:45 -07001488
Jeff Sharkey75279902011-05-24 18:39:45 -07001489 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001490 recordSnapshotLocked(currentTime);
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001491 } catch (IllegalStateException e) {
1492 Log.wtf(TAG, "problem reading network stats", e);
Jeff Sharkey905b5892011-09-30 15:19:49 -07001493 return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001494 } catch (RemoteException e) {
1495 // ignored; service lives in system_server
Jeff Sharkey905b5892011-09-30 15:19:49 -07001496 return;
1497 }
1498
Jeff Sharkey63abc372012-01-11 18:38:16 -08001499 // persist any pending data depending on requested flags
Jeff Sharkey00072392018-04-12 14:26:32 -06001500 Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001501 if (persistForce) {
1502 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001503 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001504 mUidRecorder.forcePersistLocked(currentTime);
1505 mUidTagRecorder.forcePersistLocked(currentTime);
1506 } else {
1507 if (persistNetwork) {
1508 mDevRecorder.maybePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001509 mXtRecorder.maybePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001510 }
1511 if (persistUid) {
1512 mUidRecorder.maybePersistLocked(currentTime);
1513 mUidTagRecorder.maybePersistLocked(currentTime);
1514 }
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001515 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001516 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001517
Jeff Sharkey63abc372012-01-11 18:38:16 -08001518 if (mSettings.getSampleEnabled()) {
Jeff Sharkey905b5892011-09-30 15:19:49 -07001519 // sample stats after each full poll
Jeff Sharkey63abc372012-01-11 18:38:16 -08001520 performSampleLocked();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001521 }
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001522
Jeff Sharkey497e4432011-06-14 17:27:29 -07001523 // finally, dispatch updated event to any listeners
Lucas Lin62ee8f62020-05-07 10:12:30 +00001524 mHandler.sendMessage(mHandler.obtainMessage(MSG_BROADCAST_NETWORK_STATS_UPDATED));
Jeff Sharkey00072392018-04-12 14:26:32 -06001525
1526 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001527 }
1528
1529 /**
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001530 * Sample recent statistics summary into {@link EventLog}.
1531 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001532 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001533 private void performSampleLocked() {
1534 // TODO: migrate trustedtime fixes to separate binary log events
Jeff Sharkey9911a282018-02-14 22:29:11 -07001535 final long currentTime = mClock.millis();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001536
Jeff Sharkey63abc372012-01-11 18:38:16 -08001537 NetworkTemplate template;
1538 NetworkStats.Entry devTotal;
1539 NetworkStats.Entry xtTotal;
1540 NetworkStats.Entry uidTotal;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001541
1542 // collect mobile sample
Jeff Sharkey234766a2012-04-10 19:48:07 -07001543 template = buildTemplateMobileWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001544 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001545 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001546 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001547
Jeff Sharkey905b5892011-09-30 15:19:49 -07001548 EventLogTags.writeNetstatsMobileSample(
1549 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1550 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1551 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001552 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001553
1554 // collect wifi sample
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001555 template = buildTemplateWifiWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001556 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001557 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001558 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1559
Jeff Sharkey905b5892011-09-30 15:19:49 -07001560 EventLogTags.writeNetstatsWifiSample(
1561 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1562 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1563 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001564 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001565 }
1566
1567 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001568 * Clean up {@link #mUidRecorder} after UID is removed.
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001569 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001570 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001571 private void removeUidsLocked(int... uids) {
1572 if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1573
1574 // Perform one last poll before removing
Jeff Sharkey163e6442011-10-31 16:37:52 -07001575 performPollLocked(FLAG_PERSIST_ALL);
1576
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001577 mUidRecorder.removeUidsLocked(uids);
1578 mUidTagRecorder.removeUidsLocked(uids);
Jeff Sharkey163e6442011-10-31 16:37:52 -07001579
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001580 // Clear kernel stats associated with UID
1581 for (int uid : uids) {
1582 resetKernelUidStats(uid);
1583 }
1584 }
1585
1586 /**
1587 * Clean up {@link #mUidRecorder} after user is removed.
1588 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001589 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001590 private void removeUserLocked(int userId) {
1591 if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1592
1593 // Build list of UIDs that we should clean up
1594 int[] uids = new int[0];
1595 final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001596 PackageManager.MATCH_ANY_USER
1597 | PackageManager.MATCH_DISABLED_COMPONENTS);
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001598 for (ApplicationInfo app : apps) {
1599 final int uid = UserHandle.getUid(userId, app.uid);
1600 uids = ArrayUtils.appendInt(uids, uid);
1601 }
1602
1603 removeUidsLocked(uids);
Jeff Sharkey75279902011-05-24 18:39:45 -07001604 }
1605
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001606 private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
1607 @Override
1608 public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001609 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
1610 try {
1611 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
1612 } finally {
1613 Trace.traceEnd(TRACE_TAG_NETWORK);
1614 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001615 }
1616
1617 @Override
1618 public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001619 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
1620 try {
1621 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
1622 } finally {
1623 Trace.traceEnd(TRACE_TAG_NETWORK);
1624 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001625 }
1626
1627 @Override
1628 public void setUidForeground(int uid, boolean uidForeground) {
1629 NetworkStatsService.this.setUidForeground(uid, uidForeground);
1630 }
1631
1632 @Override
1633 public void advisePersistThreshold(long thresholdBytes) {
1634 NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
1635 }
1636
1637 @Override
1638 public void forceUpdate() {
1639 NetworkStatsService.this.forceUpdate();
1640 }
junyulai80831d22019-11-21 16:26:27 +08001641
1642 @Override
junyulai7d058ec2020-01-21 13:52:04 +08001643 public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
Treehugger Robot37ec8672020-05-12 11:06:23 +00001644 if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
junyulaiea8f185b2020-03-06 14:50:48 +08001645 invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
junyulai80831d22019-11-21 16:26:27 +08001646 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001647 }
1648
Jeff Sharkey75279902011-05-24 18:39:45 -07001649 @Override
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001650 protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001651 if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
Jeff Sharkey75279902011-05-24 18:39:45 -07001652
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001653 long duration = DateUtils.DAY_IN_MILLIS;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001654 final HashSet<String> argSet = new HashSet<String>();
1655 for (String arg : args) {
1656 argSet.add(arg);
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001657
1658 if (arg.startsWith("--duration=")) {
1659 try {
1660 duration = Long.parseLong(arg.substring(11));
1661 } catch (NumberFormatException ignored) {
1662 }
1663 }
Jeff Sharkey75279902011-05-24 18:39:45 -07001664 }
1665
Jeff Sharkey706498d2012-02-06 17:35:07 -08001666 // usage: dumpsys netstats --full --uid --tag --poll --checkin
Jeff Sharkey63abc372012-01-11 18:38:16 -08001667 final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
Jeff Sharkey706498d2012-02-06 17:35:07 -08001668 final boolean checkin = argSet.contains("--checkin");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001669 final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1670 final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1671 final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1672
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001673 final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
Jeff Sharkey350083e2011-06-29 10:45:16 -07001674
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001675 synchronized (mStatsLock) {
Makoto Onukida65a522017-01-13 10:23:30 -08001676 if (args.length > 0 && "--proto".equals(args[0])) {
1677 // In this case ignore all other arguments.
Jeff Sharkey4635f102017-09-01 11:27:13 -06001678 dumpProtoLocked(fd);
Makoto Onukida65a522017-01-13 10:23:30 -08001679 return;
1680 }
1681
Jeff Sharkey63abc372012-01-11 18:38:16 -08001682 if (poll) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001683 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
Jeff Sharkey3f391352011-06-05 17:42:53 -07001684 pw.println("Forced poll");
1685 return;
1686 }
1687
Jeff Sharkey706498d2012-02-06 17:35:07 -08001688 if (checkin) {
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001689 final long end = System.currentTimeMillis();
1690 final long start = end - duration;
1691
1692 pw.print("v1,");
1693 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1694 pw.print(end / SECOND_IN_MILLIS); pw.println();
1695
1696 pw.println("xt");
1697 mXtRecorder.dumpCheckin(rawWriter, start, end);
1698
1699 if (includeUid) {
1700 pw.println("uid");
1701 mUidRecorder.dumpCheckin(rawWriter, start, end);
Jeff Sharkey706498d2012-02-06 17:35:07 -08001702 }
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001703 if (includeTag) {
1704 pw.println("tag");
1705 mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1706 }
Jeff Sharkey706498d2012-02-06 17:35:07 -08001707 return;
1708 }
1709
junyulai1be2d732020-01-02 19:35:59 +08001710 pw.println("Configs:");
1711 pw.increaseIndent();
1712 pw.printPair(NETSTATS_COMBINE_SUBTYPE_ENABLED, mSettings.getCombineSubtypeEnabled());
1713 pw.println();
1714 pw.decreaseIndent();
1715
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001716 pw.println("Active interfaces:");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001717 pw.increaseIndent();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001718 for (int i = 0; i < mActiveIfaces.size(); i++) {
1719 pw.printPair("iface", mActiveIfaces.keyAt(i));
1720 pw.printPair("ident", mActiveIfaces.valueAt(i));
1721 pw.println();
1722 }
1723 pw.decreaseIndent();
1724
1725 pw.println("Active UID interfaces:");
1726 pw.increaseIndent();
1727 for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1728 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1729 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1730 pw.println();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001731 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001732 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001733
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +09001734 // Get the top openSession callers
1735 final SparseIntArray calls;
1736 synchronized (mOpenSessionCallsPerUid) {
1737 calls = mOpenSessionCallsPerUid.clone();
1738 }
1739
1740 final int N = calls.size();
1741 final long[] values = new long[N];
1742 for (int j = 0; j < N; j++) {
1743 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
1744 }
1745 Arrays.sort(values);
1746
1747 pw.println("Top openSession callers (uid=count):");
1748 pw.increaseIndent();
1749 final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
1750 for (int j = N - 1; j >= end; j--) {
1751 final int uid = (int) (values[j] & 0xffffffff);
1752 final int count = (int) (values[j] >> 32);
1753 pw.print(uid); pw.print("="); pw.println(count);
1754 }
1755 pw.decreaseIndent();
1756 pw.println();
1757
junyulai3cd84eb2020-01-10 13:57:07 +08001758 pw.println("Stats Providers:");
1759 pw.increaseIndent();
1760 invokeForAllStatsProviderCallbacks((cb) -> {
1761 pw.println(cb.mTag + " Xt:");
1762 pw.increaseIndent();
1763 pw.print(cb.getCachedStats(STATS_PER_IFACE).toString());
1764 pw.decreaseIndent();
1765 if (includeUid) {
1766 pw.println(cb.mTag + " Uid:");
1767 pw.increaseIndent();
1768 pw.print(cb.getCachedStats(STATS_PER_UID).toString());
1769 pw.decreaseIndent();
1770 }
1771 });
1772 pw.decreaseIndent();
1773
Jeff Sharkey63abc372012-01-11 18:38:16 -08001774 pw.println("Dev stats:");
1775 pw.increaseIndent();
1776 mDevRecorder.dumpLocked(pw, fullHistory);
1777 pw.decreaseIndent();
1778
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001779 pw.println("Xt stats:");
1780 pw.increaseIndent();
1781 mXtRecorder.dumpLocked(pw, fullHistory);
1782 pw.decreaseIndent();
1783
Jeff Sharkey63abc372012-01-11 18:38:16 -08001784 if (includeUid) {
1785 pw.println("UID stats:");
1786 pw.increaseIndent();
1787 mUidRecorder.dumpLocked(pw, fullHistory);
1788 pw.decreaseIndent();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001789 }
1790
Jeff Sharkey63abc372012-01-11 18:38:16 -08001791 if (includeTag) {
1792 pw.println("UID tag stats:");
1793 pw.increaseIndent();
1794 mUidTagRecorder.dumpLocked(pw, fullHistory);
1795 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001796 }
1797 }
1798 }
1799
Andreas Gampea36dc622018-02-05 17:19:22 -08001800 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001801 private void dumpProtoLocked(FileDescriptor fd) {
Makoto Onukida65a522017-01-13 10:23:30 -08001802 final ProtoOutputStream proto = new ProtoOutputStream(fd);
1803
1804 // TODO Right now it writes all history. Should it limit to the "since-boot" log?
1805
1806 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1807 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
Jeffrey Huangcb782852019-12-05 11:28:11 -08001808 mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1809 mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1810 mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1811 mUidTagRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
Makoto Onukida65a522017-01-13 10:23:30 -08001812
1813 proto.flush();
1814 }
1815
1816 private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1817 ArrayMap<String, NetworkIdentitySet> ifaces) {
1818 for (int i = 0; i < ifaces.size(); i++) {
1819 final long start = proto.start(tag);
1820
1821 proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
Jeffrey Huangcb782852019-12-05 11:28:11 -08001822 ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
Makoto Onukida65a522017-01-13 10:23:30 -08001823
1824 proto.end(start);
1825 }
1826 }
1827
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001828 private NetworkStats readNetworkStatsSummaryDev() {
1829 try {
1830 return mStatsFactory.readNetworkStatsSummaryDev();
1831 } catch (IOException e) {
1832 throw new IllegalStateException(e);
1833 }
1834 }
1835
1836 private NetworkStats readNetworkStatsSummaryXt() {
1837 try {
1838 return mStatsFactory.readNetworkStatsSummaryXt();
1839 } catch (IOException e) {
1840 throw new IllegalStateException(e);
1841 }
1842 }
1843
1844 private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
1845 try {
1846 return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
1847 } catch (IOException e) {
1848 throw new IllegalStateException(e);
1849 }
1850 }
1851
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001852 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001853 * Return snapshot of current UID statistics, including any
Jack Yuf9d559c2017-05-26 16:08:22 -07001854 * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1855 * values.
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001856 *
1857 * @param ifaces A list of interfaces the stats should be restricted to, or
1858 * {@link NetworkStats#INTERFACES_ALL}.
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001859 */
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001860 private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
1861 throws RemoteException {
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001862 final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL, ifaces, TAG_ALL);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001863
Jeff Sharkey63abc372012-01-11 18:38:16 -08001864 // fold tethering stats and operations into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001865 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001866 tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
Lorenzo Colitti4aa87602019-06-24 13:50:45 +09001867 mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
junyulaic33ac0d2018-10-19 21:14:30 +08001868 mUseBpfTrafficStats);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001869 uidSnapshot.combineAllValues(tetherSnapshot);
Jack Yuf9d559c2017-05-26 16:08:22 -07001870
junyulai80831d22019-11-21 16:26:27 +08001871 // get a stale copy of uid stats snapshot provided by providers.
1872 final NetworkStats providerStats = getNetworkStatsFromProviders(STATS_PER_UID);
1873 providerStats.filter(UID_ALL, ifaces, TAG_ALL);
1874 mStatsFactory.apply464xlatAdjustments(uidSnapshot, providerStats, mUseBpfTrafficStats);
1875 uidSnapshot.combineAllValues(providerStats);
1876
Jeff Sharkey63abc372012-01-11 18:38:16 -08001877 uidSnapshot.combineAllValues(mUidOperations);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001878
Jeff Sharkey63abc372012-01-11 18:38:16 -08001879 return uidSnapshot;
Jeff Sharkey75279902011-05-24 18:39:45 -07001880 }
1881
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001882 /**
1883 * Return snapshot of current tethering statistics. Will return empty
1884 * {@link NetworkStats} if any problems are encountered.
1885 */
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001886 private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001887 try {
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001888 return mNetworkManager.getNetworkStatsTethering(how);
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001889 } catch (IllegalStateException e) {
1890 Log.wtf(TAG, "problem reading network stats", e);
1891 return new NetworkStats(0L, 10);
1892 }
1893 }
1894
junyulai74fcf722020-03-16 15:00:24 +08001895 // TODO: It is copied from ConnectivityService, consider refactor these check permission
Automerger Merge Worker9b3ff072020-03-12 09:46:43 +00001896 // functions to a proper util.
1897 private boolean checkAnyPermissionOf(String... permissions) {
1898 for (String permission : permissions) {
1899 if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
1900 return true;
1901 }
1902 }
1903 return false;
1904 }
1905
1906 private void enforceAnyPermissionOf(String... permissions) {
1907 if (!checkAnyPermissionOf(permissions)) {
1908 throw new SecurityException("Requires one of the following permissions: "
1909 + String.join(", ", permissions) + ".");
1910 }
1911 }
1912
junyulai80831d22019-11-21 16:26:27 +08001913 /**
1914 * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
1915 * statistics that cannot be seen by the kernel to system. To unregister, invoke the
1916 * {@code unregister()} of the returned callback.
1917 *
1918 * @param tag a human readable identifier of the custom network stats provider.
junyulai7d058ec2020-01-21 13:52:04 +08001919 * @param provider the {@link INetworkStatsProvider} binder corresponding to the
junyulaiea8f185b2020-03-06 14:50:48 +08001920 * {@link NetworkStatsProvider} to be registered.
junyulai80831d22019-11-21 16:26:27 +08001921 *
junyulaiea8f185b2020-03-06 14:50:48 +08001922 * @return a {@link INetworkStatsProviderCallback} binder
1923 * interface, which can be used to report events to the system.
junyulai80831d22019-11-21 16:26:27 +08001924 */
1925 public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
1926 @NonNull String tag, @NonNull INetworkStatsProvider provider) {
Automerger Merge Workeraf8d85f2020-03-12 09:46:48 +00001927 enforceAnyPermissionOf(NETWORK_STATS_PROVIDER,
1928 NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
junyulai80831d22019-11-21 16:26:27 +08001929 Objects.requireNonNull(provider, "provider is null");
1930 Objects.requireNonNull(tag, "tag is null");
1931 try {
1932 NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
junyulai05a04c22020-02-12 14:55:54 +08001933 tag, provider, mStatsProviderSem, mAlertObserver,
1934 mStatsProviderCbList);
Treehugger Robot37ec8672020-05-12 11:06:23 +00001935 mStatsProviderCbList.add(callback);
junyulai80831d22019-11-21 16:26:27 +08001936 Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
1937 + getCallingUid() + "/" + getCallingPid());
1938 return callback;
1939 } catch (RemoteException e) {
1940 Log.e(TAG, "registerNetworkStatsProvider failed", e);
1941 }
1942 return null;
1943 }
1944
1945 // Collect stats from local cache of providers.
1946 private @NonNull NetworkStats getNetworkStatsFromProviders(int how) {
1947 final NetworkStats ret = new NetworkStats(0L, 0);
1948 invokeForAllStatsProviderCallbacks((cb) -> ret.combineAllValues(cb.getCachedStats(how)));
1949 return ret;
1950 }
1951
1952 @FunctionalInterface
1953 private interface ThrowingConsumer<S, T extends Throwable> {
1954 void accept(S s) throws T;
1955 }
1956
1957 private void invokeForAllStatsProviderCallbacks(
1958 @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
Treehugger Robot37ec8672020-05-12 11:06:23 +00001959 for (final NetworkStatsProviderCallbackImpl cb : mStatsProviderCbList) {
junyulai80831d22019-11-21 16:26:27 +08001960 try {
Treehugger Robot37ec8672020-05-12 11:06:23 +00001961 task.accept(cb);
1962 } catch (RemoteException e) {
1963 Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
junyulai80831d22019-11-21 16:26:27 +08001964 }
1965 }
1966 }
1967
1968 private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub
1969 implements IBinder.DeathRecipient {
1970 @NonNull final String mTag;
junyulai7d058ec2020-01-21 13:52:04 +08001971
junyulai80831d22019-11-21 16:26:27 +08001972 @NonNull final INetworkStatsProvider mProvider;
junyulai05a04c22020-02-12 14:55:54 +08001973 @NonNull private final Semaphore mSemaphore;
junyulai80831d22019-11-21 16:26:27 +08001974 @NonNull final INetworkManagementEventObserver mAlertObserver;
Treehugger Robot37ec8672020-05-12 11:06:23 +00001975 @NonNull final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
junyulai80831d22019-11-21 16:26:27 +08001976
junyulai7d058ec2020-01-21 13:52:04 +08001977 @NonNull private final Object mProviderStatsLock = new Object();
1978
junyulai80831d22019-11-21 16:26:27 +08001979 @GuardedBy("mProviderStatsLock")
junyulai7d058ec2020-01-21 13:52:04 +08001980 // Track STATS_PER_IFACE and STATS_PER_UID separately.
junyulai80831d22019-11-21 16:26:27 +08001981 private final NetworkStats mIfaceStats = new NetworkStats(0L, 0);
1982 @GuardedBy("mProviderStatsLock")
1983 private final NetworkStats mUidStats = new NetworkStats(0L, 0);
1984
1985 NetworkStatsProviderCallbackImpl(
1986 @NonNull String tag, @NonNull INetworkStatsProvider provider,
junyulai05a04c22020-02-12 14:55:54 +08001987 @NonNull Semaphore semaphore,
junyulai80831d22019-11-21 16:26:27 +08001988 @NonNull INetworkManagementEventObserver alertObserver,
Treehugger Robot37ec8672020-05-12 11:06:23 +00001989 @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList)
junyulai80831d22019-11-21 16:26:27 +08001990 throws RemoteException {
1991 mTag = tag;
1992 mProvider = provider;
1993 mProvider.asBinder().linkToDeath(this, 0);
junyulai05a04c22020-02-12 14:55:54 +08001994 mSemaphore = semaphore;
junyulai80831d22019-11-21 16:26:27 +08001995 mAlertObserver = alertObserver;
1996 mStatsProviderCbList = cbList;
1997 }
1998
1999 @NonNull
2000 public NetworkStats getCachedStats(int how) {
2001 synchronized (mProviderStatsLock) {
2002 NetworkStats stats;
2003 switch (how) {
2004 case STATS_PER_IFACE:
2005 stats = mIfaceStats;
2006 break;
2007 case STATS_PER_UID:
2008 stats = mUidStats;
2009 break;
2010 default:
2011 throw new IllegalArgumentException("Invalid type: " + how);
2012 }
junyulai7d058ec2020-01-21 13:52:04 +08002013 // Callers might be able to mutate the returned object. Return a defensive copy
2014 // instead of local reference.
junyulai80831d22019-11-21 16:26:27 +08002015 return stats.clone();
2016 }
2017 }
2018
2019 @Override
junyulaiea8f185b2020-03-06 14:50:48 +08002020 public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
junyulai80831d22019-11-21 16:26:27 +08002021 @Nullable NetworkStats uidStats) {
2022 // TODO: 1. Use token to map ifaces to correct NetworkIdentity.
2023 // 2. Store the difference and store it directly to the recorder.
2024 synchronized (mProviderStatsLock) {
2025 if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats);
2026 if (uidStats != null) mUidStats.combineAllValues(uidStats);
2027 }
junyulai05a04c22020-02-12 14:55:54 +08002028 mSemaphore.release();
junyulai80831d22019-11-21 16:26:27 +08002029 }
2030
2031 @Override
junyulaiea8f185b2020-03-06 14:50:48 +08002032 public void notifyAlertReached() throws RemoteException {
junyulai80831d22019-11-21 16:26:27 +08002033 mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */);
2034 }
2035
2036 @Override
junyulaiea8f185b2020-03-06 14:50:48 +08002037 public void notifyLimitReached() {
junyulai80831d22019-11-21 16:26:27 +08002038 Log.d(TAG, mTag + ": onLimitReached");
2039 LocalServices.getService(NetworkPolicyManagerInternal.class)
2040 .onStatsProviderLimitReached(mTag);
2041 }
2042
2043 @Override
2044 public void binderDied() {
2045 Log.d(TAG, mTag + ": binderDied");
Treehugger Robot37ec8672020-05-12 11:06:23 +00002046 mStatsProviderCbList.remove(this);
junyulai80831d22019-11-21 16:26:27 +08002047 }
2048
2049 @Override
2050 public void unregister() {
2051 Log.d(TAG, mTag + ": unregister");
Treehugger Robot37ec8672020-05-12 11:06:23 +00002052 mStatsProviderCbList.remove(this);
junyulai80831d22019-11-21 16:26:27 +08002053 }
2054
2055 }
2056
Jeff Sharkeye0c29952018-02-20 17:24:55 -07002057 private void assertSystemReady() {
2058 if (!mSystemReady) {
2059 throw new IllegalStateException("System not ready");
2060 }
2061 }
2062
Jeff Sharkey63abc372012-01-11 18:38:16 -08002063 private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002064 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002065 public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
2066 int rightIndex, String cookie) {
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06002067 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
Jeff Sharkey63abc372012-01-11 18:38:16 -08002068
2069 // record error for debugging
2070 final StringBuilder builder = new StringBuilder();
2071 builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
2072 + "] - right[" + rightIndex + "]\n");
2073 builder.append("left=").append(left).append('\n');
2074 builder.append("right=").append(right).append('\n');
2075
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06002076 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
2077 builder.toString());
2078 }
2079
2080 @Override
2081 public void foundNonMonotonic(
2082 NetworkStats stats, int statsIndex, String cookie) {
2083 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
2084
2085 final StringBuilder builder = new StringBuilder();
2086 builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
2087 builder.append("stats=").append(stats).append('\n');
2088
2089 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
2090 builder.toString());
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07002091 }
2092 }
2093
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07002094 /**
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002095 * Default external settings that read from
Jeff Sharkey625239a2012-09-26 22:03:49 -07002096 * {@link android.provider.Settings.Global}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002097 */
2098 private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
2099 private final ContentResolver mResolver;
2100
2101 public DefaultNetworkStatsSettings(Context context) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +00002102 mResolver = Objects.requireNonNull(context.getContentResolver());
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002103 // TODO: adjust these timings for production builds
2104 }
2105
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002106 private long getGlobalLong(String name, long def) {
2107 return Settings.Global.getLong(mResolver, name, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002108 }
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002109 private boolean getGlobalBoolean(String name, boolean def) {
Jeff Sharkey991d1b12011-09-14 19:31:04 -07002110 final int defInt = def ? 1 : 0;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002111 return Settings.Global.getInt(mResolver, name, defInt) != 0;
Jeff Sharkey991d1b12011-09-14 19:31:04 -07002112 }
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002113
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002114 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002115 public long getPollInterval() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002116 return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002117 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002118 @Override
junyulai9ff7b4e2019-11-22 22:27:21 +08002119 public long getPollDelay() {
2120 return DEFAULT_PERFORM_POLL_DELAY_MS;
2121 }
2122 @Override
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002123 public long getGlobalAlertBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002124 return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
Jeff Sharkey63abc372012-01-11 18:38:16 -08002125 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002126 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002127 public boolean getSampleEnabled() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002128 return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
Jeff Sharkey63abc372012-01-11 18:38:16 -08002129 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002130 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -06002131 public boolean getAugmentEnabled() {
2132 return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
2133 }
2134 @Override
junyulai1be2d732020-01-02 19:35:59 +08002135 public boolean getCombineSubtypeEnabled() {
2136 return getGlobalBoolean(NETSTATS_COMBINE_SUBTYPE_ENABLED, false);
2137 }
2138 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002139 public Config getDevConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002140 return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
2141 getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
2142 getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08002143 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002144 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07002145 public Config getXtConfig() {
2146 return getDevConfig();
2147 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07002148 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002149 public Config getUidConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002150 return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
2151 getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
2152 getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08002153 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002154 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002155 public Config getUidTagConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002156 return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
2157 getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
2158 getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002159 }
2160 @Override
2161 public long getDevPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002162 return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002163 }
2164 @Override
2165 public long getXtPersistBytes(long def) {
2166 return getDevPersistBytes(def);
2167 }
2168 @Override
2169 public long getUidPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002170 return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002171 }
2172 @Override
2173 public long getUidTagPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002174 return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002175 }
2176 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08002177
2178 private static int TYPE_RX_BYTES;
2179 private static int TYPE_RX_PACKETS;
2180 private static int TYPE_TX_BYTES;
2181 private static int TYPE_TX_PACKETS;
2182 private static int TYPE_TCP_RX_PACKETS;
2183 private static int TYPE_TCP_TX_PACKETS;
2184
Chenbo Fengaedd6a32017-11-20 18:23:46 -08002185 private static native long nativeGetTotalStat(int type, boolean useBpfStats);
2186 private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
2187 private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
Jeff Sharkey75279902011-05-24 18:39:45 -07002188}