blob: 4af31b03694092dbce79ec8944c589b50a137cb0 [file] [log] [blame]
Jeff Sharkey75279902011-05-24 18:39:45 -07001/*
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07002 * Copyright (C) 2011 The Android Open Source Project
Jeff Sharkey75279902011-05-24 18:39:45 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.net;
18
Jeff Sharkeya63ba592011-07-19 23:47:12 -070019import static android.Manifest.permission.ACCESS_NETWORK_STATE;
Jeff 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;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -070026import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
Jeff Sharkey234766a2012-04-10 19:48:07 -070027import static android.net.ConnectivityManager.isNetworkTypeMobile;
Chiachang Wange05d9d82019-04-09 19:42:52 +080028import static android.net.NetworkStack.checkNetworkStackPermission;
Lorenzo Colittiada23ed2018-01-19 01:05:20 +090029import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070030import static android.net.NetworkStats.IFACE_ALL;
junyulaid27a1722019-11-15 17:15:01 +080031import static android.net.NetworkStats.IFACE_VT;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090032import static android.net.NetworkStats.INTERFACES_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060033import static android.net.NetworkStats.METERED_ALL;
34import static android.net.NetworkStats.ROAMING_ALL;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070035import static android.net.NetworkStats.SET_ALL;
36import static android.net.NetworkStats.SET_DEFAULT;
37import static android.net.NetworkStats.SET_FOREGROUND;
Lorenzo Colitti5356a352017-08-17 19:23:08 +090038import static android.net.NetworkStats.STATS_PER_IFACE;
39import static android.net.NetworkStats.STATS_PER_UID;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090040import static android.net.NetworkStats.TAG_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070041import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey75279902011-05-24 18:39:45 -070042import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060043import static android.net.NetworkStatsHistory.FIELD_ALL;
Jeff Sharkey234766a2012-04-10 19:48:07 -070044import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070045import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -070046import static android.net.TrafficStats.KB_IN_BYTES;
Jeff Sharkey241dde22012-02-03 14:50:07 -080047import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey00072392018-04-12 14:26:32 -060048import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060049import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070050import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
51import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
52import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
53import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
54import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
55import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070056import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070057import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
58import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
59import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
60import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
61import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
62import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
63import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
64import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070065import static android.text.format.DateUtils.DAY_IN_MILLIS;
66import static android.text.format.DateUtils.HOUR_IN_MILLIS;
67import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070068import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jack Yuf9d559c2017-05-26 16:08:22 -070069
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070070import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070071import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
72import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
Jeff Sharkey75279902011-05-24 18:39:45 -070073
Jeff Sharkey9911a282018-02-14 22:29:11 -070074import android.annotation.NonNull;
junyulai80831d22019-11-21 16:26:27 +080075import android.annotation.Nullable;
Jeff Sharkey75279902011-05-24 18:39:45 -070076import android.app.AlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070077import android.app.PendingIntent;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060078import android.app.usage.NetworkStatsManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070079import android.content.BroadcastReceiver;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070080import android.content.ContentResolver;
Jeff Sharkey75279902011-05-24 18:39:45 -070081import android.content.Context;
82import android.content.Intent;
83import android.content.IntentFilter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070084import android.content.pm.ApplicationInfo;
85import android.content.pm.PackageManager;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080086import android.net.DataUsageRequest;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070087import android.net.INetworkManagementEventObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070088import android.net.INetworkStatsService;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -070089import android.net.INetworkStatsSession;
Jeff Sharkey63abc372012-01-11 18:38:16 -080090import android.net.LinkProperties;
Lorenzo Colittic78da292018-01-19 00:50:48 +090091import android.net.Network;
Jack Yub6587ea2016-06-22 11:35:10 -070092import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070093import android.net.NetworkIdentity;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070094import android.net.NetworkInfo;
paulhua6af6b62019-08-12 16:25:11 +080095import android.net.NetworkStack;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070096import android.net.NetworkState;
Jeff Sharkey75279902011-05-24 18:39:45 -070097import android.net.NetworkStats;
Jeff Sharkey5a7bcf32012-01-10 17:24:44 -080098import android.net.NetworkStats.NonMonotonicObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070099import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700100import android.net.NetworkTemplate;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800101import android.net.TrafficStats;
junyulai80831d22019-11-21 16:26:27 +0800102import android.net.netstats.provider.INetworkStatsProvider;
103import android.net.netstats.provider.INetworkStatsProviderCallback;
104import android.net.netstats.provider.NetworkStatsProviderCallback;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700105import android.os.BestClock;
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700106import android.os.Binder;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700107import android.os.DropBoxManager;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700108import android.os.Environment;
Jeff Sharkey75279902011-05-24 18:39:45 -0700109import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700110import android.os.HandlerThread;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800111import android.os.IBinder;
Jeff Sharkey75279902011-05-24 18:39:45 -0700112import android.os.INetworkManagementService;
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100113import android.os.Looper;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700114import android.os.Message;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800115import android.os.Messenger;
Jeff Sharkey62489262011-07-17 12:53:28 -0700116import android.os.PowerManager;
junyulai80831d22019-11-21 16:26:27 +0800117import android.os.RemoteCallbackList;
Jeff Sharkey75279902011-05-24 18:39:45 -0700118import android.os.RemoteException;
119import android.os.SystemClock;
Jeff Sharkey00072392018-04-12 14:26:32 -0600120import android.os.Trace;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700121import android.os.UserHandle;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700122import android.provider.Settings;
Jeff Sharkey625239a2012-09-26 22:03:49 -0700123import android.provider.Settings.Global;
Makoto Onukida65a522017-01-13 10:23:30 -0800124import android.service.NetworkInterfaceProto;
125import android.service.NetworkStatsServiceDumpProto;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600126import android.telephony.SubscriptionPlan;
Jeff Sharkey75279902011-05-24 18:39:45 -0700127import android.telephony.TelephonyManager;
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800128import android.text.format.DateUtils;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700129import android.util.ArrayMap;
130import android.util.ArraySet;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700131import android.util.EventLog;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700132import android.util.Log;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700133import android.util.MathUtils;
Jeff Sharkey75279902011-05-24 18:39:45 -0700134import android.util.Slog;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700135import android.util.SparseIntArray;
Makoto Onukida65a522017-01-13 10:23:30 -0800136import android.util.proto.ProtoOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -0700137
Jeff Sharkey4635f102017-09-01 11:27:13 -0600138import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800139import com.android.internal.annotations.VisibleForTesting;
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900140import com.android.internal.net.VpnInfo;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700141import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600142import com.android.internal.util.DumpUtils;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800143import com.android.internal.util.FileRotator;
144import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700145import com.android.server.EventLogTags;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700146import com.android.server.LocalServices;
Jeff Sharkey75279902011-05-24 18:39:45 -0700147
Jeff Sharkey3f391352011-06-05 17:42:53 -0700148import java.io.File;
Jeff Sharkey75279902011-05-24 18:39:45 -0700149import java.io.FileDescriptor;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700150import java.io.IOException;
Jeff Sharkey75279902011-05-24 18:39:45 -0700151import java.io.PrintWriter;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700152import java.time.Clock;
153import java.time.ZoneOffset;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700154import java.util.Arrays;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700155import java.util.HashSet;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700156import java.util.List;
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000157import java.util.Objects;
junyulai05a04c22020-02-12 14:55:54 +0800158import java.util.concurrent.Semaphore;
159import java.util.concurrent.TimeUnit;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700160
Jeff Sharkey75279902011-05-24 18:39:45 -0700161/**
162 * Collect and persist detailed network statistics, and provide this data to
163 * other system services.
164 */
165public class NetworkStatsService extends INetworkStatsService.Stub {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600166 static final String TAG = "NetworkStats";
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700167 static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
168 static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700169
Chalard Jeand7c6e122018-08-22 10:21:26 +0900170 // Perform polling and persist all (FLAG_PERSIST_ALL).
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700171 private static final int MSG_PERFORM_POLL = 1;
Chalard Jeand7c6e122018-08-22 10:21:26 +0900172 // Perform polling, persist network, and register the global alert again.
173 private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700174
175 /** Flags to control detail level of poll event. */
Jeff Sharkey905b5892011-09-30 15:19:49 -0700176 private static final int FLAG_PERSIST_NETWORK = 0x1;
177 private static final int FLAG_PERSIST_UID = 0x2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700178 private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700179 private static final int FLAG_PERSIST_FORCE = 0x100;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700180
Chalard Jeand7c6e122018-08-22 10:21:26 +0900181 /**
182 * When global alert quota is high, wait for this delay before processing each polling,
183 * and do not schedule further polls once there is already one queued.
184 * This avoids firing the global alert too often on devices with high transfer speeds and
185 * high quota.
186 */
junyulai9ff7b4e2019-11-22 22:27:21 +0800187 private static final int DEFAULT_PERFORM_POLL_DELAY_MS = 1000;
Chalard Jeand7c6e122018-08-22 10:21:26 +0900188
Jeff Sharkey163e6442011-10-31 16:37:52 -0700189 private static final String TAG_NETSTATS_ERROR = "netstats_error";
190
Jeff Sharkey75279902011-05-24 18:39:45 -0700191 private final Context mContext;
192 private final INetworkManagementService mNetworkManager;
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900193 private final NetworkStatsFactory mStatsFactory;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700194 private final AlarmManager mAlarmManager;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700195 private final Clock mClock;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700196 private final TelephonyManager mTeleManager;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700197 private final NetworkStatsSettings mSettings;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800198 private final NetworkStatsObservers mStatsObservers;
Jeff Sharkey75279902011-05-24 18:39:45 -0700199
Jeff Sharkey63abc372012-01-11 18:38:16 -0800200 private final File mSystemDir;
201 private final File mBaseDir;
202
Jeff Sharkey62489262011-07-17 12:53:28 -0700203 private final PowerManager.WakeLock mWakeLock;
204
Chenbo Feng00499822018-05-18 17:10:07 -0700205 private final boolean mUseBpfTrafficStats;
206
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800207 @VisibleForTesting
Jeff Sharkey3f391352011-06-05 17:42:53 -0700208 public static final String ACTION_NETWORK_STATS_POLL =
Jeff Sharkey75279902011-05-24 18:39:45 -0700209 "com.android.server.action.NETWORK_STATS_POLL";
Jeff Sharkey497e4432011-06-14 17:27:29 -0700210 public static final String ACTION_NETWORK_STATS_UPDATED =
211 "com.android.server.action.NETWORK_STATS_UPDATED";
Jeff Sharkey75279902011-05-24 18:39:45 -0700212
213 private PendingIntent mPollIntent;
214
Jeff Sharkey63abc372012-01-11 18:38:16 -0800215 private static final String PREFIX_DEV = "dev";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700216 private static final String PREFIX_XT = "xt";
Jeff Sharkey63abc372012-01-11 18:38:16 -0800217 private static final String PREFIX_UID = "uid";
218 private static final String PREFIX_UID_TAG = "uid_tag";
219
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700220 /**
Jack Yub6587ea2016-06-22 11:35:10 -0700221 * Virtual network interface for video telephony. This is for VT data usage counting purpose.
222 */
junyulaid27a1722019-11-15 17:15:01 +0800223 // TODO: Remove this after no one is using it.
224 public static final String VT_INTERFACE = NetworkStats.IFACE_VT;
Jack Yub6587ea2016-06-22 11:35:10 -0700225
226 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700227 * Settings that can be changed externally.
228 */
229 public interface NetworkStatsSettings {
230 public long getPollInterval();
junyulai9ff7b4e2019-11-22 22:27:21 +0800231 public long getPollDelay();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800232 public boolean getSampleEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600233 public boolean getAugmentEnabled();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800234
235 public static class Config {
236 public final long bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800237 public final long rotateAgeMillis;
238 public final long deleteAgeMillis;
239
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700240 public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800241 this.bucketDuration = bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800242 this.rotateAgeMillis = rotateAgeMillis;
243 this.deleteAgeMillis = deleteAgeMillis;
244 }
245 }
246
247 public Config getDevConfig();
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700248 public Config getXtConfig();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800249 public Config getUidConfig();
250 public Config getUidTagConfig();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700251
252 public long getGlobalAlertBytes(long def);
253 public long getDevPersistBytes(long def);
254 public long getXtPersistBytes(long def);
255 public long getUidPersistBytes(long def);
256 public long getUidTagPersistBytes(long def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700257 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700258
259 private final Object mStatsLock = new Object();
260
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700261 /** Set of currently active ifaces. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900262 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700263 private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900264
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700265 /** Set of currently active ifaces for UID stats. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900266 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700267 private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900268
Jeff Sharkey63abc372012-01-11 18:38:16 -0800269 /** Current default active iface. */
Varun Anandd33cbc62019-02-07 14:13:13 -0800270 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800271 private String mActiveIface;
Lorenzo Colittic78da292018-01-19 00:50:48 +0900272
Jeff Sharkey234766a2012-04-10 19:48:07 -0700273 /** Set of any ifaces associated with mobile networks since boot. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900274 @GuardedBy("mStatsLock")
Jeff Sharkey234766a2012-04-10 19:48:07 -0700275 private String[] mMobileIfaces = new String[0];
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700276
Lorenzo Colittic78da292018-01-19 00:50:48 +0900277 /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
278 @GuardedBy("mStatsLock")
279 private Network[] mDefaultNetworks = new Network[0];
280
Jeff Sharkey63abc372012-01-11 18:38:16 -0800281 private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
282 new DropBoxNonMonotonicObserver();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700283
junyulai05a04c22020-02-12 14:55:54 +0800284 private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
junyulai80831d22019-11-21 16:26:27 +0800285 private final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
286 new RemoteCallbackList<>();
junyulai05a04c22020-02-12 14:55:54 +0800287 /** Semaphore used to wait for stats provider to respond to request stats update. */
288 private final Semaphore mStatsProviderSem = new Semaphore(0, true);
junyulai80831d22019-11-21 16:26:27 +0800289
Jeff Sharkey4635f102017-09-01 11:27:13 -0600290 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800291 private NetworkStatsRecorder mDevRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600292 @GuardedBy("mStatsLock")
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700293 private NetworkStatsRecorder mXtRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600294 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800295 private NetworkStatsRecorder mUidRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600296 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800297 private NetworkStatsRecorder mUidTagRecorder;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700298
Jeff Sharkey70c70532012-05-16 14:51:19 -0700299 /** Cached {@link #mXtRecorder} stats. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600300 @GuardedBy("mStatsLock")
Jeff Sharkey70c70532012-05-16 14:51:19 -0700301 private NetworkStatsCollection mXtStatsCached;
Jeff Sharkey75279902011-05-24 18:39:45 -0700302
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700303 /** Current counter sets for each UID. */
304 private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
305
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700306 /** Data layer operation counters for splicing into other structures. */
Jeff Sharkey63abc372012-01-11 18:38:16 -0800307 private NetworkStats mUidOperations = new NetworkStats(0L, 10);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700308
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000309 @NonNull
310 private final Handler mHandler;
Jeff Sharkey75279902011-05-24 18:39:45 -0700311
Jeff Sharkey050151e2018-04-13 14:28:30 -0600312 private volatile boolean mSystemReady;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700313 private long mPersistThreshold = 2 * MB_IN_BYTES;
314 private long mGlobalAlertBytes;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800315
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900316 private static final long POLL_RATE_LIMIT_MS = 15_000;
317
318 private long mLastStatsSessionPoll;
319
320 /** Map from UID to number of opened sessions */
321 @GuardedBy("mOpenSessionCallsPerUid")
322 private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
323
324 private final static int DUMP_STATS_SESSION_COUNT = 20;
325
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000326 @NonNull
327 private final Dependencies mDeps;
328
Jeff Sharkey9911a282018-02-14 22:29:11 -0700329 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700330 return new File(Environment.getDataDirectory(), "system");
Jeff Sharkey75279902011-05-24 18:39:45 -0700331 }
332
Jeff Sharkey9911a282018-02-14 22:29:11 -0700333 private static @NonNull File getDefaultBaseDir() {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800334 File baseDir = new File(getDefaultSystemDir(), "netstats");
335 baseDir.mkdirs();
336 return baseDir;
337 }
338
Jeff Sharkey9911a282018-02-14 22:29:11 -0700339 private static @NonNull Clock getDefaultClock() {
340 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
341 Clock.systemUTC());
342 }
343
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000344 private final class NetworkStatsHandler extends Handler {
345 NetworkStatsHandler(@NonNull Looper looper) {
346 super(looper);
347 }
348
349 @Override
350 public void handleMessage(Message msg) {
351 switch (msg.what) {
352 case MSG_PERFORM_POLL: {
353 performPoll(FLAG_PERSIST_ALL);
354 break;
355 }
356 case MSG_PERFORM_POLL_REGISTER_ALERT: {
357 performPoll(FLAG_PERSIST_NETWORK);
358 registerGlobalAlert();
359 break;
360 }
361 }
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100362 }
363 }
364
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800365 public static NetworkStatsService create(Context context,
366 INetworkManagementService networkManager) {
367 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
368 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
369 PowerManager.WakeLock wakeLock =
370 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
371
372 NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
Jayachandran C43fa1be2019-11-15 09:58:04 -0800373 wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class),
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900374 new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(),
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000375 new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(),
376 new Dependencies());
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900377 service.registerLocalService();
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800378
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800379 return service;
380 }
381
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900382 // This must not be called outside of tests, even within the same package, as this constructor
383 // does not register the local service. Use the create() helper above.
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800384 @VisibleForTesting
385 NetworkStatsService(Context context, INetworkManagementService networkManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700386 AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800387 TelephonyManager teleManager, NetworkStatsSettings settings,
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900388 NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir,
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000389 File baseDir, @NonNull Dependencies deps) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000390 mContext = Objects.requireNonNull(context, "missing Context");
391 mNetworkManager = Objects.requireNonNull(networkManager,
392 "missing INetworkManagementService");
393 mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager");
394 mClock = Objects.requireNonNull(clock, "missing Clock");
395 mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings");
396 mTeleManager = Objects.requireNonNull(teleManager, "missing TelephonyManager");
397 mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock");
398 mStatsFactory = Objects.requireNonNull(factory, "missing factory");
399 mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers");
400 mSystemDir = Objects.requireNonNull(systemDir, "missing systemDir");
401 mBaseDir = Objects.requireNonNull(baseDir, "missing baseDir");
Chenbo Feng6880d632018-12-22 13:20:31 -0800402 mUseBpfTrafficStats = new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists();
Automerger Merge Workerce07d8d2020-03-04 13:36:11 +0000403 mDeps = Objects.requireNonNull(deps, "missing Dependencies");
404
405 final HandlerThread handlerThread = mDeps.makeHandlerThread();
406 handlerThread.start();
407 mHandler = new NetworkStatsHandler(handlerThread.getLooper());
408 }
409
410 /**
411 * Dependencies of NetworkStatsService, for injection in tests.
412 */
413 // TODO: Move more stuff into dependencies object.
414 @VisibleForTesting
415 public static class Dependencies {
416 /**
417 * Create a HandlerThread to use in NetworkStatsService.
418 */
419 @NonNull
420 public HandlerThread makeHandlerThread() {
421 return new HandlerThread(TAG);
422 }
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900423 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700424
Remi NGUYEN VANa8e90902018-04-26 17:52:03 +0900425 private void registerLocalService() {
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700426 LocalServices.addService(NetworkStatsManagerInternal.class,
427 new NetworkStatsManagerInternalImpl());
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800428 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700429
Jeff Sharkey75279902011-05-24 18:39:45 -0700430 public void systemReady() {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800431 synchronized (mStatsLock) {
Hugo Benichi96dc0c12019-05-15 23:38:43 +0900432 mSystemReady = true;
433
Jeff Sharkey4635f102017-09-01 11:27:13 -0600434 // create data recorders along with historical rotators
435 mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
436 mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
437 mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
438 mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
439
440 updatePersistThresholdsLocked();
441
Jeff Sharkey63abc372012-01-11 18:38:16 -0800442 // upgrade any legacy stats, migrating them to rotated files
443 maybeUpgradeLegacyStatsLocked();
444
445 // read historical network stats from disk, since policy service
446 // might need them right away.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700447 mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800448
449 // bootstrap initial stats to prevent double-counting later
450 bootstrapStatsLocked();
451 }
Jeff Sharkey3359aca2011-11-08 18:08:48 -0800452
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700453 // watch for tethering changes
454 final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
Vinit Deshpande92d141f2014-09-10 18:05:10 -0700455 mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700456
Jeff Sharkey75279902011-05-24 18:39:45 -0700457 // listen for periodic polling events
458 final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700459 mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
Jeff Sharkey75279902011-05-24 18:39:45 -0700460
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700461 // listen for uid removal to clean stats
462 final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
463 mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
464
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700465 // listen for user changes to clean stats
466 final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
467 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
468
Jeff Sharkey75279902011-05-24 18:39:45 -0700469 // persist stats during clean shutdown
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700470 final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
471 mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
Jeff Sharkey75279902011-05-24 18:39:45 -0700472
473 try {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700474 mNetworkManager.registerObserver(mAlertObserver);
Jeff Sharkey75279902011-05-24 18:39:45 -0700475 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700476 // ignored; service lives in system_server
Jeff Sharkey75279902011-05-24 18:39:45 -0700477 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700478
Hugo Benichi96dc0c12019-05-15 23:38:43 +0900479 // schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}.
480 final PendingIntent pollIntent =
481 PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
482
483 final long currentRealtime = SystemClock.elapsedRealtime();
484 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
485 mSettings.getPollInterval(), pollIntent);
486
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700487 registerGlobalAlert();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800488 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700489
Jeff Sharkey63abc372012-01-11 18:38:16 -0800490 private NetworkStatsRecorder buildRecorder(
491 String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700492 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
493 Context.DROPBOX_SERVICE);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700494 return new NetworkStatsRecorder(new FileRotator(
495 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700496 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
Jeff Sharkey75279902011-05-24 18:39:45 -0700497 }
498
Andreas Gampea36dc622018-02-05 17:19:22 -0800499 @GuardedBy("mStatsLock")
Jeff Sharkey3f391352011-06-05 17:42:53 -0700500 private void shutdownLocked() {
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700501 mContext.unregisterReceiver(mTetherReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700502 mContext.unregisterReceiver(mPollReceiver);
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700503 mContext.unregisterReceiver(mRemovedReceiver);
Ryuki Nakamuraa47b0c92017-03-01 10:40:36 +0900504 mContext.unregisterReceiver(mUserReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700505 mContext.unregisterReceiver(mShutdownReceiver);
506
Jeff Sharkey9911a282018-02-14 22:29:11 -0700507 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800508
509 // persist any pending stats
510 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700511 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800512 mUidRecorder.forcePersistLocked(currentTime);
513 mUidTagRecorder.forcePersistLocked(currentTime);
514
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800515 mSystemReady = false;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800516 }
517
Andreas Gampea36dc622018-02-05 17:19:22 -0800518 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800519 private void maybeUpgradeLegacyStatsLocked() {
520 File file;
521 try {
522 file = new File(mSystemDir, "netstats.bin");
523 if (file.exists()) {
524 mDevRecorder.importLegacyNetworkLocked(file);
525 file.delete();
526 }
527
528 file = new File(mSystemDir, "netstats_xt.bin");
529 if (file.exists()) {
530 file.delete();
531 }
532
533 file = new File(mSystemDir, "netstats_uid.bin");
534 if (file.exists()) {
535 mUidRecorder.importLegacyUidLocked(file);
536 mUidTagRecorder.importLegacyUidLocked(file);
537 file.delete();
538 }
539 } catch (IOException e) {
540 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700541 } catch (OutOfMemoryError e) {
542 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeyc506ff62011-11-17 11:59:29 -0800543 }
Jeff Sharkey3f391352011-06-05 17:42:53 -0700544 }
545
Jeff Sharkey75279902011-05-24 18:39:45 -0700546 /**
junyulai80831d22019-11-21 16:26:27 +0800547 * Register for a global alert that is delivered through {@link INetworkManagementEventObserver}
548 * or {@link NetworkStatsProviderCallback#onAlertReached()} once a threshold amount of data has
549 * been transferred.
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700550 */
551 private void registerGlobalAlert() {
552 try {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700553 mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700554 } catch (IllegalStateException e) {
555 Slog.w(TAG, "problem registering for global alert: " + e);
556 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700557 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700558 }
junyulai80831d22019-11-21 16:26:27 +0800559 invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setAlert(mGlobalAlertBytes));
Jeff Sharkey75279902011-05-24 18:39:45 -0700560 }
561
562 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700563 public INetworkStatsSession openSession() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600564 // NOTE: if callers want to get non-augmented data, they should go
565 // through the public API
566 return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000567 }
568
569 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600570 public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
571 return openSessionInternal(flags, callingPackage);
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100572 }
573
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900574 private boolean isRateLimitedForPoll(int callingUid) {
575 if (callingUid == android.os.Process.SYSTEM_UID) {
576 return false;
577 }
578
579 final long lastCallTime;
580 final long now = SystemClock.elapsedRealtime();
581 synchronized (mOpenSessionCallsPerUid) {
582 int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
583 mOpenSessionCallsPerUid.put(callingUid, calls + 1);
584 lastCallTime = mLastStatsSessionPoll;
585 mLastStatsSessionPoll = now;
586 }
587
588 return now - lastCallTime < POLL_RATE_LIMIT_MS;
589 }
590
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600591 private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900592 final int callingUid = Binder.getCallingUid();
593 final int usedFlags = isRateLimitedForPoll(callingUid)
594 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
595 : flags;
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600596 if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
597 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100598 final long ident = Binder.clearCallingIdentity();
599 try {
600 performPoll(FLAG_PERSIST_ALL);
601 } finally {
602 Binder.restoreCallingIdentity(ident);
603 }
604 }
605
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700606 // return an IBinder which holds strong references to any loaded stats
607 // for its lifetime; when caller closes only weak references remain.
608
609 return new INetworkStatsSession.Stub() {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900610 private final int mCallingUid = callingUid;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600611 private final String mCallingPackage = callingPackage;
612 private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
613 callingPackage);
614
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700615 private NetworkStatsCollection mUidComplete;
616 private NetworkStatsCollection mUidTagComplete;
617
618 private NetworkStatsCollection getUidComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700619 synchronized (mStatsLock) {
620 if (mUidComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700621 mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
622 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700623 return mUidComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700624 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700625 }
626
627 private NetworkStatsCollection getUidTagComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700628 synchronized (mStatsLock) {
629 if (mUidTagComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700630 mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
631 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700632 return mUidTagComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700633 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700634 }
635
636 @Override
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000637 public int[] getRelevantUids() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600638 return getUidComplete().getRelevantUids(mAccessLevel);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000639 }
640
641 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600642 public NetworkStats getDeviceSummaryForNetwork(
643 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900644 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600645 mCallingUid);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000646 }
647
648 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700649 public NetworkStats getSummaryForNetwork(
650 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900651 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600652 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700653 }
654
655 @Override
656 public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900657 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600658 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700659 }
660
661 @Override
662 public NetworkStats getSummaryForAllUid(
663 NetworkTemplate template, long start, long end, boolean includeTags) {
Jeff Davidson39583b52016-12-12 11:55:37 -0800664 try {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600665 final NetworkStats stats = getUidComplete()
666 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800667 if (includeTags) {
668 final NetworkStats tagStats = getUidTagComplete()
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600669 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800670 stats.combineAllValues(tagStats);
671 }
672 return stats;
673 } catch (NullPointerException e) {
674 // TODO: Track down and fix the cause of this crash and remove this catch block.
675 Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
676 throw e;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700677 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700678 }
679
680 @Override
681 public NetworkStatsHistory getHistoryForUid(
682 NetworkTemplate template, int uid, int set, int tag, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600683 // NOTE: We don't augment UID-level statistics
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700684 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600685 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
686 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700687 } else {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600688 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
689 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700690 }
691 }
692
693 @Override
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100694 public NetworkStatsHistory getHistoryIntervalForUid(
695 NetworkTemplate template, int uid, int set, int tag, int fields,
696 long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600697 // NOTE: We don't augment UID-level statistics
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100698 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600699 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
700 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700701 } else if (uid == Binder.getCallingUid()) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600702 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
703 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700704 } else {
705 throw new SecurityException("Calling package " + mCallingPackage
706 + " cannot access tag information from a different uid");
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100707 }
708 }
709
710 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700711 public void close() {
712 mUidComplete = null;
713 mUidTagComplete = null;
714 }
715 };
Jeff Sharkey905b5892011-09-30 15:19:49 -0700716 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700717
Jeff Davidson1efb1332015-12-09 18:04:50 -0800718 private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
719 return NetworkStatsAccess.checkAccessLevel(
720 mContext, Binder.getCallingUid(), callingPackage);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000721 }
722
Jeff Sharkey70c70532012-05-16 14:51:19 -0700723 /**
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600724 * Find the most relevant {@link SubscriptionPlan} for the given
725 * {@link NetworkTemplate} and flags. This is typically used to augment
726 * local measurement results to match a known anchor from the carrier.
727 */
728 private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
729 SubscriptionPlan plan = null;
730 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600731 && mSettings.getAugmentEnabled()) {
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700732 if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600733 final long token = Binder.clearCallingIdentity();
734 try {
Jeff Sharkey146bb332018-04-18 15:42:57 -0600735 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
736 .getSubscriptionPlan(template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600737 } finally {
738 Binder.restoreCallingIdentity(token);
739 }
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700740 if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600741 }
742 return plan;
743 }
744
745 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700746 * Return network summary, splicing between DEV and XT stats when
747 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700748 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600749 private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
750 long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700751 // We've been using pure XT stats long enough that we no longer need to
752 // splice DEV and XT together.
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600753 final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
754 accessLevel, callingUid);
755
756 final long now = System.currentTimeMillis();
757 final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
758
759 final NetworkStats stats = new NetworkStats(end - start, 1);
junyulaid27a1722019-11-15 17:15:01 +0800760 stats.addEntry(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
Lorenzo Colittiada23ed2018-01-19 01:05:20 +0900761 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
762 entry.txBytes, entry.txPackets, entry.operations));
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600763 return stats;
Jeff Sharkey70c70532012-05-16 14:51:19 -0700764 }
765
766 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700767 * Return network history, splicing between DEV and XT stats when
768 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700769 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600770 private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
771 int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700772 // We've been using pure XT stats long enough that we no longer need to
773 // splice DEV and XT together.
Jeff Sharkey4635f102017-09-01 11:27:13 -0600774 final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
775 synchronized (mStatsLock) {
776 return mXtStatsCached.getHistory(template, augmentPlan,
777 UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
778 accessLevel, callingUid);
779 }
Jeff Sharkey70c70532012-05-16 14:51:19 -0700780 }
781
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700782 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
783 assertSystemReady();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600784
785 // NOTE: if callers want to get non-augmented data, they should go
786 // through the public API
787 return internalGetSummaryForNetwork(template,
788 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
789 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700790 }
791
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700792 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
793 assertSystemReady();
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700794
795 final NetworkStatsCollection uidComplete;
796 synchronized (mStatsLock) {
797 uidComplete = mUidRecorder.getOrLoadCompleteLocked();
798 }
799 return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
800 android.os.Process.SYSTEM_UID);
801 }
802
Jeff Sharkey350083e2011-06-29 10:45:16 -0700803 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700804 public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
805 if (Binder.getCallingUid() != uid) {
806 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
807 }
808
809 // TODO: switch to data layer stats once kernel exports
810 // for now, read network layer stats and flatten across all ifaces
Lorenzo Colitti8b577132019-06-24 13:28:04 +0900811 final NetworkStats networkLayer = readNetworkStatsUidDetail(uid, INTERFACES_ALL, TAG_ALL);
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800812
Jeff Sharkey21a54782012-04-09 10:27:55 -0700813 // splice in operation counts
814 networkLayer.spliceOperationsFrom(mUidOperations);
815
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700816 final NetworkStats dataLayer = new NetworkStats(
817 networkLayer.getElapsedRealtime(), networkLayer.size());
818
819 NetworkStats.Entry entry = null;
820 for (int i = 0; i < networkLayer.size(); i++) {
821 entry = networkLayer.getValues(i, entry);
822 entry.iface = IFACE_ALL;
823 dataLayer.combineValues(entry);
824 }
825
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700826 return dataLayer;
827 }
828
829 @Override
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900830 public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
831 try {
832 final String[] ifacesToQuery =
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900833 mStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
Varun Anand6a04d492019-06-10 22:43:52 +0000834 return getNetworkStatsUidDetail(ifacesToQuery);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900835 } catch (RemoteException e) {
836 Log.wtf(TAG, "Error compiling UID stats", e);
837 return new NetworkStats(0L, 0);
838 }
839 }
840
841 @Override
Jeff Sharkey234766a2012-04-10 19:48:07 -0700842 public String[] getMobileIfaces() {
843 return mMobileIfaces;
844 }
845
846 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700847 public void incrementOperationCount(int uid, int tag, int operationCount) {
848 if (Binder.getCallingUid() != uid) {
junyulai80831d22019-11-21 16:26:27 +0800849 mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700850 }
851
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700852 if (operationCount < 0) {
853 throw new IllegalArgumentException("operation count can only be incremented");
854 }
855 if (tag == TAG_NONE) {
856 throw new IllegalArgumentException("operation count must have specific tag");
857 }
858
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700859 synchronized (mStatsLock) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700860 final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800861 mUidOperations.combineValues(
862 mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
863 mUidOperations.combineValues(
864 mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700865 }
866 }
867
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700868 @VisibleForTesting
869 void setUidForeground(int uid, boolean uidForeground) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700870 synchronized (mStatsLock) {
871 final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
872 final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
873 if (oldSet != set) {
874 mActiveUidCounterSet.put(uid, set);
875 setKernelCounterSet(uid, set);
876 }
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700877 }
878 }
879
880 @Override
Varun Anandd33cbc62019-02-07 14:13:13 -0800881 public void forceUpdateIfaces(
882 Network[] defaultNetworks,
Varun Anandd33cbc62019-02-07 14:13:13 -0800883 NetworkState[] networkStates,
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900884 String activeIface,
885 VpnInfo[] vpnInfos) {
Chiachang Wange05d9d82019-04-09 19:42:52 +0800886 checkNetworkStackPermission(mContext);
Jeff Sharkey69736342014-12-08 14:50:12 -0800887
888 final long token = Binder.clearCallingIdentity();
889 try {
Benedict Wong9fbbdeb2019-06-12 17:46:31 +0000890 updateIfaces(defaultNetworks, networkStates, activeIface);
Jeff Sharkey69736342014-12-08 14:50:12 -0800891 } finally {
892 Binder.restoreCallingIdentity(token);
893 }
Lorenzo Colitti4aa87602019-06-24 13:50:45 +0900894
895 // Update the VPN underlying interfaces only after the poll is made and tun data has been
896 // migrated. Otherwise the migration would use the new interfaces instead of the ones that
897 // were current when the polled data was transferred.
898 mStatsFactory.updateVpnInfos(vpnInfos);
Jeff Sharkey69736342014-12-08 14:50:12 -0800899 }
900
901 @Override
Jeff Sharkey350083e2011-06-29 10:45:16 -0700902 public void forceUpdate() {
903 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkeye630f7b2012-01-31 17:12:53 -0800904
905 final long token = Binder.clearCallingIdentity();
906 try {
907 performPoll(FLAG_PERSIST_ALL);
908 } finally {
909 Binder.restoreCallingIdentity(token);
910 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700911 }
912
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700913 private void advisePersistThreshold(long thresholdBytes) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700914 // clamp threshold into safe range
915 mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700916 if (LOGV) {
917 Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
918 + mPersistThreshold);
919 }
920
junyulai41c13c92019-12-06 18:50:41 +0800921 final long oldGlobalAlertBytes = mGlobalAlertBytes;
922
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700923 // update and persist if beyond new thresholds
Jeff Sharkey9911a282018-02-14 22:29:11 -0700924 final long currentTime = mClock.millis();
Jeff Sharkey58015972012-05-07 11:08:49 -0700925 synchronized (mStatsLock) {
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700926 if (!mSystemReady) return;
927
Jeff Sharkey4635f102017-09-01 11:27:13 -0600928 updatePersistThresholdsLocked();
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700929
Jeff Sharkey58015972012-05-07 11:08:49 -0700930 mDevRecorder.maybePersistLocked(currentTime);
931 mXtRecorder.maybePersistLocked(currentTime);
932 mUidRecorder.maybePersistLocked(currentTime);
933 mUidTagRecorder.maybePersistLocked(currentTime);
934 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700935
junyulai41c13c92019-12-06 18:50:41 +0800936 if (oldGlobalAlertBytes != mGlobalAlertBytes) {
937 registerGlobalAlert();
938 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700939 }
940
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800941 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700942 public DataUsageRequest registerUsageCallback(String callingPackage,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800943 DataUsageRequest request, Messenger messenger, IBinder binder) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000944 Objects.requireNonNull(callingPackage, "calling package is null");
945 Objects.requireNonNull(request, "DataUsageRequest is null");
946 Objects.requireNonNull(request.template, "NetworkTemplate is null");
947 Objects.requireNonNull(messenger, "messenger is null");
948 Objects.requireNonNull(binder, "binder is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800949
950 int callingUid = Binder.getCallingUid();
951 @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
952 DataUsageRequest normalizedRequest;
953 final long token = Binder.clearCallingIdentity();
954 try {
955 normalizedRequest = mStatsObservers.register(request, messenger, binder,
956 callingUid, accessLevel);
957 } finally {
958 Binder.restoreCallingIdentity(token);
959 }
960
961 // Create baseline stats
Chalard Jeand7c6e122018-08-22 10:21:26 +0900962 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800963
964 return normalizedRequest;
965 }
966
967 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700968 public void unregisterUsageRequest(DataUsageRequest request) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +0000969 Objects.requireNonNull(request, "DataUsageRequest is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800970
971 int callingUid = Binder.getCallingUid();
972 final long token = Binder.clearCallingIdentity();
973 try {
974 mStatsObservers.unregister(request, callingUid);
975 } finally {
976 Binder.restoreCallingIdentity(token);
977 }
978 }
979
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800980 @Override
981 public long getUidStats(int uid, int type) {
Chenbo Fengaedd6a32017-11-20 18:23:46 -0800982 return nativeGetUidStat(uid, type, checkBpfStatsEnable());
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800983 }
984
985 @Override
986 public long getIfaceStats(String iface, int type) {
Mike SUce756752018-11-26 15:05:13 +0800987 long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
988 if (nativeIfaceStats == -1) {
989 return nativeIfaceStats;
990 } else {
991 // When tethering offload is in use, nativeIfaceStats does not contain usage from
992 // offload, add it back here.
993 // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
994 // this does not cause double-counting of tethering traffic, because
995 // NetdTetheringStatsProvider returns zero NetworkStats
996 // when called with STATS_PER_IFACE.
997 return nativeIfaceStats + getTetherStats(iface, type);
998 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800999 }
1000
1001 @Override
1002 public long getTotalStats(int type) {
Mike SUce756752018-11-26 15:05:13 +08001003 long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
1004 if (nativeTotalStats == -1) {
1005 return nativeTotalStats;
1006 } else {
1007 // Refer to comment in getIfaceStats
1008 return nativeTotalStats + getTetherStats(IFACE_ALL, type);
1009 }
1010 }
1011
1012 private long getTetherStats(String iface, int type) {
1013 final NetworkStats tetherSnapshot;
1014 final long token = Binder.clearCallingIdentity();
1015 try {
1016 tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
1017 } catch (RemoteException e) {
1018 Slog.w(TAG, "Error get TetherStats: " + e);
1019 return 0;
1020 } finally {
1021 Binder.restoreCallingIdentity(token);
1022 }
1023 HashSet<String> limitIfaces;
1024 if (iface == IFACE_ALL) {
1025 limitIfaces = null;
1026 } else {
1027 limitIfaces = new HashSet<String>();
1028 limitIfaces.add(iface);
1029 }
1030 NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
1031 if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
1032 " entry=" + entry);
1033 switch (type) {
1034 case 0: // TYPE_RX_BYTES
1035 return entry.rxBytes;
1036 case 1: // TYPE_RX_PACKETS
1037 return entry.rxPackets;
1038 case 2: // TYPE_TX_BYTES
1039 return entry.txBytes;
1040 case 3: // TYPE_TX_PACKETS
1041 return entry.txPackets;
1042 default:
1043 return 0;
1044 }
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001045 }
1046
1047 private boolean checkBpfStatsEnable() {
Chenbo Feng00499822018-05-18 17:10:07 -07001048 return mUseBpfTrafficStats;
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001049 }
1050
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001051 /**
1052 * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
1053 * reflect current {@link #mPersistThreshold} value. Always defers to
Jeff Sharkey625239a2012-09-26 22:03:49 -07001054 * {@link Global} values when defined.
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001055 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001056 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001057 private void updatePersistThresholdsLocked() {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001058 mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
1059 mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
1060 mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
1061 mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
1062 mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
1063 }
1064
Jeff Sharkey75279902011-05-24 18:39:45 -07001065 /**
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001066 * Receiver that watches for {@link Tethering} to claim interface pairs.
1067 */
1068 private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
1069 @Override
1070 public void onReceive(Context context, Intent intent) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001071 performPoll(FLAG_PERSIST_NETWORK);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001072 }
1073 };
1074
Jeff Sharkey75279902011-05-24 18:39:45 -07001075 private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
1076 @Override
1077 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001078 // on background handler thread, and verified UPDATE_DEVICE_STATS
1079 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001080 performPoll(FLAG_PERSIST_ALL);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001081
1082 // verify that we're watching global alert
1083 registerGlobalAlert();
Jeff Sharkey75279902011-05-24 18:39:45 -07001084 }
1085 };
1086
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001087 private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
1088 @Override
1089 public void onReceive(Context context, Intent intent) {
1090 // on background handler thread, and UID_REMOVED is protected
1091 // broadcast.
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001092
1093 final int uid = intent.getIntExtra(EXTRA_UID, -1);
1094 if (uid == -1) return;
1095
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001096 synchronized (mStatsLock) {
Jeff Sharkey62489262011-07-17 12:53:28 -07001097 mWakeLock.acquire();
1098 try {
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001099 removeUidsLocked(uid);
1100 } finally {
1101 mWakeLock.release();
1102 }
1103 }
1104 }
1105 };
1106
1107 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1108 @Override
1109 public void onReceive(Context context, Intent intent) {
1110 // On background handler thread, and USER_REMOVED is protected
1111 // broadcast.
1112
1113 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1114 if (userId == -1) return;
1115
1116 synchronized (mStatsLock) {
1117 mWakeLock.acquire();
1118 try {
1119 removeUserLocked(userId);
Jeff Sharkey62489262011-07-17 12:53:28 -07001120 } finally {
1121 mWakeLock.release();
1122 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001123 }
1124 }
1125 };
1126
Jeff Sharkey75279902011-05-24 18:39:45 -07001127 private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
1128 @Override
1129 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001130 // SHUTDOWN is protected broadcast.
Jeff Sharkey75279902011-05-24 18:39:45 -07001131 synchronized (mStatsLock) {
Jeff Sharkey3f391352011-06-05 17:42:53 -07001132 shutdownLocked();
Jeff Sharkey75279902011-05-24 18:39:45 -07001133 }
1134 }
1135 };
1136
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001137 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001138 * Observer that watches for {@link INetworkManagementService} alerts.
1139 */
junyulai80831d22019-11-21 16:26:27 +08001140 private final INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001141 @Override
1142 public void limitReached(String limitName, String iface) {
1143 // only someone like NMS should be calling us
paulhua6af6b62019-08-12 16:25:11 +08001144 NetworkStack.checkNetworkStackPermission(mContext);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001145
1146 if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001147 // kick off background poll to collect network stats unless there is already
1148 // such a call pending; UID stats are handled during normal polling interval.
1149 if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
1150 mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
junyulai9ff7b4e2019-11-22 22:27:21 +08001151 mSettings.getPollDelay());
Chalard Jeand7c6e122018-08-22 10:21:26 +09001152 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001153 }
1154 }
1155 };
1156
Varun Anandd33cbc62019-02-07 14:13:13 -08001157 private void updateIfaces(
1158 Network[] defaultNetworks,
Varun Anandd33cbc62019-02-07 14:13:13 -08001159 NetworkState[] networkStates,
1160 String activeIface) {
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001161 synchronized (mStatsLock) {
1162 mWakeLock.acquire();
1163 try {
Varun Anandd33cbc62019-02-07 14:13:13 -08001164 mActiveIface = activeIface;
1165 updateIfacesLocked(defaultNetworks, networkStates);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001166 } finally {
1167 mWakeLock.release();
1168 }
1169 }
1170 }
1171
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001172 /**
Benedict Wong9fbbdeb2019-06-12 17:46:31 +00001173 * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
1174 * NetworkStatsHistory}. When multiple {@link NetworkInfo} are active on a single {@code iface},
1175 * they are combined under a single {@link NetworkIdentitySet}.
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001176 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001177 @GuardedBy("mStatsLock")
Varun Anandd33cbc62019-02-07 14:13:13 -08001178 private void updateIfacesLocked(Network[] defaultNetworks, NetworkState[] states) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001179 if (!mSystemReady) return;
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001180 if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001181
1182 // take one last stats snapshot before updating iface mapping. this
1183 // isn't perfect, since the kernel may already be counting traffic from
1184 // the updated network.
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001185
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001186 // poll, but only persist network stats to keep codepath fast. UID stats
1187 // will be persisted during next alarm poll event.
1188 performPollLocked(FLAG_PERSIST_NETWORK);
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001189
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001190 // Rebuild active interfaces based on connected networks
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001191 mActiveIfaces.clear();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001192 mActiveUidIfaces.clear();
Lorenzo Colittic78da292018-01-19 00:50:48 +09001193 if (defaultNetworks != null) {
1194 // Caller is ConnectivityService. Update the list of default networks.
1195 mDefaultNetworks = defaultNetworks;
1196 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001197
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001198 final ArraySet<String> mobileIfaces = new ArraySet<>();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001199 for (NetworkState state : states) {
1200 if (state.networkInfo.isConnected()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001201 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001202 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
1203 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1204 isDefault);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001205
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001206 // Traffic occurring on the base interface is always counted for
1207 // both total usage and UID details.
1208 final String baseIface = state.linkProperties.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001209 if (baseIface != null) {
1210 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1211 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
Jack Yub6587ea2016-06-22 11:35:10 -07001212
1213 // Build a separate virtual interface for VT (Video Telephony) data usage.
1214 // Only do this when IMS is not metered, but VT is metered.
1215 // If IMS is metered, then the IMS network usage has already included VT usage.
1216 // VT is considered always metered in framework's layer. If VT is not metered
1217 // per carrier's policy, modem will report 0 usage for VT calls.
1218 if (state.networkCapabilities.hasCapability(
1219 NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1220
1221 // Copy the identify from IMS one but mark it as metered.
1222 NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1223 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001224 ident.getRoaming(), true /* metered */,
1225 true /* onDefaultNetwork */);
junyulaid27a1722019-11-15 17:15:01 +08001226 findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent);
1227 findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent);
Jack Yub6587ea2016-06-22 11:35:10 -07001228 }
1229
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001230 if (isMobile) {
1231 mobileIfaces.add(baseIface);
1232 }
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001233 }
1234
junyulai669ef462019-06-28 16:47:49 +08001235 // Traffic occurring on stacked interfaces is usually clatd.
1236 // UID stats are always counted on the stacked interface and never
1237 // on the base interface, because the packets on the base interface
1238 // do not actually match application sockets until they are translated.
1239 //
1240 // Interface stats are more complicated. Packets subject to BPF offload
1241 // never appear on the base interface and only appear on the stacked
1242 // interface, so to ensure those packets increment interface stats, interface
1243 // stats from stacked interfaces must be collected.
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001244 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1245 for (LinkProperties stackedLink : stackedLinks) {
1246 final String stackedIface = stackedLink.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001247 if (stackedIface != null) {
junyulai669ef462019-06-28 16:47:49 +08001248 if (mUseBpfTrafficStats) {
1249 findOrCreateNetworkIdentitySet(mActiveIfaces, stackedIface).add(ident);
1250 }
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001251 findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1252 if (isMobile) {
1253 mobileIfaces.add(stackedIface);
1254 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001255
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001256 mStatsFactory.noteStackedIface(stackedIface, baseIface);
Jeff Sharkey234766a2012-04-10 19:48:07 -07001257 }
1258 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001259 }
1260 }
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001261
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001262 mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1263 }
1264
1265 private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1266 ArrayMap<K, NetworkIdentitySet> map, K key) {
1267 NetworkIdentitySet ident = map.get(key);
1268 if (ident == null) {
1269 ident = new NetworkIdentitySet();
1270 map.put(key, ident);
1271 }
1272 return ident;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001273 }
1274
Andreas Gampea36dc622018-02-05 17:19:22 -08001275 @GuardedBy("mStatsLock")
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001276 private void recordSnapshotLocked(long currentTime) throws RemoteException {
1277 // snapshot and record current counters; read UID stats first to
Jack Yub6587ea2016-06-22 11:35:10 -07001278 // avoid over counting dev stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001279 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001280 final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
Jeff Sharkey00072392018-04-12 14:26:32 -06001281 Trace.traceEnd(TRACE_TAG_NETWORK);
1282 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
junyulai5bbd6262020-01-14 18:41:08 +08001283 final NetworkStats xtSnapshot = readNetworkStatsSummaryXt();
Jeff Sharkey00072392018-04-12 14:26:32 -06001284 Trace.traceEnd(TRACE_TAG_NETWORK);
1285 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001286 final NetworkStats devSnapshot = readNetworkStatsSummaryDev();
Jeff Sharkey00072392018-04-12 14:26:32 -06001287 Trace.traceEnd(TRACE_TAG_NETWORK);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001288
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001289 // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1290 // providers that isn't already counted by dev and XT stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001291 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001292 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
Jeff Sharkey00072392018-04-12 14:26:32 -06001293 Trace.traceEnd(TRACE_TAG_NETWORK);
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001294 xtSnapshot.combineAllValues(tetherSnapshot);
1295 devSnapshot.combineAllValues(tetherSnapshot);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001296
junyulai80831d22019-11-21 16:26:27 +08001297 // Snapshot for dev/xt stats from all custom stats providers. Counts per-interface data
1298 // from stats providers that isn't already counted by dev and XT stats.
1299 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotStatsProvider");
1300 final NetworkStats providersnapshot = getNetworkStatsFromProviders(STATS_PER_IFACE);
1301 Trace.traceEnd(TRACE_TAG_NETWORK);
1302 xtSnapshot.combineAllValues(providersnapshot);
1303 devSnapshot.combineAllValues(providersnapshot);
1304
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001305 // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1306 // can't be reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001307 Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
Benedict Wong833603c2019-06-13 10:54:38 -07001308 mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001309 Trace.traceEnd(TRACE_TAG_NETWORK);
1310 Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
Benedict Wong833603c2019-06-13 10:54:38 -07001311 mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001312 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001313
1314 // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001315 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
Benedict Wong833603c2019-06-13 10:54:38 -07001316 mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001317 Trace.traceEnd(TRACE_TAG_NETWORK);
1318 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
Benedict Wong833603c2019-06-13 10:54:38 -07001319 mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001320 Trace.traceEnd(TRACE_TAG_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001321
1322 // We need to make copies of member fields that are sent to the observer to avoid
1323 // a race condition between the service handler thread and the observer's
1324 mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
Benedict Wong833603c2019-06-13 10:54:38 -07001325 new ArrayMap<>(mActiveUidIfaces), currentTime);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001326 }
1327
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001328 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001329 * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1330 * so we have baseline values without double-counting.
1331 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001332 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001333 private void bootstrapStatsLocked() {
Jeff Sharkey9911a282018-02-14 22:29:11 -07001334 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001335
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001336 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001337 recordSnapshotLocked(currentTime);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001338 } catch (IllegalStateException e) {
1339 Slog.w(TAG, "problem reading network stats: " + e);
1340 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001341 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001342 }
1343 }
1344
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001345 private void performPoll(int flags) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001346 synchronized (mStatsLock) {
1347 mWakeLock.acquire();
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001348
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001349 try {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001350 performPollLocked(flags);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001351 } finally {
1352 mWakeLock.release();
1353 }
1354 }
1355 }
1356
1357 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001358 * Periodic poll operation, reading current statistics and recording into
1359 * {@link NetworkStatsHistory}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001360 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001361 @GuardedBy("mStatsLock")
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001362 private void performPollLocked(int flags) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001363 if (!mSystemReady) return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001364 if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
Jeff Sharkey00072392018-04-12 14:26:32 -06001365 Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
Jeff Sharkey75279902011-05-24 18:39:45 -07001366
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001367 final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1368 final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001369 final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001370
junyulai05a04c22020-02-12 14:55:54 +08001371 // Request asynchronous stats update from all providers for next poll. And wait a bit of
1372 // time to allow providers report-in given that normally binder call should be fast.
1373 // TODO: request with a valid token.
1374 Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
1375 final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
1376 mStatsProviderSem.drainPermits();
1377 invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */));
1378 try {
1379 mStatsProviderSem.tryAcquire(registeredCallbackCount,
1380 MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS);
1381 } catch (InterruptedException e) {
1382 // Strictly speaking it's possible a provider happened to deliver between the timeout
1383 // and the log, and that doesn't matter too much as this is just a debug log.
1384 Log.d(TAG, "requestStatsUpdate - providers responded "
1385 + mStatsProviderSem.availablePermits()
1386 + "/" + registeredCallbackCount + " : " + e);
1387 }
1388 Trace.traceEnd(TRACE_TAG_NETWORK);
1389
Jeff Sharkey75279902011-05-24 18:39:45 -07001390 // TODO: consider marking "untrusted" times in historical stats
Jeff Sharkey9911a282018-02-14 22:29:11 -07001391 final long currentTime = mClock.millis();
Jeff Sharkey75279902011-05-24 18:39:45 -07001392
Jeff Sharkey75279902011-05-24 18:39:45 -07001393 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001394 recordSnapshotLocked(currentTime);
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001395 } catch (IllegalStateException e) {
1396 Log.wtf(TAG, "problem reading network stats", e);
Jeff Sharkey905b5892011-09-30 15:19:49 -07001397 return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001398 } catch (RemoteException e) {
1399 // ignored; service lives in system_server
Jeff Sharkey905b5892011-09-30 15:19:49 -07001400 return;
1401 }
1402
Jeff Sharkey63abc372012-01-11 18:38:16 -08001403 // persist any pending data depending on requested flags
Jeff Sharkey00072392018-04-12 14:26:32 -06001404 Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001405 if (persistForce) {
1406 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001407 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001408 mUidRecorder.forcePersistLocked(currentTime);
1409 mUidTagRecorder.forcePersistLocked(currentTime);
1410 } else {
1411 if (persistNetwork) {
1412 mDevRecorder.maybePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001413 mXtRecorder.maybePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001414 }
1415 if (persistUid) {
1416 mUidRecorder.maybePersistLocked(currentTime);
1417 mUidTagRecorder.maybePersistLocked(currentTime);
1418 }
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001419 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001420 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001421
Jeff Sharkey63abc372012-01-11 18:38:16 -08001422 if (mSettings.getSampleEnabled()) {
Jeff Sharkey905b5892011-09-30 15:19:49 -07001423 // sample stats after each full poll
Jeff Sharkey63abc372012-01-11 18:38:16 -08001424 performSampleLocked();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001425 }
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001426
Jeff Sharkey497e4432011-06-14 17:27:29 -07001427 // finally, dispatch updated event to any listeners
1428 final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
1429 updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001430 mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
1431 READ_NETWORK_USAGE_HISTORY);
Jeff Sharkey00072392018-04-12 14:26:32 -06001432
1433 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001434 }
1435
1436 /**
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001437 * Sample recent statistics summary into {@link EventLog}.
1438 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001439 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001440 private void performSampleLocked() {
1441 // TODO: migrate trustedtime fixes to separate binary log events
Jeff Sharkey9911a282018-02-14 22:29:11 -07001442 final long currentTime = mClock.millis();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001443
Jeff Sharkey63abc372012-01-11 18:38:16 -08001444 NetworkTemplate template;
1445 NetworkStats.Entry devTotal;
1446 NetworkStats.Entry xtTotal;
1447 NetworkStats.Entry uidTotal;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001448
1449 // collect mobile sample
Jeff Sharkey234766a2012-04-10 19:48:07 -07001450 template = buildTemplateMobileWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001451 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001452 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001453 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001454
Jeff Sharkey905b5892011-09-30 15:19:49 -07001455 EventLogTags.writeNetstatsMobileSample(
1456 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1457 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1458 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001459 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001460
1461 // collect wifi sample
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001462 template = buildTemplateWifiWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001463 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001464 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001465 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1466
Jeff Sharkey905b5892011-09-30 15:19:49 -07001467 EventLogTags.writeNetstatsWifiSample(
1468 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1469 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1470 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001471 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001472 }
1473
1474 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001475 * Clean up {@link #mUidRecorder} after UID is removed.
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001476 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001477 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001478 private void removeUidsLocked(int... uids) {
1479 if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1480
1481 // Perform one last poll before removing
Jeff Sharkey163e6442011-10-31 16:37:52 -07001482 performPollLocked(FLAG_PERSIST_ALL);
1483
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001484 mUidRecorder.removeUidsLocked(uids);
1485 mUidTagRecorder.removeUidsLocked(uids);
Jeff Sharkey163e6442011-10-31 16:37:52 -07001486
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001487 // Clear kernel stats associated with UID
1488 for (int uid : uids) {
1489 resetKernelUidStats(uid);
1490 }
1491 }
1492
1493 /**
1494 * Clean up {@link #mUidRecorder} after user is removed.
1495 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001496 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001497 private void removeUserLocked(int userId) {
1498 if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1499
1500 // Build list of UIDs that we should clean up
1501 int[] uids = new int[0];
1502 final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001503 PackageManager.MATCH_ANY_USER
1504 | PackageManager.MATCH_DISABLED_COMPONENTS);
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001505 for (ApplicationInfo app : apps) {
1506 final int uid = UserHandle.getUid(userId, app.uid);
1507 uids = ArrayUtils.appendInt(uids, uid);
1508 }
1509
1510 removeUidsLocked(uids);
Jeff Sharkey75279902011-05-24 18:39:45 -07001511 }
1512
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001513 private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
1514 @Override
1515 public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001516 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
1517 try {
1518 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
1519 } finally {
1520 Trace.traceEnd(TRACE_TAG_NETWORK);
1521 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001522 }
1523
1524 @Override
1525 public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001526 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
1527 try {
1528 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
1529 } finally {
1530 Trace.traceEnd(TRACE_TAG_NETWORK);
1531 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001532 }
1533
1534 @Override
1535 public void setUidForeground(int uid, boolean uidForeground) {
1536 NetworkStatsService.this.setUidForeground(uid, uidForeground);
1537 }
1538
1539 @Override
1540 public void advisePersistThreshold(long thresholdBytes) {
1541 NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
1542 }
1543
1544 @Override
1545 public void forceUpdate() {
1546 NetworkStatsService.this.forceUpdate();
1547 }
junyulai80831d22019-11-21 16:26:27 +08001548
1549 @Override
junyulai7d058ec2020-01-21 13:52:04 +08001550 public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
1551 Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
junyulai80831d22019-11-21 16:26:27 +08001552 invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota));
1553 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001554 }
1555
Jeff Sharkey75279902011-05-24 18:39:45 -07001556 @Override
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001557 protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001558 if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
Jeff Sharkey75279902011-05-24 18:39:45 -07001559
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001560 long duration = DateUtils.DAY_IN_MILLIS;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001561 final HashSet<String> argSet = new HashSet<String>();
1562 for (String arg : args) {
1563 argSet.add(arg);
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001564
1565 if (arg.startsWith("--duration=")) {
1566 try {
1567 duration = Long.parseLong(arg.substring(11));
1568 } catch (NumberFormatException ignored) {
1569 }
1570 }
Jeff Sharkey75279902011-05-24 18:39:45 -07001571 }
1572
Jeff Sharkey706498d2012-02-06 17:35:07 -08001573 // usage: dumpsys netstats --full --uid --tag --poll --checkin
Jeff Sharkey63abc372012-01-11 18:38:16 -08001574 final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
Jeff Sharkey706498d2012-02-06 17:35:07 -08001575 final boolean checkin = argSet.contains("--checkin");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001576 final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1577 final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1578 final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1579
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001580 final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
Jeff Sharkey350083e2011-06-29 10:45:16 -07001581
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001582 synchronized (mStatsLock) {
Makoto Onukida65a522017-01-13 10:23:30 -08001583 if (args.length > 0 && "--proto".equals(args[0])) {
1584 // In this case ignore all other arguments.
Jeff Sharkey4635f102017-09-01 11:27:13 -06001585 dumpProtoLocked(fd);
Makoto Onukida65a522017-01-13 10:23:30 -08001586 return;
1587 }
1588
Jeff Sharkey63abc372012-01-11 18:38:16 -08001589 if (poll) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001590 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
Jeff Sharkey3f391352011-06-05 17:42:53 -07001591 pw.println("Forced poll");
1592 return;
1593 }
1594
Jeff Sharkey706498d2012-02-06 17:35:07 -08001595 if (checkin) {
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001596 final long end = System.currentTimeMillis();
1597 final long start = end - duration;
1598
1599 pw.print("v1,");
1600 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1601 pw.print(end / SECOND_IN_MILLIS); pw.println();
1602
1603 pw.println("xt");
1604 mXtRecorder.dumpCheckin(rawWriter, start, end);
1605
1606 if (includeUid) {
1607 pw.println("uid");
1608 mUidRecorder.dumpCheckin(rawWriter, start, end);
Jeff Sharkey706498d2012-02-06 17:35:07 -08001609 }
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001610 if (includeTag) {
1611 pw.println("tag");
1612 mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1613 }
Jeff Sharkey706498d2012-02-06 17:35:07 -08001614 return;
1615 }
1616
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001617 pw.println("Active interfaces:");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001618 pw.increaseIndent();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001619 for (int i = 0; i < mActiveIfaces.size(); i++) {
1620 pw.printPair("iface", mActiveIfaces.keyAt(i));
1621 pw.printPair("ident", mActiveIfaces.valueAt(i));
1622 pw.println();
1623 }
1624 pw.decreaseIndent();
1625
1626 pw.println("Active UID interfaces:");
1627 pw.increaseIndent();
1628 for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1629 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1630 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1631 pw.println();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001632 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001633 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001634
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +09001635 // Get the top openSession callers
1636 final SparseIntArray calls;
1637 synchronized (mOpenSessionCallsPerUid) {
1638 calls = mOpenSessionCallsPerUid.clone();
1639 }
1640
1641 final int N = calls.size();
1642 final long[] values = new long[N];
1643 for (int j = 0; j < N; j++) {
1644 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
1645 }
1646 Arrays.sort(values);
1647
1648 pw.println("Top openSession callers (uid=count):");
1649 pw.increaseIndent();
1650 final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
1651 for (int j = N - 1; j >= end; j--) {
1652 final int uid = (int) (values[j] & 0xffffffff);
1653 final int count = (int) (values[j] >> 32);
1654 pw.print(uid); pw.print("="); pw.println(count);
1655 }
1656 pw.decreaseIndent();
1657 pw.println();
1658
junyulai3cd84eb2020-01-10 13:57:07 +08001659 pw.println("Stats Providers:");
1660 pw.increaseIndent();
1661 invokeForAllStatsProviderCallbacks((cb) -> {
1662 pw.println(cb.mTag + " Xt:");
1663 pw.increaseIndent();
1664 pw.print(cb.getCachedStats(STATS_PER_IFACE).toString());
1665 pw.decreaseIndent();
1666 if (includeUid) {
1667 pw.println(cb.mTag + " Uid:");
1668 pw.increaseIndent();
1669 pw.print(cb.getCachedStats(STATS_PER_UID).toString());
1670 pw.decreaseIndent();
1671 }
1672 });
1673 pw.decreaseIndent();
1674
Jeff Sharkey63abc372012-01-11 18:38:16 -08001675 pw.println("Dev stats:");
1676 pw.increaseIndent();
1677 mDevRecorder.dumpLocked(pw, fullHistory);
1678 pw.decreaseIndent();
1679
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001680 pw.println("Xt stats:");
1681 pw.increaseIndent();
1682 mXtRecorder.dumpLocked(pw, fullHistory);
1683 pw.decreaseIndent();
1684
Jeff Sharkey63abc372012-01-11 18:38:16 -08001685 if (includeUid) {
1686 pw.println("UID stats:");
1687 pw.increaseIndent();
1688 mUidRecorder.dumpLocked(pw, fullHistory);
1689 pw.decreaseIndent();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001690 }
1691
Jeff Sharkey63abc372012-01-11 18:38:16 -08001692 if (includeTag) {
1693 pw.println("UID tag stats:");
1694 pw.increaseIndent();
1695 mUidTagRecorder.dumpLocked(pw, fullHistory);
1696 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001697 }
1698 }
1699 }
1700
Andreas Gampea36dc622018-02-05 17:19:22 -08001701 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001702 private void dumpProtoLocked(FileDescriptor fd) {
Makoto Onukida65a522017-01-13 10:23:30 -08001703 final ProtoOutputStream proto = new ProtoOutputStream(fd);
1704
1705 // TODO Right now it writes all history. Should it limit to the "since-boot" log?
1706
1707 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1708 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
Jeffrey Huangcb782852019-12-05 11:28:11 -08001709 mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1710 mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1711 mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1712 mUidTagRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
Makoto Onukida65a522017-01-13 10:23:30 -08001713
1714 proto.flush();
1715 }
1716
1717 private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1718 ArrayMap<String, NetworkIdentitySet> ifaces) {
1719 for (int i = 0; i < ifaces.size(); i++) {
1720 final long start = proto.start(tag);
1721
1722 proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
Jeffrey Huangcb782852019-12-05 11:28:11 -08001723 ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
Makoto Onukida65a522017-01-13 10:23:30 -08001724
1725 proto.end(start);
1726 }
1727 }
1728
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001729 private NetworkStats readNetworkStatsSummaryDev() {
1730 try {
1731 return mStatsFactory.readNetworkStatsSummaryDev();
1732 } catch (IOException e) {
1733 throw new IllegalStateException(e);
1734 }
1735 }
1736
1737 private NetworkStats readNetworkStatsSummaryXt() {
1738 try {
1739 return mStatsFactory.readNetworkStatsSummaryXt();
1740 } catch (IOException e) {
1741 throw new IllegalStateException(e);
1742 }
1743 }
1744
1745 private NetworkStats readNetworkStatsUidDetail(int uid, String[] ifaces, int tag) {
1746 try {
1747 return mStatsFactory.readNetworkStatsDetail(uid, ifaces, tag);
1748 } catch (IOException e) {
1749 throw new IllegalStateException(e);
1750 }
1751 }
1752
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001753 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001754 * Return snapshot of current UID statistics, including any
Jack Yuf9d559c2017-05-26 16:08:22 -07001755 * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1756 * values.
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001757 *
1758 * @param ifaces A list of interfaces the stats should be restricted to, or
1759 * {@link NetworkStats#INTERFACES_ALL}.
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001760 */
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001761 private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
1762 throws RemoteException {
Lorenzo Colitti8b577132019-06-24 13:28:04 +09001763 final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL, ifaces, TAG_ALL);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001764
Jeff Sharkey63abc372012-01-11 18:38:16 -08001765 // fold tethering stats and operations into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001766 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001767 tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
Lorenzo Colitti4aa87602019-06-24 13:50:45 +09001768 mStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
junyulaic33ac0d2018-10-19 21:14:30 +08001769 mUseBpfTrafficStats);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001770 uidSnapshot.combineAllValues(tetherSnapshot);
Jack Yuf9d559c2017-05-26 16:08:22 -07001771
junyulai80831d22019-11-21 16:26:27 +08001772 // get a stale copy of uid stats snapshot provided by providers.
1773 final NetworkStats providerStats = getNetworkStatsFromProviders(STATS_PER_UID);
1774 providerStats.filter(UID_ALL, ifaces, TAG_ALL);
1775 mStatsFactory.apply464xlatAdjustments(uidSnapshot, providerStats, mUseBpfTrafficStats);
1776 uidSnapshot.combineAllValues(providerStats);
1777
Jeff Sharkey63abc372012-01-11 18:38:16 -08001778 uidSnapshot.combineAllValues(mUidOperations);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001779
Jeff Sharkey63abc372012-01-11 18:38:16 -08001780 return uidSnapshot;
Jeff Sharkey75279902011-05-24 18:39:45 -07001781 }
1782
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001783 /**
1784 * Return snapshot of current tethering statistics. Will return empty
1785 * {@link NetworkStats} if any problems are encountered.
1786 */
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001787 private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001788 try {
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001789 return mNetworkManager.getNetworkStatsTethering(how);
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001790 } catch (IllegalStateException e) {
1791 Log.wtf(TAG, "problem reading network stats", e);
1792 return new NetworkStats(0L, 10);
1793 }
1794 }
1795
junyulai80831d22019-11-21 16:26:27 +08001796 /**
1797 * Registers a custom provider of {@link android.net.NetworkStats} to combine the network
1798 * statistics that cannot be seen by the kernel to system. To unregister, invoke the
1799 * {@code unregister()} of the returned callback.
1800 *
1801 * @param tag a human readable identifier of the custom network stats provider.
junyulai7d058ec2020-01-21 13:52:04 +08001802 * @param provider the {@link INetworkStatsProvider} binder corresponding to the
1803 * {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be
1804 * registered.
junyulai80831d22019-11-21 16:26:27 +08001805 *
1806 * @return a binder interface of
1807 * {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be
1808 * used to report events to the system.
1809 */
1810 public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider(
1811 @NonNull String tag, @NonNull INetworkStatsProvider provider) {
1812 mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
1813 Objects.requireNonNull(provider, "provider is null");
1814 Objects.requireNonNull(tag, "tag is null");
1815 try {
1816 NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
junyulai05a04c22020-02-12 14:55:54 +08001817 tag, provider, mStatsProviderSem, mAlertObserver,
1818 mStatsProviderCbList);
junyulai80831d22019-11-21 16:26:27 +08001819 mStatsProviderCbList.register(callback);
1820 Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
1821 + getCallingUid() + "/" + getCallingPid());
1822 return callback;
1823 } catch (RemoteException e) {
1824 Log.e(TAG, "registerNetworkStatsProvider failed", e);
1825 }
1826 return null;
1827 }
1828
1829 // Collect stats from local cache of providers.
1830 private @NonNull NetworkStats getNetworkStatsFromProviders(int how) {
1831 final NetworkStats ret = new NetworkStats(0L, 0);
1832 invokeForAllStatsProviderCallbacks((cb) -> ret.combineAllValues(cb.getCachedStats(how)));
1833 return ret;
1834 }
1835
1836 @FunctionalInterface
1837 private interface ThrowingConsumer<S, T extends Throwable> {
1838 void accept(S s) throws T;
1839 }
1840
1841 private void invokeForAllStatsProviderCallbacks(
1842 @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
junyulai7d058ec2020-01-21 13:52:04 +08001843 synchronized (mStatsLock) {
junyulai80831d22019-11-21 16:26:27 +08001844 final int length = mStatsProviderCbList.beginBroadcast();
1845 try {
1846 for (int i = 0; i < length; i++) {
1847 final NetworkStatsProviderCallbackImpl cb =
1848 mStatsProviderCbList.getBroadcastItem(i);
1849 try {
1850 task.accept(cb);
1851 } catch (RemoteException e) {
1852 Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
1853 }
1854 }
1855 } finally {
1856 mStatsProviderCbList.finishBroadcast();
1857 }
1858 }
1859 }
1860
1861 private static class NetworkStatsProviderCallbackImpl extends INetworkStatsProviderCallback.Stub
1862 implements IBinder.DeathRecipient {
1863 @NonNull final String mTag;
junyulai7d058ec2020-01-21 13:52:04 +08001864
junyulai80831d22019-11-21 16:26:27 +08001865 @NonNull final INetworkStatsProvider mProvider;
junyulai05a04c22020-02-12 14:55:54 +08001866 @NonNull private final Semaphore mSemaphore;
junyulai80831d22019-11-21 16:26:27 +08001867 @NonNull final INetworkManagementEventObserver mAlertObserver;
1868 @NonNull final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
1869
junyulai7d058ec2020-01-21 13:52:04 +08001870 @NonNull private final Object mProviderStatsLock = new Object();
1871
junyulai80831d22019-11-21 16:26:27 +08001872 @GuardedBy("mProviderStatsLock")
junyulai7d058ec2020-01-21 13:52:04 +08001873 // Track STATS_PER_IFACE and STATS_PER_UID separately.
junyulai80831d22019-11-21 16:26:27 +08001874 private final NetworkStats mIfaceStats = new NetworkStats(0L, 0);
1875 @GuardedBy("mProviderStatsLock")
1876 private final NetworkStats mUidStats = new NetworkStats(0L, 0);
1877
1878 NetworkStatsProviderCallbackImpl(
1879 @NonNull String tag, @NonNull INetworkStatsProvider provider,
junyulai05a04c22020-02-12 14:55:54 +08001880 @NonNull Semaphore semaphore,
junyulai80831d22019-11-21 16:26:27 +08001881 @NonNull INetworkManagementEventObserver alertObserver,
1882 @NonNull RemoteCallbackList<NetworkStatsProviderCallbackImpl> cbList)
1883 throws RemoteException {
1884 mTag = tag;
1885 mProvider = provider;
1886 mProvider.asBinder().linkToDeath(this, 0);
junyulai05a04c22020-02-12 14:55:54 +08001887 mSemaphore = semaphore;
junyulai80831d22019-11-21 16:26:27 +08001888 mAlertObserver = alertObserver;
1889 mStatsProviderCbList = cbList;
1890 }
1891
1892 @NonNull
1893 public NetworkStats getCachedStats(int how) {
1894 synchronized (mProviderStatsLock) {
1895 NetworkStats stats;
1896 switch (how) {
1897 case STATS_PER_IFACE:
1898 stats = mIfaceStats;
1899 break;
1900 case STATS_PER_UID:
1901 stats = mUidStats;
1902 break;
1903 default:
1904 throw new IllegalArgumentException("Invalid type: " + how);
1905 }
junyulai7d058ec2020-01-21 13:52:04 +08001906 // Callers might be able to mutate the returned object. Return a defensive copy
1907 // instead of local reference.
junyulai80831d22019-11-21 16:26:27 +08001908 return stats.clone();
1909 }
1910 }
1911
1912 @Override
1913 public void onStatsUpdated(int token, @Nullable NetworkStats ifaceStats,
1914 @Nullable NetworkStats uidStats) {
1915 // TODO: 1. Use token to map ifaces to correct NetworkIdentity.
1916 // 2. Store the difference and store it directly to the recorder.
1917 synchronized (mProviderStatsLock) {
1918 if (ifaceStats != null) mIfaceStats.combineAllValues(ifaceStats);
1919 if (uidStats != null) mUidStats.combineAllValues(uidStats);
1920 }
junyulai05a04c22020-02-12 14:55:54 +08001921 mSemaphore.release();
junyulai80831d22019-11-21 16:26:27 +08001922 }
1923
1924 @Override
1925 public void onAlertReached() throws RemoteException {
1926 mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */);
1927 }
1928
1929 @Override
1930 public void onLimitReached() {
1931 Log.d(TAG, mTag + ": onLimitReached");
1932 LocalServices.getService(NetworkPolicyManagerInternal.class)
1933 .onStatsProviderLimitReached(mTag);
1934 }
1935
1936 @Override
1937 public void binderDied() {
1938 Log.d(TAG, mTag + ": binderDied");
1939 mStatsProviderCbList.unregister(this);
1940 }
1941
1942 @Override
1943 public void unregister() {
1944 Log.d(TAG, mTag + ": unregister");
1945 mStatsProviderCbList.unregister(this);
1946 }
1947
1948 }
1949
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001950 private void assertSystemReady() {
1951 if (!mSystemReady) {
1952 throw new IllegalStateException("System not ready");
1953 }
1954 }
1955
Jeff Sharkey63abc372012-01-11 18:38:16 -08001956 private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001957 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001958 public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
1959 int rightIndex, String cookie) {
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001960 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001961
1962 // record error for debugging
1963 final StringBuilder builder = new StringBuilder();
1964 builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
1965 + "] - right[" + rightIndex + "]\n");
1966 builder.append("left=").append(left).append('\n');
1967 builder.append("right=").append(right).append('\n');
1968
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001969 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1970 builder.toString());
1971 }
1972
1973 @Override
1974 public void foundNonMonotonic(
1975 NetworkStats stats, int statsIndex, String cookie) {
1976 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
1977
1978 final StringBuilder builder = new StringBuilder();
1979 builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
1980 builder.append("stats=").append(stats).append('\n');
1981
1982 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1983 builder.toString());
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001984 }
1985 }
1986
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001987 /**
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001988 * Default external settings that read from
Jeff Sharkey625239a2012-09-26 22:03:49 -07001989 * {@link android.provider.Settings.Global}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001990 */
1991 private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
1992 private final ContentResolver mResolver;
1993
1994 public DefaultNetworkStatsSettings(Context context) {
Daulet Zhanguzin8d0b7f12020-01-03 13:37:24 +00001995 mResolver = Objects.requireNonNull(context.getContentResolver());
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001996 // TODO: adjust these timings for production builds
1997 }
1998
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001999 private long getGlobalLong(String name, long def) {
2000 return Settings.Global.getLong(mResolver, name, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002001 }
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002002 private boolean getGlobalBoolean(String name, boolean def) {
Jeff Sharkey991d1b12011-09-14 19:31:04 -07002003 final int defInt = def ? 1 : 0;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002004 return Settings.Global.getInt(mResolver, name, defInt) != 0;
Jeff Sharkey991d1b12011-09-14 19:31:04 -07002005 }
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002006
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002007 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002008 public long getPollInterval() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002009 return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002010 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002011 @Override
junyulai9ff7b4e2019-11-22 22:27:21 +08002012 public long getPollDelay() {
2013 return DEFAULT_PERFORM_POLL_DELAY_MS;
2014 }
2015 @Override
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002016 public long getGlobalAlertBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002017 return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
Jeff Sharkey63abc372012-01-11 18:38:16 -08002018 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002019 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002020 public boolean getSampleEnabled() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002021 return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
Jeff Sharkey63abc372012-01-11 18:38:16 -08002022 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002023 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -06002024 public boolean getAugmentEnabled() {
2025 return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
2026 }
2027 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002028 public Config getDevConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002029 return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
2030 getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
2031 getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08002032 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002033 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07002034 public Config getXtConfig() {
2035 return getDevConfig();
2036 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07002037 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002038 public Config getUidConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002039 return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
2040 getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
2041 getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08002042 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07002043 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08002044 public Config getUidTagConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002045 return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
2046 getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
2047 getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002048 }
2049 @Override
2050 public long getDevPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002051 return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002052 }
2053 @Override
2054 public long getXtPersistBytes(long def) {
2055 return getDevPersistBytes(def);
2056 }
2057 @Override
2058 public long getUidPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002059 return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07002060 }
2061 @Override
2062 public long getUidTagPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07002063 return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07002064 }
2065 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08002066
2067 private static int TYPE_RX_BYTES;
2068 private static int TYPE_RX_PACKETS;
2069 private static int TYPE_TX_BYTES;
2070 private static int TYPE_TX_PACKETS;
2071 private static int TYPE_TCP_RX_PACKETS;
2072 private static int TYPE_TCP_TX_PACKETS;
2073
Chenbo Fengaedd6a32017-11-20 18:23:46 -08002074 private static native long nativeGetTotalStat(int type, boolean useBpfStats);
2075 private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
2076 private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
Jeff Sharkey75279902011-05-24 18:39:45 -07002077}