blob: bffd60bcb87f5dd9c5b5ab8fe290b323d0310a6a [file] [log] [blame]
Jeff Sharkey75279902011-05-24 18:39:45 -07001/*
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07002 * Copyright (C) 2011 The Android Open Source Project
Jeff Sharkey75279902011-05-24 18:39:45 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.net;
18
Jeff Sharkeya63ba592011-07-19 23:47:12 -070019import static android.Manifest.permission.ACCESS_NETWORK_STATE;
Jeff Sharkey63d27a92011-08-03 17:04:22 -070020import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070021import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070022import static android.content.Intent.ACTION_SHUTDOWN;
23import static android.content.Intent.ACTION_UID_REMOVED;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070024import static android.content.Intent.ACTION_USER_REMOVED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070025import static android.content.Intent.EXTRA_UID;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -070026import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
Jeff Sharkey234766a2012-04-10 19:48:07 -070027import static android.net.ConnectivityManager.isNetworkTypeMobile;
Lorenzo Colittiada23ed2018-01-19 01:05:20 +090028import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070029import static android.net.NetworkStats.IFACE_ALL;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090030import static android.net.NetworkStats.INTERFACES_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060031import static android.net.NetworkStats.METERED_ALL;
32import static android.net.NetworkStats.ROAMING_ALL;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070033import static android.net.NetworkStats.SET_ALL;
34import static android.net.NetworkStats.SET_DEFAULT;
35import static android.net.NetworkStats.SET_FOREGROUND;
Lorenzo Colitti5356a352017-08-17 19:23:08 +090036import static android.net.NetworkStats.STATS_PER_IFACE;
37import static android.net.NetworkStats.STATS_PER_UID;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090038import static android.net.NetworkStats.TAG_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070039import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey75279902011-05-24 18:39:45 -070040import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060041import static android.net.NetworkStatsHistory.FIELD_ALL;
Jeff Sharkey234766a2012-04-10 19:48:07 -070042import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070043import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -070044import static android.net.TrafficStats.KB_IN_BYTES;
Jeff Sharkey241dde22012-02-03 14:50:07 -080045import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey00072392018-04-12 14:26:32 -060046import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060047import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070048import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
49import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
50import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
51import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
52import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
53import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070054import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070055import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
56import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
57import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
58import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
59import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
60import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
61import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
62import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070063import static android.text.format.DateUtils.DAY_IN_MILLIS;
64import static android.text.format.DateUtils.HOUR_IN_MILLIS;
65import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070066import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jack Yuf9d559c2017-05-26 16:08:22 -070067
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070068import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070069import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070070import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
71import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
Jeff Sharkey75279902011-05-24 18:39:45 -070072
Jeff Sharkey9911a282018-02-14 22:29:11 -070073import android.annotation.NonNull;
Jeff Sharkey75279902011-05-24 18:39:45 -070074import android.app.AlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070075import android.app.PendingIntent;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060076import android.app.usage.NetworkStatsManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070077import android.content.BroadcastReceiver;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070078import android.content.ContentResolver;
Jeff Sharkey75279902011-05-24 18:39:45 -070079import android.content.Context;
80import android.content.Intent;
81import android.content.IntentFilter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070082import android.content.pm.ApplicationInfo;
83import android.content.pm.PackageManager;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080084import android.net.DataUsageRequest;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070085import android.net.IConnectivityManager;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070086import android.net.INetworkManagementEventObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070087import android.net.INetworkStatsService;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -070088import android.net.INetworkStatsSession;
Jeff Sharkey63abc372012-01-11 18:38:16 -080089import android.net.LinkProperties;
Lorenzo Colittic78da292018-01-19 00:50:48 +090090import android.net.Network;
Jack Yub6587ea2016-06-22 11:35:10 -070091import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070092import android.net.NetworkIdentity;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070093import android.net.NetworkInfo;
94import android.net.NetworkState;
Jeff Sharkey75279902011-05-24 18:39:45 -070095import android.net.NetworkStats;
Jeff Sharkey5a7bcf32012-01-10 17:24:44 -080096import android.net.NetworkStats.NonMonotonicObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070097import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070098import android.net.NetworkTemplate;
Jeff Sharkey63abc372012-01-11 18:38:16 -080099import android.net.TrafficStats;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700100import android.os.BestClock;
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700101import android.os.Binder;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700102import android.os.DropBoxManager;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700103import android.os.Environment;
Jeff Sharkey75279902011-05-24 18:39:45 -0700104import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700105import android.os.HandlerThread;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800106import android.os.IBinder;
Jeff Sharkey75279902011-05-24 18:39:45 -0700107import android.os.INetworkManagementService;
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100108import android.os.Looper;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700109import android.os.Message;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800110import android.os.Messenger;
Jeff Sharkey62489262011-07-17 12:53:28 -0700111import android.os.PowerManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700112import android.os.RemoteException;
113import android.os.SystemClock;
Jeff Sharkey00072392018-04-12 14:26:32 -0600114import android.os.Trace;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700115import android.os.UserHandle;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700116import android.provider.Settings;
Jeff Sharkey625239a2012-09-26 22:03:49 -0700117import android.provider.Settings.Global;
Makoto Onukida65a522017-01-13 10:23:30 -0800118import android.service.NetworkInterfaceProto;
119import android.service.NetworkStatsServiceDumpProto;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600120import android.telephony.SubscriptionPlan;
Jeff Sharkey75279902011-05-24 18:39:45 -0700121import android.telephony.TelephonyManager;
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800122import android.text.format.DateUtils;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700123import android.util.ArrayMap;
124import android.util.ArraySet;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700125import android.util.EventLog;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700126import android.util.Log;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700127import android.util.MathUtils;
Jeff Sharkey75279902011-05-24 18:39:45 -0700128import android.util.Slog;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700129import android.util.SparseIntArray;
Makoto Onukida65a522017-01-13 10:23:30 -0800130import android.util.proto.ProtoOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -0700131
Jeff Sharkey4635f102017-09-01 11:27:13 -0600132import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800133import com.android.internal.annotations.VisibleForTesting;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900134import com.android.internal.net.NetworkStatsFactory;
Wenchao Tongf5ea3402015-03-04 13:26:38 -0800135import com.android.internal.net.VpnInfo;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700136import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600137import com.android.internal.util.DumpUtils;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800138import com.android.internal.util.FileRotator;
139import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700140import com.android.server.EventLogTags;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700141import com.android.server.LocalServices;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700142import com.android.server.connectivity.Tethering;
Jeff Sharkey75279902011-05-24 18:39:45 -0700143
Jeff Sharkey3f391352011-06-05 17:42:53 -0700144import java.io.File;
Jeff Sharkey75279902011-05-24 18:39:45 -0700145import java.io.FileDescriptor;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700146import java.io.IOException;
Jeff Sharkey75279902011-05-24 18:39:45 -0700147import java.io.PrintWriter;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700148import java.time.Clock;
149import java.time.ZoneOffset;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700150import java.util.Arrays;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700151import java.util.HashSet;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700152import java.util.List;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700153
Jeff Sharkey75279902011-05-24 18:39:45 -0700154/**
155 * Collect and persist detailed network statistics, and provide this data to
156 * other system services.
157 */
158public class NetworkStatsService extends INetworkStatsService.Stub {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600159 static final String TAG = "NetworkStats";
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700160 static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
161 static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700162
Chalard Jeand7c6e122018-08-22 10:21:26 +0900163 // Perform polling and persist all (FLAG_PERSIST_ALL).
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700164 private static final int MSG_PERFORM_POLL = 1;
Chalard Jeand7c6e122018-08-22 10:21:26 +0900165 // Perform polling, persist network, and register the global alert again.
166 private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700167
168 /** Flags to control detail level of poll event. */
Jeff Sharkey905b5892011-09-30 15:19:49 -0700169 private static final int FLAG_PERSIST_NETWORK = 0x1;
170 private static final int FLAG_PERSIST_UID = 0x2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700171 private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700172 private static final int FLAG_PERSIST_FORCE = 0x100;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700173
Chalard Jeand7c6e122018-08-22 10:21:26 +0900174 /**
175 * When global alert quota is high, wait for this delay before processing each polling,
176 * and do not schedule further polls once there is already one queued.
177 * This avoids firing the global alert too often on devices with high transfer speeds and
178 * high quota.
179 */
180 private static final int PERFORM_POLL_DELAY_MS = 1000;
181
Jeff Sharkey163e6442011-10-31 16:37:52 -0700182 private static final String TAG_NETSTATS_ERROR = "netstats_error";
183
Jeff Sharkey75279902011-05-24 18:39:45 -0700184 private final Context mContext;
185 private final INetworkManagementService mNetworkManager;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700186 private final AlarmManager mAlarmManager;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700187 private final Clock mClock;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700188 private final TelephonyManager mTeleManager;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700189 private final NetworkStatsSettings mSettings;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800190 private final NetworkStatsObservers mStatsObservers;
Jeff Sharkey75279902011-05-24 18:39:45 -0700191
Jeff Sharkey63abc372012-01-11 18:38:16 -0800192 private final File mSystemDir;
193 private final File mBaseDir;
194
Jeff Sharkey62489262011-07-17 12:53:28 -0700195 private final PowerManager.WakeLock mWakeLock;
196
Chenbo Feng00499822018-05-18 17:10:07 -0700197 private final boolean mUseBpfTrafficStats;
198
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700199 private IConnectivityManager mConnManager;
200
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800201 @VisibleForTesting
Jeff Sharkey3f391352011-06-05 17:42:53 -0700202 public static final String ACTION_NETWORK_STATS_POLL =
Jeff Sharkey75279902011-05-24 18:39:45 -0700203 "com.android.server.action.NETWORK_STATS_POLL";
Jeff Sharkey497e4432011-06-14 17:27:29 -0700204 public static final String ACTION_NETWORK_STATS_UPDATED =
205 "com.android.server.action.NETWORK_STATS_UPDATED";
Jeff Sharkey75279902011-05-24 18:39:45 -0700206
207 private PendingIntent mPollIntent;
208
Jeff Sharkey63abc372012-01-11 18:38:16 -0800209 private static final String PREFIX_DEV = "dev";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700210 private static final String PREFIX_XT = "xt";
Jeff Sharkey63abc372012-01-11 18:38:16 -0800211 private static final String PREFIX_UID = "uid";
212 private static final String PREFIX_UID_TAG = "uid_tag";
213
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700214 /**
Jack Yub6587ea2016-06-22 11:35:10 -0700215 * Virtual network interface for video telephony. This is for VT data usage counting purpose.
216 */
217 public static final String VT_INTERFACE = "vt_data0";
218
219 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700220 * Settings that can be changed externally.
221 */
222 public interface NetworkStatsSettings {
223 public long getPollInterval();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800224 public boolean getSampleEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600225 public boolean getAugmentEnabled();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800226
227 public static class Config {
228 public final long bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800229 public final long rotateAgeMillis;
230 public final long deleteAgeMillis;
231
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700232 public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800233 this.bucketDuration = bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800234 this.rotateAgeMillis = rotateAgeMillis;
235 this.deleteAgeMillis = deleteAgeMillis;
236 }
237 }
238
239 public Config getDevConfig();
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700240 public Config getXtConfig();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800241 public Config getUidConfig();
242 public Config getUidTagConfig();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700243
244 public long getGlobalAlertBytes(long def);
245 public long getDevPersistBytes(long def);
246 public long getXtPersistBytes(long def);
247 public long getUidPersistBytes(long def);
248 public long getUidTagPersistBytes(long def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700249 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700250
251 private final Object mStatsLock = new Object();
252
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700253 /** Set of currently active ifaces. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900254 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700255 private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900256
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700257 /** Set of currently active ifaces for UID stats. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900258 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700259 private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900260
Jeff Sharkey63abc372012-01-11 18:38:16 -0800261 /** Current default active iface. */
262 private String mActiveIface;
Lorenzo Colittic78da292018-01-19 00:50:48 +0900263
Jeff Sharkey234766a2012-04-10 19:48:07 -0700264 /** Set of any ifaces associated with mobile networks since boot. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900265 @GuardedBy("mStatsLock")
Jeff Sharkey234766a2012-04-10 19:48:07 -0700266 private String[] mMobileIfaces = new String[0];
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700267
Lorenzo Colittic78da292018-01-19 00:50:48 +0900268 /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
269 @GuardedBy("mStatsLock")
270 private Network[] mDefaultNetworks = new Network[0];
271
Jeff Sharkey63abc372012-01-11 18:38:16 -0800272 private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
273 new DropBoxNonMonotonicObserver();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700274
Jeff Sharkey4635f102017-09-01 11:27:13 -0600275 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800276 private NetworkStatsRecorder mDevRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600277 @GuardedBy("mStatsLock")
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700278 private NetworkStatsRecorder mXtRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600279 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800280 private NetworkStatsRecorder mUidRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600281 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800282 private NetworkStatsRecorder mUidTagRecorder;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700283
Jeff Sharkey70c70532012-05-16 14:51:19 -0700284 /** Cached {@link #mXtRecorder} stats. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600285 @GuardedBy("mStatsLock")
Jeff Sharkey70c70532012-05-16 14:51:19 -0700286 private NetworkStatsCollection mXtStatsCached;
Jeff Sharkey75279902011-05-24 18:39:45 -0700287
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700288 /** Current counter sets for each UID. */
289 private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
290
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700291 /** Data layer operation counters for splicing into other structures. */
Jeff Sharkey63abc372012-01-11 18:38:16 -0800292 private NetworkStats mUidOperations = new NetworkStats(0L, 10);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700293
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800294 /** Must be set in factory by calling #setHandler. */
295 private Handler mHandler;
296 private Handler.Callback mHandlerCallback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700297
Jeff Sharkey050151e2018-04-13 14:28:30 -0600298 private volatile boolean mSystemReady;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700299 private long mPersistThreshold = 2 * MB_IN_BYTES;
300 private long mGlobalAlertBytes;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800301
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900302 private static final long POLL_RATE_LIMIT_MS = 15_000;
303
304 private long mLastStatsSessionPoll;
305
306 /** Map from UID to number of opened sessions */
307 @GuardedBy("mOpenSessionCallsPerUid")
308 private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
309
310 private final static int DUMP_STATS_SESSION_COUNT = 20;
311
Jeff Sharkey9911a282018-02-14 22:29:11 -0700312 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700313 return new File(Environment.getDataDirectory(), "system");
Jeff Sharkey75279902011-05-24 18:39:45 -0700314 }
315
Jeff Sharkey9911a282018-02-14 22:29:11 -0700316 private static @NonNull File getDefaultBaseDir() {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800317 File baseDir = new File(getDefaultSystemDir(), "netstats");
318 baseDir.mkdirs();
319 return baseDir;
320 }
321
Jeff Sharkey9911a282018-02-14 22:29:11 -0700322 private static @NonNull Clock getDefaultClock() {
323 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
324 Clock.systemUTC());
325 }
326
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100327 private static final class NetworkStatsHandler extends Handler {
328 NetworkStatsHandler(Looper looper, Handler.Callback callback) {
329 super(looper, callback);
330 }
331 }
332
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800333 public static NetworkStatsService create(Context context,
334 INetworkManagementService networkManager) {
335 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
336 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
337 PowerManager.WakeLock wakeLock =
338 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
339
340 NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700341 wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800342 new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
343 getDefaultSystemDir(), getDefaultBaseDir());
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900344 service.registerLocalService();
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800345
346 HandlerThread handlerThread = new HandlerThread(TAG);
347 Handler.Callback callback = new HandlerCallback(service);
348 handlerThread.start();
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100349 Handler handler = new NetworkStatsHandler(handlerThread.getLooper(), callback);
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800350 service.setHandler(handler, callback);
351 return service;
352 }
353
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900354 // This must not be called outside of tests, even within the same package, as this constructor
355 // does not register the local service. Use the create() helper above.
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800356 @VisibleForTesting
357 NetworkStatsService(Context context, INetworkManagementService networkManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700358 AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800359 TelephonyManager teleManager, NetworkStatsSettings settings,
360 NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
Jeff Sharkey75279902011-05-24 18:39:45 -0700361 mContext = checkNotNull(context, "missing Context");
362 mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800363 mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
Jeff Sharkey9911a282018-02-14 22:29:11 -0700364 mClock = checkNotNull(clock, "missing Clock");
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700365 mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800366 mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
367 mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
368 mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
369 mSystemDir = checkNotNull(systemDir, "missing systemDir");
370 mBaseDir = checkNotNull(baseDir, "missing baseDir");
Chenbo Feng6880d632018-12-22 13:20:31 -0800371 mUseBpfTrafficStats = new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists();
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900372 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700373
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900374 private void registerLocalService() {
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700375 LocalServices.addService(NetworkStatsManagerInternal.class,
376 new NetworkStatsManagerInternalImpl());
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800377 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700378
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800379 @VisibleForTesting
380 void setHandler(Handler handler, Handler.Callback callback) {
381 mHandler = handler;
382 mHandlerCallback = callback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700383 }
384
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700385 public void bindConnectivityManager(IConnectivityManager connManager) {
386 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
387 }
388
Jeff Sharkey75279902011-05-24 18:39:45 -0700389 public void systemReady() {
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800390 mSystemReady = true;
391
Jeff Sharkey418d12d2011-12-13 15:38:03 -0800392 if (!isBandwidthControlEnabled()) {
393 Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
394 return;
395 }
396
Jeff Sharkey63abc372012-01-11 18:38:16 -0800397 synchronized (mStatsLock) {
Jeff Sharkey4635f102017-09-01 11:27:13 -0600398 // create data recorders along with historical rotators
399 mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
400 mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
401 mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
402 mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
403
404 updatePersistThresholdsLocked();
405
Jeff Sharkey63abc372012-01-11 18:38:16 -0800406 // upgrade any legacy stats, migrating them to rotated files
407 maybeUpgradeLegacyStatsLocked();
408
409 // read historical network stats from disk, since policy service
410 // might need them right away.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700411 mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800412
413 // bootstrap initial stats to prevent double-counting later
414 bootstrapStatsLocked();
415 }
Jeff Sharkey3359aca2011-11-08 18:08:48 -0800416
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700417 // watch for tethering changes
418 final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
Vinit Deshpande92d141f2014-09-10 18:05:10 -0700419 mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700420
Jeff Sharkey75279902011-05-24 18:39:45 -0700421 // listen for periodic polling events
422 final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700423 mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
Jeff Sharkey75279902011-05-24 18:39:45 -0700424
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700425 // listen for uid removal to clean stats
426 final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
427 mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
428
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700429 // listen for user changes to clean stats
430 final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
431 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
432
Jeff Sharkey75279902011-05-24 18:39:45 -0700433 // persist stats during clean shutdown
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700434 final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
435 mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
Jeff Sharkey75279902011-05-24 18:39:45 -0700436
437 try {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700438 mNetworkManager.registerObserver(mAlertObserver);
Jeff Sharkey75279902011-05-24 18:39:45 -0700439 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700440 // ignored; service lives in system_server
Jeff Sharkey75279902011-05-24 18:39:45 -0700441 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700442
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700443 registerPollAlarmLocked();
444 registerGlobalAlert();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800445 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700446
Jeff Sharkey63abc372012-01-11 18:38:16 -0800447 private NetworkStatsRecorder buildRecorder(
448 String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700449 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
450 Context.DROPBOX_SERVICE);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700451 return new NetworkStatsRecorder(new FileRotator(
452 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700453 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
Jeff Sharkey75279902011-05-24 18:39:45 -0700454 }
455
Andreas Gampea36dc622018-02-05 17:19:22 -0800456 @GuardedBy("mStatsLock")
Jeff Sharkey3f391352011-06-05 17:42:53 -0700457 private void shutdownLocked() {
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700458 mContext.unregisterReceiver(mTetherReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700459 mContext.unregisterReceiver(mPollReceiver);
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700460 mContext.unregisterReceiver(mRemovedReceiver);
Ryuki Nakamuraa47b0c92017-03-01 10:40:36 +0900461 mContext.unregisterReceiver(mUserReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700462 mContext.unregisterReceiver(mShutdownReceiver);
463
Jeff Sharkey9911a282018-02-14 22:29:11 -0700464 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800465
466 // persist any pending stats
467 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700468 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800469 mUidRecorder.forcePersistLocked(currentTime);
470 mUidTagRecorder.forcePersistLocked(currentTime);
471
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800472 mSystemReady = false;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800473 }
474
Andreas Gampea36dc622018-02-05 17:19:22 -0800475 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800476 private void maybeUpgradeLegacyStatsLocked() {
477 File file;
478 try {
479 file = new File(mSystemDir, "netstats.bin");
480 if (file.exists()) {
481 mDevRecorder.importLegacyNetworkLocked(file);
482 file.delete();
483 }
484
485 file = new File(mSystemDir, "netstats_xt.bin");
486 if (file.exists()) {
487 file.delete();
488 }
489
490 file = new File(mSystemDir, "netstats_uid.bin");
491 if (file.exists()) {
492 mUidRecorder.importLegacyUidLocked(file);
493 mUidTagRecorder.importLegacyUidLocked(file);
494 file.delete();
495 }
496 } catch (IOException e) {
497 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700498 } catch (OutOfMemoryError e) {
499 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeyc506ff62011-11-17 11:59:29 -0800500 }
Jeff Sharkey3f391352011-06-05 17:42:53 -0700501 }
502
Jeff Sharkey75279902011-05-24 18:39:45 -0700503 /**
504 * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700505 * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
Jeff Sharkey75279902011-05-24 18:39:45 -0700506 */
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700507 private void registerPollAlarmLocked() {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700508 if (mPollIntent != null) {
509 mAlarmManager.cancel(mPollIntent);
Jeff Sharkey75279902011-05-24 18:39:45 -0700510 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700511
512 mPollIntent = PendingIntent.getBroadcast(
513 mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
514
515 final long currentRealtime = SystemClock.elapsedRealtime();
516 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
517 mSettings.getPollInterval(), mPollIntent);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700518 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700519
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700520 /**
521 * Register for a global alert that is delivered through
522 * {@link INetworkManagementEventObserver} once a threshold amount of data
523 * has been transferred.
524 */
525 private void registerGlobalAlert() {
526 try {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700527 mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700528 } catch (IllegalStateException e) {
529 Slog.w(TAG, "problem registering for global alert: " + e);
530 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700531 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700532 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700533 }
534
535 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700536 public INetworkStatsSession openSession() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600537 // NOTE: if callers want to get non-augmented data, they should go
538 // through the public API
539 return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000540 }
541
542 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600543 public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
544 return openSessionInternal(flags, callingPackage);
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100545 }
546
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900547 private boolean isRateLimitedForPoll(int callingUid) {
548 if (callingUid == android.os.Process.SYSTEM_UID) {
549 return false;
550 }
551
552 final long lastCallTime;
553 final long now = SystemClock.elapsedRealtime();
554 synchronized (mOpenSessionCallsPerUid) {
555 int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
556 mOpenSessionCallsPerUid.put(callingUid, calls + 1);
557 lastCallTime = mLastStatsSessionPoll;
558 mLastStatsSessionPoll = now;
559 }
560
561 return now - lastCallTime < POLL_RATE_LIMIT_MS;
562 }
563
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600564 private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
Jeff Sharkey4190a042012-04-21 15:36:48 -0700565 assertBandwidthControlEnabled();
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700566
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900567 final int callingUid = Binder.getCallingUid();
568 final int usedFlags = isRateLimitedForPoll(callingUid)
569 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
570 : flags;
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600571 if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
572 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100573 final long ident = Binder.clearCallingIdentity();
574 try {
575 performPoll(FLAG_PERSIST_ALL);
576 } finally {
577 Binder.restoreCallingIdentity(ident);
578 }
579 }
580
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700581 // return an IBinder which holds strong references to any loaded stats
582 // for its lifetime; when caller closes only weak references remain.
583
584 return new INetworkStatsSession.Stub() {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900585 private final int mCallingUid = callingUid;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600586 private final String mCallingPackage = callingPackage;
587 private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
588 callingPackage);
589
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700590 private NetworkStatsCollection mUidComplete;
591 private NetworkStatsCollection mUidTagComplete;
592
593 private NetworkStatsCollection getUidComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700594 synchronized (mStatsLock) {
595 if (mUidComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700596 mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
597 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700598 return mUidComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700599 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700600 }
601
602 private NetworkStatsCollection getUidTagComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700603 synchronized (mStatsLock) {
604 if (mUidTagComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700605 mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
606 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700607 return mUidTagComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700608 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700609 }
610
611 @Override
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000612 public int[] getRelevantUids() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600613 return getUidComplete().getRelevantUids(mAccessLevel);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000614 }
615
616 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600617 public NetworkStats getDeviceSummaryForNetwork(
618 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900619 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600620 mCallingUid);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000621 }
622
623 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700624 public NetworkStats getSummaryForNetwork(
625 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900626 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600627 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700628 }
629
630 @Override
631 public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900632 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600633 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700634 }
635
636 @Override
637 public NetworkStats getSummaryForAllUid(
638 NetworkTemplate template, long start, long end, boolean includeTags) {
Jeff Davidson39583b52016-12-12 11:55:37 -0800639 try {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600640 final NetworkStats stats = getUidComplete()
641 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800642 if (includeTags) {
643 final NetworkStats tagStats = getUidTagComplete()
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600644 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800645 stats.combineAllValues(tagStats);
646 }
647 return stats;
648 } catch (NullPointerException e) {
649 // TODO: Track down and fix the cause of this crash and remove this catch block.
650 Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
651 throw e;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700652 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700653 }
654
655 @Override
656 public NetworkStatsHistory getHistoryForUid(
657 NetworkTemplate template, int uid, int set, int tag, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600658 // NOTE: We don't augment UID-level statistics
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700659 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600660 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
661 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700662 } else {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600663 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
664 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700665 }
666 }
667
668 @Override
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100669 public NetworkStatsHistory getHistoryIntervalForUid(
670 NetworkTemplate template, int uid, int set, int tag, int fields,
671 long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600672 // NOTE: We don't augment UID-level statistics
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100673 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600674 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
675 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700676 } else if (uid == Binder.getCallingUid()) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600677 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
678 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700679 } else {
680 throw new SecurityException("Calling package " + mCallingPackage
681 + " cannot access tag information from a different uid");
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100682 }
683 }
684
685 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700686 public void close() {
687 mUidComplete = null;
688 mUidTagComplete = null;
689 }
690 };
Jeff Sharkey905b5892011-09-30 15:19:49 -0700691 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700692
Jeff Davidson1efb1332015-12-09 18:04:50 -0800693 private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
694 return NetworkStatsAccess.checkAccessLevel(
695 mContext, Binder.getCallingUid(), callingPackage);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000696 }
697
Jeff Sharkey70c70532012-05-16 14:51:19 -0700698 /**
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600699 * Find the most relevant {@link SubscriptionPlan} for the given
700 * {@link NetworkTemplate} and flags. This is typically used to augment
701 * local measurement results to match a known anchor from the carrier.
702 */
703 private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
704 SubscriptionPlan plan = null;
705 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600706 && mSettings.getAugmentEnabled()) {
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700707 if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600708 final long token = Binder.clearCallingIdentity();
709 try {
Jeff Sharkey146bb332018-04-18 15:42:57 -0600710 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
711 .getSubscriptionPlan(template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600712 } finally {
713 Binder.restoreCallingIdentity(token);
714 }
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700715 if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600716 }
717 return plan;
718 }
719
720 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700721 * Return network summary, splicing between DEV and XT stats when
722 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700723 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600724 private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
725 long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700726 // We've been using pure XT stats long enough that we no longer need to
727 // splice DEV and XT together.
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600728 final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
729 accessLevel, callingUid);
730
731 final long now = System.currentTimeMillis();
732 final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
733
734 final NetworkStats stats = new NetworkStats(end - start, 1);
Lorenzo Colittiada23ed2018-01-19 01:05:20 +0900735 stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
736 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
737 entry.txBytes, entry.txPackets, entry.operations));
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600738 return stats;
Jeff Sharkey70c70532012-05-16 14:51:19 -0700739 }
740
741 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700742 * Return network history, splicing between DEV and XT stats when
743 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700744 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600745 private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
746 int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700747 // We've been using pure XT stats long enough that we no longer need to
748 // splice DEV and XT together.
Jeff Sharkey4635f102017-09-01 11:27:13 -0600749 final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
750 synchronized (mStatsLock) {
751 return mXtStatsCached.getHistory(template, augmentPlan,
752 UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
753 accessLevel, callingUid);
754 }
Jeff Sharkey70c70532012-05-16 14:51:19 -0700755 }
756
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700757 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
758 assertSystemReady();
Jeff Sharkey4190a042012-04-21 15:36:48 -0700759 assertBandwidthControlEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600760
761 // NOTE: if callers want to get non-augmented data, they should go
762 // through the public API
763 return internalGetSummaryForNetwork(template,
764 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
765 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700766 }
767
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700768 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
769 assertSystemReady();
770 assertBandwidthControlEnabled();
771
772 final NetworkStatsCollection uidComplete;
773 synchronized (mStatsLock) {
774 uidComplete = mUidRecorder.getOrLoadCompleteLocked();
775 }
776 return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
777 android.os.Process.SYSTEM_UID);
778 }
779
Jeff Sharkey350083e2011-06-29 10:45:16 -0700780 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700781 public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
782 if (Binder.getCallingUid() != uid) {
783 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
784 }
Jeff Sharkey4190a042012-04-21 15:36:48 -0700785 assertBandwidthControlEnabled();
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700786
787 // TODO: switch to data layer stats once kernel exports
788 // for now, read network layer stats and flatten across all ifaces
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800789 final long token = Binder.clearCallingIdentity();
790 final NetworkStats networkLayer;
791 try {
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900792 networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid,
793 NetworkStats.INTERFACES_ALL);
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800794 } finally {
795 Binder.restoreCallingIdentity(token);
796 }
797
Jeff Sharkey21a54782012-04-09 10:27:55 -0700798 // splice in operation counts
799 networkLayer.spliceOperationsFrom(mUidOperations);
800
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700801 final NetworkStats dataLayer = new NetworkStats(
802 networkLayer.getElapsedRealtime(), networkLayer.size());
803
804 NetworkStats.Entry entry = null;
805 for (int i = 0; i < networkLayer.size(); i++) {
806 entry = networkLayer.getValues(i, entry);
807 entry.iface = IFACE_ALL;
808 dataLayer.combineValues(entry);
809 }
810
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700811 return dataLayer;
812 }
813
814 @Override
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900815 public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
816 try {
817 final String[] ifacesToQuery =
Remi NGUYEN VAN9fb55e42018-02-27 16:47:22 +0900818 NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900819 return getNetworkStatsUidDetail(ifacesToQuery);
820 } catch (RemoteException e) {
821 Log.wtf(TAG, "Error compiling UID stats", e);
822 return new NetworkStats(0L, 0);
823 }
824 }
825
826 @Override
Jeff Sharkey234766a2012-04-10 19:48:07 -0700827 public String[] getMobileIfaces() {
828 return mMobileIfaces;
829 }
830
831 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700832 public void incrementOperationCount(int uid, int tag, int operationCount) {
833 if (Binder.getCallingUid() != uid) {
Jeff Sharkey9f09e6a72017-06-26 11:24:47 -0600834 mContext.enforceCallingOrSelfPermission(
835 android.Manifest.permission.UPDATE_DEVICE_STATS, TAG);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700836 }
837
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700838 if (operationCount < 0) {
839 throw new IllegalArgumentException("operation count can only be incremented");
840 }
841 if (tag == TAG_NONE) {
842 throw new IllegalArgumentException("operation count must have specific tag");
843 }
844
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700845 synchronized (mStatsLock) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700846 final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800847 mUidOperations.combineValues(
848 mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
849 mUidOperations.combineValues(
850 mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700851 }
852 }
853
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700854 @VisibleForTesting
855 void setUidForeground(int uid, boolean uidForeground) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700856 synchronized (mStatsLock) {
857 final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
858 final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
859 if (oldSet != set) {
860 mActiveUidCounterSet.put(uid, set);
861 setKernelCounterSet(uid, set);
862 }
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700863 }
864 }
865
866 @Override
Lorenzo Colittic78da292018-01-19 00:50:48 +0900867 public void forceUpdateIfaces(Network[] defaultNetworks) {
Jeff Sharkey69736342014-12-08 14:50:12 -0800868 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
869 assertBandwidthControlEnabled();
870
871 final long token = Binder.clearCallingIdentity();
872 try {
Lorenzo Colittic78da292018-01-19 00:50:48 +0900873 updateIfaces(defaultNetworks);
Jeff Sharkey69736342014-12-08 14:50:12 -0800874 } finally {
875 Binder.restoreCallingIdentity(token);
876 }
877 }
878
879 @Override
Jeff Sharkey350083e2011-06-29 10:45:16 -0700880 public void forceUpdate() {
881 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkey4190a042012-04-21 15:36:48 -0700882 assertBandwidthControlEnabled();
Jeff Sharkeye630f7b2012-01-31 17:12:53 -0800883
884 final long token = Binder.clearCallingIdentity();
885 try {
886 performPoll(FLAG_PERSIST_ALL);
887 } finally {
888 Binder.restoreCallingIdentity(token);
889 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700890 }
891
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700892 private void advisePersistThreshold(long thresholdBytes) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700893 assertBandwidthControlEnabled();
894
895 // clamp threshold into safe range
896 mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700897 if (LOGV) {
898 Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
899 + mPersistThreshold);
900 }
901
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700902 // update and persist if beyond new thresholds
Jeff Sharkey9911a282018-02-14 22:29:11 -0700903 final long currentTime = mClock.millis();
Jeff Sharkey58015972012-05-07 11:08:49 -0700904 synchronized (mStatsLock) {
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700905 if (!mSystemReady) return;
906
Jeff Sharkey4635f102017-09-01 11:27:13 -0600907 updatePersistThresholdsLocked();
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700908
Jeff Sharkey58015972012-05-07 11:08:49 -0700909 mDevRecorder.maybePersistLocked(currentTime);
910 mXtRecorder.maybePersistLocked(currentTime);
911 mUidRecorder.maybePersistLocked(currentTime);
912 mUidTagRecorder.maybePersistLocked(currentTime);
913 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700914
915 // re-arm global alert
916 registerGlobalAlert();
917 }
918
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800919 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700920 public DataUsageRequest registerUsageCallback(String callingPackage,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800921 DataUsageRequest request, Messenger messenger, IBinder binder) {
922 checkNotNull(callingPackage, "calling package is null");
923 checkNotNull(request, "DataUsageRequest is null");
Antonio Cansado6965c182016-03-30 11:37:18 -0700924 checkNotNull(request.template, "NetworkTemplate is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800925 checkNotNull(messenger, "messenger is null");
926 checkNotNull(binder, "binder is null");
927
928 int callingUid = Binder.getCallingUid();
929 @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
930 DataUsageRequest normalizedRequest;
931 final long token = Binder.clearCallingIdentity();
932 try {
933 normalizedRequest = mStatsObservers.register(request, messenger, binder,
934 callingUid, accessLevel);
935 } finally {
936 Binder.restoreCallingIdentity(token);
937 }
938
939 // Create baseline stats
Chalard Jeand7c6e122018-08-22 10:21:26 +0900940 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800941
942 return normalizedRequest;
943 }
944
945 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700946 public void unregisterUsageRequest(DataUsageRequest request) {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800947 checkNotNull(request, "DataUsageRequest is null");
948
949 int callingUid = Binder.getCallingUid();
950 final long token = Binder.clearCallingIdentity();
951 try {
952 mStatsObservers.unregister(request, callingUid);
953 } finally {
954 Binder.restoreCallingIdentity(token);
955 }
956 }
957
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800958 @Override
959 public long getUidStats(int uid, int type) {
Chenbo Fengaedd6a32017-11-20 18:23:46 -0800960 return nativeGetUidStat(uid, type, checkBpfStatsEnable());
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800961 }
962
963 @Override
964 public long getIfaceStats(String iface, int type) {
Mike SU1f9ed0b2018-11-26 15:05:13 +0800965 long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
966 if (nativeIfaceStats == -1) {
967 return nativeIfaceStats;
968 } else {
969 // When tethering offload is in use, nativeIfaceStats does not contain usage from
970 // offload, add it back here.
971 // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
972 // this does not cause double-counting of tethering traffic, because
973 // NetdTetheringStatsProvider returns zero NetworkStats
974 // when called with STATS_PER_IFACE.
975 return nativeIfaceStats + getTetherStats(iface, type);
976 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800977 }
978
979 @Override
980 public long getTotalStats(int type) {
Mike SU1f9ed0b2018-11-26 15:05:13 +0800981 long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
982 if (nativeTotalStats == -1) {
983 return nativeTotalStats;
984 } else {
985 // Refer to comment in getIfaceStats
986 return nativeTotalStats + getTetherStats(IFACE_ALL, type);
987 }
988 }
989
990 private long getTetherStats(String iface, int type) {
991 final NetworkStats tetherSnapshot;
992 final long token = Binder.clearCallingIdentity();
993 try {
994 tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
995 } catch (RemoteException e) {
996 Slog.w(TAG, "Error get TetherStats: " + e);
997 return 0;
998 } finally {
999 Binder.restoreCallingIdentity(token);
1000 }
1001 HashSet<String> limitIfaces;
1002 if (iface == IFACE_ALL) {
1003 limitIfaces = null;
1004 } else {
1005 limitIfaces = new HashSet<String>();
1006 limitIfaces.add(iface);
1007 }
1008 NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
1009 if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
1010 " entry=" + entry);
1011 switch (type) {
1012 case 0: // TYPE_RX_BYTES
1013 return entry.rxBytes;
1014 case 1: // TYPE_RX_PACKETS
1015 return entry.rxPackets;
1016 case 2: // TYPE_TX_BYTES
1017 return entry.txBytes;
1018 case 3: // TYPE_TX_PACKETS
1019 return entry.txPackets;
1020 default:
1021 return 0;
1022 }
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001023 }
1024
1025 private boolean checkBpfStatsEnable() {
Chenbo Feng00499822018-05-18 17:10:07 -07001026 return mUseBpfTrafficStats;
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001027 }
1028
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001029 /**
1030 * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
1031 * reflect current {@link #mPersistThreshold} value. Always defers to
Jeff Sharkey625239a2012-09-26 22:03:49 -07001032 * {@link Global} values when defined.
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001033 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001034 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001035 private void updatePersistThresholdsLocked() {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001036 mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
1037 mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
1038 mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
1039 mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
1040 mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
1041 }
1042
Jeff Sharkey75279902011-05-24 18:39:45 -07001043 /**
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001044 * Receiver that watches for {@link Tethering} to claim interface pairs.
1045 */
1046 private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
1047 @Override
1048 public void onReceive(Context context, Intent intent) {
1049 // on background handler thread, and verified CONNECTIVITY_INTERNAL
1050 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001051 performPoll(FLAG_PERSIST_NETWORK);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001052 }
1053 };
1054
Jeff Sharkey75279902011-05-24 18:39:45 -07001055 private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
1056 @Override
1057 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001058 // on background handler thread, and verified UPDATE_DEVICE_STATS
1059 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001060 performPoll(FLAG_PERSIST_ALL);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001061
1062 // verify that we're watching global alert
1063 registerGlobalAlert();
Jeff Sharkey75279902011-05-24 18:39:45 -07001064 }
1065 };
1066
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001067 private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
1068 @Override
1069 public void onReceive(Context context, Intent intent) {
1070 // on background handler thread, and UID_REMOVED is protected
1071 // broadcast.
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001072
1073 final int uid = intent.getIntExtra(EXTRA_UID, -1);
1074 if (uid == -1) return;
1075
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001076 synchronized (mStatsLock) {
Jeff Sharkey62489262011-07-17 12:53:28 -07001077 mWakeLock.acquire();
1078 try {
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001079 removeUidsLocked(uid);
1080 } finally {
1081 mWakeLock.release();
1082 }
1083 }
1084 }
1085 };
1086
1087 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1088 @Override
1089 public void onReceive(Context context, Intent intent) {
1090 // On background handler thread, and USER_REMOVED is protected
1091 // broadcast.
1092
1093 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1094 if (userId == -1) return;
1095
1096 synchronized (mStatsLock) {
1097 mWakeLock.acquire();
1098 try {
1099 removeUserLocked(userId);
Jeff Sharkey62489262011-07-17 12:53:28 -07001100 } finally {
1101 mWakeLock.release();
1102 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001103 }
1104 }
1105 };
1106
Jeff Sharkey75279902011-05-24 18:39:45 -07001107 private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
1108 @Override
1109 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001110 // SHUTDOWN is protected broadcast.
Jeff Sharkey75279902011-05-24 18:39:45 -07001111 synchronized (mStatsLock) {
Jeff Sharkey3f391352011-06-05 17:42:53 -07001112 shutdownLocked();
Jeff Sharkey75279902011-05-24 18:39:45 -07001113 }
1114 }
1115 };
1116
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001117 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001118 * Observer that watches for {@link INetworkManagementService} alerts.
1119 */
Jeff Sharkey216c1812012-08-05 14:29:23 -07001120 private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001121 @Override
1122 public void limitReached(String limitName, String iface) {
1123 // only someone like NMS should be calling us
1124 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1125
1126 if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001127 // kick off background poll to collect network stats unless there is already
1128 // such a call pending; UID stats are handled during normal polling interval.
1129 if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
1130 mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
1131 PERFORM_POLL_DELAY_MS);
1132 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001133 }
1134 }
1135 };
1136
Lorenzo Colittic78da292018-01-19 00:50:48 +09001137 private void updateIfaces(Network[] defaultNetworks) {
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001138 synchronized (mStatsLock) {
1139 mWakeLock.acquire();
1140 try {
Lorenzo Colittic78da292018-01-19 00:50:48 +09001141 updateIfacesLocked(defaultNetworks);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001142 } finally {
1143 mWakeLock.release();
1144 }
1145 }
1146 }
1147
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001148 /**
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001149 * Inspect all current {@link NetworkState} to derive mapping from {@code
1150 * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
1151 * are active on a single {@code iface}, they are combined under a single
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001152 * {@link NetworkIdentitySet}.
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001153 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001154 @GuardedBy("mStatsLock")
Lorenzo Colittic78da292018-01-19 00:50:48 +09001155 private void updateIfacesLocked(Network[] defaultNetworks) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001156 if (!mSystemReady) return;
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001157 if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001158
1159 // take one last stats snapshot before updating iface mapping. this
1160 // isn't perfect, since the kernel may already be counting traffic from
1161 // the updated network.
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001162
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001163 // poll, but only persist network stats to keep codepath fast. UID stats
1164 // will be persisted during next alarm poll event.
1165 performPollLocked(FLAG_PERSIST_NETWORK);
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001166
1167 final NetworkState[] states;
Jeff Sharkey63abc372012-01-11 18:38:16 -08001168 final LinkProperties activeLink;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001169 try {
1170 states = mConnManager.getAllNetworkState();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001171 activeLink = mConnManager.getActiveLinkProperties();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001172 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001173 // ignored; service lives in system_server
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001174 return;
1175 }
1176
Jeff Sharkey63abc372012-01-11 18:38:16 -08001177 mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
1178
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001179 // Rebuild active interfaces based on connected networks
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001180 mActiveIfaces.clear();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001181 mActiveUidIfaces.clear();
Lorenzo Colittic78da292018-01-19 00:50:48 +09001182 if (defaultNetworks != null) {
1183 // Caller is ConnectivityService. Update the list of default networks.
1184 mDefaultNetworks = defaultNetworks;
1185 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001186
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001187 final ArraySet<String> mobileIfaces = new ArraySet<>();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001188 for (NetworkState state : states) {
1189 if (state.networkInfo.isConnected()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001190 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001191 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
1192 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1193 isDefault);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001194
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001195 // Traffic occurring on the base interface is always counted for
1196 // both total usage and UID details.
1197 final String baseIface = state.linkProperties.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001198 if (baseIface != null) {
1199 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1200 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
Jack Yub6587ea2016-06-22 11:35:10 -07001201
1202 // Build a separate virtual interface for VT (Video Telephony) data usage.
1203 // Only do this when IMS is not metered, but VT is metered.
1204 // If IMS is metered, then the IMS network usage has already included VT usage.
1205 // VT is considered always metered in framework's layer. If VT is not metered
1206 // per carrier's policy, modem will report 0 usage for VT calls.
1207 if (state.networkCapabilities.hasCapability(
1208 NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1209
1210 // Copy the identify from IMS one but mark it as metered.
1211 NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1212 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001213 ident.getRoaming(), true /* metered */,
1214 true /* onDefaultNetwork */);
Jack Yub6587ea2016-06-22 11:35:10 -07001215 findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent);
1216 findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent);
1217 }
1218
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001219 if (isMobile) {
1220 mobileIfaces.add(baseIface);
1221 }
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001222 }
1223
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001224 // Traffic occurring on stacked interfaces is usually clatd,
1225 // which is already accounted against its final egress interface
1226 // by the kernel. Thus, we only need to collect stacked
1227 // interface stats at the UID level.
1228 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1229 for (LinkProperties stackedLink : stackedLinks) {
1230 final String stackedIface = stackedLink.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001231 if (stackedIface != null) {
1232 findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1233 if (isMobile) {
1234 mobileIfaces.add(stackedIface);
1235 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001236
1237 NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
Jeff Sharkey234766a2012-04-10 19:48:07 -07001238 }
1239 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001240 }
1241 }
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001242
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001243 mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1244 }
1245
1246 private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1247 ArrayMap<K, NetworkIdentitySet> map, K key) {
1248 NetworkIdentitySet ident = map.get(key);
1249 if (ident == null) {
1250 ident = new NetworkIdentitySet();
1251 map.put(key, ident);
1252 }
1253 return ident;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001254 }
1255
Andreas Gampea36dc622018-02-05 17:19:22 -08001256 @GuardedBy("mStatsLock")
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001257 private void recordSnapshotLocked(long currentTime) throws RemoteException {
1258 // snapshot and record current counters; read UID stats first to
Jack Yub6587ea2016-06-22 11:35:10 -07001259 // avoid over counting dev stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001260 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001261 final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
Jeff Sharkey00072392018-04-12 14:26:32 -06001262 Trace.traceEnd(TRACE_TAG_NETWORK);
1263 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
Jack Yuf9d559c2017-05-26 16:08:22 -07001264 final NetworkStats xtSnapshot = getNetworkStatsXt();
Jeff Sharkey00072392018-04-12 14:26:32 -06001265 Trace.traceEnd(TRACE_TAG_NETWORK);
1266 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001267 final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
Jeff Sharkey00072392018-04-12 14:26:32 -06001268 Trace.traceEnd(TRACE_TAG_NETWORK);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001269
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001270 // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1271 // providers that isn't already counted by dev and XT stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001272 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001273 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
Jeff Sharkey00072392018-04-12 14:26:32 -06001274 Trace.traceEnd(TRACE_TAG_NETWORK);
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001275 xtSnapshot.combineAllValues(tetherSnapshot);
1276 devSnapshot.combineAllValues(tetherSnapshot);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001277
1278 // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1279 // can't be reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001280 Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001281 mDevRecorder.recordSnapshotLocked(
1282 devSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001283 Trace.traceEnd(TRACE_TAG_NETWORK);
1284 Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001285 mXtRecorder.recordSnapshotLocked(
1286 xtSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001287 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001288
1289 // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001290 VpnInfo[] vpnArray = mConnManager.getAllVpnInfo();
Jeff Sharkey00072392018-04-12 14:26:32 -06001291 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001292 mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001293 Trace.traceEnd(TRACE_TAG_NETWORK);
1294 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001295 mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001296 Trace.traceEnd(TRACE_TAG_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001297
1298 // We need to make copies of member fields that are sent to the observer to avoid
1299 // a race condition between the service handler thread and the observer's
1300 mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
1301 new ArrayMap<>(mActiveUidIfaces), vpnArray, currentTime);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001302 }
1303
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001304 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001305 * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1306 * so we have baseline values without double-counting.
1307 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001308 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001309 private void bootstrapStatsLocked() {
Jeff Sharkey9911a282018-02-14 22:29:11 -07001310 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001311
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001312 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001313 recordSnapshotLocked(currentTime);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001314 } catch (IllegalStateException e) {
1315 Slog.w(TAG, "problem reading network stats: " + e);
1316 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001317 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001318 }
1319 }
1320
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001321 private void performPoll(int flags) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001322 synchronized (mStatsLock) {
1323 mWakeLock.acquire();
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001324
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001325 try {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001326 performPollLocked(flags);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001327 } finally {
1328 mWakeLock.release();
1329 }
1330 }
1331 }
1332
1333 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001334 * Periodic poll operation, reading current statistics and recording into
1335 * {@link NetworkStatsHistory}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001336 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001337 @GuardedBy("mStatsLock")
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001338 private void performPollLocked(int flags) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001339 if (!mSystemReady) return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001340 if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
Jeff Sharkey00072392018-04-12 14:26:32 -06001341 Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
Jeff Sharkey75279902011-05-24 18:39:45 -07001342
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001343 final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1344 final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001345 final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001346
Jeff Sharkey75279902011-05-24 18:39:45 -07001347 // TODO: consider marking "untrusted" times in historical stats
Jeff Sharkey9911a282018-02-14 22:29:11 -07001348 final long currentTime = mClock.millis();
Jeff Sharkey75279902011-05-24 18:39:45 -07001349
Jeff Sharkey75279902011-05-24 18:39:45 -07001350 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001351 recordSnapshotLocked(currentTime);
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001352 } catch (IllegalStateException e) {
1353 Log.wtf(TAG, "problem reading network stats", e);
Jeff Sharkey905b5892011-09-30 15:19:49 -07001354 return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001355 } catch (RemoteException e) {
1356 // ignored; service lives in system_server
Jeff Sharkey905b5892011-09-30 15:19:49 -07001357 return;
1358 }
1359
Jeff Sharkey63abc372012-01-11 18:38:16 -08001360 // persist any pending data depending on requested flags
Jeff Sharkey00072392018-04-12 14:26:32 -06001361 Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001362 if (persistForce) {
1363 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001364 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001365 mUidRecorder.forcePersistLocked(currentTime);
1366 mUidTagRecorder.forcePersistLocked(currentTime);
1367 } else {
1368 if (persistNetwork) {
1369 mDevRecorder.maybePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001370 mXtRecorder.maybePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001371 }
1372 if (persistUid) {
1373 mUidRecorder.maybePersistLocked(currentTime);
1374 mUidTagRecorder.maybePersistLocked(currentTime);
1375 }
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001376 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001377 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001378
Jeff Sharkey63abc372012-01-11 18:38:16 -08001379 if (mSettings.getSampleEnabled()) {
Jeff Sharkey905b5892011-09-30 15:19:49 -07001380 // sample stats after each full poll
Jeff Sharkey63abc372012-01-11 18:38:16 -08001381 performSampleLocked();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001382 }
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001383
Jeff Sharkey497e4432011-06-14 17:27:29 -07001384 // finally, dispatch updated event to any listeners
1385 final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
1386 updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001387 mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
1388 READ_NETWORK_USAGE_HISTORY);
Jeff Sharkey00072392018-04-12 14:26:32 -06001389
1390 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001391 }
1392
1393 /**
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001394 * Sample recent statistics summary into {@link EventLog}.
1395 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001396 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001397 private void performSampleLocked() {
1398 // TODO: migrate trustedtime fixes to separate binary log events
Jeff Sharkey9911a282018-02-14 22:29:11 -07001399 final long currentTime = mClock.millis();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001400
Jeff Sharkey63abc372012-01-11 18:38:16 -08001401 NetworkTemplate template;
1402 NetworkStats.Entry devTotal;
1403 NetworkStats.Entry xtTotal;
1404 NetworkStats.Entry uidTotal;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001405
1406 // collect mobile sample
Jeff Sharkey234766a2012-04-10 19:48:07 -07001407 template = buildTemplateMobileWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001408 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001409 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001410 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001411
Jeff Sharkey905b5892011-09-30 15:19:49 -07001412 EventLogTags.writeNetstatsMobileSample(
1413 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1414 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1415 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001416 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001417
1418 // collect wifi sample
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001419 template = buildTemplateWifiWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001420 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001421 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001422 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1423
Jeff Sharkey905b5892011-09-30 15:19:49 -07001424 EventLogTags.writeNetstatsWifiSample(
1425 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1426 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1427 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001428 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001429 }
1430
1431 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001432 * Clean up {@link #mUidRecorder} after UID is removed.
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001433 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001434 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001435 private void removeUidsLocked(int... uids) {
1436 if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1437
1438 // Perform one last poll before removing
Jeff Sharkey163e6442011-10-31 16:37:52 -07001439 performPollLocked(FLAG_PERSIST_ALL);
1440
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001441 mUidRecorder.removeUidsLocked(uids);
1442 mUidTagRecorder.removeUidsLocked(uids);
Jeff Sharkey163e6442011-10-31 16:37:52 -07001443
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001444 // Clear kernel stats associated with UID
1445 for (int uid : uids) {
1446 resetKernelUidStats(uid);
1447 }
1448 }
1449
1450 /**
1451 * Clean up {@link #mUidRecorder} after user is removed.
1452 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001453 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001454 private void removeUserLocked(int userId) {
1455 if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1456
1457 // Build list of UIDs that we should clean up
1458 int[] uids = new int[0];
1459 final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001460 PackageManager.MATCH_ANY_USER
1461 | PackageManager.MATCH_DISABLED_COMPONENTS);
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001462 for (ApplicationInfo app : apps) {
1463 final int uid = UserHandle.getUid(userId, app.uid);
1464 uids = ArrayUtils.appendInt(uids, uid);
1465 }
1466
1467 removeUidsLocked(uids);
Jeff Sharkey75279902011-05-24 18:39:45 -07001468 }
1469
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001470 private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
1471 @Override
1472 public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001473 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
1474 try {
1475 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
1476 } finally {
1477 Trace.traceEnd(TRACE_TAG_NETWORK);
1478 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001479 }
1480
1481 @Override
1482 public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001483 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
1484 try {
1485 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
1486 } finally {
1487 Trace.traceEnd(TRACE_TAG_NETWORK);
1488 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001489 }
1490
1491 @Override
1492 public void setUidForeground(int uid, boolean uidForeground) {
1493 NetworkStatsService.this.setUidForeground(uid, uidForeground);
1494 }
1495
1496 @Override
1497 public void advisePersistThreshold(long thresholdBytes) {
1498 NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
1499 }
1500
1501 @Override
1502 public void forceUpdate() {
1503 NetworkStatsService.this.forceUpdate();
1504 }
1505 }
1506
Jeff Sharkey75279902011-05-24 18:39:45 -07001507 @Override
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001508 protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001509 if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
Jeff Sharkey75279902011-05-24 18:39:45 -07001510
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001511 long duration = DateUtils.DAY_IN_MILLIS;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001512 final HashSet<String> argSet = new HashSet<String>();
1513 for (String arg : args) {
1514 argSet.add(arg);
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001515
1516 if (arg.startsWith("--duration=")) {
1517 try {
1518 duration = Long.parseLong(arg.substring(11));
1519 } catch (NumberFormatException ignored) {
1520 }
1521 }
Jeff Sharkey75279902011-05-24 18:39:45 -07001522 }
1523
Jeff Sharkey706498d2012-02-06 17:35:07 -08001524 // usage: dumpsys netstats --full --uid --tag --poll --checkin
Jeff Sharkey63abc372012-01-11 18:38:16 -08001525 final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
Jeff Sharkey706498d2012-02-06 17:35:07 -08001526 final boolean checkin = argSet.contains("--checkin");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001527 final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1528 final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1529 final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1530
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001531 final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
Jeff Sharkey350083e2011-06-29 10:45:16 -07001532
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001533 synchronized (mStatsLock) {
Makoto Onukida65a522017-01-13 10:23:30 -08001534 if (args.length > 0 && "--proto".equals(args[0])) {
1535 // In this case ignore all other arguments.
Jeff Sharkey4635f102017-09-01 11:27:13 -06001536 dumpProtoLocked(fd);
Makoto Onukida65a522017-01-13 10:23:30 -08001537 return;
1538 }
1539
Jeff Sharkey63abc372012-01-11 18:38:16 -08001540 if (poll) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001541 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
Jeff Sharkey3f391352011-06-05 17:42:53 -07001542 pw.println("Forced poll");
1543 return;
1544 }
1545
Jeff Sharkey706498d2012-02-06 17:35:07 -08001546 if (checkin) {
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001547 final long end = System.currentTimeMillis();
1548 final long start = end - duration;
1549
1550 pw.print("v1,");
1551 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1552 pw.print(end / SECOND_IN_MILLIS); pw.println();
1553
1554 pw.println("xt");
1555 mXtRecorder.dumpCheckin(rawWriter, start, end);
1556
1557 if (includeUid) {
1558 pw.println("uid");
1559 mUidRecorder.dumpCheckin(rawWriter, start, end);
Jeff Sharkey706498d2012-02-06 17:35:07 -08001560 }
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001561 if (includeTag) {
1562 pw.println("tag");
1563 mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1564 }
Jeff Sharkey706498d2012-02-06 17:35:07 -08001565 return;
1566 }
1567
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001568 pw.println("Active interfaces:");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001569 pw.increaseIndent();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001570 for (int i = 0; i < mActiveIfaces.size(); i++) {
1571 pw.printPair("iface", mActiveIfaces.keyAt(i));
1572 pw.printPair("ident", mActiveIfaces.valueAt(i));
1573 pw.println();
1574 }
1575 pw.decreaseIndent();
1576
1577 pw.println("Active UID interfaces:");
1578 pw.increaseIndent();
1579 for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1580 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1581 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1582 pw.println();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001583 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001584 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001585
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +09001586 // Get the top openSession callers
1587 final SparseIntArray calls;
1588 synchronized (mOpenSessionCallsPerUid) {
1589 calls = mOpenSessionCallsPerUid.clone();
1590 }
1591
1592 final int N = calls.size();
1593 final long[] values = new long[N];
1594 for (int j = 0; j < N; j++) {
1595 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
1596 }
1597 Arrays.sort(values);
1598
1599 pw.println("Top openSession callers (uid=count):");
1600 pw.increaseIndent();
1601 final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
1602 for (int j = N - 1; j >= end; j--) {
1603 final int uid = (int) (values[j] & 0xffffffff);
1604 final int count = (int) (values[j] >> 32);
1605 pw.print(uid); pw.print("="); pw.println(count);
1606 }
1607 pw.decreaseIndent();
1608 pw.println();
1609
Jeff Sharkey63abc372012-01-11 18:38:16 -08001610 pw.println("Dev stats:");
1611 pw.increaseIndent();
1612 mDevRecorder.dumpLocked(pw, fullHistory);
1613 pw.decreaseIndent();
1614
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001615 pw.println("Xt stats:");
1616 pw.increaseIndent();
1617 mXtRecorder.dumpLocked(pw, fullHistory);
1618 pw.decreaseIndent();
1619
Jeff Sharkey63abc372012-01-11 18:38:16 -08001620 if (includeUid) {
1621 pw.println("UID stats:");
1622 pw.increaseIndent();
1623 mUidRecorder.dumpLocked(pw, fullHistory);
1624 pw.decreaseIndent();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001625 }
1626
Jeff Sharkey63abc372012-01-11 18:38:16 -08001627 if (includeTag) {
1628 pw.println("UID tag stats:");
1629 pw.increaseIndent();
1630 mUidTagRecorder.dumpLocked(pw, fullHistory);
1631 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001632 }
1633 }
1634 }
1635
Andreas Gampea36dc622018-02-05 17:19:22 -08001636 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001637 private void dumpProtoLocked(FileDescriptor fd) {
Makoto Onukida65a522017-01-13 10:23:30 -08001638 final ProtoOutputStream proto = new ProtoOutputStream(fd);
1639
1640 // TODO Right now it writes all history. Should it limit to the "since-boot" log?
1641
1642 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1643 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
1644 mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1645 mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1646 mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1647 mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
1648
1649 proto.flush();
1650 }
1651
1652 private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1653 ArrayMap<String, NetworkIdentitySet> ifaces) {
1654 for (int i = 0; i < ifaces.size(); i++) {
1655 final long start = proto.start(tag);
1656
1657 proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
1658 ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
1659
1660 proto.end(start);
1661 }
1662 }
1663
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001664 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001665 * Return snapshot of current UID statistics, including any
Jack Yuf9d559c2017-05-26 16:08:22 -07001666 * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1667 * values.
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001668 *
1669 * @param ifaces A list of interfaces the stats should be restricted to, or
1670 * {@link NetworkStats#INTERFACES_ALL}.
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001671 */
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001672 private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
1673 throws RemoteException {
1674
Remi NGUYEN VAN9fb55e42018-02-27 16:47:22 +09001675 // TODO: remove 464xlat adjustments from NetworkStatsFactory and apply all at once here.
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001676 final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL,
1677 ifaces);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001678
Jeff Sharkey63abc372012-01-11 18:38:16 -08001679 // fold tethering stats and operations into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001680 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001681 tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
junyulaic33ac0d2018-10-19 21:14:30 +08001682 NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
1683 mUseBpfTrafficStats);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001684 uidSnapshot.combineAllValues(tetherSnapshot);
Jack Yuf9d559c2017-05-26 16:08:22 -07001685
1686 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
1687 Context.TELEPHONY_SERVICE);
1688
1689 // fold video calling data usage stats into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001690 final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
Jack Yuf9d559c2017-05-26 16:08:22 -07001691 if (vtStats != null) {
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001692 vtStats.filter(UID_ALL, ifaces, TAG_ALL);
junyulaic33ac0d2018-10-19 21:14:30 +08001693 NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
1694 mUseBpfTrafficStats);
Jack Yuf9d559c2017-05-26 16:08:22 -07001695 uidSnapshot.combineAllValues(vtStats);
1696 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001697
Jeff Sharkey63abc372012-01-11 18:38:16 -08001698 uidSnapshot.combineAllValues(mUidOperations);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001699
Jeff Sharkey63abc372012-01-11 18:38:16 -08001700 return uidSnapshot;
Jeff Sharkey75279902011-05-24 18:39:45 -07001701 }
1702
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001703 /**
Jack Yuf9d559c2017-05-26 16:08:22 -07001704 * Return snapshot of current XT statistics with video calling data usage statistics.
Jack Yub6587ea2016-06-22 11:35:10 -07001705 */
Jack Yuf9d559c2017-05-26 16:08:22 -07001706 private NetworkStats getNetworkStatsXt() throws RemoteException {
Jack Yub6587ea2016-06-22 11:35:10 -07001707 final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
1708
Jack Yuf9d559c2017-05-26 16:08:22 -07001709 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Jack Yub6587ea2016-06-22 11:35:10 -07001710 Context.TELEPHONY_SERVICE);
1711
Jack Yuf9d559c2017-05-26 16:08:22 -07001712 // Merge video calling data usage into XT
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001713 final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
Jack Yuf9d559c2017-05-26 16:08:22 -07001714 if (vtSnapshot != null) {
1715 xtSnapshot.combineAllValues(vtSnapshot);
1716 }
Jack Yub6587ea2016-06-22 11:35:10 -07001717
1718 return xtSnapshot;
1719 }
1720
1721 /**
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001722 * Return snapshot of current tethering statistics. Will return empty
1723 * {@link NetworkStats} if any problems are encountered.
1724 */
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001725 private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001726 try {
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001727 return mNetworkManager.getNetworkStatsTethering(how);
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001728 } catch (IllegalStateException e) {
1729 Log.wtf(TAG, "problem reading network stats", e);
1730 return new NetworkStats(0L, 10);
1731 }
1732 }
1733
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001734 @VisibleForTesting
1735 static class HandlerCallback implements Handler.Callback {
1736 private final NetworkStatsService mService;
1737
1738 HandlerCallback(NetworkStatsService service) {
1739 this.mService = service;
1740 }
1741
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001742 @Override
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001743 public boolean handleMessage(Message msg) {
1744 switch (msg.what) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001745 case MSG_PERFORM_POLL: {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001746 mService.performPoll(FLAG_PERSIST_ALL);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001747 return true;
1748 }
Chalard Jeand7c6e122018-08-22 10:21:26 +09001749 case MSG_PERFORM_POLL_REGISTER_ALERT: {
1750 mService.performPoll(FLAG_PERSIST_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001751 mService.registerGlobalAlert();
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -08001752 return true;
1753 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001754 default: {
1755 return false;
1756 }
1757 }
1758 }
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001759 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001760
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001761 private void assertSystemReady() {
1762 if (!mSystemReady) {
1763 throw new IllegalStateException("System not ready");
1764 }
1765 }
1766
Jeff Sharkey4190a042012-04-21 15:36:48 -07001767 private void assertBandwidthControlEnabled() {
1768 if (!isBandwidthControlEnabled()) {
1769 throw new IllegalStateException("Bandwidth module disabled");
1770 }
1771 }
1772
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001773 private boolean isBandwidthControlEnabled() {
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001774 final long token = Binder.clearCallingIdentity();
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001775 try {
1776 return mNetworkManager.isBandwidthControlEnabled();
1777 } catch (RemoteException e) {
1778 // ignored; service lives in system_server
1779 return false;
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001780 } finally {
1781 Binder.restoreCallingIdentity(token);
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001782 }
1783 }
1784
Jeff Sharkey63abc372012-01-11 18:38:16 -08001785 private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001786 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001787 public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
1788 int rightIndex, String cookie) {
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001789 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001790
1791 // record error for debugging
1792 final StringBuilder builder = new StringBuilder();
1793 builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
1794 + "] - right[" + rightIndex + "]\n");
1795 builder.append("left=").append(left).append('\n');
1796 builder.append("right=").append(right).append('\n');
1797
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001798 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1799 builder.toString());
1800 }
1801
1802 @Override
1803 public void foundNonMonotonic(
1804 NetworkStats stats, int statsIndex, String cookie) {
1805 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
1806
1807 final StringBuilder builder = new StringBuilder();
1808 builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
1809 builder.append("stats=").append(stats).append('\n');
1810
1811 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1812 builder.toString());
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001813 }
1814 }
1815
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001816 /**
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001817 * Default external settings that read from
Jeff Sharkey625239a2012-09-26 22:03:49 -07001818 * {@link android.provider.Settings.Global}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001819 */
1820 private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
1821 private final ContentResolver mResolver;
1822
1823 public DefaultNetworkStatsSettings(Context context) {
1824 mResolver = checkNotNull(context.getContentResolver());
1825 // TODO: adjust these timings for production builds
1826 }
1827
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001828 private long getGlobalLong(String name, long def) {
1829 return Settings.Global.getLong(mResolver, name, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001830 }
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001831 private boolean getGlobalBoolean(String name, boolean def) {
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001832 final int defInt = def ? 1 : 0;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001833 return Settings.Global.getInt(mResolver, name, defInt) != 0;
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001834 }
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001835
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001836 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001837 public long getPollInterval() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001838 return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001839 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001840 @Override
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001841 public long getGlobalAlertBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001842 return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001843 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001844 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001845 public boolean getSampleEnabled() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001846 return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001847 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001848 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -06001849 public boolean getAugmentEnabled() {
1850 return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
1851 }
1852 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001853 public Config getDevConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001854 return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
1855 getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1856 getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001857 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001858 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001859 public Config getXtConfig() {
1860 return getDevConfig();
1861 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001862 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001863 public Config getUidConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001864 return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1865 getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1866 getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001867 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001868 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001869 public Config getUidTagConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001870 return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1871 getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
1872 getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001873 }
1874 @Override
1875 public long getDevPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001876 return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001877 }
1878 @Override
1879 public long getXtPersistBytes(long def) {
1880 return getDevPersistBytes(def);
1881 }
1882 @Override
1883 public long getUidPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001884 return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001885 }
1886 @Override
1887 public long getUidTagPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001888 return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001889 }
1890 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001891
1892 private static int TYPE_RX_BYTES;
1893 private static int TYPE_RX_PACKETS;
1894 private static int TYPE_TX_BYTES;
1895 private static int TYPE_TX_PACKETS;
1896 private static int TYPE_TCP_RX_PACKETS;
1897 private static int TYPE_TCP_TX_PACKETS;
1898
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001899 private static native long nativeGetTotalStat(int type, boolean useBpfStats);
1900 private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
1901 private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
Jeff Sharkey75279902011-05-24 18:39:45 -07001902}