blob: 9bf3874088d7cfd7f4ada8308ebbed269240bddd [file] [log] [blame]
Jeff Sharkey75279902011-05-24 18:39:45 -07001/*
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07002 * Copyright (C) 2011 The Android Open Source Project
Jeff Sharkey75279902011-05-24 18:39:45 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.net;
18
Jeff Sharkeya63ba592011-07-19 23:47:12 -070019import static android.Manifest.permission.ACCESS_NETWORK_STATE;
Jeff Sharkey63d27a92011-08-03 17:04:22 -070020import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
Jeff Sharkey21c9c452011-06-07 12:26:43 -070021import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070022import static android.content.Intent.ACTION_SHUTDOWN;
23import static android.content.Intent.ACTION_UID_REMOVED;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070024import static android.content.Intent.ACTION_USER_REMOVED;
Jeff Sharkeyb09540f2011-06-19 01:08:12 -070025import static android.content.Intent.EXTRA_UID;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -070026import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED;
Jeff Sharkey234766a2012-04-10 19:48:07 -070027import static android.net.ConnectivityManager.isNetworkTypeMobile;
Lorenzo Colittiada23ed2018-01-19 01:05:20 +090028import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070029import static android.net.NetworkStats.IFACE_ALL;
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +090030import static android.net.NetworkStats.INTERFACES_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060031import static android.net.NetworkStats.METERED_ALL;
32import static android.net.NetworkStats.ROAMING_ALL;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070033import static android.net.NetworkStats.SET_ALL;
34import static android.net.NetworkStats.SET_DEFAULT;
35import static android.net.NetworkStats.SET_FOREGROUND;
Lorenzo Colitti5356a352017-08-17 19:23:08 +090036import static android.net.NetworkStats.STATS_PER_IFACE;
37import static android.net.NetworkStats.STATS_PER_UID;
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +090038import static android.net.NetworkStats.TAG_ALL;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070039import static android.net.NetworkStats.TAG_NONE;
Jeff Sharkey75279902011-05-24 18:39:45 -070040import static android.net.NetworkStats.UID_ALL;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060041import static android.net.NetworkStatsHistory.FIELD_ALL;
Jeff Sharkey234766a2012-04-10 19:48:07 -070042import static android.net.NetworkTemplate.buildTemplateMobileWildcard;
Jeff Sharkey8fc27e82012-04-04 20:40:58 -070043import static android.net.NetworkTemplate.buildTemplateWifiWildcard;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -070044import static android.net.TrafficStats.KB_IN_BYTES;
Jeff Sharkey241dde22012-02-03 14:50:07 -080045import static android.net.TrafficStats.MB_IN_BYTES;
Jeff Sharkey00072392018-04-12 14:26:32 -060046import static android.os.Trace.TRACE_TAG_NETWORK;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060047import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070048import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION;
49import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE;
50import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES;
51import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE;
52import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES;
53import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070054import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED;
Jeff Sharkey023c05a2012-09-14 13:09:57 -070055import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
56import static android.provider.Settings.Global.NETSTATS_UID_DELETE_AGE;
57import static android.provider.Settings.Global.NETSTATS_UID_PERSIST_BYTES;
58import static android.provider.Settings.Global.NETSTATS_UID_ROTATE_AGE;
59import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION;
60import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE;
61import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES;
62import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -070063import static android.text.format.DateUtils.DAY_IN_MILLIS;
64import static android.text.format.DateUtils.HOUR_IN_MILLIS;
65import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
Jeff Sharkey367d15a2011-09-22 14:59:51 -070066import static android.text.format.DateUtils.SECOND_IN_MILLIS;
Jack Yuf9d559c2017-05-26 16:08:22 -070067
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070068import static com.android.internal.util.Preconditions.checkNotNull;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070069import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -070070import static com.android.server.NetworkManagementSocketTagger.resetKernelUidStats;
71import static com.android.server.NetworkManagementSocketTagger.setKernelCounterSet;
Jeff Sharkey75279902011-05-24 18:39:45 -070072
Jeff Sharkey9911a282018-02-14 22:29:11 -070073import android.annotation.NonNull;
Jeff Sharkey75279902011-05-24 18:39:45 -070074import android.app.AlarmManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070075import android.app.PendingIntent;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -060076import android.app.usage.NetworkStatsManager;
Jeff Sharkey75279902011-05-24 18:39:45 -070077import android.content.BroadcastReceiver;
Jeff Sharkey39ebc212011-06-11 17:25:42 -070078import android.content.ContentResolver;
Jeff Sharkey75279902011-05-24 18:39:45 -070079import android.content.Context;
80import android.content.Intent;
81import android.content.IntentFilter;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -070082import android.content.pm.ApplicationInfo;
83import android.content.pm.PackageManager;
Antonio Cansadocd42acd2016-02-17 13:03:38 -080084import android.net.DataUsageRequest;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070085import android.net.IConnectivityManager;
Jeff Sharkey8e9992a2011-08-23 18:37:23 -070086import android.net.INetworkManagementEventObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070087import android.net.INetworkStatsService;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -070088import android.net.INetworkStatsSession;
Jeff Sharkey63abc372012-01-11 18:38:16 -080089import android.net.LinkProperties;
Lorenzo Colittic78da292018-01-19 00:50:48 +090090import android.net.Network;
Jack Yub6587ea2016-06-22 11:35:10 -070091import android.net.NetworkCapabilities;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070092import android.net.NetworkIdentity;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -070093import android.net.NetworkInfo;
94import android.net.NetworkState;
Jeff Sharkey75279902011-05-24 18:39:45 -070095import android.net.NetworkStats;
Jeff Sharkey5a7bcf32012-01-10 17:24:44 -080096import android.net.NetworkStats.NonMonotonicObserver;
Jeff Sharkey75279902011-05-24 18:39:45 -070097import android.net.NetworkStatsHistory;
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -070098import android.net.NetworkTemplate;
Jeff Sharkey63abc372012-01-11 18:38:16 -080099import android.net.TrafficStats;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700100import android.os.BestClock;
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700101import android.os.Binder;
Jeff Sharkey163e6442011-10-31 16:37:52 -0700102import android.os.DropBoxManager;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700103import android.os.Environment;
Jeff Sharkey75279902011-05-24 18:39:45 -0700104import android.os.Handler;
Amith Yamasani450a16b2013-09-18 16:28:50 -0700105import android.os.HandlerThread;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800106import android.os.IBinder;
Jeff Sharkey75279902011-05-24 18:39:45 -0700107import android.os.INetworkManagementService;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700108import android.os.Message;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800109import android.os.Messenger;
Jeff Sharkey62489262011-07-17 12:53:28 -0700110import android.os.PowerManager;
Jeff Sharkey75279902011-05-24 18:39:45 -0700111import android.os.RemoteException;
112import android.os.SystemClock;
Jeff Sharkey00072392018-04-12 14:26:32 -0600113import android.os.Trace;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700114import android.os.UserHandle;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700115import android.provider.Settings;
Jeff Sharkey625239a2012-09-26 22:03:49 -0700116import android.provider.Settings.Global;
Makoto Onukida65a522017-01-13 10:23:30 -0800117import android.service.NetworkInterfaceProto;
118import android.service.NetworkStatsServiceDumpProto;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600119import android.telephony.SubscriptionPlan;
Jeff Sharkey75279902011-05-24 18:39:45 -0700120import android.telephony.TelephonyManager;
Jeff Sharkey55a442e2014-11-18 18:22:21 -0800121import android.text.format.DateUtils;
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700122import android.util.ArrayMap;
123import android.util.ArraySet;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700124import android.util.EventLog;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700125import android.util.Log;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700126import android.util.MathUtils;
Jeff Sharkey75279902011-05-24 18:39:45 -0700127import android.util.Slog;
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700128import android.util.SparseIntArray;
Makoto Onukida65a522017-01-13 10:23:30 -0800129import android.util.proto.ProtoOutputStream;
Jeff Sharkey75279902011-05-24 18:39:45 -0700130
Jeff Sharkey4635f102017-09-01 11:27:13 -0600131import com.android.internal.annotations.GuardedBy;
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800132import com.android.internal.annotations.VisibleForTesting;
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +0900133import com.android.internal.net.NetworkStatsFactory;
Wenchao Tongf5ea3402015-03-04 13:26:38 -0800134import com.android.internal.net.VpnInfo;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700135import com.android.internal.util.ArrayUtils;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600136import com.android.internal.util.DumpUtils;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800137import com.android.internal.util.FileRotator;
138import com.android.internal.util.IndentingPrintWriter;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -0700139import com.android.server.EventLogTags;
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700140import com.android.server.LocalServices;
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700141import com.android.server.connectivity.Tethering;
Jeff Sharkey75279902011-05-24 18:39:45 -0700142
Jeff Sharkey3f391352011-06-05 17:42:53 -0700143import java.io.File;
Jeff Sharkey75279902011-05-24 18:39:45 -0700144import java.io.FileDescriptor;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700145import java.io.IOException;
Jeff Sharkey75279902011-05-24 18:39:45 -0700146import java.io.PrintWriter;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700147import java.time.Clock;
148import java.time.ZoneOffset;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700149import java.util.Arrays;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700150import java.util.HashSet;
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700151import java.util.List;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700152
Jeff Sharkey75279902011-05-24 18:39:45 -0700153/**
154 * Collect and persist detailed network statistics, and provide this data to
155 * other system services.
156 */
157public class NetworkStatsService extends INetworkStatsService.Stub {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600158 static final String TAG = "NetworkStats";
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700159 static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
160 static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700161
Chalard Jean5ecd5f12018-08-22 10:21:26 +0900162 // Perform polling and persist all (FLAG_PERSIST_ALL).
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700163 private static final int MSG_PERFORM_POLL = 1;
164 private static final int MSG_UPDATE_IFACES = 2;
Chalard Jean5ecd5f12018-08-22 10:21:26 +0900165 // Perform polling, persist network, and register the global alert again.
166 private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 3;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700167
168 /** Flags to control detail level of poll event. */
Jeff Sharkey905b5892011-09-30 15:19:49 -0700169 private static final int FLAG_PERSIST_NETWORK = 0x1;
170 private static final int FLAG_PERSIST_UID = 0x2;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700171 private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700172 private static final int FLAG_PERSIST_FORCE = 0x100;
Jeff Sharkey3f391352011-06-05 17:42:53 -0700173
Chalard Jean5ecd5f12018-08-22 10:21:26 +0900174 /**
175 * When global alert quota is high, wait for this delay before processing each polling,
176 * and do not schedule further polls once there is already one queued.
177 * This avoids firing the global alert too often on devices with high transfer speeds and
178 * high quota.
179 */
180 private static final int PERFORM_POLL_DELAY_MS = 1000;
181
Jeff Sharkey163e6442011-10-31 16:37:52 -0700182 private static final String TAG_NETSTATS_ERROR = "netstats_error";
183
Jeff Sharkey75279902011-05-24 18:39:45 -0700184 private final Context mContext;
185 private final INetworkManagementService mNetworkManager;
Christopher Tatee0a22b32013-07-11 14:43:13 -0700186 private final AlarmManager mAlarmManager;
Jeff Sharkey9911a282018-02-14 22:29:11 -0700187 private final Clock mClock;
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700188 private final TelephonyManager mTeleManager;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700189 private final NetworkStatsSettings mSettings;
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800190 private final NetworkStatsObservers mStatsObservers;
Jeff Sharkey75279902011-05-24 18:39:45 -0700191
Jeff Sharkey63abc372012-01-11 18:38:16 -0800192 private final File mSystemDir;
193 private final File mBaseDir;
194
Jeff Sharkey62489262011-07-17 12:53:28 -0700195 private final PowerManager.WakeLock mWakeLock;
196
Chenbo Feng00499822018-05-18 17:10:07 -0700197 private final boolean mUseBpfTrafficStats;
198
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700199 private IConnectivityManager mConnManager;
200
Jeff Sharkey8b2c3a142012-11-12 11:45:05 -0800201 @VisibleForTesting
Jeff Sharkey3f391352011-06-05 17:42:53 -0700202 public static final String ACTION_NETWORK_STATS_POLL =
Jeff Sharkey75279902011-05-24 18:39:45 -0700203 "com.android.server.action.NETWORK_STATS_POLL";
Jeff Sharkey497e4432011-06-14 17:27:29 -0700204 public static final String ACTION_NETWORK_STATS_UPDATED =
205 "com.android.server.action.NETWORK_STATS_UPDATED";
Jeff Sharkey75279902011-05-24 18:39:45 -0700206
207 private PendingIntent mPollIntent;
208
Jeff Sharkey63abc372012-01-11 18:38:16 -0800209 private static final String PREFIX_DEV = "dev";
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700210 private static final String PREFIX_XT = "xt";
Jeff Sharkey63abc372012-01-11 18:38:16 -0800211 private static final String PREFIX_UID = "uid";
212 private static final String PREFIX_UID_TAG = "uid_tag";
213
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700214 /**
Jack Yub6587ea2016-06-22 11:35:10 -0700215 * Virtual network interface for video telephony. This is for VT data usage counting purpose.
216 */
217 public static final String VT_INTERFACE = "vt_data0";
218
219 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700220 * Settings that can be changed externally.
221 */
222 public interface NetworkStatsSettings {
223 public long getPollInterval();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800224 public boolean getSampleEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600225 public boolean getAugmentEnabled();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800226
227 public static class Config {
228 public final long bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800229 public final long rotateAgeMillis;
230 public final long deleteAgeMillis;
231
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700232 public Config(long bucketDuration, long rotateAgeMillis, long deleteAgeMillis) {
Jeff Sharkey63abc372012-01-11 18:38:16 -0800233 this.bucketDuration = bucketDuration;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800234 this.rotateAgeMillis = rotateAgeMillis;
235 this.deleteAgeMillis = deleteAgeMillis;
236 }
237 }
238
239 public Config getDevConfig();
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700240 public Config getXtConfig();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800241 public Config getUidConfig();
242 public Config getUidTagConfig();
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700243
244 public long getGlobalAlertBytes(long def);
245 public long getDevPersistBytes(long def);
246 public long getXtPersistBytes(long def);
247 public long getUidPersistBytes(long def);
248 public long getUidTagPersistBytes(long def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700249 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700250
251 private final Object mStatsLock = new Object();
252
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -0700253 /** Set of currently active ifaces. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900254 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700255 private final ArrayMap<String, NetworkIdentitySet> mActiveIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900256
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700257 /** Set of currently active ifaces for UID stats. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900258 @GuardedBy("mStatsLock")
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -0700259 private final ArrayMap<String, NetworkIdentitySet> mActiveUidIfaces = new ArrayMap<>();
Lorenzo Colittic78da292018-01-19 00:50:48 +0900260
Jeff Sharkey63abc372012-01-11 18:38:16 -0800261 /** Current default active iface. */
262 private String mActiveIface;
Lorenzo Colittic78da292018-01-19 00:50:48 +0900263
Jeff Sharkey234766a2012-04-10 19:48:07 -0700264 /** Set of any ifaces associated with mobile networks since boot. */
Lorenzo Colittic78da292018-01-19 00:50:48 +0900265 @GuardedBy("mStatsLock")
Jeff Sharkey234766a2012-04-10 19:48:07 -0700266 private String[] mMobileIfaces = new String[0];
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700267
Lorenzo Colittic78da292018-01-19 00:50:48 +0900268 /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */
269 @GuardedBy("mStatsLock")
270 private Network[] mDefaultNetworks = new Network[0];
271
Jeff Sharkey63abc372012-01-11 18:38:16 -0800272 private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
273 new DropBoxNonMonotonicObserver();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -0700274
Jeff Sharkey4635f102017-09-01 11:27:13 -0600275 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800276 private NetworkStatsRecorder mDevRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600277 @GuardedBy("mStatsLock")
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700278 private NetworkStatsRecorder mXtRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600279 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800280 private NetworkStatsRecorder mUidRecorder;
Jeff Sharkey4635f102017-09-01 11:27:13 -0600281 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800282 private NetworkStatsRecorder mUidTagRecorder;
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700283
Jeff Sharkey70c70532012-05-16 14:51:19 -0700284 /** Cached {@link #mXtRecorder} stats. */
Jeff Sharkey4635f102017-09-01 11:27:13 -0600285 @GuardedBy("mStatsLock")
Jeff Sharkey70c70532012-05-16 14:51:19 -0700286 private NetworkStatsCollection mXtStatsCached;
Jeff Sharkey75279902011-05-24 18:39:45 -0700287
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700288 /** Current counter sets for each UID. */
289 private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
290
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700291 /** Data layer operation counters for splicing into other structures. */
Jeff Sharkey63abc372012-01-11 18:38:16 -0800292 private NetworkStats mUidOperations = new NetworkStats(0L, 10);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700293
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800294 /** Must be set in factory by calling #setHandler. */
295 private Handler mHandler;
296 private Handler.Callback mHandlerCallback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700297
Jeff Sharkey050151e2018-04-13 14:28:30 -0600298 private volatile boolean mSystemReady;
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700299 private long mPersistThreshold = 2 * MB_IN_BYTES;
300 private long mGlobalAlertBytes;
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800301
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900302 private static final long POLL_RATE_LIMIT_MS = 15_000;
303
304 private long mLastStatsSessionPoll;
305
306 /** Map from UID to number of opened sessions */
307 @GuardedBy("mOpenSessionCallsPerUid")
308 private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
309
310 private final static int DUMP_STATS_SESSION_COUNT = 20;
311
Jeff Sharkey9911a282018-02-14 22:29:11 -0700312 private static @NonNull File getDefaultSystemDir() {
Jeff Sharkey3f391352011-06-05 17:42:53 -0700313 return new File(Environment.getDataDirectory(), "system");
Jeff Sharkey75279902011-05-24 18:39:45 -0700314 }
315
Jeff Sharkey9911a282018-02-14 22:29:11 -0700316 private static @NonNull File getDefaultBaseDir() {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800317 File baseDir = new File(getDefaultSystemDir(), "netstats");
318 baseDir.mkdirs();
319 return baseDir;
320 }
321
Jeff Sharkey9911a282018-02-14 22:29:11 -0700322 private static @NonNull Clock getDefaultClock() {
323 return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
324 Clock.systemUTC());
325 }
326
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800327 public static NetworkStatsService create(Context context,
328 INetworkManagementService networkManager) {
329 AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
330 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
331 PowerManager.WakeLock wakeLock =
332 powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
333
334 NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700335 wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800336 new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
337 getDefaultSystemDir(), getDefaultBaseDir());
338
339 HandlerThread handlerThread = new HandlerThread(TAG);
340 Handler.Callback callback = new HandlerCallback(service);
341 handlerThread.start();
342 Handler handler = new Handler(handlerThread.getLooper(), callback);
343 service.setHandler(handler, callback);
344 return service;
345 }
346
347 @VisibleForTesting
348 NetworkStatsService(Context context, INetworkManagementService networkManager,
Jeff Sharkey9911a282018-02-14 22:29:11 -0700349 AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800350 TelephonyManager teleManager, NetworkStatsSettings settings,
351 NetworkStatsObservers statsObservers, File systemDir, File baseDir) {
Jeff Sharkey75279902011-05-24 18:39:45 -0700352 mContext = checkNotNull(context, "missing Context");
353 mNetworkManager = checkNotNull(networkManager, "missing INetworkManagementService");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800354 mAlarmManager = checkNotNull(alarmManager, "missing AlarmManager");
Jeff Sharkey9911a282018-02-14 22:29:11 -0700355 mClock = checkNotNull(clock, "missing Clock");
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700356 mSettings = checkNotNull(settings, "missing NetworkStatsSettings");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800357 mTeleManager = checkNotNull(teleManager, "missing TelephonyManager");
358 mWakeLock = checkNotNull(wakeLock, "missing WakeLock");
359 mStatsObservers = checkNotNull(statsObservers, "missing NetworkStatsObservers");
360 mSystemDir = checkNotNull(systemDir, "missing systemDir");
361 mBaseDir = checkNotNull(baseDir, "missing baseDir");
Chenbo Feng00499822018-05-18 17:10:07 -0700362 mUseBpfTrafficStats = new File("/sys/fs/bpf/traffic_uid_stats_map").exists();
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700363
364 LocalServices.addService(NetworkStatsManagerInternal.class,
365 new NetworkStatsManagerInternalImpl());
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800366 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700367
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800368 @VisibleForTesting
369 void setHandler(Handler handler, Handler.Callback callback) {
370 mHandler = handler;
371 mHandlerCallback = callback;
Jeff Sharkey75279902011-05-24 18:39:45 -0700372 }
373
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700374 public void bindConnectivityManager(IConnectivityManager connManager) {
375 mConnManager = checkNotNull(connManager, "missing IConnectivityManager");
376 }
377
Jeff Sharkey75279902011-05-24 18:39:45 -0700378 public void systemReady() {
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800379 mSystemReady = true;
380
Jeff Sharkey418d12d2011-12-13 15:38:03 -0800381 if (!isBandwidthControlEnabled()) {
382 Slog.w(TAG, "bandwidth controls disabled, unable to track stats");
383 return;
384 }
385
Jeff Sharkey63abc372012-01-11 18:38:16 -0800386 synchronized (mStatsLock) {
Jeff Sharkey4635f102017-09-01 11:27:13 -0600387 // create data recorders along with historical rotators
388 mDevRecorder = buildRecorder(PREFIX_DEV, mSettings.getDevConfig(), false);
389 mXtRecorder = buildRecorder(PREFIX_XT, mSettings.getXtConfig(), false);
390 mUidRecorder = buildRecorder(PREFIX_UID, mSettings.getUidConfig(), false);
391 mUidTagRecorder = buildRecorder(PREFIX_UID_TAG, mSettings.getUidTagConfig(), true);
392
393 updatePersistThresholdsLocked();
394
Jeff Sharkey63abc372012-01-11 18:38:16 -0800395 // upgrade any legacy stats, migrating them to rotated files
396 maybeUpgradeLegacyStatsLocked();
397
398 // read historical network stats from disk, since policy service
399 // might need them right away.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700400 mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800401
402 // bootstrap initial stats to prevent double-counting later
403 bootstrapStatsLocked();
404 }
Jeff Sharkey3359aca2011-11-08 18:08:48 -0800405
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700406 // watch for tethering changes
407 final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
Vinit Deshpande92d141f2014-09-10 18:05:10 -0700408 mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700409
Jeff Sharkey75279902011-05-24 18:39:45 -0700410 // listen for periodic polling events
411 final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
Jeff Sharkey21c9c452011-06-07 12:26:43 -0700412 mContext.registerReceiver(mPollReceiver, pollFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
Jeff Sharkey75279902011-05-24 18:39:45 -0700413
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700414 // listen for uid removal to clean stats
415 final IntentFilter removedFilter = new IntentFilter(ACTION_UID_REMOVED);
416 mContext.registerReceiver(mRemovedReceiver, removedFilter, null, mHandler);
417
Jeff Sharkeydaa57e82012-09-19 14:10:39 -0700418 // listen for user changes to clean stats
419 final IntentFilter userFilter = new IntentFilter(ACTION_USER_REMOVED);
420 mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
421
Jeff Sharkey75279902011-05-24 18:39:45 -0700422 // persist stats during clean shutdown
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700423 final IntentFilter shutdownFilter = new IntentFilter(ACTION_SHUTDOWN);
424 mContext.registerReceiver(mShutdownReceiver, shutdownFilter);
Jeff Sharkey75279902011-05-24 18:39:45 -0700425
426 try {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700427 mNetworkManager.registerObserver(mAlertObserver);
Jeff Sharkey75279902011-05-24 18:39:45 -0700428 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700429 // ignored; service lives in system_server
Jeff Sharkey75279902011-05-24 18:39:45 -0700430 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700431
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700432 registerPollAlarmLocked();
433 registerGlobalAlert();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800434 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700435
Jeff Sharkey63abc372012-01-11 18:38:16 -0800436 private NetworkStatsRecorder buildRecorder(
437 String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700438 final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
439 Context.DROPBOX_SERVICE);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700440 return new NetworkStatsRecorder(new FileRotator(
441 mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
Jeff Sharkey6de357e2012-05-09 13:33:52 -0700442 mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
Jeff Sharkey75279902011-05-24 18:39:45 -0700443 }
444
Andreas Gampea36dc622018-02-05 17:19:22 -0800445 @GuardedBy("mStatsLock")
Jeff Sharkey3f391352011-06-05 17:42:53 -0700446 private void shutdownLocked() {
Jeff Sharkey367d15a2011-09-22 14:59:51 -0700447 mContext.unregisterReceiver(mTetherReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700448 mContext.unregisterReceiver(mPollReceiver);
Jeff Sharkeyb09540f2011-06-19 01:08:12 -0700449 mContext.unregisterReceiver(mRemovedReceiver);
Ryuki Nakamuraa47b0c92017-03-01 10:40:36 +0900450 mContext.unregisterReceiver(mUserReceiver);
Jeff Sharkey3f391352011-06-05 17:42:53 -0700451 mContext.unregisterReceiver(mShutdownReceiver);
452
Jeff Sharkey9911a282018-02-14 22:29:11 -0700453 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -0800454
455 // persist any pending stats
456 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -0700457 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800458 mUidRecorder.forcePersistLocked(currentTime);
459 mUidTagRecorder.forcePersistLocked(currentTime);
460
Jeff Sharkey6341fce2012-03-06 19:59:57 -0800461 mSystemReady = false;
Jeff Sharkey63abc372012-01-11 18:38:16 -0800462 }
463
Andreas Gampea36dc622018-02-05 17:19:22 -0800464 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -0800465 private void maybeUpgradeLegacyStatsLocked() {
466 File file;
467 try {
468 file = new File(mSystemDir, "netstats.bin");
469 if (file.exists()) {
470 mDevRecorder.importLegacyNetworkLocked(file);
471 file.delete();
472 }
473
474 file = new File(mSystemDir, "netstats_xt.bin");
475 if (file.exists()) {
476 file.delete();
477 }
478
479 file = new File(mSystemDir, "netstats_uid.bin");
480 if (file.exists()) {
481 mUidRecorder.importLegacyUidLocked(file);
482 mUidTagRecorder.importLegacyUidLocked(file);
483 file.delete();
484 }
485 } catch (IOException e) {
486 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeye4984be2013-09-10 21:03:27 -0700487 } catch (OutOfMemoryError e) {
488 Log.wtf(TAG, "problem during legacy upgrade", e);
Jeff Sharkeyc506ff62011-11-17 11:59:29 -0800489 }
Jeff Sharkey3f391352011-06-05 17:42:53 -0700490 }
491
Jeff Sharkey75279902011-05-24 18:39:45 -0700492 /**
493 * Clear any existing {@link #ACTION_NETWORK_STATS_POLL} alarms, and
Jeff Sharkey39ebc212011-06-11 17:25:42 -0700494 * reschedule based on current {@link NetworkStatsSettings#getPollInterval()}.
Jeff Sharkey75279902011-05-24 18:39:45 -0700495 */
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700496 private void registerPollAlarmLocked() {
Christopher Tatee0a22b32013-07-11 14:43:13 -0700497 if (mPollIntent != null) {
498 mAlarmManager.cancel(mPollIntent);
Jeff Sharkey75279902011-05-24 18:39:45 -0700499 }
Christopher Tatee0a22b32013-07-11 14:43:13 -0700500
501 mPollIntent = PendingIntent.getBroadcast(
502 mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0);
503
504 final long currentRealtime = SystemClock.elapsedRealtime();
505 mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime,
506 mSettings.getPollInterval(), mPollIntent);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700507 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700508
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700509 /**
510 * Register for a global alert that is delivered through
511 * {@link INetworkManagementEventObserver} once a threshold amount of data
512 * has been transferred.
513 */
514 private void registerGlobalAlert() {
515 try {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700516 mNetworkManager.setGlobalAlert(mGlobalAlertBytes);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700517 } catch (IllegalStateException e) {
518 Slog.w(TAG, "problem registering for global alert: " + e);
519 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -0700520 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -0700521 }
Jeff Sharkey75279902011-05-24 18:39:45 -0700522 }
523
524 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700525 public INetworkStatsSession openSession() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600526 // NOTE: if callers want to get non-augmented data, they should go
527 // through the public API
528 return openSessionInternal(NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, null);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000529 }
530
531 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600532 public INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage) {
533 return openSessionInternal(flags, callingPackage);
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100534 }
535
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900536 private boolean isRateLimitedForPoll(int callingUid) {
537 if (callingUid == android.os.Process.SYSTEM_UID) {
538 return false;
539 }
540
541 final long lastCallTime;
542 final long now = SystemClock.elapsedRealtime();
543 synchronized (mOpenSessionCallsPerUid) {
544 int calls = mOpenSessionCallsPerUid.get(callingUid, 0);
545 mOpenSessionCallsPerUid.put(callingUid, calls + 1);
546 lastCallTime = mLastStatsSessionPoll;
547 mLastStatsSessionPoll = now;
548 }
549
550 return now - lastCallTime < POLL_RATE_LIMIT_MS;
551 }
552
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600553 private INetworkStatsSession openSessionInternal(final int flags, final String callingPackage) {
Jeff Sharkey4190a042012-04-21 15:36:48 -0700554 assertBandwidthControlEnabled();
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700555
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900556 final int callingUid = Binder.getCallingUid();
557 final int usedFlags = isRateLimitedForPoll(callingUid)
558 ? flags & (~NetworkStatsManager.FLAG_POLL_ON_OPEN)
559 : flags;
Jeff Sharkeyc3c8d162018-04-20 10:59:09 -0600560 if ((usedFlags & (NetworkStatsManager.FLAG_POLL_ON_OPEN
561 | NetworkStatsManager.FLAG_POLL_FORCE)) != 0) {
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100562 final long ident = Binder.clearCallingIdentity();
563 try {
564 performPoll(FLAG_PERSIST_ALL);
565 } finally {
566 Binder.restoreCallingIdentity(ident);
567 }
568 }
569
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700570 // return an IBinder which holds strong references to any loaded stats
571 // for its lifetime; when caller closes only weak references remain.
572
573 return new INetworkStatsSession.Stub() {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900574 private final int mCallingUid = callingUid;
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600575 private final String mCallingPackage = callingPackage;
576 private final @NetworkStatsAccess.Level int mAccessLevel = checkAccessLevel(
577 callingPackage);
578
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700579 private NetworkStatsCollection mUidComplete;
580 private NetworkStatsCollection mUidTagComplete;
581
582 private NetworkStatsCollection getUidComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700583 synchronized (mStatsLock) {
584 if (mUidComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700585 mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
586 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700587 return mUidComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700588 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700589 }
590
591 private NetworkStatsCollection getUidTagComplete() {
Ashish Sharmac13b9452013-11-01 14:57:30 -0700592 synchronized (mStatsLock) {
593 if (mUidTagComplete == null) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700594 mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
595 }
Ashish Sharmac13b9452013-11-01 14:57:30 -0700596 return mUidTagComplete;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700597 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700598 }
599
600 @Override
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000601 public int[] getRelevantUids() {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600602 return getUidComplete().getRelevantUids(mAccessLevel);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000603 }
604
605 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600606 public NetworkStats getDeviceSummaryForNetwork(
607 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900608 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600609 mCallingUid);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000610 }
611
612 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700613 public NetworkStats getSummaryForNetwork(
614 NetworkTemplate template, long start, long end) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900615 return internalGetSummaryForNetwork(template, usedFlags, start, end, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600616 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700617 }
618
619 @Override
620 public NetworkStatsHistory getHistoryForNetwork(NetworkTemplate template, int fields) {
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +0900621 return internalGetHistoryForNetwork(template, usedFlags, fields, mAccessLevel,
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600622 mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700623 }
624
625 @Override
626 public NetworkStats getSummaryForAllUid(
627 NetworkTemplate template, long start, long end, boolean includeTags) {
Jeff Davidson39583b52016-12-12 11:55:37 -0800628 try {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600629 final NetworkStats stats = getUidComplete()
630 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800631 if (includeTags) {
632 final NetworkStats tagStats = getUidTagComplete()
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600633 .getSummary(template, start, end, mAccessLevel, mCallingUid);
Jeff Davidson39583b52016-12-12 11:55:37 -0800634 stats.combineAllValues(tagStats);
635 }
636 return stats;
637 } catch (NullPointerException e) {
638 // TODO: Track down and fix the cause of this crash and remove this catch block.
639 Slog.wtf(TAG, "NullPointerException in getSummaryForAllUid", e);
640 throw e;
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700641 }
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700642 }
643
644 @Override
645 public NetworkStatsHistory getHistoryForUid(
646 NetworkTemplate template, int uid, int set, int tag, int fields) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600647 // NOTE: We don't augment UID-level statistics
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700648 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600649 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
650 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700651 } else {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600652 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
653 Long.MIN_VALUE, Long.MAX_VALUE, mAccessLevel, mCallingUid);
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700654 }
655 }
656
657 @Override
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100658 public NetworkStatsHistory getHistoryIntervalForUid(
659 NetworkTemplate template, int uid, int set, int tag, int fields,
660 long start, long end) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600661 // NOTE: We don't augment UID-level statistics
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100662 if (tag == TAG_NONE) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600663 return getUidComplete().getHistory(template, null, uid, set, tag, fields,
664 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700665 } else if (uid == Binder.getCallingUid()) {
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600666 return getUidTagComplete().getHistory(template, null, uid, set, tag, fields,
667 start, end, mAccessLevel, mCallingUid);
Antonio Cansado6965c182016-03-30 11:37:18 -0700668 } else {
669 throw new SecurityException("Calling package " + mCallingPackage
670 + " cannot access tag information from a different uid");
Zoltan Szatmary-Ban72027d22015-06-16 15:49:16 +0100671 }
672 }
673
674 @Override
Jeff Sharkeyb52e3e52012-04-06 11:12:08 -0700675 public void close() {
676 mUidComplete = null;
677 mUidTagComplete = null;
678 }
679 };
Jeff Sharkey905b5892011-09-30 15:19:49 -0700680 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700681
Jeff Davidson1efb1332015-12-09 18:04:50 -0800682 private @NetworkStatsAccess.Level int checkAccessLevel(String callingPackage) {
683 return NetworkStatsAccess.checkAccessLevel(
684 mContext, Binder.getCallingUid(), callingPackage);
Zoltan Szatmary-Ban9c5dfa52015-02-23 17:20:20 +0000685 }
686
Jeff Sharkey70c70532012-05-16 14:51:19 -0700687 /**
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600688 * Find the most relevant {@link SubscriptionPlan} for the given
689 * {@link NetworkTemplate} and flags. This is typically used to augment
690 * local measurement results to match a known anchor from the carrier.
691 */
692 private SubscriptionPlan resolveSubscriptionPlan(NetworkTemplate template, int flags) {
693 SubscriptionPlan plan = null;
694 if ((flags & NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN) != 0
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600695 && mSettings.getAugmentEnabled()) {
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700696 if (LOGD) Slog.d(TAG, "Resolving plan for " + template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600697 final long token = Binder.clearCallingIdentity();
698 try {
Jeff Sharkey146bb332018-04-18 15:42:57 -0600699 plan = LocalServices.getService(NetworkPolicyManagerInternal.class)
700 .getSubscriptionPlan(template);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600701 } finally {
702 Binder.restoreCallingIdentity(token);
703 }
Jeff Sharkey4e0d3072018-02-20 13:36:14 -0700704 if (LOGD) Slog.d(TAG, "Resolved to plan " + plan);
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600705 }
706 return plan;
707 }
708
709 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700710 * Return network summary, splicing between DEV and XT stats when
711 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700712 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600713 private NetworkStats internalGetSummaryForNetwork(NetworkTemplate template, int flags,
714 long start, long end, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700715 // We've been using pure XT stats long enough that we no longer need to
716 // splice DEV and XT together.
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600717 final NetworkStatsHistory history = internalGetHistoryForNetwork(template, flags, FIELD_ALL,
718 accessLevel, callingUid);
719
720 final long now = System.currentTimeMillis();
721 final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
722
723 final NetworkStats stats = new NetworkStats(end - start, 1);
Lorenzo Colittiada23ed2018-01-19 01:05:20 +0900724 stats.addValues(new NetworkStats.Entry(IFACE_ALL, UID_ALL, SET_ALL, TAG_NONE,
725 METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, entry.rxBytes, entry.rxPackets,
726 entry.txBytes, entry.txPackets, entry.operations));
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600727 return stats;
Jeff Sharkey70c70532012-05-16 14:51:19 -0700728 }
729
730 /**
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700731 * Return network history, splicing between DEV and XT stats when
732 * appropriate.
Jeff Sharkey70c70532012-05-16 14:51:19 -0700733 */
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600734 private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template,
735 int flags, int fields, @NetworkStatsAccess.Level int accessLevel, int callingUid) {
Jeff Sharkey5274dcc2014-10-24 13:15:15 -0700736 // We've been using pure XT stats long enough that we no longer need to
737 // splice DEV and XT together.
Jeff Sharkey4635f102017-09-01 11:27:13 -0600738 final SubscriptionPlan augmentPlan = resolveSubscriptionPlan(template, flags);
739 synchronized (mStatsLock) {
740 return mXtStatsCached.getHistory(template, augmentPlan,
741 UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, Long.MAX_VALUE,
742 accessLevel, callingUid);
743 }
Jeff Sharkey70c70532012-05-16 14:51:19 -0700744 }
745
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700746 private long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
747 assertSystemReady();
Jeff Sharkey4190a042012-04-21 15:36:48 -0700748 assertBandwidthControlEnabled();
Jeff Sharkeyf4de2942017-08-29 15:32:13 -0600749
750 // NOTE: if callers want to get non-augmented data, they should go
751 // through the public API
752 return internalGetSummaryForNetwork(template,
753 NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN, start, end,
754 NetworkStatsAccess.Level.DEVICE, Binder.getCallingUid()).getTotalBytes();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -0700755 }
756
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700757 private NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
758 assertSystemReady();
759 assertBandwidthControlEnabled();
760
761 final NetworkStatsCollection uidComplete;
762 synchronized (mStatsLock) {
763 uidComplete = mUidRecorder.getOrLoadCompleteLocked();
764 }
765 return uidComplete.getSummary(template, start, end, NetworkStatsAccess.Level.DEVICE,
766 android.os.Process.SYSTEM_UID);
767 }
768
Jeff Sharkey350083e2011-06-29 10:45:16 -0700769 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700770 public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
771 if (Binder.getCallingUid() != uid) {
772 mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
773 }
Jeff Sharkey4190a042012-04-21 15:36:48 -0700774 assertBandwidthControlEnabled();
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700775
776 // TODO: switch to data layer stats once kernel exports
777 // for now, read network layer stats and flatten across all ifaces
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800778 final long token = Binder.clearCallingIdentity();
779 final NetworkStats networkLayer;
780 try {
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +0900781 networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid,
782 NetworkStats.INTERFACES_ALL);
Jeff Sharkey4529bb62011-12-14 10:31:54 -0800783 } finally {
784 Binder.restoreCallingIdentity(token);
785 }
786
Jeff Sharkey21a54782012-04-09 10:27:55 -0700787 // splice in operation counts
788 networkLayer.spliceOperationsFrom(mUidOperations);
789
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700790 final NetworkStats dataLayer = new NetworkStats(
791 networkLayer.getElapsedRealtime(), networkLayer.size());
792
793 NetworkStats.Entry entry = null;
794 for (int i = 0; i < networkLayer.size(); i++) {
795 entry = networkLayer.getValues(i, entry);
796 entry.iface = IFACE_ALL;
797 dataLayer.combineValues(entry);
798 }
799
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700800 return dataLayer;
801 }
802
803 @Override
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +0900804 public NetworkStats getDetailedUidStats(String[] requiredIfaces) {
805 try {
806 final String[] ifacesToQuery =
Remi NGUYEN VAN75525b32018-02-27 16:47:22 +0900807 NetworkStatsFactory.augmentWithStackedInterfaces(requiredIfaces);
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +0900808 return getNetworkStatsUidDetail(ifacesToQuery);
809 } catch (RemoteException e) {
810 Log.wtf(TAG, "Error compiling UID stats", e);
811 return new NetworkStats(0L, 0);
812 }
813 }
814
815 @Override
Jeff Sharkey234766a2012-04-10 19:48:07 -0700816 public String[] getMobileIfaces() {
817 return mMobileIfaces;
818 }
819
820 @Override
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700821 public void incrementOperationCount(int uid, int tag, int operationCount) {
822 if (Binder.getCallingUid() != uid) {
Jeff Sharkey9f09e6a72017-06-26 11:24:47 -0600823 mContext.enforceCallingOrSelfPermission(
824 android.Manifest.permission.UPDATE_DEVICE_STATS, TAG);
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700825 }
826
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700827 if (operationCount < 0) {
828 throw new IllegalArgumentException("operation count can only be incremented");
829 }
830 if (tag == TAG_NONE) {
831 throw new IllegalArgumentException("operation count must have specific tag");
832 }
833
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700834 synchronized (mStatsLock) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700835 final int set = mActiveUidCounterSet.get(uid, SET_DEFAULT);
Jeff Sharkey63abc372012-01-11 18:38:16 -0800836 mUidOperations.combineValues(
837 mActiveIface, uid, set, tag, 0L, 0L, 0L, 0L, operationCount);
838 mUidOperations.combineValues(
839 mActiveIface, uid, set, TAG_NONE, 0L, 0L, 0L, 0L, operationCount);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700840 }
841 }
842
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700843 @VisibleForTesting
844 void setUidForeground(int uid, boolean uidForeground) {
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -0700845 synchronized (mStatsLock) {
846 final int set = uidForeground ? SET_FOREGROUND : SET_DEFAULT;
847 final int oldSet = mActiveUidCounterSet.get(uid, SET_DEFAULT);
848 if (oldSet != set) {
849 mActiveUidCounterSet.put(uid, set);
850 setKernelCounterSet(uid, set);
851 }
Jeff Sharkeya63ba592011-07-19 23:47:12 -0700852 }
853 }
854
855 @Override
Lorenzo Colittic78da292018-01-19 00:50:48 +0900856 public void forceUpdateIfaces(Network[] defaultNetworks) {
Jeff Sharkey69736342014-12-08 14:50:12 -0800857 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
858 assertBandwidthControlEnabled();
859
860 final long token = Binder.clearCallingIdentity();
861 try {
Lorenzo Colittic78da292018-01-19 00:50:48 +0900862 updateIfaces(defaultNetworks);
Jeff Sharkey69736342014-12-08 14:50:12 -0800863 } finally {
864 Binder.restoreCallingIdentity(token);
865 }
866 }
867
868 @Override
Jeff Sharkey350083e2011-06-29 10:45:16 -0700869 public void forceUpdate() {
870 mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
Jeff Sharkey4190a042012-04-21 15:36:48 -0700871 assertBandwidthControlEnabled();
Jeff Sharkeye630f7b2012-01-31 17:12:53 -0800872
873 final long token = Binder.clearCallingIdentity();
874 try {
875 performPoll(FLAG_PERSIST_ALL);
876 } finally {
877 Binder.restoreCallingIdentity(token);
878 }
Jeff Sharkey350083e2011-06-29 10:45:16 -0700879 }
880
Jeff Sharkeye0c29952018-02-20 17:24:55 -0700881 private void advisePersistThreshold(long thresholdBytes) {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700882 assertBandwidthControlEnabled();
883
884 // clamp threshold into safe range
885 mPersistThreshold = MathUtils.constrain(thresholdBytes, 128 * KB_IN_BYTES, 2 * MB_IN_BYTES);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700886 if (LOGV) {
887 Slog.v(TAG, "advisePersistThreshold() given " + thresholdBytes + ", clamped to "
888 + mPersistThreshold);
889 }
890
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700891 // update and persist if beyond new thresholds
Jeff Sharkey9911a282018-02-14 22:29:11 -0700892 final long currentTime = mClock.millis();
Jeff Sharkey58015972012-05-07 11:08:49 -0700893 synchronized (mStatsLock) {
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700894 if (!mSystemReady) return;
895
Jeff Sharkey4635f102017-09-01 11:27:13 -0600896 updatePersistThresholdsLocked();
Jeff Sharkey20f5c3d2012-05-09 19:59:07 -0700897
Jeff Sharkey58015972012-05-07 11:08:49 -0700898 mDevRecorder.maybePersistLocked(currentTime);
899 mXtRecorder.maybePersistLocked(currentTime);
900 mUidRecorder.maybePersistLocked(currentTime);
901 mUidTagRecorder.maybePersistLocked(currentTime);
902 }
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700903
904 // re-arm global alert
905 registerGlobalAlert();
906 }
907
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800908 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700909 public DataUsageRequest registerUsageCallback(String callingPackage,
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800910 DataUsageRequest request, Messenger messenger, IBinder binder) {
911 checkNotNull(callingPackage, "calling package is null");
912 checkNotNull(request, "DataUsageRequest is null");
Antonio Cansado6965c182016-03-30 11:37:18 -0700913 checkNotNull(request.template, "NetworkTemplate is null");
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800914 checkNotNull(messenger, "messenger is null");
915 checkNotNull(binder, "binder is null");
916
917 int callingUid = Binder.getCallingUid();
918 @NetworkStatsAccess.Level int accessLevel = checkAccessLevel(callingPackage);
919 DataUsageRequest normalizedRequest;
920 final long token = Binder.clearCallingIdentity();
921 try {
922 normalizedRequest = mStatsObservers.register(request, messenger, binder,
923 callingUid, accessLevel);
924 } finally {
925 Binder.restoreCallingIdentity(token);
926 }
927
928 // Create baseline stats
Chalard Jean5ecd5f12018-08-22 10:21:26 +0900929 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800930
931 return normalizedRequest;
932 }
933
934 @Override
Antonio Cansado6965c182016-03-30 11:37:18 -0700935 public void unregisterUsageRequest(DataUsageRequest request) {
Antonio Cansadocd42acd2016-02-17 13:03:38 -0800936 checkNotNull(request, "DataUsageRequest is null");
937
938 int callingUid = Binder.getCallingUid();
939 final long token = Binder.clearCallingIdentity();
940 try {
941 mStatsObservers.unregister(request, callingUid);
942 } finally {
943 Binder.restoreCallingIdentity(token);
944 }
945 }
946
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800947 @Override
948 public long getUidStats(int uid, int type) {
Chenbo Fengaedd6a32017-11-20 18:23:46 -0800949 return nativeGetUidStat(uid, type, checkBpfStatsEnable());
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800950 }
951
952 @Override
953 public long getIfaceStats(String iface, int type) {
junyulaia5c3fb12018-06-25 21:51:14 +0800954 // eBPF code doesn't provide per-interface TCP counters. Use xt_qtaguid for now.
955 // TODO: delete getMobileTcp(Rx|Tx)Packets entirely. See b/110443385 .
956 if (type == TYPE_TCP_TX_PACKETS || type == TYPE_TCP_RX_PACKETS) {
957 return nativeGetIfaceStat(iface, type, false);
958 } else {
959 return nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
960 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800961 }
962
963 @Override
964 public long getTotalStats(int type) {
Chenbo Fengaedd6a32017-11-20 18:23:46 -0800965 return nativeGetTotalStat(type, checkBpfStatsEnable());
966 }
967
968 private boolean checkBpfStatsEnable() {
Chenbo Feng00499822018-05-18 17:10:07 -0700969 return mUseBpfTrafficStats;
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -0800970 }
971
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700972 /**
973 * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to
974 * reflect current {@link #mPersistThreshold} value. Always defers to
Jeff Sharkey625239a2012-09-26 22:03:49 -0700975 * {@link Global} values when defined.
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700976 */
Andreas Gampea36dc622018-02-05 17:19:22 -0800977 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -0600978 private void updatePersistThresholdsLocked() {
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -0700979 mDevRecorder.setPersistThreshold(mSettings.getDevPersistBytes(mPersistThreshold));
980 mXtRecorder.setPersistThreshold(mSettings.getXtPersistBytes(mPersistThreshold));
981 mUidRecorder.setPersistThreshold(mSettings.getUidPersistBytes(mPersistThreshold));
982 mUidTagRecorder.setPersistThreshold(mSettings.getUidTagPersistBytes(mPersistThreshold));
983 mGlobalAlertBytes = mSettings.getGlobalAlertBytes(mPersistThreshold);
984 }
985
Jeff Sharkey75279902011-05-24 18:39:45 -0700986 /**
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700987 * Receiver that watches for {@link Tethering} to claim interface pairs.
988 */
989 private BroadcastReceiver mTetherReceiver = new BroadcastReceiver() {
990 @Override
991 public void onReceive(Context context, Intent intent) {
992 // on background handler thread, and verified CONNECTIVITY_INTERNAL
993 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -0700994 performPoll(FLAG_PERSIST_NETWORK);
Jeff Sharkeycdd02c5d2011-09-16 01:52:49 -0700995 }
996 };
997
Jeff Sharkey75279902011-05-24 18:39:45 -0700998 private BroadcastReceiver mPollReceiver = new BroadcastReceiver() {
999 @Override
1000 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001001 // on background handler thread, and verified UPDATE_DEVICE_STATS
1002 // permission above.
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001003 performPoll(FLAG_PERSIST_ALL);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001004
1005 // verify that we're watching global alert
1006 registerGlobalAlert();
Jeff Sharkey75279902011-05-24 18:39:45 -07001007 }
1008 };
1009
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001010 private BroadcastReceiver mRemovedReceiver = new BroadcastReceiver() {
1011 @Override
1012 public void onReceive(Context context, Intent intent) {
1013 // on background handler thread, and UID_REMOVED is protected
1014 // broadcast.
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001015
1016 final int uid = intent.getIntExtra(EXTRA_UID, -1);
1017 if (uid == -1) return;
1018
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001019 synchronized (mStatsLock) {
Jeff Sharkey62489262011-07-17 12:53:28 -07001020 mWakeLock.acquire();
1021 try {
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001022 removeUidsLocked(uid);
1023 } finally {
1024 mWakeLock.release();
1025 }
1026 }
1027 }
1028 };
1029
1030 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() {
1031 @Override
1032 public void onReceive(Context context, Intent intent) {
1033 // On background handler thread, and USER_REMOVED is protected
1034 // broadcast.
1035
1036 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
1037 if (userId == -1) return;
1038
1039 synchronized (mStatsLock) {
1040 mWakeLock.acquire();
1041 try {
1042 removeUserLocked(userId);
Jeff Sharkey62489262011-07-17 12:53:28 -07001043 } finally {
1044 mWakeLock.release();
1045 }
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001046 }
1047 }
1048 };
1049
Jeff Sharkey75279902011-05-24 18:39:45 -07001050 private BroadcastReceiver mShutdownReceiver = new BroadcastReceiver() {
1051 @Override
1052 public void onReceive(Context context, Intent intent) {
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001053 // SHUTDOWN is protected broadcast.
Jeff Sharkey75279902011-05-24 18:39:45 -07001054 synchronized (mStatsLock) {
Jeff Sharkey3f391352011-06-05 17:42:53 -07001055 shutdownLocked();
Jeff Sharkey75279902011-05-24 18:39:45 -07001056 }
1057 }
1058 };
1059
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001060 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001061 * Observer that watches for {@link INetworkManagementService} alerts.
1062 */
Jeff Sharkey216c1812012-08-05 14:29:23 -07001063 private INetworkManagementEventObserver mAlertObserver = new BaseNetworkObserver() {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001064 @Override
1065 public void limitReached(String limitName, String iface) {
1066 // only someone like NMS should be calling us
1067 mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
1068
1069 if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
Chalard Jean5ecd5f12018-08-22 10:21:26 +09001070 // kick off background poll to collect network stats unless there is already
1071 // such a call pending; UID stats are handled during normal polling interval.
1072 if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
1073 mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
1074 PERFORM_POLL_DELAY_MS);
1075 }
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001076 }
1077 }
1078 };
1079
Lorenzo Colittic78da292018-01-19 00:50:48 +09001080 private void updateIfaces(Network[] defaultNetworks) {
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001081 synchronized (mStatsLock) {
1082 mWakeLock.acquire();
1083 try {
Lorenzo Colittic78da292018-01-19 00:50:48 +09001084 updateIfacesLocked(defaultNetworks);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001085 } finally {
1086 mWakeLock.release();
1087 }
1088 }
1089 }
1090
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001091 /**
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001092 * Inspect all current {@link NetworkState} to derive mapping from {@code
1093 * iface} to {@link NetworkStatsHistory}. When multiple {@link NetworkInfo}
1094 * are active on a single {@code iface}, they are combined under a single
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001095 * {@link NetworkIdentitySet}.
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001096 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001097 @GuardedBy("mStatsLock")
Lorenzo Colittic78da292018-01-19 00:50:48 +09001098 private void updateIfacesLocked(Network[] defaultNetworks) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001099 if (!mSystemReady) return;
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001100 if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001101
1102 // take one last stats snapshot before updating iface mapping. this
1103 // isn't perfect, since the kernel may already be counting traffic from
1104 // the updated network.
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001105
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001106 // poll, but only persist network stats to keep codepath fast. UID stats
1107 // will be persisted during next alarm poll event.
1108 performPollLocked(FLAG_PERSIST_NETWORK);
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001109
1110 final NetworkState[] states;
Jeff Sharkey63abc372012-01-11 18:38:16 -08001111 final LinkProperties activeLink;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001112 try {
1113 states = mConnManager.getAllNetworkState();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001114 activeLink = mConnManager.getActiveLinkProperties();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001115 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001116 // ignored; service lives in system_server
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001117 return;
1118 }
1119
Jeff Sharkey63abc372012-01-11 18:38:16 -08001120 mActiveIface = activeLink != null ? activeLink.getInterfaceName() : null;
1121
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001122 // Rebuild active interfaces based on connected networks
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001123 mActiveIfaces.clear();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001124 mActiveUidIfaces.clear();
Lorenzo Colittic78da292018-01-19 00:50:48 +09001125 if (defaultNetworks != null) {
1126 // Caller is ConnectivityService. Update the list of default networks.
1127 mDefaultNetworks = defaultNetworks;
1128 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001129
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001130 final ArraySet<String> mobileIfaces = new ArraySet<>();
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001131 for (NetworkState state : states) {
1132 if (state.networkInfo.isConnected()) {
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001133 final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType());
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001134 final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
1135 final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
1136 isDefault);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001137
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001138 // Traffic occurring on the base interface is always counted for
1139 // both total usage and UID details.
1140 final String baseIface = state.linkProperties.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001141 if (baseIface != null) {
1142 findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
1143 findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
Jack Yub6587ea2016-06-22 11:35:10 -07001144
1145 // Build a separate virtual interface for VT (Video Telephony) data usage.
1146 // Only do this when IMS is not metered, but VT is metered.
1147 // If IMS is metered, then the IMS network usage has already included VT usage.
1148 // VT is considered always metered in framework's layer. If VT is not metered
1149 // per carrier's policy, modem will report 0 usage for VT calls.
1150 if (state.networkCapabilities.hasCapability(
1151 NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
1152
1153 // Copy the identify from IMS one but mark it as metered.
1154 NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
1155 ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
Lorenzo Colittid3e4a1e2018-01-19 01:12:04 +09001156 ident.getRoaming(), true /* metered */,
1157 true /* onDefaultNetwork */);
Jack Yub6587ea2016-06-22 11:35:10 -07001158 findOrCreateNetworkIdentitySet(mActiveIfaces, VT_INTERFACE).add(vtIdent);
1159 findOrCreateNetworkIdentitySet(mActiveUidIfaces, VT_INTERFACE).add(vtIdent);
1160 }
1161
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001162 if (isMobile) {
1163 mobileIfaces.add(baseIface);
1164 }
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001165 }
1166
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001167 // Traffic occurring on stacked interfaces is usually clatd,
1168 // which is already accounted against its final egress interface
1169 // by the kernel. Thus, we only need to collect stacked
1170 // interface stats at the UID level.
1171 final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
1172 for (LinkProperties stackedLink : stackedLinks) {
1173 final String stackedIface = stackedLink.getInterfaceName();
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07001174 if (stackedIface != null) {
1175 findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident);
1176 if (isMobile) {
1177 mobileIfaces.add(stackedIface);
1178 }
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001179
1180 NetworkStatsFactory.noteStackedIface(stackedIface, baseIface);
Jeff Sharkey234766a2012-04-10 19:48:07 -07001181 }
1182 }
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001183 }
1184 }
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001185
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001186 mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]);
1187 }
1188
1189 private static <K> NetworkIdentitySet findOrCreateNetworkIdentitySet(
1190 ArrayMap<K, NetworkIdentitySet> map, K key) {
1191 NetworkIdentitySet ident = map.get(key);
1192 if (ident == null) {
1193 ident = new NetworkIdentitySet();
1194 map.put(key, ident);
1195 }
1196 return ident;
Jeff Sharkeyd2a45872011-05-28 20:56:34 -07001197 }
1198
Andreas Gampea36dc622018-02-05 17:19:22 -08001199 @GuardedBy("mStatsLock")
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001200 private void recordSnapshotLocked(long currentTime) throws RemoteException {
1201 // snapshot and record current counters; read UID stats first to
Jack Yub6587ea2016-06-22 11:35:10 -07001202 // avoid over counting dev stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001203 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotUid");
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001204 final NetworkStats uidSnapshot = getNetworkStatsUidDetail(INTERFACES_ALL);
Jeff Sharkey00072392018-04-12 14:26:32 -06001205 Trace.traceEnd(TRACE_TAG_NETWORK);
1206 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotXt");
Jack Yuf9d559c2017-05-26 16:08:22 -07001207 final NetworkStats xtSnapshot = getNetworkStatsXt();
Jeff Sharkey00072392018-04-12 14:26:32 -06001208 Trace.traceEnd(TRACE_TAG_NETWORK);
1209 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotDev");
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001210 final NetworkStats devSnapshot = mNetworkManager.getNetworkStatsSummaryDev();
Jeff Sharkey00072392018-04-12 14:26:32 -06001211 Trace.traceEnd(TRACE_TAG_NETWORK);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001212
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001213 // Tethering snapshot for dev and xt stats. Counts per-interface data from tethering stats
1214 // providers that isn't already counted by dev and XT stats.
Jeff Sharkey00072392018-04-12 14:26:32 -06001215 Trace.traceBegin(TRACE_TAG_NETWORK, "snapshotTether");
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001216 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_IFACE);
Jeff Sharkey00072392018-04-12 14:26:32 -06001217 Trace.traceEnd(TRACE_TAG_NETWORK);
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001218 xtSnapshot.combineAllValues(tetherSnapshot);
1219 devSnapshot.combineAllValues(tetherSnapshot);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001220
1221 // For xt/dev, we pass a null VPN array because usage is aggregated by UID, so VPN traffic
1222 // can't be reattributed to responsible apps.
Jeff Sharkey00072392018-04-12 14:26:32 -06001223 Trace.traceBegin(TRACE_TAG_NETWORK, "recordDev");
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001224 mDevRecorder.recordSnapshotLocked(
1225 devSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001226 Trace.traceEnd(TRACE_TAG_NETWORK);
1227 Trace.traceBegin(TRACE_TAG_NETWORK, "recordXt");
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001228 mXtRecorder.recordSnapshotLocked(
1229 xtSnapshot, mActiveIfaces, null /* vpnArray */, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001230 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Davidson4ff3bcf2016-06-15 13:31:52 -07001231
1232 // For per-UID stats, pass the VPN info so VPN traffic is reattributed to responsible apps.
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001233 VpnInfo[] vpnArray = mConnManager.getAllVpnInfo();
Jeff Sharkey00072392018-04-12 14:26:32 -06001234 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUid");
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001235 mUidRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001236 Trace.traceEnd(TRACE_TAG_NETWORK);
1237 Trace.traceBegin(TRACE_TAG_NETWORK, "recordUidTag");
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001238 mUidTagRecorder.recordSnapshotLocked(uidSnapshot, mActiveUidIfaces, vpnArray, currentTime);
Jeff Sharkey00072392018-04-12 14:26:32 -06001239 Trace.traceEnd(TRACE_TAG_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001240
1241 // We need to make copies of member fields that are sent to the observer to avoid
1242 // a race condition between the service handler thread and the observer's
1243 mStatsObservers.updateStats(xtSnapshot, uidSnapshot, new ArrayMap<>(mActiveIfaces),
1244 new ArrayMap<>(mActiveUidIfaces), vpnArray, currentTime);
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001245 }
1246
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001247 /**
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001248 * Bootstrap initial stats snapshot, usually during {@link #systemReady()}
1249 * so we have baseline values without double-counting.
1250 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001251 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001252 private void bootstrapStatsLocked() {
Jeff Sharkey9911a282018-02-14 22:29:11 -07001253 final long currentTime = mClock.millis();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001254
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001255 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001256 recordSnapshotLocked(currentTime);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001257 } catch (IllegalStateException e) {
1258 Slog.w(TAG, "problem reading network stats: " + e);
1259 } catch (RemoteException e) {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001260 // ignored; service lives in system_server
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001261 }
1262 }
1263
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001264 private void performPoll(int flags) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001265 synchronized (mStatsLock) {
1266 mWakeLock.acquire();
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001267
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001268 try {
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001269 performPollLocked(flags);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001270 } finally {
1271 mWakeLock.release();
1272 }
1273 }
1274 }
1275
1276 /**
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001277 * Periodic poll operation, reading current statistics and recording into
1278 * {@link NetworkStatsHistory}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001279 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001280 @GuardedBy("mStatsLock")
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001281 private void performPollLocked(int flags) {
Jeff Sharkey6341fce2012-03-06 19:59:57 -08001282 if (!mSystemReady) return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001283 if (LOGV) Slog.v(TAG, "performPollLocked(flags=0x" + Integer.toHexString(flags) + ")");
Jeff Sharkey00072392018-04-12 14:26:32 -06001284 Trace.traceBegin(TRACE_TAG_NETWORK, "performPollLocked");
Jeff Sharkey75279902011-05-24 18:39:45 -07001285
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001286 final boolean persistNetwork = (flags & FLAG_PERSIST_NETWORK) != 0;
1287 final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001288 final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001289
Jeff Sharkey75279902011-05-24 18:39:45 -07001290 // TODO: consider marking "untrusted" times in historical stats
Jeff Sharkey9911a282018-02-14 22:29:11 -07001291 final long currentTime = mClock.millis();
Jeff Sharkey75279902011-05-24 18:39:45 -07001292
Jeff Sharkey75279902011-05-24 18:39:45 -07001293 try {
Wenchao Tongf5ea3402015-03-04 13:26:38 -08001294 recordSnapshotLocked(currentTime);
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001295 } catch (IllegalStateException e) {
1296 Log.wtf(TAG, "problem reading network stats", e);
Jeff Sharkey905b5892011-09-30 15:19:49 -07001297 return;
Jeff Sharkeyb3d59572011-09-07 17:20:27 -07001298 } catch (RemoteException e) {
1299 // ignored; service lives in system_server
Jeff Sharkey905b5892011-09-30 15:19:49 -07001300 return;
1301 }
1302
Jeff Sharkey63abc372012-01-11 18:38:16 -08001303 // persist any pending data depending on requested flags
Jeff Sharkey00072392018-04-12 14:26:32 -06001304 Trace.traceBegin(TRACE_TAG_NETWORK, "[persisting]");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001305 if (persistForce) {
1306 mDevRecorder.forcePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001307 mXtRecorder.forcePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001308 mUidRecorder.forcePersistLocked(currentTime);
1309 mUidTagRecorder.forcePersistLocked(currentTime);
1310 } else {
1311 if (persistNetwork) {
1312 mDevRecorder.maybePersistLocked(currentTime);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001313 mXtRecorder.maybePersistLocked(currentTime);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001314 }
1315 if (persistUid) {
1316 mUidRecorder.maybePersistLocked(currentTime);
1317 mUidTagRecorder.maybePersistLocked(currentTime);
1318 }
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001319 }
Jeff Sharkey00072392018-04-12 14:26:32 -06001320 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001321
Jeff Sharkey63abc372012-01-11 18:38:16 -08001322 if (mSettings.getSampleEnabled()) {
Jeff Sharkey905b5892011-09-30 15:19:49 -07001323 // sample stats after each full poll
Jeff Sharkey63abc372012-01-11 18:38:16 -08001324 performSampleLocked();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001325 }
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001326
Jeff Sharkey497e4432011-06-14 17:27:29 -07001327 // finally, dispatch updated event to any listeners
1328 final Intent updatedIntent = new Intent(ACTION_NETWORK_STATS_UPDATED);
1329 updatedIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001330 mContext.sendBroadcastAsUser(updatedIntent, UserHandle.ALL,
1331 READ_NETWORK_USAGE_HISTORY);
Jeff Sharkey00072392018-04-12 14:26:32 -06001332
1333 Trace.traceEnd(TRACE_TAG_NETWORK);
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001334 }
1335
1336 /**
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001337 * Sample recent statistics summary into {@link EventLog}.
1338 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001339 @GuardedBy("mStatsLock")
Jeff Sharkey63abc372012-01-11 18:38:16 -08001340 private void performSampleLocked() {
1341 // TODO: migrate trustedtime fixes to separate binary log events
Jeff Sharkey9911a282018-02-14 22:29:11 -07001342 final long currentTime = mClock.millis();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001343
Jeff Sharkey63abc372012-01-11 18:38:16 -08001344 NetworkTemplate template;
1345 NetworkStats.Entry devTotal;
1346 NetworkStats.Entry xtTotal;
1347 NetworkStats.Entry uidTotal;
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001348
1349 // collect mobile sample
Jeff Sharkey234766a2012-04-10 19:48:07 -07001350 template = buildTemplateMobileWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001351 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001352 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001353 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey684c54a2011-11-16 17:46:30 -08001354
Jeff Sharkey905b5892011-09-30 15:19:49 -07001355 EventLogTags.writeNetstatsMobileSample(
1356 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1357 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1358 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001359 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001360
1361 // collect wifi sample
Jeff Sharkey8fc27e82012-04-04 20:40:58 -07001362 template = buildTemplateWifiWildcard();
Jeff Sharkey63abc372012-01-11 18:38:16 -08001363 devTotal = mDevRecorder.getTotalSinceBootLocked(template);
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001364 xtTotal = mXtRecorder.getTotalSinceBootLocked(template);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001365 uidTotal = mUidRecorder.getTotalSinceBootLocked(template);
1366
Jeff Sharkey905b5892011-09-30 15:19:49 -07001367 EventLogTags.writeNetstatsWifiSample(
1368 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
1369 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
1370 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
Jeff Sharkey9911a282018-02-14 22:29:11 -07001371 currentTime);
Jeff Sharkey07b0dd92011-09-01 13:06:19 -07001372 }
1373
1374 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001375 * Clean up {@link #mUidRecorder} after UID is removed.
Jeff Sharkeyb09540f2011-06-19 01:08:12 -07001376 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001377 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001378 private void removeUidsLocked(int... uids) {
1379 if (LOGV) Slog.v(TAG, "removeUidsLocked() for UIDs " + Arrays.toString(uids));
1380
1381 // Perform one last poll before removing
Jeff Sharkey163e6442011-10-31 16:37:52 -07001382 performPollLocked(FLAG_PERSIST_ALL);
1383
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001384 mUidRecorder.removeUidsLocked(uids);
1385 mUidTagRecorder.removeUidsLocked(uids);
Jeff Sharkey163e6442011-10-31 16:37:52 -07001386
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001387 // Clear kernel stats associated with UID
1388 for (int uid : uids) {
1389 resetKernelUidStats(uid);
1390 }
1391 }
1392
1393 /**
1394 * Clean up {@link #mUidRecorder} after user is removed.
1395 */
Andreas Gampea36dc622018-02-05 17:19:22 -08001396 @GuardedBy("mStatsLock")
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001397 private void removeUserLocked(int userId) {
1398 if (LOGV) Slog.v(TAG, "removeUserLocked() for userId=" + userId);
1399
1400 // Build list of UIDs that we should clean up
1401 int[] uids = new int[0];
1402 final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001403 PackageManager.MATCH_ANY_USER
1404 | PackageManager.MATCH_DISABLED_COMPONENTS);
Jeff Sharkeydaa57e82012-09-19 14:10:39 -07001405 for (ApplicationInfo app : apps) {
1406 final int uid = UserHandle.getUid(userId, app.uid);
1407 uids = ArrayUtils.appendInt(uids, uid);
1408 }
1409
1410 removeUidsLocked(uids);
Jeff Sharkey75279902011-05-24 18:39:45 -07001411 }
1412
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001413 private class NetworkStatsManagerInternalImpl extends NetworkStatsManagerInternal {
1414 @Override
1415 public long getNetworkTotalBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001416 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkTotalBytes");
1417 try {
1418 return NetworkStatsService.this.getNetworkTotalBytes(template, start, end);
1419 } finally {
1420 Trace.traceEnd(TRACE_TAG_NETWORK);
1421 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001422 }
1423
1424 @Override
1425 public NetworkStats getNetworkUidBytes(NetworkTemplate template, long start, long end) {
Jeff Sharkey00072392018-04-12 14:26:32 -06001426 Trace.traceBegin(TRACE_TAG_NETWORK, "getNetworkUidBytes");
1427 try {
1428 return NetworkStatsService.this.getNetworkUidBytes(template, start, end);
1429 } finally {
1430 Trace.traceEnd(TRACE_TAG_NETWORK);
1431 }
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001432 }
1433
1434 @Override
1435 public void setUidForeground(int uid, boolean uidForeground) {
1436 NetworkStatsService.this.setUidForeground(uid, uidForeground);
1437 }
1438
1439 @Override
1440 public void advisePersistThreshold(long thresholdBytes) {
1441 NetworkStatsService.this.advisePersistThreshold(thresholdBytes);
1442 }
1443
1444 @Override
1445 public void forceUpdate() {
1446 NetworkStatsService.this.forceUpdate();
1447 }
1448 }
1449
Jeff Sharkey75279902011-05-24 18:39:45 -07001450 @Override
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001451 protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -06001452 if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
Jeff Sharkey75279902011-05-24 18:39:45 -07001453
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001454 long duration = DateUtils.DAY_IN_MILLIS;
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001455 final HashSet<String> argSet = new HashSet<String>();
1456 for (String arg : args) {
1457 argSet.add(arg);
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001458
1459 if (arg.startsWith("--duration=")) {
1460 try {
1461 duration = Long.parseLong(arg.substring(11));
1462 } catch (NumberFormatException ignored) {
1463 }
1464 }
Jeff Sharkey75279902011-05-24 18:39:45 -07001465 }
1466
Jeff Sharkey706498d2012-02-06 17:35:07 -08001467 // usage: dumpsys netstats --full --uid --tag --poll --checkin
Jeff Sharkey63abc372012-01-11 18:38:16 -08001468 final boolean poll = argSet.contains("--poll") || argSet.contains("poll");
Jeff Sharkey706498d2012-02-06 17:35:07 -08001469 final boolean checkin = argSet.contains("--checkin");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001470 final boolean fullHistory = argSet.contains("--full") || argSet.contains("full");
1471 final boolean includeUid = argSet.contains("--uid") || argSet.contains("detail");
1472 final boolean includeTag = argSet.contains("--tag") || argSet.contains("detail");
1473
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001474 final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, " ");
Jeff Sharkey350083e2011-06-29 10:45:16 -07001475
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001476 synchronized (mStatsLock) {
Makoto Onukida65a522017-01-13 10:23:30 -08001477 if (args.length > 0 && "--proto".equals(args[0])) {
1478 // In this case ignore all other arguments.
Jeff Sharkey4635f102017-09-01 11:27:13 -06001479 dumpProtoLocked(fd);
Makoto Onukida65a522017-01-13 10:23:30 -08001480 return;
1481 }
1482
Jeff Sharkey63abc372012-01-11 18:38:16 -08001483 if (poll) {
Jeff Sharkey1f0b13b2011-09-18 13:30:23 -07001484 performPollLocked(FLAG_PERSIST_ALL | FLAG_PERSIST_FORCE);
Jeff Sharkey3f391352011-06-05 17:42:53 -07001485 pw.println("Forced poll");
1486 return;
1487 }
1488
Jeff Sharkey706498d2012-02-06 17:35:07 -08001489 if (checkin) {
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001490 final long end = System.currentTimeMillis();
1491 final long start = end - duration;
1492
1493 pw.print("v1,");
1494 pw.print(start / SECOND_IN_MILLIS); pw.print(',');
1495 pw.print(end / SECOND_IN_MILLIS); pw.println();
1496
1497 pw.println("xt");
1498 mXtRecorder.dumpCheckin(rawWriter, start, end);
1499
1500 if (includeUid) {
1501 pw.println("uid");
1502 mUidRecorder.dumpCheckin(rawWriter, start, end);
Jeff Sharkey706498d2012-02-06 17:35:07 -08001503 }
Jeff Sharkey55a442e2014-11-18 18:22:21 -08001504 if (includeTag) {
1505 pw.println("tag");
1506 mUidTagRecorder.dumpCheckin(rawWriter, start, end);
1507 }
Jeff Sharkey706498d2012-02-06 17:35:07 -08001508 return;
1509 }
1510
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001511 pw.println("Active interfaces:");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001512 pw.increaseIndent();
Jeff Sharkeyeb2c2c72014-08-11 15:22:51 -07001513 for (int i = 0; i < mActiveIfaces.size(); i++) {
1514 pw.printPair("iface", mActiveIfaces.keyAt(i));
1515 pw.printPair("ident", mActiveIfaces.valueAt(i));
1516 pw.println();
1517 }
1518 pw.decreaseIndent();
1519
1520 pw.println("Active UID interfaces:");
1521 pw.increaseIndent();
1522 for (int i = 0; i < mActiveUidIfaces.size(); i++) {
1523 pw.printPair("iface", mActiveUidIfaces.keyAt(i));
1524 pw.printPair("ident", mActiveUidIfaces.valueAt(i));
1525 pw.println();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001526 }
Jeff Sharkey63abc372012-01-11 18:38:16 -08001527 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001528
Remi NGUYEN VANabc6e182018-04-12 19:26:34 +09001529 // Get the top openSession callers
1530 final SparseIntArray calls;
1531 synchronized (mOpenSessionCallsPerUid) {
1532 calls = mOpenSessionCallsPerUid.clone();
1533 }
1534
1535 final int N = calls.size();
1536 final long[] values = new long[N];
1537 for (int j = 0; j < N; j++) {
1538 values[j] = ((long) calls.valueAt(j) << 32) | calls.keyAt(j);
1539 }
1540 Arrays.sort(values);
1541
1542 pw.println("Top openSession callers (uid=count):");
1543 pw.increaseIndent();
1544 final int end = Math.max(0, N - DUMP_STATS_SESSION_COUNT);
1545 for (int j = N - 1; j >= end; j--) {
1546 final int uid = (int) (values[j] & 0xffffffff);
1547 final int count = (int) (values[j] >> 32);
1548 pw.print(uid); pw.print("="); pw.println(count);
1549 }
1550 pw.decreaseIndent();
1551 pw.println();
1552
Jeff Sharkey63abc372012-01-11 18:38:16 -08001553 pw.println("Dev stats:");
1554 pw.increaseIndent();
1555 mDevRecorder.dumpLocked(pw, fullHistory);
1556 pw.decreaseIndent();
1557
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001558 pw.println("Xt stats:");
1559 pw.increaseIndent();
1560 mXtRecorder.dumpLocked(pw, fullHistory);
1561 pw.decreaseIndent();
1562
Jeff Sharkey63abc372012-01-11 18:38:16 -08001563 if (includeUid) {
1564 pw.println("UID stats:");
1565 pw.increaseIndent();
1566 mUidRecorder.dumpLocked(pw, fullHistory);
1567 pw.decreaseIndent();
Jeff Sharkey905b5892011-09-30 15:19:49 -07001568 }
1569
Jeff Sharkey63abc372012-01-11 18:38:16 -08001570 if (includeTag) {
1571 pw.println("UID tag stats:");
1572 pw.increaseIndent();
1573 mUidTagRecorder.dumpLocked(pw, fullHistory);
1574 pw.decreaseIndent();
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001575 }
1576 }
1577 }
1578
Andreas Gampea36dc622018-02-05 17:19:22 -08001579 @GuardedBy("mStatsLock")
Jeff Sharkey4635f102017-09-01 11:27:13 -06001580 private void dumpProtoLocked(FileDescriptor fd) {
Makoto Onukida65a522017-01-13 10:23:30 -08001581 final ProtoOutputStream proto = new ProtoOutputStream(fd);
1582
1583 // TODO Right now it writes all history. Should it limit to the "since-boot" log?
1584
1585 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
1586 dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
1587 mDevRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
1588 mXtRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
1589 mUidRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
1590 mUidTagRecorder.writeToProtoLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
1591
1592 proto.flush();
1593 }
1594
1595 private static void dumpInterfaces(ProtoOutputStream proto, long tag,
1596 ArrayMap<String, NetworkIdentitySet> ifaces) {
1597 for (int i = 0; i < ifaces.size(); i++) {
1598 final long start = proto.start(tag);
1599
1600 proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
1601 ifaces.valueAt(i).writeToProto(proto, NetworkInterfaceProto.IDENTITIES);
1602
1603 proto.end(start);
1604 }
1605 }
1606
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001607 /**
Jeff Sharkey63abc372012-01-11 18:38:16 -08001608 * Return snapshot of current UID statistics, including any
Jack Yuf9d559c2017-05-26 16:08:22 -07001609 * {@link TrafficStats#UID_TETHERING}, video calling data usage, and {@link #mUidOperations}
1610 * values.
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001611 *
1612 * @param ifaces A list of interfaces the stats should be restricted to, or
1613 * {@link NetworkStats#INTERFACES_ALL}.
Jeff Sharkey61ee0bb2011-05-29 22:50:42 -07001614 */
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001615 private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
1616 throws RemoteException {
1617
Remi NGUYEN VAN75525b32018-02-27 16:47:22 +09001618 // TODO: remove 464xlat adjustments from NetworkStatsFactory and apply all at once here.
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001619 final NetworkStats uidSnapshot = mNetworkManager.getNetworkStatsUidDetail(UID_ALL,
1620 ifaces);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001621
Jeff Sharkey63abc372012-01-11 18:38:16 -08001622 // fold tethering stats and operations into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001623 final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001624 tetherSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
Remi NGUYEN VAN75525b32018-02-27 16:47:22 +09001625 NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, tetherSnapshot);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001626 uidSnapshot.combineAllValues(tetherSnapshot);
Jack Yuf9d559c2017-05-26 16:08:22 -07001627
1628 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
1629 Context.TELEPHONY_SERVICE);
1630
1631 // fold video calling data usage stats into uid snapshot
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001632 final NetworkStats vtStats = telephonyManager.getVtDataUsage(STATS_PER_UID);
Jack Yuf9d559c2017-05-26 16:08:22 -07001633 if (vtStats != null) {
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001634 vtStats.filter(UID_ALL, ifaces, TAG_ALL);
Remi NGUYEN VAN75525b32018-02-27 16:47:22 +09001635 NetworkStatsFactory.apply464xlatAdjustments(uidSnapshot, vtStats);
Jack Yuf9d559c2017-05-26 16:08:22 -07001636 uidSnapshot.combineAllValues(vtStats);
1637 }
Remi NGUYEN VANb6a92012018-03-06 12:36:54 +09001638
Jeff Sharkey63abc372012-01-11 18:38:16 -08001639 uidSnapshot.combineAllValues(mUidOperations);
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001640
Jeff Sharkey63abc372012-01-11 18:38:16 -08001641 return uidSnapshot;
Jeff Sharkey75279902011-05-24 18:39:45 -07001642 }
1643
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001644 /**
Jack Yuf9d559c2017-05-26 16:08:22 -07001645 * Return snapshot of current XT statistics with video calling data usage statistics.
Jack Yub6587ea2016-06-22 11:35:10 -07001646 */
Jack Yuf9d559c2017-05-26 16:08:22 -07001647 private NetworkStats getNetworkStatsXt() throws RemoteException {
Jack Yub6587ea2016-06-22 11:35:10 -07001648 final NetworkStats xtSnapshot = mNetworkManager.getNetworkStatsSummaryXt();
1649
Jack Yuf9d559c2017-05-26 16:08:22 -07001650 final TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(
Jack Yub6587ea2016-06-22 11:35:10 -07001651 Context.TELEPHONY_SERVICE);
1652
Jack Yuf9d559c2017-05-26 16:08:22 -07001653 // Merge video calling data usage into XT
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001654 final NetworkStats vtSnapshot = telephonyManager.getVtDataUsage(STATS_PER_IFACE);
Jack Yuf9d559c2017-05-26 16:08:22 -07001655 if (vtSnapshot != null) {
1656 xtSnapshot.combineAllValues(vtSnapshot);
1657 }
Jack Yub6587ea2016-06-22 11:35:10 -07001658
1659 return xtSnapshot;
1660 }
1661
1662 /**
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001663 * Return snapshot of current tethering statistics. Will return empty
1664 * {@link NetworkStats} if any problems are encountered.
1665 */
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001666 private NetworkStats getNetworkStatsTethering(int how) throws RemoteException {
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001667 try {
Lorenzo Colitti5356a352017-08-17 19:23:08 +09001668 return mNetworkManager.getNetworkStatsTethering(how);
Jeff Sharkeyd4ef8c8f2011-11-10 17:54:23 -08001669 } catch (IllegalStateException e) {
1670 Log.wtf(TAG, "problem reading network stats", e);
1671 return new NetworkStats(0L, 10);
1672 }
1673 }
1674
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001675 @VisibleForTesting
1676 static class HandlerCallback implements Handler.Callback {
1677 private final NetworkStatsService mService;
1678
1679 HandlerCallback(NetworkStatsService service) {
1680 this.mService = service;
1681 }
1682
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001683 @Override
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001684 public boolean handleMessage(Message msg) {
1685 switch (msg.what) {
Jeff Sharkey8e9992a2011-08-23 18:37:23 -07001686 case MSG_PERFORM_POLL: {
Chalard Jean5ecd5f12018-08-22 10:21:26 +09001687 mService.performPoll(FLAG_PERSIST_ALL);
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001688 return true;
1689 }
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001690 case MSG_UPDATE_IFACES: {
Lorenzo Colittic78da292018-01-19 00:50:48 +09001691 mService.updateIfaces(null);
Jeff Sharkey367d15a2011-09-22 14:59:51 -07001692 return true;
1693 }
Chalard Jean5ecd5f12018-08-22 10:21:26 +09001694 case MSG_PERFORM_POLL_REGISTER_ALERT: {
1695 mService.performPoll(FLAG_PERSIST_NETWORK);
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001696 mService.registerGlobalAlert();
Jeff Sharkey25ce9ed2012-02-02 13:07:47 -08001697 return true;
1698 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001699 default: {
1700 return false;
1701 }
1702 }
1703 }
Antonio Cansadocd42acd2016-02-17 13:03:38 -08001704 }
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001705
Jeff Sharkeye0c29952018-02-20 17:24:55 -07001706 private void assertSystemReady() {
1707 if (!mSystemReady) {
1708 throw new IllegalStateException("System not ready");
1709 }
1710 }
1711
Jeff Sharkey4190a042012-04-21 15:36:48 -07001712 private void assertBandwidthControlEnabled() {
1713 if (!isBandwidthControlEnabled()) {
1714 throw new IllegalStateException("Bandwidth module disabled");
1715 }
1716 }
1717
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001718 private boolean isBandwidthControlEnabled() {
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001719 final long token = Binder.clearCallingIdentity();
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001720 try {
1721 return mNetworkManager.isBandwidthControlEnabled();
1722 } catch (RemoteException e) {
1723 // ignored; service lives in system_server
1724 return false;
Jeff Sharkey49c1d172012-04-23 14:39:19 -07001725 } finally {
1726 Binder.restoreCallingIdentity(token);
Jeff Sharkey418d12d2011-12-13 15:38:03 -08001727 }
1728 }
1729
Jeff Sharkey63abc372012-01-11 18:38:16 -08001730 private class DropBoxNonMonotonicObserver implements NonMonotonicObserver<String> {
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001731 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001732 public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
1733 int rightIndex, String cookie) {
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001734 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
Jeff Sharkey63abc372012-01-11 18:38:16 -08001735
1736 // record error for debugging
1737 final StringBuilder builder = new StringBuilder();
1738 builder.append("found non-monotonic " + cookie + " values at left[" + leftIndex
1739 + "] - right[" + rightIndex + "]\n");
1740 builder.append("left=").append(left).append('\n');
1741 builder.append("right=").append(right).append('\n');
1742
Jeff Sharkeyb5a97e62018-05-22 11:35:29 -06001743 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1744 builder.toString());
1745 }
1746
1747 @Override
1748 public void foundNonMonotonic(
1749 NetworkStats stats, int statsIndex, String cookie) {
1750 Log.w(TAG, "Found non-monotonic values; saving to dropbox");
1751
1752 final StringBuilder builder = new StringBuilder();
1753 builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
1754 builder.append("stats=").append(stats).append('\n');
1755
1756 mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
1757 builder.toString());
Jeff Sharkeyb5d55e32011-08-10 17:53:27 -07001758 }
1759 }
1760
Jeff Sharkey1b5a2a92011-06-18 18:34:16 -07001761 /**
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001762 * Default external settings that read from
Jeff Sharkey625239a2012-09-26 22:03:49 -07001763 * {@link android.provider.Settings.Global}.
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001764 */
1765 private static class DefaultNetworkStatsSettings implements NetworkStatsSettings {
1766 private final ContentResolver mResolver;
1767
1768 public DefaultNetworkStatsSettings(Context context) {
1769 mResolver = checkNotNull(context.getContentResolver());
1770 // TODO: adjust these timings for production builds
1771 }
1772
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001773 private long getGlobalLong(String name, long def) {
1774 return Settings.Global.getLong(mResolver, name, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001775 }
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001776 private boolean getGlobalBoolean(String name, boolean def) {
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001777 final int defInt = def ? 1 : 0;
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001778 return Settings.Global.getInt(mResolver, name, defInt) != 0;
Jeff Sharkey991d1b12011-09-14 19:31:04 -07001779 }
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001780
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001781 @Override
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001782 public long getPollInterval() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001783 return getGlobalLong(NETSTATS_POLL_INTERVAL, 30 * MINUTE_IN_MILLIS);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001784 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001785 @Override
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001786 public long getGlobalAlertBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001787 return getGlobalLong(NETSTATS_GLOBAL_ALERT_BYTES, def);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001788 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001789 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001790 public boolean getSampleEnabled() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001791 return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true);
Jeff Sharkey63abc372012-01-11 18:38:16 -08001792 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001793 @Override
Jeff Sharkeyf4de2942017-08-29 15:32:13 -06001794 public boolean getAugmentEnabled() {
1795 return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true);
1796 }
1797 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001798 public Config getDevConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001799 return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS),
1800 getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1801 getGlobalLong(NETSTATS_DEV_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001802 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001803 @Override
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001804 public Config getXtConfig() {
1805 return getDevConfig();
1806 }
Jeff Sharkeye8914c32012-05-01 16:26:09 -07001807 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001808 public Config getUidConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001809 return new Config(getGlobalLong(NETSTATS_UID_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1810 getGlobalLong(NETSTATS_UID_ROTATE_AGE, 15 * DAY_IN_MILLIS),
1811 getGlobalLong(NETSTATS_UID_DELETE_AGE, 90 * DAY_IN_MILLIS));
Jeff Sharkey63abc372012-01-11 18:38:16 -08001812 }
Jeff Sharkeybfdd6802012-04-09 10:49:19 -07001813 @Override
Jeff Sharkey63abc372012-01-11 18:38:16 -08001814 public Config getUidTagConfig() {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001815 return new Config(getGlobalLong(NETSTATS_UID_TAG_BUCKET_DURATION, 2 * HOUR_IN_MILLIS),
1816 getGlobalLong(NETSTATS_UID_TAG_ROTATE_AGE, 5 * DAY_IN_MILLIS),
1817 getGlobalLong(NETSTATS_UID_TAG_DELETE_AGE, 15 * DAY_IN_MILLIS));
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001818 }
1819 @Override
1820 public long getDevPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001821 return getGlobalLong(NETSTATS_DEV_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001822 }
1823 @Override
1824 public long getXtPersistBytes(long def) {
1825 return getDevPersistBytes(def);
1826 }
1827 @Override
1828 public long getUidPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001829 return getGlobalLong(NETSTATS_UID_PERSIST_BYTES, def);
Jeff Sharkeyac3fcb12012-05-02 18:11:52 -07001830 }
1831 @Override
1832 public long getUidTagPersistBytes(long def) {
Jeff Sharkeye6e61972012-09-14 13:47:51 -07001833 return getGlobalLong(NETSTATS_UID_TAG_PERSIST_BYTES, def);
Jeff Sharkey39ebc212011-06-11 17:25:42 -07001834 }
1835 }
Chenbo Fengd3d9c4e2017-11-14 17:54:17 -08001836
1837 private static int TYPE_RX_BYTES;
1838 private static int TYPE_RX_PACKETS;
1839 private static int TYPE_TX_BYTES;
1840 private static int TYPE_TX_PACKETS;
1841 private static int TYPE_TCP_RX_PACKETS;
1842 private static int TYPE_TCP_TX_PACKETS;
1843
Chenbo Fengaedd6a32017-11-20 18:23:46 -08001844 private static native long nativeGetTotalStat(int type, boolean useBpfStats);
1845 private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats);
1846 private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats);
Jeff Sharkey75279902011-05-24 18:39:45 -07001847}