blob: 42802f6c3cec0574716bbcd71452187bc69c197c [file] [log] [blame]
Jeff Sharkey75279902011-05-24 18:39:45 -07001/*
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07002 * Copyright (C) 2011 The Android Open Source Project
Jeff Sharkey75279902011-05-24 18:39:45 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.net;
18
Jeff Sharkeya63ba592011-07-19 23:47:12 -070019import static android.Manifest.permission.ACCESS_NETWORK_STATE;
Jeff Sharkey63d27a92011-08-03 17:04:22 -070020import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070021import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070022import static android.content.Intent.ACTION_SHUTDOWN;
23import static android.content.Intent.ACTION_UID_REMOVED;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070024import static android.content.Intent.ACTION_USER_REMOVED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070025import static android.content.Intent.EXTRA_UID;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -070026import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
Jeff Sharkey234766a2012-04-10 19:48:07 -070027import static android.net.ConnectivityManager.isNetworkTypeMobile;
Chiachang Wangbd92d152019-04-09 23:24:41 -070028import static android.net.NetworkStack.checkNetworkStackPermission;
Lorenzo Colittiada23ed2018-01-19 01:05:20 +090029import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070030import static android.net.NetworkStats.IFACE_ALL;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090031import static android.net.NetworkStats.INTERFACES_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060032import static android.net.NetworkStats.METERED_ALL;
33import static android.net.NetworkStats.ROAMING_ALL;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070034import static android.net.NetworkStats.SET_ALL;
35import static android.net.NetworkStats.SET_DEFAULT;
36import static android.net.NetworkStats.SET_FOREGROUND;
Lorenzo Colitti5356a352017-08-17 19:23:08 +090037import static android.net.NetworkStats.STATS_PER_IFACE;
38import static android.net.NetworkStats.STATS_PER_UID;
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +090039import static android.net.NetworkStats.TAG_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070040import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey75279902011-05-24 18:39:45 -070041import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060042import static android.net.NetworkStatsHistory.FIELD_ALL;
Jeff Sharkey234766a2012-04-10 19:48:07 -070043import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070044import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -070045import static android.net.TrafficStats.KB_IN_BYTES;
Jeff Sharkey241dde22012-02-03 14:50:07 -080046import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey00072392018-04-12 14:26:32 -060047import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060048import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070049import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
50import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
51import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
52import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
53import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
54import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070055import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070056import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
57import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
58import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
59import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
60import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
61import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
62import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
63import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070064import static android.text.format.DateUtils.DAY_IN_MILLIS;
65import static android.text.format.DateUtils.HOUR_IN_MILLIS;
66import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070067import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jack Yuf9d559c2017-05-26 16:08:22 -070068
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070069import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070070import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070071import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
72import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
Jeff Sharkey75279902011-05-24 18:39:45 -070073
Jeff Sharkey9911a282018-02-14 22:29:11 -070074import android.annotation.NonNull;
Jeff Sharkey75279902011-05-24 18:39:45 -070075import android.app.AlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070076import android.app.PendingIntent;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060077import android.app.usage.NetworkStatsManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070078import android.content.BroadcastReceiver;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070079import android.content.ContentResolver;
Jeff Sharkey75279902011-05-24 18:39:45 -070080import android.content.Context;
81import android.content.Intent;
82import android.content.IntentFilter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070083import android.content.pm.ApplicationInfo;
84import android.content.pm.PackageManager;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080085import android.net.DataUsageRequest;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070086import android.net.INetworkManagementEventObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070087import android.net.INetworkStatsService;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -070088import android.net.INetworkStatsSession;
Jeff Sharkey63abc372012-01-11 18:38:16 -080089import android.net.LinkProperties;
Lorenzo Colittic78da292018-01-19 00:50:48 +090090import android.net.Network;
Jack Yub6587ea2016-06-22 11:35:10 -070091import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070092import android.net.NetworkIdentity;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070093import android.net.NetworkInfo;
94import android.net.NetworkState;
Jeff Sharkey75279902011-05-24 18:39:45 -070095import android.net.NetworkStats;
Jeff Sharkey5a7bcf32012-01-10 17:24:44 -080096import android.net.NetworkStats.NonMonotonicObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070097import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070098import android.net.NetworkTemplate;
Jeff Sharkey63abc372012-01-11 18:38:16 -080099import android.net.TrafficStats;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700100import android.os.BestClock;
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700101import android.os.Binder;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700102import android.os.DropBoxManager;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700103import android.os.Environment;
Jeff Sharkey75279902011-05-24 18:39:45 -0700104import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700105import android.os.HandlerThread;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800106import android.os.IBinder;
Jeff Sharkey75279902011-05-24 18:39:45 -0700107import android.os.INetworkManagementService;
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100108import android.os.Looper;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700109import android.os.Message;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800110import android.os.Messenger;
Jeff Sharkey62489262011-07-17 12:53:28 -0700111import android.os.PowerManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700112import android.os.RemoteException;
113import android.os.SystemClock;
Jeff Sharkey00072392018-04-12 14:26:32 -0600114import android.os.Trace;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700115import android.os.UserHandle;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700116import android.provider.Settings;
Jeff Sharkey625239a2012-09-26 22:03:49 -0700117import android.provider.Settings.Global;
Makoto Onukida65a522017-01-13 10:23:30 -0800118import android.service.NetworkInterfaceProto;
119import android.service.NetworkStatsServiceDumpProto;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600120import android.telephony.SubscriptionPlan;
Jeff Sharkey75279902011-05-24 18:39:45 -0700121import android.telephony.TelephonyManager;
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800122import android.text.format.DateUtils;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700123import android.util.ArrayMap;
124import android.util.ArraySet;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700125import android.util.EventLog;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700126import android.util.Log;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700127import android.util.MathUtils;
Jeff Sharkey75279902011-05-24 18:39:45 -0700128import android.util.Slog;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700129import android.util.SparseIntArray;
Makoto Onukida65a522017-01-13 10:23:30 -0800130import android.util.proto.ProtoOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -0700131
Jeff Sharkey4635f102017-09-01 11:27:13 -0600132import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800133import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700134import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600135import com.android.internal.util.DumpUtils;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800136import com.android.internal.util.FileRotator;
137import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700138import com.android.server.EventLogTags;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700139import com.android.server.LocalServices;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700140import com.android.server.connectivity.Tethering;
Jeff Sharkey75279902011-05-24 18:39:45 -0700141
Jeff Sharkey3f391352011-06-05 17:42:53 -0700142import java.io.File;
Jeff Sharkey75279902011-05-24 18:39:45 -0700143import java.io.FileDescriptor;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700144import java.io.IOException;
Jeff Sharkey75279902011-05-24 18:39:45 -0700145import java.io.PrintWriter;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700146import java.time.Clock;
147import java.time.ZoneOffset;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700148import java.util.Arrays;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700149import java.util.HashSet;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700150import java.util.List;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700151
Jeff Sharkey75279902011-05-24 18:39:45 -0700152/**
153 * Collect and persist detailed network statistics, and provide this data to
154 * other system services.
155 */
156public class NetworkStatsService extends INetworkStatsService.Stub {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600157 static final String TAG = "NetworkStats";
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700158 static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
159 static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700160
Chalard Jeand7c6e122018-08-22 10:21:26 +0900161 // Perform polling and persist all (FLAG_PERSIST_ALL).
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700162 private static final int MSG_PERFORM_POLL = 1;
Chalard Jeand7c6e122018-08-22 10:21:26 +0900163 // Perform polling, persist network, and register the global alert again.
164 private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700165
166 /** Flags to control detail level of poll event. */
Jeff Sharkey905b5892011-09-30 15:19:49 -0700167 private static final int FLAG_PERSIST_NETWORK = 0x1;
168 private static final int FLAG_PERSIST_UID = 0x2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700169 private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700170 private static final int FLAG_PERSIST_FORCE = 0x100;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700171
Chalard Jeand7c6e122018-08-22 10:21:26 +0900172 /**
173 * When global alert quota is high, wait for this delay before processing each polling,
174 * and do not schedule further polls once there is already one queued.
175 * This avoids firing the global alert too often on devices with high transfer speeds and
176 * high quota.
177 */
178 private static final int PERFORM_POLL_DELAY_MS = 1000;
179
Jeff Sharkey163e6442011-10-31 16:37:52 -0700180 private static final String TAG_NETSTATS_ERROR = "netstats_error";
181
Jeff Sharkey75279902011-05-24 18:39:45 -0700182 private final Context mContext;
183 private final INetworkManagementService mNetworkManager;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700184 private final AlarmManager mAlarmManager;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700185 private final Clock mClock;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700186 private final TelephonyManager mTeleManager;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700187 private final NetworkStatsSettings mSettings;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800188 private final NetworkStatsObservers mStatsObservers;
Jeff Sharkey75279902011-05-24 18:39:45 -0700189
Jeff Sharkey63abc372012-01-11 18:38:16 -0800190 private final File mSystemDir;
191 private final File mBaseDir;
192
Jeff Sharkey62489262011-07-17 12:53:28 -0700193 private final PowerManager.WakeLock mWakeLock;
194
Chenbo Feng00499822018-05-18 17:10:07 -0700195 private final boolean mUseBpfTrafficStats;
196
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800197 @VisibleForTesting
Jeff Sharkey3f391352011-06-05 17:42:53 -0700198 public static final String ACTION_NETWORK_STATS_POLL =
Jeff Sharkey75279902011-05-24 18:39:45 -0700199 "com.android.server.action.NETWORK_STATS_POLL";
Jeff Sharkey497e4432011-06-14 17:27:29 -0700200 public static final String ACTION_NETWORK_STATS_UPDATED =
201 "com.android.server.action.NETWORK_STATS_UPDATED";
Jeff Sharkey75279902011-05-24 18:39:45 -0700202
203 private PendingIntent mPollIntent;
204
Jeff Sharkey63abc372012-01-11 18:38:16 -0800205 private static final String PREFIX_DEV = "dev";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700206 private static final String PREFIX_XT = "xt";
Jeff Sharkey63abc372012-01-11 18:38:16 -0800207 private static final String PREFIX_UID = "uid";
208 private static final String PREFIX_UID_TAG = "uid_tag";
209
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700210 /**
Jack Yub6587ea2016-06-22 11:35:10 -0700211 * Virtual network interface for video telephony. This is for VT data usage counting purpose.
212 */
213 public static final String VT_INTERFACE = "vt_data0";
214
215 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700216 * Settings that can be changed externally.
217 */
218 public interface NetworkStatsSettings {
219 public long getPollInterval();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800220 public boolean getSampleEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600221 public boolean getAugmentEnabled();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800222
223 public static class Config {
224 public final long bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800225 public final long rotateAgeMillis;
226 public final long deleteAgeMillis;
227
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700228 public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800229 this.bucketDuration = bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800230 this.rotateAgeMillis = rotateAgeMillis;
231 this.deleteAgeMillis = deleteAgeMillis;
232 }
233 }
234
235 public Config getDevConfig();
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700236 public Config getXtConfig();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800237 public Config getUidConfig();
238 public Config getUidTagConfig();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700239
240 public long getGlobalAlertBytes(long def);
241 public long getDevPersistBytes(long def);
242 public long getXtPersistBytes(long def);
243 public long getUidPersistBytes(long def);
244 public long getUidTagPersistBytes(long def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700245 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700246
247 private final Object mStatsLock = new Object();
248
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700249 /** Set of currently active ifaces. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900250 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700251 private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900252
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700253 /** Set of currently active ifaces for UID stats. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900254 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700255 private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900256
Jeff Sharkey63abc372012-01-11 18:38:16 -0800257 /** Current default active iface. */
Varun Anand02c50ef2019-02-07 14:13:13 -0800258 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800259 private String mActiveIface;
Lorenzo Colittic78da292018-01-19 00:50:48 +0900260
Jeff Sharkey234766a2012-04-10 19:48:07 -0700261 /** Set of any ifaces associated with mobile networks since boot. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900262 @GuardedBy("mStatsLock")
Jeff Sharkey234766a2012-04-10 19:48:07 -0700263 private String[] mMobileIfaces = new String[0];
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700264
Lorenzo Colittic78da292018-01-19 00:50:48 +0900265 /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
266 @GuardedBy("mStatsLock")
267 private Network[] mDefaultNetworks = new Network[0];
268
Jeff Sharkey63abc372012-01-11 18:38:16 -0800269 private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
270 new DropBoxNonMonotonicObserver();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700271
Jeff Sharkey4635f102017-09-01 11:27:13 -0600272 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800273 private NetworkStatsRecorder mDevRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600274 @GuardedBy("mStatsLock")
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700275 private NetworkStatsRecorder mXtRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600276 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800277 private NetworkStatsRecorder mUidRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600278 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800279 private NetworkStatsRecorder mUidTagRecorder;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700280
Jeff Sharkey70c70532012-05-16 14:51:19 -0700281 /** Cached {@link #mXtRecorder} stats. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600282 @GuardedBy("mStatsLock")
Jeff Sharkey70c70532012-05-16 14:51:19 -0700283 private NetworkStatsCollection mXtStatsCached;
Jeff Sharkey75279902011-05-24 18:39:45 -0700284
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700285 /** Current counter sets for each UID. */
286 private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
287
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700288 /** Data layer operation counters for splicing into other structures. */
Jeff Sharkey63abc372012-01-11 18:38:16 -0800289 private NetworkStats mUidOperations = new NetworkStats(0L, 10);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700290
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800291 /** Must be set in factory by calling #setHandler. */
292 private Handler mHandler;
293 private Handler.Callback mHandlerCallback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700294
Jeff Sharkey050151e2018-04-13 14:28:30 -0600295 private volatile boolean mSystemReady;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700296 private long mPersistThreshold = 2 * MB_IN_BYTES;
297 private long mGlobalAlertBytes;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800298
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900299 private static final long POLL_RATE_LIMIT_MS = 15_000;
300
301 private long mLastStatsSessionPoll;
302
303 /** Map from UID to number of opened sessions */
304 @GuardedBy("mOpenSessionCallsPerUid")
305 private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
306
307 private final static int DUMP_STATS_SESSION_COUNT = 20;
308
Jeff Sharkey9911a282018-02-14 22:29:11 -0700309 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700310 return new File(Environment.getDataDirectory(), "system");
Jeff Sharkey75279902011-05-24 18:39:45 -0700311 }
312
Jeff Sharkey9911a282018-02-14 22:29:11 -0700313 private static @NonNull File getDefaultBaseDir() {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800314 File baseDir = new File(getDefaultSystemDir(), "netstats");
315 baseDir.mkdirs();
316 return baseDir;
317 }
318
Jeff Sharkey9911a282018-02-14 22:29:11 -0700319 private static @NonNull Clock getDefaultClock() {
320 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
321 Clock.systemUTC());
322 }
323
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100324 private static final class NetworkStatsHandler extends Handler {
325 NetworkStatsHandler(Looper looper, Handler.Callback callback) {
326 super(looper, callback);
327 }
328 }
329
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800330 public static NetworkStatsService create(Context context,
331 INetworkManagementService networkManager) {
332 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
333 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
334 PowerManager.WakeLock wakeLock =
335 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
336
337 NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700338 wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800339 new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
340 getDefaultSystemDir(), getDefaultBaseDir());
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900341 service.registerLocalService();
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800342
343 HandlerThread handlerThread = new HandlerThread(TAG);
344 Handler.Callback callback = new HandlerCallback(service);
345 handlerThread.start();
Olivier Gaillardf9867ad2018-09-10 15:35:58 +0100346 Handler handler = new NetworkStatsHandler(handlerThread.getLooper(), callback);
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800347 service.setHandler(handler, callback);
348 return service;
349 }
350
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900351 // This must not be called outside of tests, even within the same package, as this constructor
352 // does not register the local service. Use the create() helper above.
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800353 @VisibleForTesting
354 NetworkStatsService(Context context, INetworkManagementService networkManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700355 AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800356 TelephonyManager teleManager, NetworkStatsSettings settings,
357 NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
Jeff Sharkey75279902011-05-24 18:39:45 -0700358 mContext = checkNotNull(context, "missing Context");
359 mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800360 mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
Jeff Sharkey9911a282018-02-14 22:29:11 -0700361 mClock = checkNotNull(clock, "missing Clock");
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700362 mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800363 mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
364 mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
365 mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
366 mSystemDir = checkNotNull(systemDir, "missing systemDir");
367 mBaseDir = checkNotNull(baseDir, "missing baseDir");
Chenbo Feng6880d632018-12-22 13:20:31 -0800368 mUseBpfTrafficStats = new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists();
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900369 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700370
Remi NGUYEN VAN4cdb2b72018-04-26 17:52:03 +0900371 private void registerLocalService() {
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700372 LocalServices.addService(NetworkStatsManagerInternal.class,
373 new NetworkStatsManagerInternalImpl());
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800374 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700375
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800376 @VisibleForTesting
377 void setHandler(Handler handler, Handler.Callback callback) {
378 mHandler = handler;
379 mHandlerCallback = callback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700380 }
381
382 public void systemReady() {
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800383 mSystemReady = true;
384
Jeff Sharkey418d12d2011-12-13 15:38:03 -0800385 if (!isBandwidthControlEnabled()) {
386 Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
387 return;
388 }
389
Jeff Sharkey63abc372012-01-11 18:38:16 -0800390 synchronized (mStatsLock) {
Jeff Sharkey4635f102017-09-01 11:27:13 -0600391 // create data recorders along with historical rotators
392 mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
393 mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
394 mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
395 mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
396
397 updatePersistThresholdsLocked();
398
Jeff Sharkey63abc372012-01-11 18:38:16 -0800399 // upgrade any legacy stats, migrating them to rotated files
400 maybeUpgradeLegacyStatsLocked();
401
402 // read historical network stats from disk, since policy service
403 // might need them right away.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700404 mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800405
406 // bootstrap initial stats to prevent double-counting later
407 bootstrapStatsLocked();
408 }
Jeff Sharkey3359aca2011-11-08 18:08:48 -0800409
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700410 // watch for tethering changes
411 final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
Vinit Deshpande92d141f2014-09-10 18:05:10 -0700412 mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700413
Jeff Sharkey75279902011-05-24 18:39:45 -0700414 // listen for periodic polling events
415 final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700416 mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
Jeff Sharkey75279902011-05-24 18:39:45 -0700417
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700418 // listen for uid removal to clean stats
419 final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
420 mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
421
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700422 // listen for user changes to clean stats
423 final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
424 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
425
Jeff Sharkey75279902011-05-24 18:39:45 -0700426 // persist stats during clean shutdown
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700427 final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
428 mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
Jeff Sharkey75279902011-05-24 18:39:45 -0700429
430 try {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700431 mNetworkManager.registerObserver(mAlertObserver);
Jeff Sharkey75279902011-05-24 18:39:45 -0700432 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700433 // ignored; service lives in system_server
Jeff Sharkey75279902011-05-24 18:39:45 -0700434 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700435
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700436 registerPollAlarmLocked();
437 registerGlobalAlert();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800438 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700439
Jeff Sharkey63abc372012-01-11 18:38:16 -0800440 private NetworkStatsRecorder buildRecorder(
441 String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700442 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
443 Context.DROPBOX_SERVICE);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700444 return new NetworkStatsRecorder(new FileRotator(
445 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700446 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
Jeff Sharkey75279902011-05-24 18:39:45 -0700447 }
448
Andreas Gampea36dc622018-02-05 17:19:22 -0800449 @GuardedBy("mStatsLock")
Jeff Sharkey3f391352011-06-05 17:42:53 -0700450 private void shutdownLocked() {
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700451 mContext.unregisterReceiver(mTetherReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700452 mContext.unregisterReceiver(mPollReceiver);
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700453 mContext.unregisterReceiver(mRemovedReceiver);
Ryuki Nakamuraa47b0c92017-03-01 10:40:36 +0900454 mContext.unregisterReceiver(mUserReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700455 mContext.unregisterReceiver(mShutdownReceiver);
456
Jeff Sharkey9911a282018-02-14 22:29:11 -0700457 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800458
459 // persist any pending stats
460 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700461 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800462 mUidRecorder.forcePersistLocked(currentTime);
463 mUidTagRecorder.forcePersistLocked(currentTime);
464
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800465 mSystemReady = false;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800466 }
467
Andreas Gampea36dc622018-02-05 17:19:22 -0800468 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800469 private void maybeUpgradeLegacyStatsLocked() {
470 File file;
471 try {
472 file = new File(mSystemDir, "netstats.bin");
473 if (file.exists()) {
474 mDevRecorder.importLegacyNetworkLocked(file);
475 file.delete();
476 }
477
478 file = new File(mSystemDir, "netstats_xt.bin");
479 if (file.exists()) {
480 file.delete();
481 }
482
483 file = new File(mSystemDir, "netstats_uid.bin");
484 if (file.exists()) {
485 mUidRecorder.importLegacyUidLocked(file);
486 mUidTagRecorder.importLegacyUidLocked(file);
487 file.delete();
488 }
489 } catch (IOException e) {
490 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700491 } catch (OutOfMemoryError e) {
492 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeyc506ff62011-11-17 11:59:29 -0800493 }
Jeff Sharkey3f391352011-06-05 17:42:53 -0700494 }
495
Jeff Sharkey75279902011-05-24 18:39:45 -0700496 /**
497 * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700498 * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
Jeff Sharkey75279902011-05-24 18:39:45 -0700499 */
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700500 private void registerPollAlarmLocked() {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700501 if (mPollIntent != null) {
502 mAlarmManager.cancel(mPollIntent);
Jeff Sharkey75279902011-05-24 18:39:45 -0700503 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700504
505 mPollIntent = PendingIntent.getBroadcast(
506 mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
507
508 final long currentRealtime = SystemClock.elapsedRealtime();
509 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
510 mSettings.getPollInterval(), mPollIntent);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700511 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700512
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700513 /**
514 * Register for a global alert that is delivered through
515 * {@link INetworkManagementEventObserver} once a threshold amount of data
516 * has been transferred.
517 */
518 private void registerGlobalAlert() {
519 try {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700520 mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700521 } catch (IllegalStateException e) {
522 Slog.w(TAG, "problem registering for global alert: " + e);
523 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700524 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700525 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700526 }
527
528 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700529 public INetworkStatsSession openSession() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600530 // NOTE: if callers want to get non-augmented data, they should go
531 // through the public API
532 return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000533 }
534
535 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600536 public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
537 return openSessionInternal(flags, callingPackage);
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100538 }
539
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900540 private boolean isRateLimitedForPoll(int callingUid) {
541 if (callingUid == android.os.Process.SYSTEM_UID) {
542 return false;
543 }
544
545 final long lastCallTime;
546 final long now = SystemClock.elapsedRealtime();
547 synchronized (mOpenSessionCallsPerUid) {
548 int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
549 mOpenSessionCallsPerUid.put(callingUid, calls + 1);
550 lastCallTime = mLastStatsSessionPoll;
551 mLastStatsSessionPoll = now;
552 }
553
554 return now - lastCallTime < POLL_RATE_LIMIT_MS;
555 }
556
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600557 private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
Jeff Sharkey4190a042012-04-21 15:36:48 -0700558 assertBandwidthControlEnabled();
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700559
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900560 final int callingUid = Binder.getCallingUid();
561 final int usedFlags = isRateLimitedForPoll(callingUid)
562 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
563 : flags;
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600564 if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
565 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100566 final long ident = Binder.clearCallingIdentity();
567 try {
568 performPoll(FLAG_PERSIST_ALL);
569 } finally {
570 Binder.restoreCallingIdentity(ident);
571 }
572 }
573
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700574 // return an IBinder which holds strong references to any loaded stats
575 // for its lifetime; when caller closes only weak references remain.
576
577 return new INetworkStatsSession.Stub() {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900578 private final int mCallingUid = callingUid;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600579 private final String mCallingPackage = callingPackage;
580 private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
581 callingPackage);
582
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700583 private NetworkStatsCollection mUidComplete;
584 private NetworkStatsCollection mUidTagComplete;
585
586 private NetworkStatsCollection getUidComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700587 synchronized (mStatsLock) {
588 if (mUidComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700589 mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
590 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700591 return mUidComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700592 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700593 }
594
595 private NetworkStatsCollection getUidTagComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700596 synchronized (mStatsLock) {
597 if (mUidTagComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700598 mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
599 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700600 return mUidTagComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700601 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700602 }
603
604 @Override
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000605 public int[] getRelevantUids() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600606 return getUidComplete().getRelevantUids(mAccessLevel);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000607 }
608
609 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600610 public NetworkStats getDeviceSummaryForNetwork(
611 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900612 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600613 mCallingUid);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000614 }
615
616 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700617 public NetworkStats getSummaryForNetwork(
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);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700621 }
622
623 @Override
624 public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900625 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600626 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700627 }
628
629 @Override
630 public NetworkStats getSummaryForAllUid(
631 NetworkTemplate template, long start, long end, boolean includeTags) {
Jeff Davidson39583b52016-12-12 11:55:37 -0800632 try {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600633 final NetworkStats stats = getUidComplete()
634 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800635 if (includeTags) {
636 final NetworkStats tagStats = getUidTagComplete()
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600637 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800638 stats.combineAllValues(tagStats);
639 }
640 return stats;
641 } catch (NullPointerException e) {
642 // TODO: Track down and fix the cause of this crash and remove this catch block.
643 Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
644 throw e;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700645 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700646 }
647
648 @Override
649 public NetworkStatsHistory getHistoryForUid(
650 NetworkTemplate template, int uid, int set, int tag, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600651 // NOTE: We don't augment UID-level statistics
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700652 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600653 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
654 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700655 } else {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600656 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
657 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700658 }
659 }
660
661 @Override
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100662 public NetworkStatsHistory getHistoryIntervalForUid(
663 NetworkTemplate template, int uid, int set, int tag, int fields,
664 long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600665 // NOTE: We don't augment UID-level statistics
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100666 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600667 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
668 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700669 } else if (uid == Binder.getCallingUid()) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600670 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
671 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700672 } else {
673 throw new SecurityException("Calling package " + mCallingPackage
674 + " cannot access tag information from a different uid");
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100675 }
676 }
677
678 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700679 public void close() {
680 mUidComplete = null;
681 mUidTagComplete = null;
682 }
683 };
Jeff Sharkey905b5892011-09-30 15:19:49 -0700684 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700685
Jeff Davidson1efb1332015-12-09 18:04:50 -0800686 private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
687 return NetworkStatsAccess.checkAccessLevel(
688 mContext, Binder.getCallingUid(), callingPackage);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000689 }
690
Jeff Sharkey70c70532012-05-16 14:51:19 -0700691 /**
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600692 * Find the most relevant {@link SubscriptionPlan} for the given
693 * {@link NetworkTemplate} and flags. This is typically used to augment
694 * local measurement results to match a known anchor from the carrier.
695 */
696 private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
697 SubscriptionPlan plan = null;
698 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600699 && mSettings.getAugmentEnabled()) {
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700700 if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600701 final long token = Binder.clearCallingIdentity();
702 try {
Jeff Sharkey146bb332018-04-18 15:42:57 -0600703 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
704 .getSubscriptionPlan(template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600705 } finally {
706 Binder.restoreCallingIdentity(token);
707 }
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700708 if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600709 }
710 return plan;
711 }
712
713 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700714 * Return network summary, splicing between DEV and XT stats when
715 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700716 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600717 private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
718 long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700719 // We've been using pure XT stats long enough that we no longer need to
720 // splice DEV and XT together.
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600721 final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
722 accessLevel, callingUid);
723
724 final long now = System.currentTimeMillis();
725 final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
726
727 final NetworkStats stats = new NetworkStats(end - start, 1);
Lorenzo Colittiada23ed2018-01-19 01:05:20 +0900728 stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
729 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
730 entry.txBytes, entry.txPackets, entry.operations));
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600731 return stats;
Jeff Sharkey70c70532012-05-16 14:51:19 -0700732 }
733
734 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700735 * Return network history, splicing between DEV and XT stats when
736 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700737 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600738 private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
739 int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700740 // We've been using pure XT stats long enough that we no longer need to
741 // splice DEV and XT together.
Jeff Sharkey4635f102017-09-01 11:27:13 -0600742 final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
743 synchronized (mStatsLock) {
744 return mXtStatsCached.getHistory(template, augmentPlan,
745 UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
746 accessLevel, callingUid);
747 }
Jeff Sharkey70c70532012-05-16 14:51:19 -0700748 }
749
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700750 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
751 assertSystemReady();
Jeff Sharkey4190a042012-04-21 15:36:48 -0700752 assertBandwidthControlEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600753
754 // NOTE: if callers want to get non-augmented data, they should go
755 // through the public API
756 return internalGetSummaryForNetwork(template,
757 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
758 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700759 }
760
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700761 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
762 assertSystemReady();
763 assertBandwidthControlEnabled();
764
765 final NetworkStatsCollection uidComplete;
766 synchronized (mStatsLock) {
767 uidComplete = mUidRecorder.getOrLoadCompleteLocked();
768 }
769 return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
770 android.os.Process.SYSTEM_UID);
771 }
772
Jeff Sharkey350083e2011-06-29 10:45:16 -0700773 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700774 public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
775 if (Binder.getCallingUid() != uid) {
776 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
777 }
Jeff Sharkey4190a042012-04-21 15:36:48 -0700778 assertBandwidthControlEnabled();
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700779
780 // TODO: switch to data layer stats once kernel exports
781 // for now, read network layer stats and flatten across all ifaces
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800782 final long token = Binder.clearCallingIdentity();
783 final NetworkStats networkLayer;
784 try {
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900785 networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid,
786 NetworkStats.INTERFACES_ALL);
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800787 } finally {
788 Binder.restoreCallingIdentity(token);
789 }
790
Jeff Sharkey21a54782012-04-09 10:27:55 -0700791 // splice in operation counts
792 networkLayer.spliceOperationsFrom(mUidOperations);
793
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700794 final NetworkStats dataLayer = new NetworkStats(
795 networkLayer.getElapsedRealtime(), networkLayer.size());
796
797 NetworkStats.Entry entry = null;
798 for (int i = 0; i < networkLayer.size(); i++) {
799 entry = networkLayer.getValues(i, entry);
800 entry.iface = IFACE_ALL;
801 dataLayer.combineValues(entry);
802 }
803
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700804 return dataLayer;
805 }
806
807 @Override
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900808 public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
809 try {
810 final String[] ifacesToQuery =
Remi NGUYEN VAN9fb55e42018-02-27 16:47:22 +0900811 NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
Benedict Wong055992b2019-06-06 17:06:48 -0700812 return getNetworkStatsUidDetail(ifacesToQuery);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +0900813 } catch (RemoteException e) {
814 Log.wtf(TAG, "Error compiling UID stats", e);
815 return new NetworkStats(0L, 0);
816 }
817 }
818
819 @Override
Jeff Sharkey234766a2012-04-10 19:48:07 -0700820 public String[] getMobileIfaces() {
821 return mMobileIfaces;
822 }
823
824 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700825 public void incrementOperationCount(int uid, int tag, int operationCount) {
826 if (Binder.getCallingUid() != uid) {
Jeff Sharkey9f09e6a72017-06-26 11:24:47 -0600827 mContext.enforceCallingOrSelfPermission(
828 android.Manifest.permission.UPDATE_DEVICE_STATS, TAG);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700829 }
830
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700831 if (operationCount < 0) {
832 throw new IllegalArgumentException("operation count can only be incremented");
833 }
834 if (tag == TAG_NONE) {
835 throw new IllegalArgumentException("operation count must have specific tag");
836 }
837
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700838 synchronized (mStatsLock) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700839 final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800840 mUidOperations.combineValues(
841 mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
842 mUidOperations.combineValues(
843 mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700844 }
845 }
846
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700847 @VisibleForTesting
848 void setUidForeground(int uid, boolean uidForeground) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700849 synchronized (mStatsLock) {
850 final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
851 final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
852 if (oldSet != set) {
853 mActiveUidCounterSet.put(uid, set);
854 setKernelCounterSet(uid, set);
855 }
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700856 }
857 }
858
859 @Override
Varun Anand02c50ef2019-02-07 14:13:13 -0800860 public void forceUpdateIfaces(
861 Network[] defaultNetworks,
Varun Anand02c50ef2019-02-07 14:13:13 -0800862 NetworkState[] networkStates,
863 String activeIface) {
Chiachang Wangbd92d152019-04-09 23:24:41 -0700864 checkNetworkStackPermission(mContext);
Jeff Sharkey69736342014-12-08 14:50:12 -0800865 assertBandwidthControlEnabled();
866
867 final long token = Binder.clearCallingIdentity();
868 try {
Benedict Wongc9511e72019-06-12 17:46:31 +0000869 updateIfaces(defaultNetworks, networkStates, activeIface);
Jeff Sharkey69736342014-12-08 14:50:12 -0800870 } finally {
871 Binder.restoreCallingIdentity(token);
872 }
873 }
874
875 @Override
Jeff Sharkey350083e2011-06-29 10:45:16 -0700876 public void forceUpdate() {
877 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkey4190a042012-04-21 15:36:48 -0700878 assertBandwidthControlEnabled();
Jeff Sharkeye630f7b2012-01-31 17:12:53 -0800879
880 final long token = Binder.clearCallingIdentity();
881 try {
882 performPoll(FLAG_PERSIST_ALL);
883 } finally {
884 Binder.restoreCallingIdentity(token);
885 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700886 }
887
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700888 private void advisePersistThreshold(long thresholdBytes) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700889 assertBandwidthControlEnabled();
890
891 // clamp threshold into safe range
892 mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700893 if (LOGV) {
894 Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
895 + mPersistThreshold);
896 }
897
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700898 // update and persist if beyond new thresholds
Jeff Sharkey9911a282018-02-14 22:29:11 -0700899 final long currentTime = mClock.millis();
Jeff Sharkey58015972012-05-07 11:08:49 -0700900 synchronized (mStatsLock) {
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700901 if (!mSystemReady) return;
902
Jeff Sharkey4635f102017-09-01 11:27:13 -0600903 updatePersistThresholdsLocked();
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700904
Jeff Sharkey58015972012-05-07 11:08:49 -0700905 mDevRecorder.maybePersistLocked(currentTime);
906 mXtRecorder.maybePersistLocked(currentTime);
907 mUidRecorder.maybePersistLocked(currentTime);
908 mUidTagRecorder.maybePersistLocked(currentTime);
909 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700910
911 // re-arm global alert
912 registerGlobalAlert();
913 }
914
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800915 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700916 public DataUsageRequest registerUsageCallback(String callingPackage,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800917 DataUsageRequest request, Messenger messenger, IBinder binder) {
918 checkNotNull(callingPackage, "calling package is null");
919 checkNotNull(request, "DataUsageRequest is null");
Antonio Cansado6965c182016-03-30 11:37:18 -0700920 checkNotNull(request.template, "NetworkTemplate is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800921 checkNotNull(messenger, "messenger is null");
922 checkNotNull(binder, "binder is null");
923
924 int callingUid = Binder.getCallingUid();
925 @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
926 DataUsageRequest normalizedRequest;
927 final long token = Binder.clearCallingIdentity();
928 try {
929 normalizedRequest = mStatsObservers.register(request, messenger, binder,
930 callingUid, accessLevel);
931 } finally {
932 Binder.restoreCallingIdentity(token);
933 }
934
935 // Create baseline stats
Chalard Jeand7c6e122018-08-22 10:21:26 +0900936 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800937
938 return normalizedRequest;
939 }
940
941 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700942 public void unregisterUsageRequest(DataUsageRequest request) {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800943 checkNotNull(request, "DataUsageRequest is null");
944
945 int callingUid = Binder.getCallingUid();
946 final long token = Binder.clearCallingIdentity();
947 try {
948 mStatsObservers.unregister(request, callingUid);
949 } finally {
950 Binder.restoreCallingIdentity(token);
951 }
952 }
953
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800954 @Override
955 public long getUidStats(int uid, int type) {
Chenbo Fengaedd6a32017-11-20 18:23:46 -0800956 return nativeGetUidStat(uid, type, checkBpfStatsEnable());
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800957 }
958
959 @Override
960 public long getIfaceStats(String iface, int type) {
Mike SU1f9ed0b2018-11-26 15:05:13 +0800961 long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
962 if (nativeIfaceStats == -1) {
963 return nativeIfaceStats;
964 } else {
965 // When tethering offload is in use, nativeIfaceStats does not contain usage from
966 // offload, add it back here.
967 // When tethering offload is not in use, nativeIfaceStats contains tethering usage.
968 // this does not cause double-counting of tethering traffic, because
969 // NetdTetheringStatsProvider returns zero NetworkStats
970 // when called with STATS_PER_IFACE.
971 return nativeIfaceStats + getTetherStats(iface, type);
972 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800973 }
974
975 @Override
976 public long getTotalStats(int type) {
Mike SU1f9ed0b2018-11-26 15:05:13 +0800977 long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable());
978 if (nativeTotalStats == -1) {
979 return nativeTotalStats;
980 } else {
981 // Refer to comment in getIfaceStats
982 return nativeTotalStats + getTetherStats(IFACE_ALL, type);
983 }
984 }
985
986 private long getTetherStats(String iface, int type) {
987 final NetworkStats tetherSnapshot;
988 final long token = Binder.clearCallingIdentity();
989 try {
990 tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
991 } catch (RemoteException e) {
992 Slog.w(TAG, "Error get TetherStats: " + e);
993 return 0;
994 } finally {
995 Binder.restoreCallingIdentity(token);
996 }
997 HashSet<String> limitIfaces;
998 if (iface == IFACE_ALL) {
999 limitIfaces = null;
1000 } else {
1001 limitIfaces = new HashSet<String>();
1002 limitIfaces.add(iface);
1003 }
1004 NetworkStats.Entry entry = tetherSnapshot.getTotal(null, limitIfaces);
1005 if (LOGD) Slog.d(TAG, "TetherStats: iface=" + iface + " type=" + type +
1006 " entry=" + entry);
1007 switch (type) {
1008 case 0: // TYPE_RX_BYTES
1009 return entry.rxBytes;
1010 case 1: // TYPE_RX_PACKETS
1011 return entry.rxPackets;
1012 case 2: // TYPE_TX_BYTES
1013 return entry.txBytes;
1014 case 3: // TYPE_TX_PACKETS
1015 return entry.txPackets;
1016 default:
1017 return 0;
1018 }
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001019 }
1020
1021 private boolean checkBpfStatsEnable() {
Chenbo Feng00499822018-05-18 17:10:07 -07001022 return mUseBpfTrafficStats;
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001023 }
1024
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001025 /**
1026 * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
1027 * reflect current {@link #mPersistThreshold} value. Always defers to
Jeff Sharkey625239a2012-09-26 22:03:49 -07001028 * {@link Global} values when defined.
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001029 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001030 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001031 private void updatePersistThresholdsLocked() {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001032 mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
1033 mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
1034 mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
1035 mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
1036 mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
1037 }
1038
Jeff Sharkey75279902011-05-24 18:39:45 -07001039 /**
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001040 * Receiver that watches for {@link Tethering} to claim interface pairs.
1041 */
1042 private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
1043 @Override
1044 public void onReceive(Context context, Intent intent) {
1045 // on background handler thread, and verified CONNECTIVITY_INTERNAL
1046 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001047 performPoll(FLAG_PERSIST_NETWORK);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -07001048 }
1049 };
1050
Jeff Sharkey75279902011-05-24 18:39:45 -07001051 private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
1052 @Override
1053 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001054 // on background handler thread, and verified UPDATE_DEVICE_STATS
1055 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001056 performPoll(FLAG_PERSIST_ALL);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001057
1058 // verify that we're watching global alert
1059 registerGlobalAlert();
Jeff Sharkey75279902011-05-24 18:39:45 -07001060 }
1061 };
1062
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001063 private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
1064 @Override
1065 public void onReceive(Context context, Intent intent) {
1066 // on background handler thread, and UID_REMOVED is protected
1067 // broadcast.
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001068
1069 final int uid = intent.getIntExtra(EXTRA_UID, -1);
1070 if (uid == -1) return;
1071
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001072 synchronized (mStatsLock) {
Jeff Sharkey62489262011-07-17 12:53:28 -07001073 mWakeLock.acquire();
1074 try {
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001075 removeUidsLocked(uid);
1076 } finally {
1077 mWakeLock.release();
1078 }
1079 }
1080 }
1081 };
1082
1083 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1084 @Override
1085 public void onReceive(Context context, Intent intent) {
1086 // On background handler thread, and USER_REMOVED is protected
1087 // broadcast.
1088
1089 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1090 if (userId == -1) return;
1091
1092 synchronized (mStatsLock) {
1093 mWakeLock.acquire();
1094 try {
1095 removeUserLocked(userId);
Jeff Sharkey62489262011-07-17 12:53:28 -07001096 } finally {
1097 mWakeLock.release();
1098 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001099 }
1100 }
1101 };
1102
Jeff Sharkey75279902011-05-24 18:39:45 -07001103 private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
1104 @Override
1105 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001106 // SHUTDOWN is protected broadcast.
Jeff Sharkey75279902011-05-24 18:39:45 -07001107 synchronized (mStatsLock) {
Jeff Sharkey3f391352011-06-05 17:42:53 -07001108 shutdownLocked();
Jeff Sharkey75279902011-05-24 18:39:45 -07001109 }
1110 }
1111 };
1112
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001113 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001114 * Observer that watches for {@link INetworkManagementService} alerts.
1115 */
Jeff Sharkey216c1812012-08-05 14:29:23 -07001116 private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001117 @Override
1118 public void limitReached(String limitName, String iface) {
1119 // only someone like NMS should be calling us
1120 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1121
1122 if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001123 // kick off background poll to collect network stats unless there is already
1124 // such a call pending; UID stats are handled during normal polling interval.
1125 if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
1126 mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
1127 PERFORM_POLL_DELAY_MS);
1128 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001129 }
1130 }
1131 };
1132
Varun Anand02c50ef2019-02-07 14:13:13 -08001133 private void updateIfaces(
1134 Network[] defaultNetworks,
Varun Anand02c50ef2019-02-07 14:13:13 -08001135 NetworkState[] networkStates,
1136 String activeIface) {
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001137 synchronized (mStatsLock) {
1138 mWakeLock.acquire();
1139 try {
Varun Anand02c50ef2019-02-07 14:13:13 -08001140 mActiveIface = activeIface;
1141 updateIfacesLocked(defaultNetworks, networkStates);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001142 } finally {
1143 mWakeLock.release();
1144 }
1145 }
1146 }
1147
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001148 /**
Benedict Wongc9511e72019-06-12 17:46:31 +00001149 * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
1150 * NetworkStatsHistory}. When multiple {@link NetworkInfo} are active on a single {@code iface},
1151 * they are combined under a single {@link NetworkIdentitySet}.
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001152 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001153 @GuardedBy("mStatsLock")
Varun Anand02c50ef2019-02-07 14:13:13 -08001154 private void updateIfacesLocked(Network[] defaultNetworks, NetworkState[] states) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001155 if (!mSystemReady) return;
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001156 if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001157
1158 // take one last stats snapshot before updating iface mapping. this
1159 // isn't perfect, since the kernel may already be counting traffic from
1160 // the updated network.
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001161
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001162 // poll, but only persist network stats to keep codepath fast. UID stats
1163 // will be persisted during next alarm poll event.
1164 performPollLocked(FLAG_PERSIST_NETWORK);
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001165
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001166 // Rebuild active interfaces based on connected networks
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001167 mActiveIfaces.clear();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001168 mActiveUidIfaces.clear();
Lorenzo Colittic78da292018-01-19 00:50:48 +09001169 if (defaultNetworks != null) {
1170 // Caller is ConnectivityService. Update the list of default networks.
1171 mDefaultNetworks = defaultNetworks;
1172 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001173
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001174 final ArraySet<String> mobileIfaces = new ArraySet<>();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001175 for (NetworkState state : states) {
1176 if (state.networkInfo.isConnected()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001177 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001178 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
1179 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1180 isDefault);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001181
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001182 // Traffic occurring on the base interface is always counted for
1183 // both total usage and UID details.
1184 final String baseIface = state.linkProperties.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001185 if (baseIface != null) {
1186 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1187 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
Jack Yub6587ea2016-06-22 11:35:10 -07001188
1189 // Build a separate virtual interface for VT (Video Telephony) data usage.
1190 // Only do this when IMS is not metered, but VT is metered.
1191 // If IMS is metered, then the IMS network usage has already included VT usage.
1192 // VT is considered always metered in framework's layer. If VT is not metered
1193 // per carrier's policy, modem will report 0 usage for VT calls.
1194 if (state.networkCapabilities.hasCapability(
1195 NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1196
1197 // Copy the identify from IMS one but mark it as metered.
1198 NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1199 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001200 ident.getRoaming(), true /* metered */,
1201 true /* onDefaultNetwork */);
Jack Yub6587ea2016-06-22 11:35:10 -07001202 findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent);
1203 findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent);
1204 }
1205
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001206 if (isMobile) {
1207 mobileIfaces.add(baseIface);
1208 }
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001209 }
1210
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001211 // Traffic occurring on stacked interfaces is usually clatd,
1212 // which is already accounted against its final egress interface
1213 // by the kernel. Thus, we only need to collect stacked
1214 // interface stats at the UID level.
1215 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1216 for (LinkProperties stackedLink : stackedLinks) {
1217 final String stackedIface = stackedLink.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001218 if (stackedIface != null) {
1219 findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1220 if (isMobile) {
1221 mobileIfaces.add(stackedIface);
1222 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001223
1224 NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
Jeff Sharkey234766a2012-04-10 19:48:07 -07001225 }
1226 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001227 }
1228 }
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001229
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001230 mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1231 }
1232
1233 private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1234 ArrayMap<K, NetworkIdentitySet> map, K key) {
1235 NetworkIdentitySet ident = map.get(key);
1236 if (ident == null) {
1237 ident = new NetworkIdentitySet();
1238 map.put(key, ident);
1239 }
1240 return ident;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001241 }
1242
Andreas Gampea36dc622018-02-05 17:19:22 -08001243 @GuardedBy("mStatsLock")
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001244 private void recordSnapshotLocked(long currentTime) throws RemoteException {
1245 // snapshot and record current counters; read UID stats first to
Jack Yub6587ea2016-06-22 11:35:10 -07001246 // avoid over counting dev stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001247 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001248 final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
Jeff Sharkey00072392018-04-12 14:26:32 -06001249 Trace.traceEnd(TRACE_TAG_NETWORK);
1250 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
Jack Yuf9d559c2017-05-26 16:08:22 -07001251 final NetworkStats xtSnapshot = getNetworkStatsXt();
Jeff Sharkey00072392018-04-12 14:26:32 -06001252 Trace.traceEnd(TRACE_TAG_NETWORK);
1253 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001254 final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
Jeff Sharkey00072392018-04-12 14:26:32 -06001255 Trace.traceEnd(TRACE_TAG_NETWORK);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001256
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001257 // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1258 // providers that isn't already counted by dev and XT stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001259 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001260 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
Jeff Sharkey00072392018-04-12 14:26:32 -06001261 Trace.traceEnd(TRACE_TAG_NETWORK);
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001262 xtSnapshot.combineAllValues(tetherSnapshot);
1263 devSnapshot.combineAllValues(tetherSnapshot);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001264
1265 // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1266 // can't be reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001267 Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
Benedict Wong8cdd41e2019-06-13 10:54:38 -07001268 mDevRecorder.recordSnapshotLocked(devSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001269 Trace.traceEnd(TRACE_TAG_NETWORK);
1270 Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
Benedict Wong8cdd41e2019-06-13 10:54:38 -07001271 mXtRecorder.recordSnapshotLocked(xtSnapshot, mActiveIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001272 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001273
1274 // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001275 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
Benedict Wong8cdd41e2019-06-13 10:54:38 -07001276 mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001277 Trace.traceEnd(TRACE_TAG_NETWORK);
1278 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
Benedict Wong8cdd41e2019-06-13 10:54:38 -07001279 mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001280 Trace.traceEnd(TRACE_TAG_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001281
1282 // We need to make copies of member fields that are sent to the observer to avoid
1283 // a race condition between the service handler thread and the observer's
1284 mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
Benedict Wong8cdd41e2019-06-13 10:54:38 -07001285 new ArrayMap<>(mActiveUidIfaces), currentTime);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001286 }
1287
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001288 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001289 * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1290 * so we have baseline values without double-counting.
1291 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001292 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001293 private void bootstrapStatsLocked() {
Jeff Sharkey9911a282018-02-14 22:29:11 -07001294 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001295
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001296 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001297 recordSnapshotLocked(currentTime);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001298 } catch (IllegalStateException e) {
1299 Slog.w(TAG, "problem reading network stats: " + e);
1300 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001301 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001302 }
1303 }
1304
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001305 private void performPoll(int flags) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001306 synchronized (mStatsLock) {
1307 mWakeLock.acquire();
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001308
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001309 try {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001310 performPollLocked(flags);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001311 } finally {
1312 mWakeLock.release();
1313 }
1314 }
1315 }
1316
1317 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001318 * Periodic poll operation, reading current statistics and recording into
1319 * {@link NetworkStatsHistory}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001320 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001321 @GuardedBy("mStatsLock")
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001322 private void performPollLocked(int flags) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001323 if (!mSystemReady) return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001324 if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
Jeff Sharkey00072392018-04-12 14:26:32 -06001325 Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
Jeff Sharkey75279902011-05-24 18:39:45 -07001326
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001327 final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1328 final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001329 final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001330
Jeff Sharkey75279902011-05-24 18:39:45 -07001331 // TODO: consider marking "untrusted" times in historical stats
Jeff Sharkey9911a282018-02-14 22:29:11 -07001332 final long currentTime = mClock.millis();
Jeff Sharkey75279902011-05-24 18:39:45 -07001333
Jeff Sharkey75279902011-05-24 18:39:45 -07001334 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001335 recordSnapshotLocked(currentTime);
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001336 } catch (IllegalStateException e) {
1337 Log.wtf(TAG, "problem reading network stats", e);
Jeff Sharkey905b5892011-09-30 15:19:49 -07001338 return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001339 } catch (RemoteException e) {
1340 // ignored; service lives in system_server
Jeff Sharkey905b5892011-09-30 15:19:49 -07001341 return;
1342 }
1343
Jeff Sharkey63abc372012-01-11 18:38:16 -08001344 // persist any pending data depending on requested flags
Jeff Sharkey00072392018-04-12 14:26:32 -06001345 Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001346 if (persistForce) {
1347 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001348 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001349 mUidRecorder.forcePersistLocked(currentTime);
1350 mUidTagRecorder.forcePersistLocked(currentTime);
1351 } else {
1352 if (persistNetwork) {
1353 mDevRecorder.maybePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001354 mXtRecorder.maybePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001355 }
1356 if (persistUid) {
1357 mUidRecorder.maybePersistLocked(currentTime);
1358 mUidTagRecorder.maybePersistLocked(currentTime);
1359 }
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001360 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001361 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001362
Jeff Sharkey63abc372012-01-11 18:38:16 -08001363 if (mSettings.getSampleEnabled()) {
Jeff Sharkey905b5892011-09-30 15:19:49 -07001364 // sample stats after each full poll
Jeff Sharkey63abc372012-01-11 18:38:16 -08001365 performSampleLocked();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001366 }
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001367
Jeff Sharkey497e4432011-06-14 17:27:29 -07001368 // finally, dispatch updated event to any listeners
1369 final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
1370 updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001371 mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
1372 READ_NETWORK_USAGE_HISTORY);
Jeff Sharkey00072392018-04-12 14:26:32 -06001373
1374 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001375 }
1376
1377 /**
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001378 * Sample recent statistics summary into {@link EventLog}.
1379 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001380 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001381 private void performSampleLocked() {
1382 // TODO: migrate trustedtime fixes to separate binary log events
Jeff Sharkey9911a282018-02-14 22:29:11 -07001383 final long currentTime = mClock.millis();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001384
Jeff Sharkey63abc372012-01-11 18:38:16 -08001385 NetworkTemplate template;
1386 NetworkStats.Entry devTotal;
1387 NetworkStats.Entry xtTotal;
1388 NetworkStats.Entry uidTotal;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001389
1390 // collect mobile sample
Jeff Sharkey234766a2012-04-10 19:48:07 -07001391 template = buildTemplateMobileWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001392 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001393 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001394 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001395
Jeff Sharkey905b5892011-09-30 15:19:49 -07001396 EventLogTags.writeNetstatsMobileSample(
1397 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1398 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1399 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001400 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001401
1402 // collect wifi sample
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001403 template = buildTemplateWifiWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001404 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001405 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001406 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1407
Jeff Sharkey905b5892011-09-30 15:19:49 -07001408 EventLogTags.writeNetstatsWifiSample(
1409 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1410 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1411 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001412 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001413 }
1414
1415 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001416 * Clean up {@link #mUidRecorder} after UID is removed.
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001417 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001418 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001419 private void removeUidsLocked(int... uids) {
1420 if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1421
1422 // Perform one last poll before removing
Jeff Sharkey163e6442011-10-31 16:37:52 -07001423 performPollLocked(FLAG_PERSIST_ALL);
1424
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001425 mUidRecorder.removeUidsLocked(uids);
1426 mUidTagRecorder.removeUidsLocked(uids);
Jeff Sharkey163e6442011-10-31 16:37:52 -07001427
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001428 // Clear kernel stats associated with UID
1429 for (int uid : uids) {
1430 resetKernelUidStats(uid);
1431 }
1432 }
1433
1434 /**
1435 * Clean up {@link #mUidRecorder} after user is removed.
1436 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001437 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001438 private void removeUserLocked(int userId) {
1439 if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1440
1441 // Build list of UIDs that we should clean up
1442 int[] uids = new int[0];
1443 final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001444 PackageManager.MATCH_ANY_USER
1445 | PackageManager.MATCH_DISABLED_COMPONENTS);
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001446 for (ApplicationInfo app : apps) {
1447 final int uid = UserHandle.getUid(userId, app.uid);
1448 uids = ArrayUtils.appendInt(uids, uid);
1449 }
1450
1451 removeUidsLocked(uids);
Jeff Sharkey75279902011-05-24 18:39:45 -07001452 }
1453
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001454 private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
1455 @Override
1456 public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001457 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
1458 try {
1459 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
1460 } finally {
1461 Trace.traceEnd(TRACE_TAG_NETWORK);
1462 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001463 }
1464
1465 @Override
1466 public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001467 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
1468 try {
1469 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
1470 } finally {
1471 Trace.traceEnd(TRACE_TAG_NETWORK);
1472 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001473 }
1474
1475 @Override
1476 public void setUidForeground(int uid, boolean uidForeground) {
1477 NetworkStatsService.this.setUidForeground(uid, uidForeground);
1478 }
1479
1480 @Override
1481 public void advisePersistThreshold(long thresholdBytes) {
1482 NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
1483 }
1484
1485 @Override
1486 public void forceUpdate() {
1487 NetworkStatsService.this.forceUpdate();
1488 }
1489 }
1490
Jeff Sharkey75279902011-05-24 18:39:45 -07001491 @Override
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001492 protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001493 if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
Jeff Sharkey75279902011-05-24 18:39:45 -07001494
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001495 long duration = DateUtils.DAY_IN_MILLIS;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001496 final HashSet<String> argSet = new HashSet<String>();
1497 for (String arg : args) {
1498 argSet.add(arg);
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001499
1500 if (arg.startsWith("--duration=")) {
1501 try {
1502 duration = Long.parseLong(arg.substring(11));
1503 } catch (NumberFormatException ignored) {
1504 }
1505 }
Jeff Sharkey75279902011-05-24 18:39:45 -07001506 }
1507
Jeff Sharkey706498d2012-02-06 17:35:07 -08001508 // usage: dumpsys netstats --full --uid --tag --poll --checkin
Jeff Sharkey63abc372012-01-11 18:38:16 -08001509 final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
Jeff Sharkey706498d2012-02-06 17:35:07 -08001510 final boolean checkin = argSet.contains("--checkin");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001511 final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1512 final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1513 final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1514
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001515 final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
Jeff Sharkey350083e2011-06-29 10:45:16 -07001516
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001517 synchronized (mStatsLock) {
Makoto Onukida65a522017-01-13 10:23:30 -08001518 if (args.length > 0 && "--proto".equals(args[0])) {
1519 // In this case ignore all other arguments.
Jeff Sharkey4635f102017-09-01 11:27:13 -06001520 dumpProtoLocked(fd);
Makoto Onukida65a522017-01-13 10:23:30 -08001521 return;
1522 }
1523
Jeff Sharkey63abc372012-01-11 18:38:16 -08001524 if (poll) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001525 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
Jeff Sharkey3f391352011-06-05 17:42:53 -07001526 pw.println("Forced poll");
1527 return;
1528 }
1529
Jeff Sharkey706498d2012-02-06 17:35:07 -08001530 if (checkin) {
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001531 final long end = System.currentTimeMillis();
1532 final long start = end - duration;
1533
1534 pw.print("v1,");
1535 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1536 pw.print(end / SECOND_IN_MILLIS); pw.println();
1537
1538 pw.println("xt");
1539 mXtRecorder.dumpCheckin(rawWriter, start, end);
1540
1541 if (includeUid) {
1542 pw.println("uid");
1543 mUidRecorder.dumpCheckin(rawWriter, start, end);
Jeff Sharkey706498d2012-02-06 17:35:07 -08001544 }
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001545 if (includeTag) {
1546 pw.println("tag");
1547 mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1548 }
Jeff Sharkey706498d2012-02-06 17:35:07 -08001549 return;
1550 }
1551
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001552 pw.println("Active interfaces:");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001553 pw.increaseIndent();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001554 for (int i = 0; i < mActiveIfaces.size(); i++) {
1555 pw.printPair("iface", mActiveIfaces.keyAt(i));
1556 pw.printPair("ident", mActiveIfaces.valueAt(i));
1557 pw.println();
1558 }
1559 pw.decreaseIndent();
1560
1561 pw.println("Active UID interfaces:");
1562 pw.increaseIndent();
1563 for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1564 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1565 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1566 pw.println();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001567 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001568 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001569
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +09001570 // Get the top openSession callers
1571 final SparseIntArray calls;
1572 synchronized (mOpenSessionCallsPerUid) {
1573 calls = mOpenSessionCallsPerUid.clone();
1574 }
1575
1576 final int N = calls.size();
1577 final long[] values = new long[N];
1578 for (int j = 0; j < N; j++) {
1579 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
1580 }
1581 Arrays.sort(values);
1582
1583 pw.println("Top openSession callers (uid=count):");
1584 pw.increaseIndent();
1585 final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
1586 for (int j = N - 1; j >= end; j--) {
1587 final int uid = (int) (values[j] & 0xffffffff);
1588 final int count = (int) (values[j] >> 32);
1589 pw.print(uid); pw.print("="); pw.println(count);
1590 }
1591 pw.decreaseIndent();
1592 pw.println();
1593
Jeff Sharkey63abc372012-01-11 18:38:16 -08001594 pw.println("Dev stats:");
1595 pw.increaseIndent();
1596 mDevRecorder.dumpLocked(pw, fullHistory);
1597 pw.decreaseIndent();
1598
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001599 pw.println("Xt stats:");
1600 pw.increaseIndent();
1601 mXtRecorder.dumpLocked(pw, fullHistory);
1602 pw.decreaseIndent();
1603
Jeff Sharkey63abc372012-01-11 18:38:16 -08001604 if (includeUid) {
1605 pw.println("UID stats:");
1606 pw.increaseIndent();
1607 mUidRecorder.dumpLocked(pw, fullHistory);
1608 pw.decreaseIndent();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001609 }
1610
Jeff Sharkey63abc372012-01-11 18:38:16 -08001611 if (includeTag) {
1612 pw.println("UID tag stats:");
1613 pw.increaseIndent();
1614 mUidTagRecorder.dumpLocked(pw, fullHistory);
1615 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001616 }
1617 }
1618 }
1619
Andreas Gampea36dc622018-02-05 17:19:22 -08001620 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001621 private void dumpProtoLocked(FileDescriptor fd) {
Makoto Onukida65a522017-01-13 10:23:30 -08001622 final ProtoOutputStream proto = new ProtoOutputStream(fd);
1623
1624 // TODO Right now it writes all history. Should it limit to the "since-boot" log?
1625
1626 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1627 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
1628 mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1629 mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1630 mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1631 mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
1632
1633 proto.flush();
1634 }
1635
1636 private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1637 ArrayMap<String, NetworkIdentitySet> ifaces) {
1638 for (int i = 0; i < ifaces.size(); i++) {
1639 final long start = proto.start(tag);
1640
1641 proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
1642 ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
1643
1644 proto.end(start);
1645 }
1646 }
1647
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001648 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001649 * Return snapshot of current UID statistics, including any
Jack Yuf9d559c2017-05-26 16:08:22 -07001650 * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1651 * values.
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001652 *
1653 * @param ifaces A list of interfaces the stats should be restricted to, or
1654 * {@link NetworkStats#INTERFACES_ALL}.
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001655 */
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001656 private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
1657 throws RemoteException {
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001658 final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL,
1659 ifaces);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001660
Jeff Sharkey63abc372012-01-11 18:38:16 -08001661 // fold tethering stats and operations into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001662 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001663 tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
junyulaic33ac0d2018-10-19 21:14:30 +08001664 NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot,
1665 mUseBpfTrafficStats);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001666 uidSnapshot.combineAllValues(tetherSnapshot);
Jack Yuf9d559c2017-05-26 16:08:22 -07001667
1668 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
1669 Context.TELEPHONY_SERVICE);
1670
1671 // fold video calling data usage stats into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001672 final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
Jack Yuf9d559c2017-05-26 16:08:22 -07001673 if (vtStats != null) {
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001674 vtStats.filter(UID_ALL, ifaces, TAG_ALL);
junyulaic33ac0d2018-10-19 21:14:30 +08001675 NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats,
1676 mUseBpfTrafficStats);
Jack Yuf9d559c2017-05-26 16:08:22 -07001677 uidSnapshot.combineAllValues(vtStats);
1678 }
Remi NGUYEN VAN088ff682018-03-06 12:36:54 +09001679
Jeff Sharkey63abc372012-01-11 18:38:16 -08001680 uidSnapshot.combineAllValues(mUidOperations);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001681
Jeff Sharkey63abc372012-01-11 18:38:16 -08001682 return uidSnapshot;
Jeff Sharkey75279902011-05-24 18:39:45 -07001683 }
1684
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001685 /**
Jack Yuf9d559c2017-05-26 16:08:22 -07001686 * Return snapshot of current XT statistics with video calling data usage statistics.
Jack Yub6587ea2016-06-22 11:35:10 -07001687 */
Jack Yuf9d559c2017-05-26 16:08:22 -07001688 private NetworkStats getNetworkStatsXt() throws RemoteException {
Jack Yub6587ea2016-06-22 11:35:10 -07001689 final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
1690
Jack Yuf9d559c2017-05-26 16:08:22 -07001691 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Jack Yub6587ea2016-06-22 11:35:10 -07001692 Context.TELEPHONY_SERVICE);
1693
Jack Yuf9d559c2017-05-26 16:08:22 -07001694 // Merge video calling data usage into XT
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001695 final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
Jack Yuf9d559c2017-05-26 16:08:22 -07001696 if (vtSnapshot != null) {
1697 xtSnapshot.combineAllValues(vtSnapshot);
1698 }
Jack Yub6587ea2016-06-22 11:35:10 -07001699
1700 return xtSnapshot;
1701 }
1702
1703 /**
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001704 * Return snapshot of current tethering statistics. Will return empty
1705 * {@link NetworkStats} if any problems are encountered.
1706 */
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001707 private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001708 try {
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001709 return mNetworkManager.getNetworkStatsTethering(how);
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001710 } catch (IllegalStateException e) {
1711 Log.wtf(TAG, "problem reading network stats", e);
1712 return new NetworkStats(0L, 10);
1713 }
1714 }
1715
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001716 @VisibleForTesting
1717 static class HandlerCallback implements Handler.Callback {
1718 private final NetworkStatsService mService;
1719
1720 HandlerCallback(NetworkStatsService service) {
1721 this.mService = service;
1722 }
1723
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001724 @Override
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001725 public boolean handleMessage(Message msg) {
1726 switch (msg.what) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001727 case MSG_PERFORM_POLL: {
Chalard Jeand7c6e122018-08-22 10:21:26 +09001728 mService.performPoll(FLAG_PERSIST_ALL);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001729 return true;
1730 }
Chalard Jeand7c6e122018-08-22 10:21:26 +09001731 case MSG_PERFORM_POLL_REGISTER_ALERT: {
1732 mService.performPoll(FLAG_PERSIST_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001733 mService.registerGlobalAlert();
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -08001734 return true;
1735 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001736 default: {
1737 return false;
1738 }
1739 }
1740 }
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001741 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001742
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001743 private void assertSystemReady() {
1744 if (!mSystemReady) {
1745 throw new IllegalStateException("System not ready");
1746 }
1747 }
1748
Jeff Sharkey4190a042012-04-21 15:36:48 -07001749 private void assertBandwidthControlEnabled() {
1750 if (!isBandwidthControlEnabled()) {
1751 throw new IllegalStateException("Bandwidth module disabled");
1752 }
1753 }
1754
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001755 private boolean isBandwidthControlEnabled() {
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001756 final long token = Binder.clearCallingIdentity();
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001757 try {
1758 return mNetworkManager.isBandwidthControlEnabled();
1759 } catch (RemoteException e) {
1760 // ignored; service lives in system_server
1761 return false;
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001762 } finally {
1763 Binder.restoreCallingIdentity(token);
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001764 }
1765 }
1766
Jeff Sharkey63abc372012-01-11 18:38:16 -08001767 private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001768 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001769 public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
1770 int rightIndex, String cookie) {
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001771 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001772
1773 // record error for debugging
1774 final StringBuilder builder = new StringBuilder();
1775 builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
1776 + "] - right[" + rightIndex + "]\n");
1777 builder.append("left=").append(left).append('\n');
1778 builder.append("right=").append(right).append('\n');
1779
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001780 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1781 builder.toString());
1782 }
1783
1784 @Override
1785 public void foundNonMonotonic(
1786 NetworkStats stats, int statsIndex, String cookie) {
1787 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
1788
1789 final StringBuilder builder = new StringBuilder();
1790 builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
1791 builder.append("stats=").append(stats).append('\n');
1792
1793 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1794 builder.toString());
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001795 }
1796 }
1797
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001798 /**
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001799 * Default external settings that read from
Jeff Sharkey625239a2012-09-26 22:03:49 -07001800 * {@link android.provider.Settings.Global}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001801 */
1802 private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
1803 private final ContentResolver mResolver;
1804
1805 public DefaultNetworkStatsSettings(Context context) {
1806 mResolver = checkNotNull(context.getContentResolver());
1807 // TODO: adjust these timings for production builds
1808 }
1809
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001810 private long getGlobalLong(String name, long def) {
1811 return Settings.Global.getLong(mResolver, name, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001812 }
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001813 private boolean getGlobalBoolean(String name, boolean def) {
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001814 final int defInt = def ? 1 : 0;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001815 return Settings.Global.getInt(mResolver, name, defInt) != 0;
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001816 }
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001817
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001818 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001819 public long getPollInterval() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001820 return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001821 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001822 @Override
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001823 public long getGlobalAlertBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001824 return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001825 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001826 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001827 public boolean getSampleEnabled() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001828 return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001829 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001830 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -06001831 public boolean getAugmentEnabled() {
1832 return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
1833 }
1834 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001835 public Config getDevConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001836 return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
1837 getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1838 getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001839 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001840 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001841 public Config getXtConfig() {
1842 return getDevConfig();
1843 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001844 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001845 public Config getUidConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001846 return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1847 getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1848 getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001849 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001850 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001851 public Config getUidTagConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001852 return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1853 getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
1854 getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001855 }
1856 @Override
1857 public long getDevPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001858 return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001859 }
1860 @Override
1861 public long getXtPersistBytes(long def) {
1862 return getDevPersistBytes(def);
1863 }
1864 @Override
1865 public long getUidPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001866 return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001867 }
1868 @Override
1869 public long getUidTagPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001870 return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001871 }
1872 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001873
1874 private static int TYPE_RX_BYTES;
1875 private static int TYPE_RX_PACKETS;
1876 private static int TYPE_TX_BYTES;
1877 private static int TYPE_TX_PACKETS;
1878 private static int TYPE_TCP_RX_PACKETS;
1879 private static int TYPE_TCP_TX_PACKETS;
1880
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001881 private static native long nativeGetTotalStat(int type, boolean useBpfStats);
1882 private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
1883 private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
Jeff Sharkey75279902011-05-24 18:39:45 -07001884}