From 20f4805aad99c92f082b633202e4ff54f24861b8 Mon Sep 17 00:00:00 2001 From: junyulai Date: Thu, 12 Dec 2019 19:42:59 +0800 Subject: [PATCH 01/64] [SM02] Support record mobile network stats by collapsed rat type Previously network stats could be recorded by different rat type. However, the feature was disabled by ag/173504 since rat type frequently flapping between HSPA+ and UMTS. Given that this feature might be useful for collecting metrics, re-implement it based on current architecture and reduce the overhead introduced by frequently flapping by: 1. only react when rat type changes between 2G/3G/4G/5G. 2. reduce the number of records by only recording a subset of rat type that represented for a given network class. 3. enforce 1 second rate limit if flapping too much. Note that the feature is still disabled but will be enabled in follow-up patches. Test: manual test Bug: 129082217 Change-Id: Ic6b2f10f2c8b082820e0662eb9cee70d70d28cd6 --- core/java/android/net/NetworkIdentity.java | 15 ++-- core/java/android/net/NetworkTemplate.java | 40 +++++++++ .../server/net/NetworkStatsService.java | 89 ++++++++++++++++++- 3 files changed, 134 insertions(+), 10 deletions(-) diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index c1198aac27..b67ad519b4 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -25,6 +25,7 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Build; import android.service.NetworkIdentityProto; +import android.telephony.Annotation.NetworkType; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -42,11 +43,8 @@ public class NetworkIdentity implements Comparable { /** * When enabled, combine all {@link #mSubType} together under * {@link #SUBTYPE_COMBINED}. - * - * @deprecated we no longer offer to collect statistics on a per-subtype - * basis; this is always disabled. */ - @Deprecated + // TODO: make this flag configurable through settings. See http://b/146415925 public static final boolean COMBINE_SUBTYPE_ENABLED = true; public static final int SUBTYPE_COMBINED = -1; @@ -187,13 +185,14 @@ public class NetworkIdentity implements Comparable { } /** - * Build a {@link NetworkIdentity} from the given {@link NetworkState}, - * assuming that any mobile networks are using the current IMSI. + * Build a {@link NetworkIdentity} from the given {@link NetworkState} and {@code subType}, + * assuming that any mobile networks are using the current IMSI. The subType if applicable, + * should be set as one of the TelephonyManager.NETWORK_TYPE_* constants, or + * {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not. */ public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state, - boolean defaultNetwork) { + boolean defaultNetwork, @NetworkType int subType) { final int type = state.networkInfo.getType(); - final int subType = state.networkInfo.getSubtype(); String subscriberId = null; String networkId = null; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 5498f74ba2..6080d16b9d 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -37,6 +37,7 @@ import static android.net.wifi.WifiInfo.sanitizeSsid; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.TelephonyManager; import android.util.BackupUtils; import android.util.Log; @@ -394,6 +395,45 @@ public class NetworkTemplate implements Parcelable { } } + /** + * Get a Radio Access Technology(RAT) type that is representative of a group of RAT types. + * The mapping is corresponding to {@code TelephonyManager#NETWORK_CLASS_BIT_MASK_*}. + * + * @param ratType An integer defined in {@code TelephonyManager#NETWORK_TYPE_*}. + */ + // TODO: 1. Consider move this to TelephonyManager if used by other modules. + // 2. Consider make this configurable. + // 3. Use TelephonyManager APIs when available. + public static int getCollapsedRatType(int ratType) { + switch (ratType) { + case TelephonyManager.NETWORK_TYPE_GPRS: + case TelephonyManager.NETWORK_TYPE_GSM: + case TelephonyManager.NETWORK_TYPE_EDGE: + case TelephonyManager.NETWORK_TYPE_IDEN: + case TelephonyManager.NETWORK_TYPE_CDMA: + case TelephonyManager.NETWORK_TYPE_1xRTT: + return TelephonyManager.NETWORK_TYPE_GSM; + case TelephonyManager.NETWORK_TYPE_EVDO_0: + case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_EVDO_B: + case TelephonyManager.NETWORK_TYPE_EHRPD: + case TelephonyManager.NETWORK_TYPE_UMTS: + case TelephonyManager.NETWORK_TYPE_HSDPA: + case TelephonyManager.NETWORK_TYPE_HSUPA: + case TelephonyManager.NETWORK_TYPE_HSPA: + case TelephonyManager.NETWORK_TYPE_HSPAP: + case TelephonyManager.NETWORK_TYPE_TD_SCDMA: + return TelephonyManager.NETWORK_TYPE_UMTS; + case TelephonyManager.NETWORK_TYPE_LTE: + case TelephonyManager.NETWORK_TYPE_IWLAN: + return TelephonyManager.NETWORK_TYPE_LTE; + case TelephonyManager.NETWORK_TYPE_NR: + return TelephonyManager.NETWORK_TYPE_NR; + default: + return TelephonyManager.NETWORK_TYPE_UNKNOWN; + } + } + /** * Check if matches Wi-Fi network template. */ diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 10136b3b8b..7c4624d25c 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -27,6 +27,8 @@ import static android.content.Intent.EXTRA_UID; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.isNetworkTypeMobile; +import static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED; +import static android.net.NetworkIdentity.SUBTYPE_COMBINED; import static android.net.NetworkStack.checkNetworkStackPermission; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; import static android.net.NetworkStats.IFACE_ALL; @@ -45,6 +47,7 @@ import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkTemplate.buildTemplateMobileWildcard; import static android.net.NetworkTemplate.buildTemplateWifiWildcard; +import static android.net.NetworkTemplate.getCollapsedRatType; import static android.net.TrafficStats.KB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES; import static android.os.Trace.TRACE_TAG_NETWORK; @@ -64,6 +67,9 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE; +import static android.telephony.PhoneStateListener.LISTEN_NONE; +import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE; +import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -109,6 +115,7 @@ import android.os.Binder; import android.os.DropBoxManager; import android.os.Environment; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.IBinder; import android.os.INetworkManagementService; @@ -125,6 +132,8 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.service.NetworkInterfaceProto; import android.service.NetworkStatsServiceDumpProto; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; import android.telephony.TelephonyManager; import android.text.format.DateUtils; @@ -157,6 +166,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.concurrent.Executor; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -173,6 +183,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final int MSG_PERFORM_POLL = 1; // Perform polling, persist network, and register the global alert again. private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2; + private static final int MSG_UPDATE_IFACES = 3; /** Flags to control detail level of poll event. */ private static final int FLAG_PERSIST_NETWORK = 0x1; @@ -280,6 +291,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @GuardedBy("mStatsLock") private Network[] mDefaultNetworks = new Network[0]; + /** Last states of all networks sent from ConnectivityService. */ + @GuardedBy("mStatsLock") + @Nullable + private NetworkState[] mLastNetworkStates = null; + private final DropBoxNonMonotonicObserver mNonMonotonicObserver = new DropBoxNonMonotonicObserver(); @@ -355,6 +371,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { performPoll(FLAG_PERSIST_ALL); break; } + case MSG_UPDATE_IFACES: { + // If no cached states, ignore. + if (mLastNetworkStates == null) break; + updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface); + break; + } case MSG_PERFORM_POLL_REGISTER_ALERT: { performPoll(FLAG_PERSIST_NETWORK); registerGlobalAlert(); @@ -407,6 +429,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final HandlerThread handlerThread = mDeps.makeHandlerThread(); handlerThread.start(); mHandler = new NetworkStatsHandler(handlerThread.getLooper()); + mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler)); } /** @@ -486,6 +509,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), pollIntent); + // TODO: listen to changes from all subscriptions. + // watch for networkType changes + if (!COMBINE_SUBTYPE_ENABLED) { + mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE); + } + registerGlobalAlert(); } @@ -506,6 +535,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContext.unregisterReceiver(mUserReceiver); mContext.unregisterReceiver(mShutdownReceiver); + if (!COMBINE_SUBTYPE_ENABLED) { + mTeleManager.listen(mPhoneListener, LISTEN_NONE); + } + final long currentTime = mClock.millis(); // persist any pending stats @@ -1156,6 +1189,38 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } }; + /** + * Receiver that watches for {@link TelephonyManager} changes, such as + * transitioning between Radio Access Technology(RAT) types. + */ + @NonNull + private final NetworkTypeListener mPhoneListener; + + class NetworkTypeListener extends PhoneStateListener { + private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN; + + NetworkTypeListener(@NonNull Executor executor) { + super(executor); + } + + @Override + public void onServiceStateChanged(@NonNull ServiceState ss) { + final int networkType = ss.getDataNetworkType(); + final int collapsedRatType = getCollapsedRatType(networkType); + if (collapsedRatType == mLastCollapsedRatType) return; + + if (LOGV) { + Log.d(TAG, "subtype changed for mobile: " + + mLastCollapsedRatType + " -> " + collapsedRatType); + } + // Protect service from frequently updating. Remove pending messages if any. + mHandler.removeMessages(MSG_UPDATE_IFACES); + mLastCollapsedRatType = collapsedRatType; + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS); + } + } + private void updateIfaces( Network[] defaultNetworks, NetworkState[] networkStates, @@ -1177,7 +1242,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * they are combined under a single {@link NetworkIdentitySet}. */ @GuardedBy("mStatsLock") - private void updateIfacesLocked(Network[] defaultNetworks, NetworkState[] states) { + private void updateIfacesLocked(@Nullable Network[] defaultNetworks, + @NonNull NetworkState[] states) { if (!mSystemReady) return; if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); @@ -1197,13 +1263,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mDefaultNetworks = defaultNetworks; } + mLastNetworkStates = states; + final ArraySet mobileIfaces = new ArraySet<>(); for (NetworkState state : states) { if (state.networkInfo.isConnected()) { final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType()); final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network); + final int subType = getSubTypeForState(state); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state, - isDefault); + isDefault, subType); // Traffic occurring on the base interface is always counted for // both total usage and UID details. @@ -1264,6 +1333,22 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); } + /** + * If combine subtype is not enabled. For networks with {@code TRANSPORT_CELLULAR}, get + * subType that obtained through {@link PhoneStateListener}. Otherwise, return 0 given that + * other networks with different transport types do not actually fill this value. + */ + private int getSubTypeForState(@NonNull NetworkState state) { + if (COMBINE_SUBTYPE_ENABLED) return SUBTYPE_COMBINED; + + if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + return 0; + } + + // TODO: return different subType for different subscriptions. + return mPhoneListener.mLastCollapsedRatType; + } + private static NetworkIdentitySet findOrCreateNetworkIdentitySet( ArrayMap map, K key) { NetworkIdentitySet ident = map.get(key); From ec1c5fe86ccf16db374fcc53af40c233d53e2b32 Mon Sep 17 00:00:00 2001 From: junyulai Date: Fri, 20 Dec 2019 16:35:34 +0800 Subject: [PATCH 02/64] [SM04] Support fetching data with NetworkTemplate with subType Add a NetworkTemplate build function that allows user to specify subType. NetworkStats corresponding to the same group would be retrieved. Test: atest FrameworksNetTests Bug: 129082217 Change-Id: Ie2d229be0b6bd239f799989c070475c73a096d71 --- core/java/android/net/NetworkTemplate.java | 60 +++++++++++++++++++--- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 6080d16b9d..cb9463a59d 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -34,10 +34,13 @@ import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_YES; import static android.net.wifi.WifiInfo.sanitizeSsid; +import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.Annotation.NetworkType; import android.telephony.TelephonyManager; +import android.text.TextUtils; import android.util.BackupUtils; import android.util.Log; @@ -74,6 +77,14 @@ public class NetworkTemplate implements Parcelable { public static final int MATCH_BLUETOOTH = 8; public static final int MATCH_PROXY = 9; + /** + * Include all network types when filtering. This is meant to merge in with the + * {@code TelephonyManager.NETWORK_TYPE_*} constants, and thus needs to stay in sync. + * + * @hide + */ + public static final int NETWORK_TYPE_ALL = -1; + private static boolean isKnownMatchRule(final int rule) { switch (rule) { case MATCH_MOBILE: @@ -118,7 +129,22 @@ public class NetworkTemplate implements Parcelable { } /** - * Template to match {@link ConnectivityManager#TYPE_MOBILE} networks, + * Template to match cellular networks with the given IMSI and {@code ratType}. + * Use {@link #NETWORK_TYPE_ALL} to include all network types when filtering. + * See {@code TelephonyManager.NETWORK_TYPE_*}. + */ + public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId, + @NetworkType int ratType) { + if (TextUtils.isEmpty(subscriberId)) { + return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType); + } + return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null, + METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType); + } + + /** + * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks, * regardless of IMSI. */ @UnsupportedAppUsage @@ -127,7 +153,7 @@ public class NetworkTemplate implements Parcelable { } /** - * Template to match all {@link ConnectivityManager#TYPE_WIFI} networks, + * Template to match all metered {@link ConnectivityManager#TYPE_WIFI} networks, * regardless of SSID. */ @UnsupportedAppUsage @@ -193,6 +219,7 @@ public class NetworkTemplate implements Parcelable { private final int mMetered; private final int mRoaming; private final int mDefaultNetwork; + private final int mSubType; @UnsupportedAppUsage public NetworkTemplate(int matchRule, String subscriberId, String networkId) { @@ -202,11 +229,11 @@ public class NetworkTemplate implements Parcelable { public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, String networkId) { this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL, - DEFAULT_NETWORK_ALL); + DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL); } public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds, - String networkId, int metered, int roaming, int defaultNetwork) { + String networkId, int metered, int roaming, int defaultNetwork, int subType) { mMatchRule = matchRule; mSubscriberId = subscriberId; mMatchSubscriberIds = matchSubscriberIds; @@ -214,6 +241,7 @@ public class NetworkTemplate implements Parcelable { mMetered = metered; mRoaming = roaming; mDefaultNetwork = defaultNetwork; + mSubType = subType; if (!isKnownMatchRule(matchRule)) { Log.e(TAG, "Unknown network template rule " + matchRule @@ -229,6 +257,7 @@ public class NetworkTemplate implements Parcelable { mMetered = in.readInt(); mRoaming = in.readInt(); mDefaultNetwork = in.readInt(); + mSubType = in.readInt(); } @Override @@ -240,6 +269,7 @@ public class NetworkTemplate implements Parcelable { dest.writeInt(mMetered); dest.writeInt(mRoaming); dest.writeInt(mDefaultNetwork); + dest.writeInt(mSubType); } @Override @@ -272,13 +302,16 @@ public class NetworkTemplate implements Parcelable { builder.append(", defaultNetwork=").append(NetworkStats.defaultNetworkToString( mDefaultNetwork)); } + if (mSubType != NETWORK_TYPE_ALL) { + builder.append(", subType=").append(mSubType); + } return builder.toString(); } @Override public int hashCode() { return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming, - mDefaultNetwork); + mDefaultNetwork, mSubType); } @Override @@ -290,7 +323,8 @@ public class NetworkTemplate implements Parcelable { && Objects.equals(mNetworkId, other.mNetworkId) && mMetered == other.mMetered && mRoaming == other.mRoaming - && mDefaultNetwork == other.mDefaultNetwork; + && mDefaultNetwork == other.mDefaultNetwork + && mSubType == other.mSubType; } return false; } @@ -377,6 +411,11 @@ public class NetworkTemplate implements Parcelable { || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork); } + private boolean matchesCollapsedRatType(NetworkIdentity ident) { + return mSubType == NETWORK_TYPE_ALL + || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType); + } + public boolean matchesSubscriberId(String subscriberId) { return ArrayUtils.contains(mMatchSubscriberIds, subscriberId); } @@ -389,9 +428,13 @@ public class NetworkTemplate implements Parcelable { // TODO: consider matching against WiMAX subscriber identity return true; } else { + // Only metered mobile network would be matched regardless of metered filter. + // This is used to exclude non-metered APNs, e.g. IMS. See ag/908650. + // TODO: Respect metered filter and remove mMetered condition. return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered)) && !ArrayUtils.isEmpty(mMatchSubscriberIds) - && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId); + && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId) + && matchesCollapsedRatType(ident); } } @@ -461,7 +504,8 @@ public class NetworkTemplate implements Parcelable { if (ident.mType == TYPE_WIMAX) { return true; } else { - return sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered); + return (sForceAllNetworkTypes || (ident.mType == TYPE_MOBILE && ident.mMetered)) + && matchesCollapsedRatType(ident); } } From ff1d70e3647f50ddefe1cce76d95322942896f77 Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 31 Dec 2019 13:40:15 +0800 Subject: [PATCH 03/64] [SM05] Enable record mobile network stats by collapsed rat type Switch on the recording in device side. Metrics will be collected in follow-up patches which can be independently enabled/disabled. This change also fix the fail in NetworkStatsCollectionTest which caused by enabling this feature, where the rounding problem happened when records are distributed into smaller buckets and categorized into more NetworkIdentity. Test: atest FrameworksNetTests Bug: 129082217 Change-Id: If330e85330a4ff713dd420c98d42fa741eabd90a --- core/java/android/net/NetworkIdentity.java | 2 +- .../core/java/com/android/server/net/NetworkStatsService.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index b67ad519b4..2cf3531d2f 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -45,7 +45,7 @@ public class NetworkIdentity implements Comparable { * {@link #SUBTYPE_COMBINED}. */ // TODO: make this flag configurable through settings. See http://b/146415925 - public static final boolean COMBINE_SUBTYPE_ENABLED = true; + public static final boolean COMBINE_SUBTYPE_ENABLED = false; public static final int SUBTYPE_COMBINED = -1; diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 7c4624d25c..ff4407aa12 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -1209,7 +1209,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final int collapsedRatType = getCollapsedRatType(networkType); if (collapsedRatType == mLastCollapsedRatType) return; - if (LOGV) { + if (LOGD) { Log.d(TAG, "subtype changed for mobile: " + mLastCollapsedRatType + " -> " + collapsedRatType); } @@ -1217,7 +1217,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mHandler.removeMessages(MSG_UPDATE_IFACES); mLastCollapsedRatType = collapsedRatType; mHandler.sendMessageDelayed( - mHandler.obtainMessage(MSG_UPDATE_IFACES), SECOND_IN_MILLIS); + mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay()); } } From 550d61b8facb4cb59391f38ebc364131f8fde359 Mon Sep 17 00:00:00 2001 From: junyulai Date: Thu, 2 Jan 2020 19:35:59 +0800 Subject: [PATCH 04/64] [SM07] Make combine subtype configurable from Settings Note that enabling/disabling would not take effect until device reboot. This will be addressed in follow-up patch. Test: 1. atest NetworkStatsServieTest SettingsBackupTest 2. adb shell settings put global netstats_combine_subtype_enabled 1|0 Bug: 146415925 Change-Id: Ic94da540afa479ed18f1b6fbda4ae3216c37476b --- core/java/android/net/NetworkIdentity.java | 11 +-- .../server/net/NetworkStatsService.java | 69 ++++++++++++------- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 2cf3531d2f..0948a4da1a 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -40,13 +40,6 @@ import java.util.Objects; public class NetworkIdentity implements Comparable { private static final String TAG = "NetworkIdentity"; - /** - * When enabled, combine all {@link #mSubType} together under - * {@link #SUBTYPE_COMBINED}. - */ - // TODO: make this flag configurable through settings. See http://b/146415925 - public static final boolean COMBINE_SUBTYPE_ENABLED = false; - public static final int SUBTYPE_COMBINED = -1; final int mType; @@ -61,7 +54,7 @@ public class NetworkIdentity implements Comparable { int type, int subType, String subscriberId, String networkId, boolean roaming, boolean metered, boolean defaultNetwork) { mType = type; - mSubType = COMBINE_SUBTYPE_ENABLED ? SUBTYPE_COMBINED : subType; + mSubType = subType; mSubscriberId = subscriberId; mNetworkId = networkId; mRoaming = roaming; @@ -93,7 +86,7 @@ public class NetworkIdentity implements Comparable { final StringBuilder builder = new StringBuilder("{"); builder.append("type=").append(getNetworkTypeName(mType)); builder.append(", subType="); - if (COMBINE_SUBTYPE_ENABLED) { + if (mSubType == SUBTYPE_COMBINED) { builder.append("COMBINED"); } else { builder.append(mSubType); diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index ff4407aa12..d8264b3625 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -27,7 +27,6 @@ import static android.content.Intent.EXTRA_UID; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.isNetworkTypeMobile; -import static android.net.NetworkIdentity.COMBINE_SUBTYPE_ENABLED; import static android.net.NetworkIdentity.SUBTYPE_COMBINED; import static android.net.NetworkStack.checkNetworkStackPermission; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; @@ -52,6 +51,7 @@ import static android.net.TrafficStats.KB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETSTATS_AUGMENT_ENABLED; +import static android.provider.Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED; import static android.provider.Settings.Global.NETSTATS_DEV_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_DEV_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES; @@ -240,12 +240,20 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * Settings that can be changed externally. */ public interface NetworkStatsSettings { - public long getPollInterval(); - public long getPollDelay(); - public boolean getSampleEnabled(); - public boolean getAugmentEnabled(); + long getPollInterval(); + long getPollDelay(); + boolean getSampleEnabled(); + boolean getAugmentEnabled(); + /** + * When enabled, all mobile data is reported under {@link NetworkIdentity#SUBTYPE_COMBINED}. + * When disabled, mobile data is broken down by a granular subtype representative of the + * actual subtype. {@see NetworkTemplate#getCollapsedRatType}. + * Enabling this decreases the level of detail but saves performance, disk space and + * amount of data logged. + */ + boolean getCombineSubtypeEnabled(); - public static class Config { + class Config { public final long bucketDuration; public final long rotateAgeMillis; public final long deleteAgeMillis; @@ -257,16 +265,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - public Config getDevConfig(); - public Config getXtConfig(); - public Config getUidConfig(); - public Config getUidTagConfig(); + Config getDevConfig(); + Config getXtConfig(); + Config getUidConfig(); + Config getUidTagConfig(); - public long getGlobalAlertBytes(long def); - public long getDevPersistBytes(long def); - public long getXtPersistBytes(long def); - public long getUidPersistBytes(long def); - public long getUidTagPersistBytes(long def); + long getGlobalAlertBytes(long def); + long getDevPersistBytes(long def); + long getXtPersistBytes(long def); + long getUidPersistBytes(long def); + long getUidTagPersistBytes(long def); } private final Object mStatsLock = new Object(); @@ -509,9 +517,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), pollIntent); - // TODO: listen to changes from all subscriptions. + // TODO: 1. listen to changes from all subscriptions. + // 2. listen to settings changed to support dynamically enable/disable. // watch for networkType changes - if (!COMBINE_SUBTYPE_ENABLED) { + if (!mSettings.getCombineSubtypeEnabled()) { mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE); } @@ -535,9 +544,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContext.unregisterReceiver(mUserReceiver); mContext.unregisterReceiver(mShutdownReceiver); - if (!COMBINE_SUBTYPE_ENABLED) { - mTeleManager.listen(mPhoneListener, LISTEN_NONE); - } + mTeleManager.listen(mPhoneListener, LISTEN_NONE); final long currentTime = mClock.millis(); @@ -1265,12 +1272,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mLastNetworkStates = states; + final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled(); final ArraySet mobileIfaces = new ArraySet<>(); for (NetworkState state : states) { if (state.networkInfo.isConnected()) { final boolean isMobile = isNetworkTypeMobile(state.networkInfo.getType()); final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network); - final int subType = getSubTypeForState(state); + final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED + : getSubTypeForState(state); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state, isDefault, subType); @@ -1334,13 +1343,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } /** - * If combine subtype is not enabled. For networks with {@code TRANSPORT_CELLULAR}, get - * subType that obtained through {@link PhoneStateListener}. Otherwise, return 0 given that - * other networks with different transport types do not actually fill this value. + * For networks with {@code TRANSPORT_CELLULAR}, get subType that was obtained through + * {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different + * transport types do not actually fill this value. */ private int getSubTypeForState(@NonNull NetworkState state) { - if (COMBINE_SUBTYPE_ENABLED) return SUBTYPE_COMBINED; - if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { return 0; } @@ -1702,6 +1709,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return; } + pw.println("Configs:"); + pw.increaseIndent(); + pw.printPair(NETSTATS_COMBINE_SUBTYPE_ENABLED, mSettings.getCombineSubtypeEnabled()); + pw.println(); + pw.decreaseIndent(); + pw.println("Active interfaces:"); pw.increaseIndent(); for (int i = 0; i < mActiveIfaces.size(); i++) { @@ -2130,6 +2143,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return getGlobalBoolean(NETSTATS_AUGMENT_ENABLED, true); } @Override + public boolean getCombineSubtypeEnabled() { + return getGlobalBoolean(NETSTATS_COMBINE_SUBTYPE_ENABLED, false); + } + @Override public Config getDevConfig() { return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS), getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS), From 149a1cefe3fb5bd8034e57f8c8f7a36875dc8031 Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 11 Feb 2020 14:59:38 +0800 Subject: [PATCH 05/64] [SM06] Collect mobile NetworkStats metrics by collapsed rat type Test: adb shell cmd stats pull-source 10000~10003 adb shell dumpsys netstats --uid Bug: 129082217 Change-Id: I726e74f5c63a6ed456cb13ea259b58c7a33bec76 --- core/java/android/net/NetworkTemplate.java | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index cb9463a59d..eba7ff3483 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -34,6 +34,7 @@ import static android.net.NetworkStats.ROAMING_NO; import static android.net.NetworkStats.ROAMING_YES; import static android.net.wifi.WifiInfo.sanitizeSsid; +import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.os.Parcel; @@ -52,6 +53,8 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -477,6 +480,32 @@ public class NetworkTemplate implements Parcelable { } } + /** + * Return all supported collapsed RAT types that could be returned by + * {@link #getCollapsedRatType(int)}. + */ + @NonNull + public static final int[] getAllCollapsedRatTypes() { + final int[] ratTypes = TelephonyManager.getAllNetworkTypes(); + final HashSet collapsedRatTypes = new HashSet<>(); + for (final int ratType : ratTypes) { + collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(ratType)); + } + // Ensure that unknown type is returned. + collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN); + return toIntArray(collapsedRatTypes); + } + + @NonNull + private static int[] toIntArray(@NonNull Collection list) { + final int[] array = new int[list.size()]; + int i = 0; + for (final Integer item : list) { + array[i++] = item; + } + return array; + } + /** * Check if matches Wi-Fi network template. */ From 3693a4c1ef4a66ece8575426dd916e1adec5214a Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 4 Mar 2020 12:48:50 +0800 Subject: [PATCH 06/64] [SM09] Add helper class to monitor RAT type change per sub In current design, Rat type change in NSS is only for default subscription. This is only correct for single sim project. However, it does not correct for multi-sim scenarios such as CBRS or DSDS, given that all data usage will be attributed to the Rat type of default sub. Thus, add a helper class to monitor subscription change event, and register/unregister dynamically for Rat type change for every subscription. Note that unit test of the helper class will be addressed in follow-up patch. Test: m -j Bug: 146415925 Change-Id: I0055f6b55c209a073ce997fc7a144477f9db7069 --- .../net/NetworkStatsSubscriptionsMonitor.java | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java new file mode 100644 index 0000000000..0bdf3f22ee --- /dev/null +++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.net; + +import static android.net.NetworkTemplate.getCollapsedRatType; + +import android.annotation.NonNull; +import android.content.Context; +import android.telephony.Annotation; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Log; + +import com.android.internal.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.Executor; + +/** + * Helper class that watches for events that are triggered per subscription. + */ +// TODO (b/152176562): Write tests to verify subscription changes generate corresponding +// register/unregister calls. +public class NetworkStatsSubscriptionsMonitor extends + SubscriptionManager.OnSubscriptionsChangedListener { + + /** + * Interface that this monitor uses to delegate event handling to NetworkStatsService. + */ + public interface Delegate { + /** + * Notify that the collapsed RAT type has been changed for any subscription. The method + * will also be triggered for any existing sub when start and stop monitoring. + * + * @param subscriberId IMSI of the subscription. + * @param collapsedRatType collapsed RAT type. + * @see android.net.NetworkTemplate#getCollapsedRatType(int). + */ + void onCollapsedRatTypeChanged(@NonNull String subscriberId, + @Annotation.NetworkType int collapsedRatType); + } + private final Delegate mDelegate; + + /** + * Receivers that watches for {@link ServiceState} changes for each subscription, to + * monitor the transitioning between Radio Access Technology(RAT) types for each sub. + */ + @NonNull + private final CopyOnWriteArrayList mRatListeners = + new CopyOnWriteArrayList<>(); + + @NonNull + private final SubscriptionManager mSubscriptionManager; + @NonNull + private final TelephonyManager mTeleManager; + + @NonNull + private final Executor mExecutor; + + NetworkStatsSubscriptionsMonitor(@NonNull Context context, @NonNull Executor executor, + @NonNull Delegate delegate) { + super(); + mSubscriptionManager = (SubscriptionManager) context.getSystemService( + Context.TELEPHONY_SUBSCRIPTION_SERVICE); + mTeleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + mExecutor = executor; + mDelegate = delegate; + } + + @Override + public void onSubscriptionsChanged() { + // Collect active subId list, hidden subId such as opportunistic subscriptions are + // also needed to track CBRS. + final List newSubs = getActiveSubIdList(mSubscriptionManager); + + for (final int subId : newSubs) { + final RatTypeListener match = CollectionUtils.find(mRatListeners, + it -> it.mSubId == subId); + if (match != null) continue; + + // Create listener for every newly added sub. Also store subscriberId into it to + // prevent binder call to telephony when querying RAT. + final String subscriberId = mTeleManager.getSubscriberId(subId); + if (TextUtils.isEmpty(subscriberId)) { + Log.wtf(NetworkStatsService.TAG, + "Empty subscriberId for newly added sub: " + subId); + } + final RatTypeListener listener = + new RatTypeListener(mExecutor, this, subId, subscriberId); + mRatListeners.add(listener); + + // Register listener to the telephony manager that associated with specific sub. + mTeleManager.createForSubscriptionId(subId) + .listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE); + } + + for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) { + // If the new list contains the subId of the listener, keeps it. + final Integer match = CollectionUtils.find(newSubs, it -> it == listener.mSubId); + if (match != null) continue; + + handleRemoveRatTypeListener(listener); + } + } + + @NonNull + private List getActiveSubIdList(@NonNull SubscriptionManager subscriptionManager) { + final ArrayList ret = new ArrayList<>(); + final int[] ids = subscriptionManager.getCompleteActiveSubscriptionIdList(); + for (int id : ids) ret.add(id); + return ret; + } + + /** + * Get a collapsed RatType for the given subscriberId. + * + * @param subscriberId the target subscriberId + * @return collapsed RatType for the given subscriberId + */ + public int getRatTypeForSubscriberId(@NonNull String subscriberId) { + final RatTypeListener match = CollectionUtils.find(mRatListeners, + it -> TextUtils.equals(subscriberId, it.mSubscriberId)); + return match != null ? match.mLastCollapsedRatType : TelephonyManager.NETWORK_TYPE_UNKNOWN; + } + + /** + * Start monitoring events that triggered per subscription. + */ + public void start() { + mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor, this); + } + + /** + * Unregister subscription changes and all listeners for each subscription. + */ + public void stop() { + mSubscriptionManager.removeOnSubscriptionsChangedListener(this); + + for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) { + handleRemoveRatTypeListener(listener); + } + } + + private void handleRemoveRatTypeListener(@NonNull RatTypeListener listener) { + mTeleManager.createForSubscriptionId(listener.mSubId) + .listen(listener, PhoneStateListener.LISTEN_NONE); + mRatListeners.remove(listener); + + // Removal of subscriptions doesn't generate RAT changed event, fire it for every + // RatTypeListener. + mDelegate.onCollapsedRatTypeChanged( + listener.mSubscriberId, TelephonyManager.NETWORK_TYPE_UNKNOWN); + } + + static class RatTypeListener extends PhoneStateListener { + // Unique id for the subscription. See {@link SubscriptionInfo#getSubscriptionId}. + @NonNull + private final int mSubId; + + // IMSI to identifying the corresponding network from {@link NetworkState}. + // See {@link TelephonyManager#getSubscriberId}. + @NonNull + private final String mSubscriberId; + + private volatile int mLastCollapsedRatType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + @NonNull + private final NetworkStatsSubscriptionsMonitor mMonitor; + + RatTypeListener(@NonNull Executor executor, + @NonNull NetworkStatsSubscriptionsMonitor monitor, int subId, + @NonNull String subscriberId) { + super(executor); + mSubId = subId; + mSubscriberId = subscriberId; + mMonitor = monitor; + } + + @Override + public void onServiceStateChanged(@NonNull ServiceState ss) { + final int networkType = ss.getDataNetworkType(); + final int collapsedRatType = getCollapsedRatType(networkType); + if (collapsedRatType == mLastCollapsedRatType) return; + + if (NetworkStatsService.LOGD) { + Log.d(NetworkStatsService.TAG, "subtype changed for sub(" + mSubId + "): " + + mLastCollapsedRatType + " -> " + collapsedRatType); + } + mLastCollapsedRatType = collapsedRatType; + mMonitor.mDelegate.onCollapsedRatTypeChanged(mSubscriberId, mLastCollapsedRatType); + } + } +} From ab1eb887a6e3cec180ed03c0c62501bb130cf23e Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 4 Mar 2020 12:58:00 +0800 Subject: [PATCH 07/64] [SM10] Adopt helper class to monitor RAT type change per sub Test: atest NetworkStatsServiceTest Bug: 146415925 Change-Id: I45c3aa9046b316c8cd0943543d620a22e4afefd1 --- .../server/net/NetworkStatsService.java | 86 ++++++++----------- 1 file changed, 37 insertions(+), 49 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index d8264b3625..f7d0d4ee16 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -46,7 +46,6 @@ import static android.net.NetworkStats.UID_ALL; import static android.net.NetworkStatsHistory.FIELD_ALL; import static android.net.NetworkTemplate.buildTemplateMobileWildcard; import static android.net.NetworkTemplate.buildTemplateWifiWildcard; -import static android.net.NetworkTemplate.getCollapsedRatType; import static android.net.TrafficStats.KB_IN_BYTES; import static android.net.TrafficStats.MB_IN_BYTES; import static android.os.Trace.TRACE_TAG_NETWORK; @@ -67,9 +66,6 @@ import static android.provider.Settings.Global.NETSTATS_UID_TAG_BUCKET_DURATION; import static android.provider.Settings.Global.NETSTATS_UID_TAG_DELETE_AGE; import static android.provider.Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE; -import static android.telephony.PhoneStateListener.LISTEN_NONE; -import static android.telephony.PhoneStateListener.LISTEN_SERVICE_STATE; -import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; @@ -133,9 +129,7 @@ import android.provider.Settings.Global; import android.service.NetworkInterfaceProto; import android.service.NetworkStatsServiceDumpProto; import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; import android.telephony.SubscriptionPlan; -import android.telephony.TelephonyManager; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -206,7 +200,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final NetworkStatsFactory mStatsFactory; private final AlarmManager mAlarmManager; private final Clock mClock; - private final TelephonyManager mTeleManager; private final NetworkStatsSettings mSettings; private final NetworkStatsObservers mStatsObservers; @@ -352,6 +345,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @NonNull private final Dependencies mDeps; + @NonNull + private final NetworkStatsSubscriptionsMonitor mNetworkStatsSubscriptionsMonitor; + private static @NonNull File getDefaultSystemDir() { return new File(Environment.getDataDirectory(), "system"); } @@ -401,8 +397,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - NetworkStatsService service = new NetworkStatsService(context, networkManager, alarmManager, - wakeLock, getDefaultClock(), context.getSystemService(TelephonyManager.class), + final NetworkStatsService service = new NetworkStatsService(context, networkManager, + alarmManager, wakeLock, getDefaultClock(), new DefaultNetworkStatsSettings(context), new NetworkStatsFactory(), new NetworkStatsObservers(), getDefaultSystemDir(), getDefaultBaseDir(), new Dependencies()); @@ -416,16 +412,15 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @VisibleForTesting NetworkStatsService(Context context, INetworkManagementService networkManager, AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock, - TelephonyManager teleManager, NetworkStatsSettings settings, - NetworkStatsFactory factory, NetworkStatsObservers statsObservers, File systemDir, - File baseDir, @NonNull Dependencies deps) { + NetworkStatsSettings settings, NetworkStatsFactory factory, + NetworkStatsObservers statsObservers, File systemDir, File baseDir, + @NonNull Dependencies deps) { mContext = Objects.requireNonNull(context, "missing Context"); mNetworkManager = Objects.requireNonNull(networkManager, - "missing INetworkManagementService"); + "missing INetworkManagementService"); mAlarmManager = Objects.requireNonNull(alarmManager, "missing AlarmManager"); mClock = Objects.requireNonNull(clock, "missing Clock"); mSettings = Objects.requireNonNull(settings, "missing NetworkStatsSettings"); - mTeleManager = Objects.requireNonNull(teleManager, "missing TelephonyManager"); mWakeLock = Objects.requireNonNull(wakeLock, "missing WakeLock"); mStatsFactory = Objects.requireNonNull(factory, "missing factory"); mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers"); @@ -437,7 +432,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final HandlerThread handlerThread = mDeps.makeHandlerThread(); handlerThread.start(); mHandler = new NetworkStatsHandler(handlerThread.getLooper()); - mPhoneListener = new NetworkTypeListener(new HandlerExecutor(mHandler)); + mNetworkStatsSubscriptionsMonitor = deps.makeSubscriptionsMonitor(mContext, + new HandlerExecutor(mHandler), this); } /** @@ -453,6 +449,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public HandlerThread makeHandlerThread() { return new HandlerThread(TAG); } + + /** + * Create a {@link NetworkStatsSubscriptionsMonitor}, can be used to monitor RAT change + * event in NetworkStatsService. + */ + @NonNull + public NetworkStatsSubscriptionsMonitor makeSubscriptionsMonitor(@NonNull Context context, + @NonNull Executor executor, @NonNull NetworkStatsService service) { + // TODO: Update RatType passively in NSS, instead of querying into the monitor + // when forceUpdateIface. + return new NetworkStatsSubscriptionsMonitor(context, executor, (subscriberId, type) -> + service.handleOnCollapsedRatTypeChanged()); + } } private void registerLocalService() { @@ -517,11 +526,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, mSettings.getPollInterval(), pollIntent); - // TODO: 1. listen to changes from all subscriptions. - // 2. listen to settings changed to support dynamically enable/disable. + // TODO: listen to settings changed to support dynamically enable/disable. // watch for networkType changes if (!mSettings.getCombineSubtypeEnabled()) { - mTeleManager.listen(mPhoneListener, LISTEN_SERVICE_STATE); + mNetworkStatsSubscriptionsMonitor.start(); } registerGlobalAlert(); @@ -544,7 +552,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mContext.unregisterReceiver(mUserReceiver); mContext.unregisterReceiver(mShutdownReceiver); - mTeleManager.listen(mPhoneListener, LISTEN_NONE); + if (!mSettings.getCombineSubtypeEnabled()) { + mNetworkStatsSubscriptionsMonitor.stop(); + } final long currentTime = mClock.millis(); @@ -1197,35 +1207,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { }; /** - * Receiver that watches for {@link TelephonyManager} changes, such as - * transitioning between Radio Access Technology(RAT) types. + * Handle collapsed RAT type changed event. */ - @NonNull - private final NetworkTypeListener mPhoneListener; - - class NetworkTypeListener extends PhoneStateListener { - private volatile int mLastCollapsedRatType = NETWORK_TYPE_UNKNOWN; - - NetworkTypeListener(@NonNull Executor executor) { - super(executor); - } - - @Override - public void onServiceStateChanged(@NonNull ServiceState ss) { - final int networkType = ss.getDataNetworkType(); - final int collapsedRatType = getCollapsedRatType(networkType); - if (collapsedRatType == mLastCollapsedRatType) return; - - if (LOGD) { - Log.d(TAG, "subtype changed for mobile: " - + mLastCollapsedRatType + " -> " + collapsedRatType); - } - // Protect service from frequently updating. Remove pending messages if any. - mHandler.removeMessages(MSG_UPDATE_IFACES); - mLastCollapsedRatType = collapsedRatType; - mHandler.sendMessageDelayed( - mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay()); - } + @VisibleForTesting + public void handleOnCollapsedRatTypeChanged() { + // Protect service from frequently updating. Remove pending messages if any. + mHandler.removeMessages(MSG_UPDATE_IFACES); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay()); } private void updateIfaces( @@ -1352,8 +1341,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return 0; } - // TODO: return different subType for different subscriptions. - return mPhoneListener.mLastCollapsedRatType; + return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId); } private static NetworkIdentitySet findOrCreateNetworkIdentitySet( From c7af656fa2a95ce47fa7d7b59553b65b6bbdc119 Mon Sep 17 00:00:00 2001 From: junyulai Date: Thu, 16 Jul 2020 13:48:09 +0800 Subject: [PATCH 08/64] Attribute data usage to virtual RAT type for 5G non-standalone mode Test: atest NetworkStatsSubscriptionsMonitorTest#test5g Bug: 160727498 Change-Id: I8753e68140c0993773017c9a49bd8a666a364071 --- core/java/android/net/NetworkTemplate.java | 12 ++++++++++++ .../net/NetworkStatsSubscriptionsMonitor.java | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index eba7ff3483..7234eb1d81 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -87,6 +87,15 @@ public class NetworkTemplate implements Parcelable { * @hide */ public static final int NETWORK_TYPE_ALL = -1; + /** + * Virtual RAT type to represent 5G NSA (Non Stand Alone) mode, where the primary cell is + * still LTE and network allocates a secondary 5G cell so telephony reports RAT = LTE along + * with NR state as connected. This should not be overlapped with any of the + * {@code TelephonyManager.NETWORK_TYPE_*} constants. + * + * @hide + */ + public static final int NETWORK_TYPE_5G_NSA = -2; private static boolean isKnownMatchRule(final int rule) { switch (rule) { @@ -475,6 +484,9 @@ public class NetworkTemplate implements Parcelable { return TelephonyManager.NETWORK_TYPE_LTE; case TelephonyManager.NETWORK_TYPE_NR: return TelephonyManager.NETWORK_TYPE_NR; + // Virtual RAT type for 5G NSA mode, see {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. + case NetworkTemplate.NETWORK_TYPE_5G_NSA: + return NetworkTemplate.NETWORK_TYPE_5G_NSA; default: return TelephonyManager.NETWORK_TYPE_UNKNOWN; } diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java index db553ee795..0575ac6315 100644 --- a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java +++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java @@ -16,12 +16,14 @@ package com.android.server.net; +import static android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA; import static android.net.NetworkTemplate.getCollapsedRatType; import android.annotation.NonNull; import android.content.Context; import android.os.Looper; import android.telephony.Annotation; +import android.telephony.NetworkRegistrationInfo; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.SubscriptionManager; @@ -196,7 +198,18 @@ public class NetworkStatsSubscriptionsMonitor extends @Override public void onServiceStateChanged(@NonNull ServiceState ss) { - final int networkType = ss.getDataNetworkType(); + // In 5G SA (Stand Alone) mode, the primary cell itself will be 5G hence telephony + // would report RAT = 5G_NR. + // However, in 5G NSA (Non Stand Alone) mode, the primary cell is still LTE and + // network allocates a secondary 5G cell so telephony reports RAT = LTE along with + // NR state as connected. In such case, attributes the data usage to NR. + // See b/160727498. + final boolean is5GNsa = (ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE + || ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA) + && ss.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED; + + final int networkType = + (is5GNsa ? NETWORK_TYPE_5G_NSA : ss.getDataNetworkType()); final int collapsedRatType = getCollapsedRatType(networkType); if (collapsedRatType == mLastCollapsedRatType) return; From 0f2cebfb52e38d684f5d87fb4b93a0a1f3c99631 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Wed, 29 Jul 2020 12:05:04 +0800 Subject: [PATCH 09/64] Update language to comply with Android's inclusive language guidance See https://source.android.com/setup/contribute/respectful-code for reference. Test: m ; atest TetheringTests Bug: 161896447 Change-Id: Idc58697c72fb00896bee00185fefc50c1a24dd35 Merged-In: Idc58697c72fb00896bee00185fefc50c1a24dd35 --- .../Tethering/src/android/net/util/TetheringMessageBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/Tethering/src/android/net/util/TetheringMessageBase.java b/packages/Tethering/src/android/net/util/TetheringMessageBase.java index 1b763ce920..29c0a817b6 100644 --- a/packages/Tethering/src/android/net/util/TetheringMessageBase.java +++ b/packages/Tethering/src/android/net/util/TetheringMessageBase.java @@ -19,7 +19,7 @@ package android.net.util; * This class defines Message.what base addresses for various state machine. */ public class TetheringMessageBase { - public static final int BASE_MASTER = 0; + public static final int BASE_MAIN_SM = 0; public static final int BASE_IPSERVER = 100; } From fd54bcf23f16616fa1b1448e17474d1658ccc6dd Mon Sep 17 00:00:00 2001 From: junyulai Date: Fri, 7 Aug 2020 23:27:08 +0800 Subject: [PATCH 10/64] Add 5G NSA to collapsed RAT types list Currently, getAllCollapsedRatTypes is used to retrieve all RAT types which will be recorded into NetworkStatsService. However, there is a missing part that 5G NSA virtual RAT type is not added into this list. This makes callers such as statsd do not aware of 5G NSA RAT type and missed to collect data usage of it. Test: atest NetworkStatsSubscriptionsMonitorTest#test5g Test: adb shell cmd stats pull-source 10082 Test: ./out/host/linux-x86/bin/statsd_testdrive 10082 Test: atest UidAtomTests#testMobileBytesTransfer \ UidAtomTests#testMobileBytesTransferByFgBg \ UidAtomTests#testDataUsageBytesTransfer Bug: 163021464 Change-Id: I0faeda20f0506a48ac1131b234c5fc40d95dfbe0 --- core/java/android/net/NetworkTemplate.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index 7234eb1d81..cd26079a7b 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -503,6 +503,10 @@ public class NetworkTemplate implements Parcelable { for (final int ratType : ratTypes) { collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(ratType)); } + // Add NETWORK_TYPE_5G_NSA to the returned list since 5G NSA is a virtual RAT type and + // it is not in TelephonyManager#NETWORK_TYPE_* constants. + // See {@link NetworkTemplate#NETWORK_TYPE_5G_NSA}. + collapsedRatTypes.add(NetworkTemplate.getCollapsedRatType(NETWORK_TYPE_5G_NSA)); // Ensure that unknown type is returned. collapsedRatTypes.add(TelephonyManager.NETWORK_TYPE_UNKNOWN); return toIntArray(collapsedRatTypes); From a61dac1417940dbc62640119e44749ea07c63caa Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 11 Aug 2020 08:43:33 -0700 Subject: [PATCH 11/64] WifiP2pManager: Plumb package name to service Will be used for prioritization of different ifaces in HDM. Bug: 162344695 Test: atest com.android.server.wifi Change-Id: Iac1447390f7329768b9c307b08d28ebbd4ea3b90 --- wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl index bfdd45d9f9..fd89d3b048 100644 --- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl +++ b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl @@ -25,7 +25,7 @@ import android.os.Messenger; */ interface IWifiP2pManager { - Messenger getMessenger(in IBinder binder); + Messenger getMessenger(in IBinder binder, in String packageName); Messenger getP2pStateMachineMessenger(); oneway void close(in IBinder binder); void setMiracastMode(int mode); From 43e9bf91cf306f3a1a145f5f4611754627821c69 Mon Sep 17 00:00:00 2001 From: junyulai Date: Tue, 18 Aug 2020 18:50:13 +0800 Subject: [PATCH 12/64] Skip RAT type listener registration if IMSI is not available Currently, if SIM is inserted but IMSI is not available, such as SIM PIN locked state. Information of such SIM will still be available but IMSI is not. Which makes NetworkStatsSubscriptionMonitor failed to store IMSI locally for later RAT type query. Hence, NETWORK_TYPE_UNKNOWN is always returned for such SIM. Skip the registration until the IMSI is available. This is safe since there will be another onSubscriptionsChanged event when that happens. Test: enable SIM PIN and manually test Test: atest NetworkStatsSubscriptionsMonitorTest#testSubscriberIdUnavailable Test: ./out/host/linux-x86/bin/statsd_testdrive 10082 Bug: 160941101 Change-Id: I408379b3c432d9e62e0837d6b4f6551cc7838e29 --- .../net/NetworkStatsSubscriptionsMonitor.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java index 0575ac6315..d202a2a607 100644 --- a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java +++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java @@ -100,11 +100,16 @@ public class NetworkStatsSubscriptionsMonitor extends if (match != null) continue; // Create listener for every newly added sub. Also store subscriberId into it to - // prevent binder call to telephony when querying RAT. + // prevent binder call to telephony when querying RAT. If the subscriberId is empty + // for any reason, such as SIM PIN locked, skip registration. + // SubscriberId will be unavailable again if 1. modem crashed 2. reboot + // 3. re-insert SIM. If that happens, the listeners will be eventually synchronized + // with active sub list once all subscriberIds are ready. final String subscriberId = mTeleManager.getSubscriberId(subId); if (TextUtils.isEmpty(subscriberId)) { - Log.wtf(NetworkStatsService.TAG, - "Empty subscriberId for newly added sub: " + subId); + Log.d(NetworkStatsService.TAG, "Empty subscriberId for newly added sub " + + subId + ", skip listener registration"); + continue; } final RatTypeListener listener = new RatTypeListener(mExecutor, this, subId, subscriberId); @@ -113,6 +118,7 @@ public class NetworkStatsSubscriptionsMonitor extends // Register listener to the telephony manager that associated with specific sub. mTeleManager.createForSubscriptionId(subId) .listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE); + Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + subId); } for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) { @@ -165,6 +171,7 @@ public class NetworkStatsSubscriptionsMonitor extends private void handleRemoveRatTypeListener(@NonNull RatTypeListener listener) { mTeleManager.createForSubscriptionId(listener.mSubId) .listen(listener, PhoneStateListener.LISTEN_NONE); + Log.d(NetworkStatsService.TAG, "RAT type listener unregistered for sub " + listener.mSubId); mRatListeners.remove(listener); // Removal of subscriptions doesn't generate RAT changed event, fire it for every From 885d9b04b80cc4ce9f6ee7772acace66175bc9c9 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 19 Aug 2020 16:07:22 +0900 Subject: [PATCH 13/64] Move module utils to the module package. Test: builds Change-Id: If5d1e4a58fb2d6d9544e6d01995dabe445cf1f25 (cherry picked from commit 046bf639eb7728504be35e30e3dd49af3d029728) --- services/core/java/com/android/server/NsdService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index 4a1820a8e5..d907505481 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -25,7 +25,6 @@ import android.net.Uri; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; -import android.net.util.nsd.DnsSdTxtRecord; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -42,6 +41,7 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.DumpUtils; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import com.android.net.module.util.DnsSdTxtRecord; import java.io.FileDescriptor; import java.io.PrintWriter; From de27d61e6dea6df724e3150c1fdf55b76ded0e08 Mon Sep 17 00:00:00 2001 From: Hridya Valsaraju Date: Thu, 1 Oct 2020 20:12:46 +0000 Subject: [PATCH 14/64] Revert "Move module utils to the module package." Revert "Move util classes to their destination package" Revert "Move PacketReader and FdEventReader" Revert "Move static utils to a module package" Revert "Move static utils to a module package" Revert submission 12698912-move_packetreader Reason for revert: Broke presubmit on git_master, b/169861635 Reverted Changes: If5d1e4a58:Move module utils to the module package. I44ffaad3d:Move PacketReader and FdEventReader I93e9cfd96:Move util classes to their destination package Ia84d64130:Move static utils to a module package Iaac2810c7:Move static utils to a module package Change-Id: Ibbe59075cd7bc4c38e0707ea6ae3b3703b40986f --- services/core/java/com/android/server/NsdService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index d907505481..4a1820a8e5 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -25,6 +25,7 @@ import android.net.Uri; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; +import android.net.util.nsd.DnsSdTxtRecord; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -41,7 +42,6 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.DumpUtils; import com.android.internal.util.State; import com.android.internal.util.StateMachine; -import com.android.net.module.util.DnsSdTxtRecord; import java.io.FileDescriptor; import java.io.PrintWriter; From c2bcd967ebff0fb3a027d75a3b941b62db631456 Mon Sep 17 00:00:00 2001 From: Eran Messeri Date: Fri, 25 Sep 2020 11:35:45 +0100 Subject: [PATCH 15/64] Refactoring: Use explicit methods for checking DO/PO Do not use USES_POLICY_PROFILE_OWNER / USES_POLICY_DEVICE_OWNER. Instead, use explicit methods for checking if the caller is the Device Owner or Profile Owner. USES_POLICY_PROFILE_OWNER is confusing since internally in the DevicePolicyManagerService, it implied a Device Owner is also a Profile Owner, which is not always what the caller expected. This is the first phase of the refactoring, removing external calles' dependency on these constants. The next phase will remove them internally completely in favour of an implementation that accesses mOwners directly. There are no functional changes in this CL. Bug: 163028934 Test: atest FrameworksServicesTests:DevicePolicyManagerTest Change-Id: I57c8465d190a3b4b130d57fd622cc93eaeb9c717 --- .../java/com/android/server/net/NetworkStatsAccess.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsAccess.java b/services/core/java/com/android/server/net/NetworkStatsAccess.java index 7c1c1c7ce4..5a8fbf3d26 100644 --- a/services/core/java/com/android/server/net/NetworkStatsAccess.java +++ b/services/core/java/com/android/server/net/NetworkStatsAccess.java @@ -24,7 +24,6 @@ import static android.net.TrafficStats.UID_TETHERING; import android.Manifest; import android.annotation.IntDef; import android.app.AppOpsManager; -import android.app.admin.DeviceAdminInfo; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.pm.PackageManager; @@ -111,8 +110,7 @@ public final class NetworkStatsAccess { boolean hasCarrierPrivileges = tm != null && tm.checkCarrierPrivilegesForPackageAnyPhone(callingPackage) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; - boolean isDeviceOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid, - DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); + boolean isDeviceOwner = dpmi != null && dpmi.isActiveDeviceOwner(callingUid); if (hasCarrierPrivileges || isDeviceOwner || UserHandle.getAppId(callingUid) == android.os.Process.SYSTEM_UID) { // Carrier-privileged apps and device owners, and the system can access data usage for @@ -126,8 +124,9 @@ public final class NetworkStatsAccess { return NetworkStatsAccess.Level.DEVICESUMMARY; } - boolean isProfileOwner = dpmi != null && dpmi.isActiveAdminWithPolicy(callingUid, - DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + //TODO(b/169395065) Figure out if this flow makes sense in Device Owner mode. + boolean isProfileOwner = dpmi != null && (dpmi.isActiveProfileOwner(callingUid) + || dpmi.isActiveDeviceOwner(callingUid)); if (isProfileOwner) { // Apps with the AppOps permission, profile owners, and apps with the privileged // permission can access data usage for all apps in this user/profile. From 4c1d8a48fc9f3c2f6e42c4b57ae4d73106322a19 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 7 Oct 2020 18:29:20 +0900 Subject: [PATCH 16/64] Allow the network stack to read network stats history Bug: 168984229 Test: testNetworkStatsProvider Change-Id: Ibb6342b0f263c874bb1f7ab4031a639778bad37e --- .../com/android/server/net/NetworkStatsAccess.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsAccess.java b/services/core/java/com/android/server/net/NetworkStatsAccess.java index 5a8fbf3d26..7cdc4cc747 100644 --- a/services/core/java/com/android/server/net/NetworkStatsAccess.java +++ b/services/core/java/com/android/server/net/NetworkStatsAccess.java @@ -27,6 +27,7 @@ import android.app.AppOpsManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.pm.PackageManager; +import android.os.Process; import android.os.UserHandle; import android.telephony.TelephonyManager; @@ -110,11 +111,12 @@ public final class NetworkStatsAccess { boolean hasCarrierPrivileges = tm != null && tm.checkCarrierPrivilegesForPackageAnyPhone(callingPackage) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; - boolean isDeviceOwner = dpmi != null && dpmi.isActiveDeviceOwner(callingUid); + final boolean isDeviceOwner = dpmi != null && dpmi.isActiveDeviceOwner(callingUid); + final int appId = UserHandle.getAppId(callingUid); if (hasCarrierPrivileges || isDeviceOwner - || UserHandle.getAppId(callingUid) == android.os.Process.SYSTEM_UID) { - // Carrier-privileged apps and device owners, and the system can access data usage for - // all apps on the device. + || appId == Process.SYSTEM_UID || appId == Process.NETWORK_STACK_UID) { + // Carrier-privileged apps and device owners, and the system (including the + // network stack) can access data usage for all apps on the device. return NetworkStatsAccess.Level.DEVICE; } From 76a6131fdbf042bb49a0083da50d69d9dc3ab0e1 Mon Sep 17 00:00:00 2001 From: Roman Kalukiewicz Date: Wed, 14 Oct 2020 15:59:06 -0700 Subject: [PATCH 17/64] Add @Nullable annotation to the parameter of Object.equals() methods. Those annotations could be inferred by some tools (like Kotlin), but the https://checkerframework.org/ doesn't check inherited annotations complaining about all equals() invocations that get nullable argument. The change was generated by running find . -name \*.java | xargs sed -i 's/public boolean equals(Object /public boolean equals(@Nullable Object /' in the frameworks/base directory and by automatically adding and formatting required imports if needed. No manual edits. Bug: 170883422 Test: Annotation change only. Should have not impact. Exempt-From-Owner-Approval: Mechanical change not specific to any component. Change-Id: I5eedb571c9d78862115dfdc5dae1cf2a35343580 --- core/java/android/net/DataUsageRequest.java | 3 ++- core/java/android/net/IpSecTransform.java | 3 ++- core/java/android/net/NetworkIdentity.java | 3 ++- core/java/android/net/NetworkStats.java | 2 +- core/java/android/net/NetworkTemplate.java | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/java/android/net/DataUsageRequest.java b/core/java/android/net/DataUsageRequest.java index 0ac8f7e794..b06d515b3a 100644 --- a/core/java/android/net/DataUsageRequest.java +++ b/core/java/android/net/DataUsageRequest.java @@ -16,6 +16,7 @@ package android.net; +import android.annotation.Nullable; import android.net.NetworkTemplate; import android.os.Parcel; import android.os.Parcelable; @@ -95,7 +96,7 @@ public final class DataUsageRequest implements Parcelable { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (obj instanceof DataUsageRequest == false) return false; DataUsageRequest that = (DataUsageRequest) obj; return that.requestId == this.requestId diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java index 44a0a4f3e1..fa1497dcbc 100644 --- a/core/java/android/net/IpSecTransform.java +++ b/core/java/android/net/IpSecTransform.java @@ -21,6 +21,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SystemApi; @@ -153,7 +154,7 @@ public final class IpSecTransform implements AutoCloseable { /** * Standard equals. */ - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { if (this == other) return true; if (!(other instanceof IpSecTransform)) return false; final IpSecTransform rhs = (IpSecTransform) other; diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 0948a4da1a..9c1038846d 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -20,6 +20,7 @@ import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeMobile; +import android.annotation.Nullable; import android.content.Context; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; @@ -69,7 +70,7 @@ public class NetworkIdentity implements Comparable { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (obj instanceof NetworkIdentity) { final NetworkIdentity ident = (NetworkIdentity) obj; return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index 34e48eb44f..cbee010246 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -411,7 +411,7 @@ public final class NetworkStats implements Parcelable { /** @hide */ @Override - public boolean equals(Object o) { + public boolean equals(@Nullable Object o) { if (o instanceof Entry) { final Entry e = (Entry) o; return uid == e.uid && set == e.set && tag == e.tag && metered == e.metered diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index cd26079a7b..a95ba12f65 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -327,7 +327,7 @@ public class NetworkTemplate implements Parcelable { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (obj instanceof NetworkTemplate) { final NetworkTemplate other = (NetworkTemplate) obj; return mMatchRule == other.mMatchRule From 3d20a50464d7f3c6f42621d3070aeac18c50845d Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Mon, 19 Oct 2020 18:57:17 +0100 Subject: [PATCH 18/64] Remove @TestApi from @SystemApi symbols I ran these commands: cd frameworks/base grep -rl '@TestApi' --include '*.java' | xargs perl -i -p0e \ 's/\@SystemApi[\s\n]+(\@\w+[\s\n]+)?\@TestApi/\@SystemApi\1/gs' grep -rl '@TestApi' --include '*.java' | xargs perl -i -p0e \ 's/\@TestApi[\s\n]+(\@\w+[\s\n]+)?\@SystemApi/\1\@SystemApi/gs' Bug: 171179806 Test: m checkapi Change-Id: I772790b783b0a8730b8bf680c9e569a886b8d789 Merged-In: I772790b783b0a8730b8bf680c9e569a886b8d789 --- core/java/android/net/EthernetManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index d975017f9c..5860e20ad3 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -37,7 +37,6 @@ import java.util.concurrent.Executor; * @hide */ @SystemApi -@TestApi @SystemService(Context.ETHERNET_SERVICE) public class EthernetManager { private static final String TAG = "EthernetManager"; From 088a664274fb6a1a5680fadbebbc92b72f04b029 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Mon, 19 Oct 2020 11:38:00 +0100 Subject: [PATCH 19/64] Remove @TestApi from @SystemApi symbols I ran these commands: cd frameworks/base grep -rl '@TestApi' --include '*.java' | xargs perl -i -p0e \ 's/\@SystemApi[\s\n]+(\@\w+[\s\n]+)?\@TestApi/\@SystemApi\1/gs' grep -rl '@TestApi' --include '*.java' | xargs perl -i -p0e \ 's/\@TestApi[\s\n]+(\@\w+[\s\n]+)?\@SystemApi/\1\@SystemApi/gs' Bug: 171179806 Test: m checkapi Change-Id: I772790b783b0a8730b8bf680c9e569a886b8d789 --- core/java/android/net/EthernetManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index d975017f9c..5860e20ad3 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -37,7 +37,6 @@ import java.util.concurrent.Executor; * @hide */ @SystemApi -@TestApi @SystemService(Context.ETHERNET_SERVICE) public class EthernetManager { private static final String TAG = "EthernetManager"; From 63465387ca7af2bcbac29ab3f3ec379896d228e0 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Sat, 17 Oct 2020 21:20:13 -0600 Subject: [PATCH 20/64] Apply fixes for EfficientStrings. Refactoring to avoid StringBuffer synchronization overhead. Bug: 170978902 Test: none Exempt-From-Owner-Approval: trivial refactoring Change-Id: Ibf843ed780c1202d5d96a11eaca889e592f19263 --- services/core/java/com/android/server/NsdService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index 4a1820a8e5..78bd4cdd4e 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -824,7 +824,7 @@ public class NsdService extends INsdManager.Stub { @Override public String toString() { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append("mChannel ").append(mChannel).append("\n"); sb.append("mMessenger ").append(mMessenger).append("\n"); sb.append("mResolvedService ").append(mResolvedService).append("\n"); From 3950aab83b98fbdb491f81321454ad36d95d0431 Mon Sep 17 00:00:00 2001 From: Mathew Inwood Date: Tue, 27 Oct 2020 11:47:29 +0000 Subject: [PATCH 21/64] Add maxTargetSdk restriction to unused APIs. These are APIs that have @UnsupportedAppUsage but for which we don't have any evidence of them currently being used, so should be safe to remove from the unsupported list. Bug: 170729553 Test: Treehugger Change-Id: I4c8fd0006f950de9955242e93968fb0996ceb372 --- .../app/usage/NetworkStatsManager.java | 5 +-- core/java/android/net/EthernetManager.java | 17 +++++----- .../android/net/INetworkStatsService.aidl | 2 +- core/java/android/net/NetworkStats.java | 33 ++++++++++--------- .../java/android/net/NetworkStatsHistory.java | 17 +++++----- core/java/android/net/NetworkTemplate.java | 3 +- core/java/android/net/TrafficStats.java | 4 +-- core/java/android/net/nsd/INsdManager.aidl | 2 +- 8 files changed, 44 insertions(+), 39 deletions(-) diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index fc8248e101..1ddfe0d247 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -34,6 +34,7 @@ import android.net.NetworkTemplate; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -129,7 +130,7 @@ public class NetworkStatsManager { /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStatsManager(Context context) throws ServiceNotFoundException { this(context, INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE))); @@ -153,7 +154,7 @@ public class NetworkStatsManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public void setPollForce(boolean pollForce) { if (pollForce) { diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index 5860e20ad3..84a8e1c3dc 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -23,6 +23,7 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.os.RemoteException; @@ -76,7 +77,7 @@ public class EthernetManager { * @param isAvailable {@code true} if Ethernet port exists. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void onAvailabilityChanged(String iface, boolean isAvailable); } @@ -97,7 +98,7 @@ public class EthernetManager { * @return the Ethernet Configuration, contained in {@link IpConfiguration}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IpConfiguration getConfiguration(String iface) { try { return mService.getConfiguration(iface); @@ -110,7 +111,7 @@ public class EthernetManager { * Set Ethernet configuration. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setConfiguration(String iface, IpConfiguration config) { try { mService.setConfiguration(iface, config); @@ -123,7 +124,7 @@ public class EthernetManager { * Indicates whether the system currently has one or more Ethernet interfaces. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isAvailable() { return getAvailableInterfaces().length > 0; } @@ -134,7 +135,7 @@ public class EthernetManager { * @param iface Ethernet interface name * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isAvailable(String iface) { try { return mService.isAvailable(iface); @@ -149,7 +150,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); @@ -168,7 +169,7 @@ public class EthernetManager { * Returns an array of available Ethernet interface names. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String[] getAvailableInterfaces() { try { return mService.getAvailableInterfaces(); @@ -183,7 +184,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void removeListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index 5fa515a143..1a3dc97448 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -42,7 +42,7 @@ interface INetworkStatsService { * PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted * READ_NETWORK_USAGE_STATS is checked for. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage); /** Return data layer snapshot of UID network usage. */ diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index cbee010246..d42beae601 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -219,11 +220,11 @@ public final class NetworkStats implements Parcelable { * generated. */ private long elapsedRealtime; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int size; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int capacity; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String[] iface; @UnsupportedAppUsage private int[] uid; @@ -231,21 +232,21 @@ public final class NetworkStats implements Parcelable { private int[] set; @UnsupportedAppUsage private int[] tag; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] metered; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] roaming; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] defaultNetwork; @UnsupportedAppUsage private long[] rxBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] rxPackets; @UnsupportedAppUsage private long[] txBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] txPackets; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] operations; /** @@ -258,7 +259,7 @@ public final class NetworkStats implements Parcelable { @SystemApi public static class Entry { /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String iface; /** @hide */ @UnsupportedAppUsage @@ -267,7 +268,7 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public int set; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int tag; /** * Note that this is only populated w/ the default value when read from /proc or written @@ -294,20 +295,20 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public long rxBytes; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rxPackets; /** @hide */ @UnsupportedAppUsage public long txBytes; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long txPackets; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long operations; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Entry() { this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); } @@ -454,7 +455,7 @@ public final class NetworkStats implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStats(Parcel parcel) { elapsedRealtime = parcel.readLong(); size = parcel.readInt(); diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 51f09a0103..fba7561434 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -32,6 +32,7 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.internal.util.ArrayUtils.total; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.service.NetworkStatsHistoryBucketProto; @@ -91,18 +92,18 @@ public class NetworkStatsHistory implements Parcelable { public static class Entry { public static final long UNKNOWN = -1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketDuration; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketStart; public long activeTime; @UnsupportedAppUsage public long rxBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rxPackets; @UnsupportedAppUsage public long txBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long txPackets; public long operations; } @@ -134,7 +135,7 @@ public class NetworkStatsHistory implements Parcelable { recordEntireHistory(existing); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStatsHistory(Parcel in) { bucketDuration = in.readLong(); bucketStart = readLongArray(in); @@ -220,7 +221,7 @@ public class NetworkStatsHistory implements Parcelable { return 0; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int size() { return bucketCount; } @@ -258,7 +259,7 @@ public class NetworkStatsHistory implements Parcelable { * Return index of bucket that contains or is immediately before the * requested time. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getIndexBefore(long time) { int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time); if (index < 0) { @@ -286,7 +287,7 @@ public class NetworkStatsHistory implements Parcelable { /** * Return specific stats entry. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Entry getValues(int i, Entry recycle) { final Entry entry = recycle != null ? recycle : new Entry(); entry.bucketStart = bucketStart[i]; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index a95ba12f65..dc33cc7b61 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -37,6 +37,7 @@ import static android.net.wifi.WifiInfo.sanitizeSsid; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; @@ -159,7 +160,7 @@ public class NetworkTemplate implements Parcelable { * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks, * regardless of IMSI. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static NetworkTemplate buildTemplateMobileWildcard() { return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null); } diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index e7bba69dbb..a985e934ed 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -565,7 +565,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getMobileTcpRxPackets() { long total = 0; for (String iface : getMobileIfaces()) { @@ -581,7 +581,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getMobileTcpTxPackets() { long total = 0; for (String iface : getMobileIfaces()) { diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl index 9484c74bcb..e9e8935a19 100644 --- a/core/java/android/net/nsd/INsdManager.aidl +++ b/core/java/android/net/nsd/INsdManager.aidl @@ -25,7 +25,7 @@ import android.os.Messenger; */ interface INsdManager { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Messenger getMessenger(); void setEnabled(boolean enable); } From 2feaa993c2e90cad8476aa50be29b596bc4cf817 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Wed, 28 Oct 2020 19:38:11 +0000 Subject: [PATCH 22/64] Revert "Add maxTargetSdk restriction to unused APIs." This reverts commit 3950aab83b98fbdb491f81321454ad36d95d0431. Reason for revert: Droidcop-triggered revert due to breakage https://android-build.googleplex.com/builds/quarterdeck?testMethod=testAppZygotePreload&testClass=android.app.cts.ServiceTest&atpConfigName=suite%2Ftest-mapping-presubmit-retry_cloud-tf&testModule=CtsAppTestCases&fkbb=6936597&lkbb=6936969&lkgb=6936551&testResults=true&branch=git_master&target=cf_x86_phone-userdebug>, bug b/171886397 Bug: 171886397 Change-Id: Ibe0f0430a3451477c1ee8ef56a596e91ea1e7672 --- .../app/usage/NetworkStatsManager.java | 5 ++- core/java/android/net/EthernetManager.java | 17 +++++----- .../android/net/INetworkStatsService.aidl | 2 +- core/java/android/net/NetworkStats.java | 33 +++++++++---------- .../java/android/net/NetworkStatsHistory.java | 17 +++++----- core/java/android/net/NetworkTemplate.java | 3 +- core/java/android/net/TrafficStats.java | 4 +-- core/java/android/net/nsd/INsdManager.aidl | 2 +- 8 files changed, 39 insertions(+), 44 deletions(-) diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 1ddfe0d247..fc8248e101 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -34,7 +34,6 @@ import android.net.NetworkTemplate; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; import android.os.Binder; -import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -130,7 +129,7 @@ public class NetworkStatsManager { /** * {@hide} */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public NetworkStatsManager(Context context) throws ServiceNotFoundException { this(context, INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE))); @@ -154,7 +153,7 @@ public class NetworkStatsManager { } /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage @TestApi public void setPollForce(boolean pollForce) { if (pollForce) { diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index 84a8e1c3dc..5860e20ad3 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -23,7 +23,6 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.os.Build; import android.os.Handler; import android.os.Message; import android.os.RemoteException; @@ -77,7 +76,7 @@ public class EthernetManager { * @param isAvailable {@code true} if Ethernet port exists. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage void onAvailabilityChanged(String iface, boolean isAvailable); } @@ -98,7 +97,7 @@ public class EthernetManager { * @return the Ethernet Configuration, contained in {@link IpConfiguration}. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public IpConfiguration getConfiguration(String iface) { try { return mService.getConfiguration(iface); @@ -111,7 +110,7 @@ public class EthernetManager { * Set Ethernet configuration. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public void setConfiguration(String iface, IpConfiguration config) { try { mService.setConfiguration(iface, config); @@ -124,7 +123,7 @@ public class EthernetManager { * Indicates whether the system currently has one or more Ethernet interfaces. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public boolean isAvailable() { return getAvailableInterfaces().length > 0; } @@ -135,7 +134,7 @@ public class EthernetManager { * @param iface Ethernet interface name * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public boolean isAvailable(String iface) { try { return mService.isAvailable(iface); @@ -150,7 +149,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public void addListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); @@ -169,7 +168,7 @@ public class EthernetManager { * Returns an array of available Ethernet interface names. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public String[] getAvailableInterfaces() { try { return mService.getAvailableInterfaces(); @@ -184,7 +183,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public void removeListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index 1a3dc97448..5fa515a143 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -42,7 +42,7 @@ interface INetworkStatsService { * PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted * READ_NETWORK_USAGE_STATS is checked for. */ - @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) + @UnsupportedAppUsage INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage); /** Return data layer snapshot of UID network usage. */ diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index d42beae601..cbee010246 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -21,7 +21,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -220,11 +219,11 @@ public final class NetworkStats implements Parcelable { * generated. */ private long elapsedRealtime; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private int size; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private int capacity; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private String[] iface; @UnsupportedAppUsage private int[] uid; @@ -232,21 +231,21 @@ public final class NetworkStats implements Parcelable { private int[] set; @UnsupportedAppUsage private int[] tag; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private int[] metered; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private int[] roaming; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private int[] defaultNetwork; @UnsupportedAppUsage private long[] rxBytes; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private long[] rxPackets; @UnsupportedAppUsage private long[] txBytes; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private long[] txPackets; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage private long[] operations; /** @@ -259,7 +258,7 @@ public final class NetworkStats implements Parcelable { @SystemApi public static class Entry { /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public String iface; /** @hide */ @UnsupportedAppUsage @@ -268,7 +267,7 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public int set; /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public int tag; /** * Note that this is only populated w/ the default value when read from /proc or written @@ -295,20 +294,20 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public long rxBytes; /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public long rxPackets; /** @hide */ @UnsupportedAppUsage public long txBytes; /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public long txPackets; /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public long operations; /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public Entry() { this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); } @@ -455,7 +454,7 @@ public final class NetworkStats implements Parcelable { } /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public NetworkStats(Parcel parcel) { elapsedRealtime = parcel.readLong(); size = parcel.readInt(); diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index fba7561434..51f09a0103 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -32,7 +32,6 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.internal.util.ArrayUtils.total; import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.service.NetworkStatsHistoryBucketProto; @@ -92,18 +91,18 @@ public class NetworkStatsHistory implements Parcelable { public static class Entry { public static final long UNKNOWN = -1; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public long bucketDuration; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public long bucketStart; public long activeTime; @UnsupportedAppUsage public long rxBytes; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public long rxPackets; @UnsupportedAppUsage public long txBytes; - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public long txPackets; public long operations; } @@ -135,7 +134,7 @@ public class NetworkStatsHistory implements Parcelable { recordEntireHistory(existing); } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public NetworkStatsHistory(Parcel in) { bucketDuration = in.readLong(); bucketStart = readLongArray(in); @@ -221,7 +220,7 @@ public class NetworkStatsHistory implements Parcelable { return 0; } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public int size() { return bucketCount; } @@ -259,7 +258,7 @@ public class NetworkStatsHistory implements Parcelable { * Return index of bucket that contains or is immediately before the * requested time. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public int getIndexBefore(long time) { int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time); if (index < 0) { @@ -287,7 +286,7 @@ public class NetworkStatsHistory implements Parcelable { /** * Return specific stats entry. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public Entry getValues(int i, Entry recycle) { final Entry entry = recycle != null ? recycle : new Entry(); entry.bucketStart = bucketStart[i]; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index dc33cc7b61..a95ba12f65 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -37,7 +37,6 @@ import static android.net.wifi.WifiInfo.sanitizeSsid; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; @@ -160,7 +159,7 @@ public class NetworkTemplate implements Parcelable { * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks, * regardless of IMSI. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public static NetworkTemplate buildTemplateMobileWildcard() { return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null); } diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index a985e934ed..e7bba69dbb 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -565,7 +565,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public static long getMobileTcpRxPackets() { long total = 0; for (String iface : getMobileIfaces()) { @@ -581,7 +581,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage public static long getMobileTcpTxPackets() { long total = 0; for (String iface : getMobileIfaces()) { diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl index e9e8935a19..9484c74bcb 100644 --- a/core/java/android/net/nsd/INsdManager.aidl +++ b/core/java/android/net/nsd/INsdManager.aidl @@ -25,7 +25,7 @@ import android.os.Messenger; */ interface INsdManager { - @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) + @UnsupportedAppUsage Messenger getMessenger(); void setEnabled(boolean enable); } From 2217f37fc7c748edd772b0dddd3a596669e1c18b Mon Sep 17 00:00:00 2001 From: Mathew Inwood Date: Tue, 27 Oct 2020 11:47:29 +0000 Subject: [PATCH 23/64] Add maxTargetSdk restriction to unused APIs. These are APIs that have @UnsupportedAppUsage but for which we don't have any evidence of them currently being used, so should be safe to remove from the unsupported list. This is a resubmit of ag/12929664 with some APIs excluded that caused test failures; see bugs 171886397, 171888296, 171864568. APIs excluded: Landroid/bluetooth/le/ScanRecord;->parseFromBytes([B)Landroid/bluetooth/le/ScanRecord; Landroid/os/Process;->myPpid()I Landroid/os/SharedMemory;->getFd()I Landroid/hardware/input/InputManager;->INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH:I Bug: 170729553 Test: Treehugger Change-Id: I8285daa8530260251ecad6f3f38f98e263629ca7 --- .../app/usage/NetworkStatsManager.java | 5 +-- core/java/android/net/EthernetManager.java | 17 +++++----- .../android/net/INetworkStatsService.aidl | 2 +- core/java/android/net/NetworkStats.java | 33 ++++++++++--------- .../java/android/net/NetworkStatsHistory.java | 17 +++++----- core/java/android/net/NetworkTemplate.java | 3 +- core/java/android/net/TrafficStats.java | 4 +-- core/java/android/net/nsd/INsdManager.aidl | 2 +- 8 files changed, 44 insertions(+), 39 deletions(-) diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index fc8248e101..1ddfe0d247 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -34,6 +34,7 @@ import android.net.NetworkTemplate; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; import android.os.Binder; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -129,7 +130,7 @@ public class NetworkStatsManager { /** * {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStatsManager(Context context) throws ServiceNotFoundException { this(context, INetworkStatsService.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE))); @@ -153,7 +154,7 @@ public class NetworkStatsManager { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @TestApi public void setPollForce(boolean pollForce) { if (pollForce) { diff --git a/core/java/android/net/EthernetManager.java b/core/java/android/net/EthernetManager.java index 5860e20ad3..84a8e1c3dc 100644 --- a/core/java/android/net/EthernetManager.java +++ b/core/java/android/net/EthernetManager.java @@ -23,6 +23,7 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; +import android.os.Build; import android.os.Handler; import android.os.Message; import android.os.RemoteException; @@ -76,7 +77,7 @@ public class EthernetManager { * @param isAvailable {@code true} if Ethernet port exists. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) void onAvailabilityChanged(String iface, boolean isAvailable); } @@ -97,7 +98,7 @@ public class EthernetManager { * @return the Ethernet Configuration, contained in {@link IpConfiguration}. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public IpConfiguration getConfiguration(String iface) { try { return mService.getConfiguration(iface); @@ -110,7 +111,7 @@ public class EthernetManager { * Set Ethernet configuration. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void setConfiguration(String iface, IpConfiguration config) { try { mService.setConfiguration(iface, config); @@ -123,7 +124,7 @@ public class EthernetManager { * Indicates whether the system currently has one or more Ethernet interfaces. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isAvailable() { return getAvailableInterfaces().length > 0; } @@ -134,7 +135,7 @@ public class EthernetManager { * @param iface Ethernet interface name * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public boolean isAvailable(String iface) { try { return mService.isAvailable(iface); @@ -149,7 +150,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void addListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); @@ -168,7 +169,7 @@ public class EthernetManager { * Returns an array of available Ethernet interface names. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String[] getAvailableInterfaces() { try { return mService.getAvailableInterfaces(); @@ -183,7 +184,7 @@ public class EthernetManager { * @throws IllegalArgumentException If the listener is null. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void removeListener(Listener listener) { if (listener == null) { throw new IllegalArgumentException("listener must not be null"); diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index 5fa515a143..1a3dc97448 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -42,7 +42,7 @@ interface INetworkStatsService { * PACKAGE_USAGE_STATS permission is always checked. If PACKAGE_USAGE_STATS is not granted * READ_NETWORK_USAGE_STATS is checked for. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) INetworkStatsSession openSessionForUsageStats(int flags, String callingPackage); /** Return data layer snapshot of UID network usage. */ diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index cbee010246..d42beae601 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -21,6 +21,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -219,11 +220,11 @@ public final class NetworkStats implements Parcelable { * generated. */ private long elapsedRealtime; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int size; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int capacity; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private String[] iface; @UnsupportedAppUsage private int[] uid; @@ -231,21 +232,21 @@ public final class NetworkStats implements Parcelable { private int[] set; @UnsupportedAppUsage private int[] tag; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] metered; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] roaming; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private int[] defaultNetwork; @UnsupportedAppUsage private long[] rxBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] rxPackets; @UnsupportedAppUsage private long[] txBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] txPackets; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private long[] operations; /** @@ -258,7 +259,7 @@ public final class NetworkStats implements Parcelable { @SystemApi public static class Entry { /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public String iface; /** @hide */ @UnsupportedAppUsage @@ -267,7 +268,7 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public int set; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int tag; /** * Note that this is only populated w/ the default value when read from /proc or written @@ -294,20 +295,20 @@ public final class NetworkStats implements Parcelable { @UnsupportedAppUsage public long rxBytes; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rxPackets; /** @hide */ @UnsupportedAppUsage public long txBytes; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long txPackets; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long operations; /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Entry() { this(IFACE_ALL, UID_ALL, SET_DEFAULT, TAG_NONE, 0L, 0L, 0L, 0L, 0L); } @@ -454,7 +455,7 @@ public final class NetworkStats implements Parcelable { } /** @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStats(Parcel parcel) { elapsedRealtime = parcel.readLong(); size = parcel.readInt(); diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index 51f09a0103..fba7561434 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -32,6 +32,7 @@ import static android.text.format.DateUtils.SECOND_IN_MILLIS; import static com.android.internal.util.ArrayUtils.total; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.service.NetworkStatsHistoryBucketProto; @@ -91,18 +92,18 @@ public class NetworkStatsHistory implements Parcelable { public static class Entry { public static final long UNKNOWN = -1; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketDuration; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long bucketStart; public long activeTime; @UnsupportedAppUsage public long rxBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long rxPackets; @UnsupportedAppUsage public long txBytes; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public long txPackets; public long operations; } @@ -134,7 +135,7 @@ public class NetworkStatsHistory implements Parcelable { recordEntireHistory(existing); } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public NetworkStatsHistory(Parcel in) { bucketDuration = in.readLong(); bucketStart = readLongArray(in); @@ -220,7 +221,7 @@ public class NetworkStatsHistory implements Parcelable { return 0; } - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int size() { return bucketCount; } @@ -258,7 +259,7 @@ public class NetworkStatsHistory implements Parcelable { * Return index of bucket that contains or is immediately before the * requested time. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public int getIndexBefore(long time) { int index = Arrays.binarySearch(bucketStart, 0, bucketCount, time); if (index < 0) { @@ -286,7 +287,7 @@ public class NetworkStatsHistory implements Parcelable { /** * Return specific stats entry. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public Entry getValues(int i, Entry recycle) { final Entry entry = recycle != null ? recycle : new Entry(); entry.bucketStart = bucketStart[i]; diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index a95ba12f65..dc33cc7b61 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -37,6 +37,7 @@ import static android.net.wifi.WifiInfo.sanitizeSsid; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; @@ -159,7 +160,7 @@ public class NetworkTemplate implements Parcelable { * Template to match metered {@link ConnectivityManager#TYPE_MOBILE} networks, * regardless of IMSI. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static NetworkTemplate buildTemplateMobileWildcard() { return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null); } diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index e7bba69dbb..a985e934ed 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -565,7 +565,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getMobileTcpRxPackets() { long total = 0; for (String iface : getMobileIfaces()) { @@ -581,7 +581,7 @@ public class TrafficStats { } /** {@hide} */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public static long getMobileTcpTxPackets() { long total = 0; for (String iface : getMobileIfaces()) { diff --git a/core/java/android/net/nsd/INsdManager.aidl b/core/java/android/net/nsd/INsdManager.aidl index 9484c74bcb..e9e8935a19 100644 --- a/core/java/android/net/nsd/INsdManager.aidl +++ b/core/java/android/net/nsd/INsdManager.aidl @@ -25,7 +25,7 @@ import android.os.Messenger; */ interface INsdManager { - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) Messenger getMessenger(); void setEnabled(boolean enable); } From 7199b112b5313e7c9d926cbbd7171dcf7c704ee9 Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Thu, 29 Oct 2020 15:21:39 +0000 Subject: [PATCH 24/64] Restructure Module code [ com.android.tethering ] Code Migration from frameworks/base/packages/Tethering -> packages/modules/Connectivity/Tethering BUG: 167962976 Test: TH Change-Id: I2accb96abbdfa665ef34aa79e87af040226bcf32 --- .../net/util/TetheringMessageBase.java | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 packages/Tethering/src/android/net/util/TetheringMessageBase.java diff --git a/packages/Tethering/src/android/net/util/TetheringMessageBase.java b/packages/Tethering/src/android/net/util/TetheringMessageBase.java deleted file mode 100644 index 29c0a817b6..0000000000 --- a/packages/Tethering/src/android/net/util/TetheringMessageBase.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net.util; - -/** - * This class defines Message.what base addresses for various state machine. - */ -public class TetheringMessageBase { - public static final int BASE_MAIN_SM = 0; - public static final int BASE_IPSERVER = 100; - -} From f5686f3918ac600462bcc274586093e0a836c84d Mon Sep 17 00:00:00 2001 From: Ashwini Oruganti Date: Thu, 29 Oct 2020 11:19:36 -0700 Subject: [PATCH 25/64] Apply FLAG_IMMUTABLE to the PendingIntent in NetworkStatService.java Broadcast intents sent by AlarmManager are immutable; the system dispatches them without customization. Fixes: 171815343 Test: TH Change-Id: I35ccfc0f69fd98b5803da74d9eb12902b351acc7 --- .../core/java/com/android/server/net/NetworkStatsService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 71e7c8adc5..12c24d4186 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -552,7 +552,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // schedule periodic pall alarm based on {@link NetworkStatsSettings#getPollInterval()}. final PendingIntent pollIntent = - PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), 0); + PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NETWORK_STATS_POLL), + PendingIntent.FLAG_IMMUTABLE); final long currentRealtime = SystemClock.elapsedRealtime(); mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, currentRealtime, From bbe92b335cff7a998a8a5b72a0358086d80c4769 Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Thu, 29 Oct 2020 17:58:29 +0000 Subject: [PATCH 26/64] Restructure Module code [ com.android.tethering ] Code Migration from frameworks/base/packages/Tethering -> packages/modules/Connectivity/Tethering BUG: 167962976 Test: TH Merged-In: I2accb96abbdfa665ef34aa79e87af040226bcf32 Change-Id: Id7656fe7f6a6fae044dc8defd05e83d81c6b8c11 --- .../net/util/TetheringMessageBase.java | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 packages/Tethering/src/android/net/util/TetheringMessageBase.java diff --git a/packages/Tethering/src/android/net/util/TetheringMessageBase.java b/packages/Tethering/src/android/net/util/TetheringMessageBase.java deleted file mode 100644 index 29c0a817b6..0000000000 --- a/packages/Tethering/src/android/net/util/TetheringMessageBase.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.net.util; - -/** - * This class defines Message.what base addresses for various state machine. - */ -public class TetheringMessageBase { - public static final int BASE_MAIN_SM = 0; - public static final int BASE_IPSERVER = 100; - -} From 339c010f8ff7dc6924ac881d62ee5753635d7485 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 19 Aug 2020 16:07:22 +0900 Subject: [PATCH 27/64] Move module utils to the module package. Test: FrameworksWifiTest FrameworksNetTest Change-Id: I067eeecd458c34b7f2fbfa439072682661ac750c --- services/core/java/com/android/server/NsdService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index 78bd4cdd4e..84f40cb4b8 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -25,7 +25,6 @@ import android.net.Uri; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; -import android.net.util.nsd.DnsSdTxtRecord; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -42,6 +41,7 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.DumpUtils; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import com.android.net.module.util.DnsSdTxtRecord; import java.io.FileDescriptor; import java.io.PrintWriter; From 7e8faaefbd08b807f0f63b2dff6b02ff89d88a9c Mon Sep 17 00:00:00 2001 From: Aurimas Liutikas Date: Thu, 12 Nov 2020 18:26:09 -0800 Subject: [PATCH 28/64] Remove legacy style metalava suppression @SuppressLint("Doclava125") is a legacy way of suppressing RequiresPermission check. Updating to the new style of suppression so metalava no longer has to support the legacy mode. sed -i "s/@SuppressLint(\"Doclava125/@SuppressLint(\"RequiresPermission/" \ core/java/android/app/admin/DevicePolicyManager.java \ core/java/android/hardware/hdmi/HdmiControlManager.java \ core/java/android/hardware/location/ContextHubManager.java \ core/java/android/hardware/usb/UsbDeviceConnection.java \ core/java/android/net/TrafficStats.java \ core/java/android/os/RecoverySystem.java \ core/java/android/os/storage/StorageManager.java \ core/java/android/service/persistentdata/PersistentDataBlockManager.java \ location/java/android/location/LocationManager.java \ media/java/android/media/AudioManager.java \ telecomm/java/android/telecom/TelecomManager.java \ telephony/java/android/telephony/CarrierConfigManager.java \ telephony/java/android/telephony/TelephonyManager.java \ wifi/java/android/net/wifi/RttManager.java \ wifi/java/android/net/wifi/WifiScanner.java Test: make Exempt-From-Owner-Approval: No-op change Change-Id: I6d5df95cfca2950ea86872d2f0afc1ba828841dc --- core/java/android/net/TrafficStats.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index 7376830505..4e019cf073 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -301,7 +301,7 @@ public class TrafficStats { * Changes only take effect during subsequent calls to * {@link #tagSocket(Socket)}. */ - @SuppressLint("Doclava125") + @SuppressLint("RequiresPermission") public static void setThreadStatsUid(int uid) { NetworkManagementSocketTagger.setThreadSocketStatsUid(uid); } @@ -339,7 +339,7 @@ public class TrafficStats { * * @see #setThreadStatsUid(int) */ - @SuppressLint("Doclava125") + @SuppressLint("RequiresPermission") public static void clearThreadStatsUid() { NetworkManagementSocketTagger.setThreadSocketStatsUid(-1); } From 1fc8fb75b870a75ac615084fcd29e0b2b3fc43df Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 19 Aug 2020 16:07:22 +0900 Subject: [PATCH 29/64] Move module utils to the module package. Test: FrameworksWifiTest FrameworksNetTest Change-Id: I067eeecd458c34b7f2fbfa439072682661ac750c Merged-In: I067eeecd458c34b7f2fbfa439072682661ac750c --- services/core/java/com/android/server/NsdService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index 4a1820a8e5..d907505481 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -25,7 +25,6 @@ import android.net.Uri; import android.net.nsd.INsdManager; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; -import android.net.util.nsd.DnsSdTxtRecord; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -42,6 +41,7 @@ import com.android.internal.util.AsyncChannel; import com.android.internal.util.DumpUtils; import com.android.internal.util.State; import com.android.internal.util.StateMachine; +import com.android.net.module.util.DnsSdTxtRecord; import java.io.FileDescriptor; import java.io.PrintWriter; From c36e67d355145bb10158af77cde1f1b3bc16c59c Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Wed, 23 Dec 2020 22:42:10 +0000 Subject: [PATCH 30/64] Migrate frameworks/base/wifi & frameworks/base/packages/OsuLogin Migrate to packages/modules/Wifi. This CL will be presubmit tested once migration is complete. This CL drops the code from frameworks/base/wifi and migrated to packages/modules/Wifi. Also adjusts visibility rules in frameworks/base/Android.bp Bug: 137323948 Test: TH Change-Id: Id02e28648e922a30d6a81cf92b39eff4ca3cc002 --- .../android/net/wifi/p2p/IWifiP2pManager.aidl | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl deleted file mode 100644 index fd89d3b048..0000000000 --- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.p2p; - -import android.os.Messenger; - -/** - * Interface that WifiP2pService implements - * - * {@hide} - */ -interface IWifiP2pManager -{ - Messenger getMessenger(in IBinder binder, in String packageName); - Messenger getP2pStateMachineMessenger(); - oneway void close(in IBinder binder); - void setMiracastMode(int mode); - void checkConfigureWifiDisplayPermission(); -} - From a1a576bcbe5ec09bf36849a6b7584878f0a17d85 Mon Sep 17 00:00:00 2001 From: Baligh Uddin Date: Wed, 23 Dec 2020 23:18:44 +0000 Subject: [PATCH 31/64] Migrate frameworks/base/wifi & frameworks/base/packages/OsuLogin Migrate to packages/modules/Wifi. This CL will be presubmit tested once migration is complete. This CL drops the code from frameworks/base/wifi and migrated to packages/modules/Wifi. Also adjusts visibility rules in frameworks/base/Android.bp Bug: 137323948 Test: TH Merged-In: Id02e28648e922a30d6a81cf92b39eff4ca3cc002 Change-Id: I28e35cea55001c2333374c2342f496a0340f2f32 --- .../android/net/wifi/p2p/IWifiP2pManager.aidl | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl diff --git a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl b/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl deleted file mode 100644 index bfdd45d9f9..0000000000 --- a/wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi.p2p; - -import android.os.Messenger; - -/** - * Interface that WifiP2pService implements - * - * {@hide} - */ -interface IWifiP2pManager -{ - Messenger getMessenger(in IBinder binder); - Messenger getP2pStateMachineMessenger(); - oneway void close(in IBinder binder); - void setMiracastMode(int mode); - void checkConfigureWifiDisplayPermission(); -} - From 9827c0686c16f4ff1a1ee728e00f0063c81be5d6 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Mon, 15 Feb 2021 20:16:28 +0900 Subject: [PATCH 32/64] Split parcelable .aidl files to aidl-export The one-line "parcelable X" files need to be imported by targets that do not build against SDK (the SDK has prebuilt definitions), so prepare a dedicated directory for them. This avoids having users of the classes include the whole src/ directory, which could contain definitions for classes that are not part of the public API, so should not be imported. Also move back to frameworks/base/core some .aidl definitions that were separated from their associated class. Bug: 171540887 Test: m Change-Id: I7432fe4c87cd3cab04dcb6185c9a4f3f84376549 --- core/java/android/net/UidRange.aidl | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 core/java/android/net/UidRange.aidl diff --git a/core/java/android/net/UidRange.aidl b/core/java/android/net/UidRange.aidl new file mode 100644 index 0000000000..f70fc8e2fe --- /dev/null +++ b/core/java/android/net/UidRange.aidl @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +/** + * An inclusive range of UIDs. + * + * {@hide} + */ +parcelable UidRange; \ No newline at end of file From daa23607be92b5effab9587ff2b28f610b225057 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 19 Jan 2021 10:47:55 -0700 Subject: [PATCH 33/64] Pivot network statistics to use DataInput/Output. The majority of this refactoring has already landed in AOSP, and this small CL is the remaining piece needed to begin using the new optimized classes which only exist in the internal tree. This is a no-op refactoring. Bug: 176777285 Test: atest FrameworksNetTests CtsNetTestCases Change-Id: Ifd7ac95c6cd6761e7d03cbf381dcc9e32b6406aa --- .../android/server/net/NetworkStatsCollection.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java index 6aefe41891..557fa89444 100644 --- a/services/core/java/com/android/server/net/NetworkStatsCollection.java +++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java @@ -54,6 +54,8 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.FastDataInput; +import com.android.internal.util.FastDataOutput; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; @@ -89,6 +91,9 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W /** File header magic number: "ANET" */ private static final int FILE_MAGIC = 0x414E4554; + /** Default buffer size from BufferedInputStream */ + private static final int BUFFER_SIZE = 8192; + private static final int VERSION_NETWORK_INIT = 1; private static final int VERSION_UID_INIT = 1; @@ -434,7 +439,8 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W @Override public void read(InputStream in) throws IOException { - read((DataInput) new DataInputStream(in)); + final FastDataInput dataIn = new FastDataInput(in, BUFFER_SIZE); + read(dataIn); } private void read(DataInput in) throws IOException { @@ -473,8 +479,9 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W @Override public void write(OutputStream out) throws IOException { - write((DataOutput) new DataOutputStream(out)); - out.flush(); + final FastDataOutput dataOut = new FastDataOutput(out, BUFFER_SIZE); + write(dataOut); + dataOut.flush(); } private void write(DataOutput out) throws IOException { From 537b8cfe688e31c28f642240e92fadbe7bd9a46f Mon Sep 17 00:00:00 2001 From: junyulai Date: Sat, 23 Jan 2021 11:00:10 +0800 Subject: [PATCH 34/64] [FUI18] Expose notifyNetworkStatus as system API Test: m -j doc-comment-check-docs Bug: 174123988 Change-Id: I11d4c9ab24de87fb2ad120e3787b78b73133e874 --- .../app/usage/NetworkStatsManager.java | 50 +++++++++++++++++++ .../server/net/NetworkStatsService.java | 9 ++-- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 1d5dc1d5df..098d8b6c60 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -16,6 +16,8 @@ package android.app.usage; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -28,8 +30,11 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.DataUsageRequest; import android.net.INetworkStatsService; +import android.net.Network; import android.net.NetworkStack; +import android.net.NetworkStateSnapshot; import android.net.NetworkTemplate; +import android.net.UnderlyingNetworkInfo; import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.netstats.provider.NetworkStatsProvider; import android.os.Binder; @@ -48,6 +53,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.net.module.util.NetworkIdentityUtils; +import java.util.List; import java.util.Objects; /** @@ -633,6 +639,50 @@ public class NetworkStatsManager { return template; } + /** + * Notify {@code NetworkStatsService} about network status changed. + * + * Notifies NetworkStatsService of network state changes for data usage accounting purposes. + * + * To avoid races that attribute data usage to wrong network, such as new network with + * the same interface after SIM hot-swap, this function will not return until + * {@code NetworkStatsService} finishes its work of retrieving traffic statistics from + * all data sources. + * + * @param defaultNetworks the list of all networks that could be used by network traffic that + * does not explicitly select a network. + * @param networkStateSnapshots a list of {@link NetworkStateSnapshot}s, one for + * each network that is currently connected. + * @param activeIface the active (i.e., connected) default network interface for the calling + * uid. Used to determine on which network future calls to + * {@link android.net.TrafficStats#incrementOperationCount} applies to. + * @param underlyingNetworkInfos the list of underlying network information for all + * currently-connected VPNs. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_STACK}) + public void notifyNetworkStatus( + @NonNull List defaultNetworks, + @NonNull List networkStateSnapshots, + @Nullable String activeIface, + @NonNull List underlyingNetworkInfos) { + try { + Objects.requireNonNull(defaultNetworks); + Objects.requireNonNull(networkStateSnapshots); + Objects.requireNonNull(underlyingNetworkInfos); + // TODO: Change internal namings after the name is decided. + mService.forceUpdateIfaces(defaultNetworks.toArray(new Network[0]), + networkStateSnapshots.toArray(new NetworkStateSnapshot[0]), activeIface, + underlyingNetworkInfos.toArray(new UnderlyingNetworkInfo[0])); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + private static class CallbackHandler extends Handler { private final int mNetworkType; private final String mSubscriberId; diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 3a5e10ed95..ebf1fe9d7c 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -379,6 +379,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { case MSG_UPDATE_IFACES: { // If no cached states, ignore. if (mLastNetworkStateSnapshots == null) break; + // TODO (b/181642673): Protect mDefaultNetworks from concurrent accessing. updateIfaces(mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface); break; } @@ -1266,7 +1267,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * they are combined under a single {@link NetworkIdentitySet}. */ @GuardedBy("mStatsLock") - private void updateIfacesLocked(@Nullable Network[] defaultNetworks, + private void updateIfacesLocked(@NonNull Network[] defaultNetworks, @NonNull NetworkStateSnapshot[] snapshots) { if (!mSystemReady) return; if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); @@ -1282,10 +1283,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // Rebuild active interfaces based on connected networks mActiveIfaces.clear(); mActiveUidIfaces.clear(); - if (defaultNetworks != null) { - // Caller is ConnectivityService. Update the list of default networks. - mDefaultNetworks = defaultNetworks; - } + // Update the list of default networks. + mDefaultNetworks = defaultNetworks; mLastNetworkStateSnapshots = snapshots; From a5e4ad75802fbdcba564327cc5a7ef8300f9d754 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Thu, 4 Feb 2021 14:20:19 +0900 Subject: [PATCH 35/64] Add Ethernet, TestNetworkSpecifier API Rename StringNetworkSpecifier to EthernetNetworkSpecifier (its only production user), and make it module-lib API. The original StringNetworkSpecifier file is actually kept to satisfy some invalid dependencies; it will be removed separately. This allows specifying an Ethernet interface with a non-deprecated API: until this change the only way to do so would be to use NetworkRequest#setSpecifier(String), which is deprecated. Similarly, add the TestNetworkSpecifier API for TestNetworkManager, to replace previous usage of StringNetworkSpecifier. TestNetworkManager is module API, so TestNetworkSpecifier should be module API too. This allows tests to request the test interface specifically, without using the deprecated NetworkRequest#setSpecifier(String). Bug: 179329291 Test: m Change-Id: Iee569f5c8bbdc4bc979610e1191308281f3d4620 --- .../android/net/EthernetNetworkSpecifier.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 core/java/android/net/EthernetNetworkSpecifier.java diff --git a/core/java/android/net/EthernetNetworkSpecifier.java b/core/java/android/net/EthernetNetworkSpecifier.java new file mode 100644 index 0000000000..e1685887e8 --- /dev/null +++ b/core/java/android/net/EthernetNetworkSpecifier.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import com.android.internal.util.Preconditions; + +import java.util.Objects; + +/** + * A {@link NetworkSpecifier} used to identify ethernet interfaces. + * + * @see EthernetManager + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable { + + /** + * Name of the network interface. + */ + @NonNull + private final String mInterfaceName; + + public EthernetNetworkSpecifier(@NonNull String interfaceName) { + Preconditions.checkStringNotEmpty(interfaceName); + mInterfaceName = interfaceName; + } + + // This may be null in the future to support specifiers based on data other than the interface + // name. + @Nullable + public String getInterfaceName() { + return mInterfaceName; + } + + @Override + public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) { + return equals(other); + } + + @Override + public boolean equals(@Nullable Object o) { + if (!(o instanceof EthernetNetworkSpecifier)) return false; + return TextUtils.equals(mInterfaceName, ((EthernetNetworkSpecifier) o).mInterfaceName); + } + + @Override + public int hashCode() { + return Objects.hashCode(mInterfaceName); + } + + @Override + public String toString() { + return "EthernetNetworkSpecifier (" + mInterfaceName + ")"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(mInterfaceName); + } + + public static final @NonNull Parcelable.Creator CREATOR = + new Parcelable.Creator() { + public EthernetNetworkSpecifier createFromParcel(Parcel in) { + return new EthernetNetworkSpecifier(in.readString()); + } + public EthernetNetworkSpecifier[] newArray(int size) { + return new EthernetNetworkSpecifier[size]; + } + }; +} From 3aec12c6a9a6eb3073caab670bf402a9cba715b4 Mon Sep 17 00:00:00 2001 From: lucaslin Date: Fri, 19 Mar 2021 16:06:33 +0800 Subject: [PATCH 36/64] Use public API Network#getNetId() to get netid Network class will be a part of mainline module, external callers cannot call its hidden constant. Use public API - getNetId() to get netid instead. Bug: 182963397 Test: m Change-Id: I6d5dd0a8c3879df7bdc1d58e36022045c303bb40 --- services/core/java/com/android/server/IpSecService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java index 4c3c6ef21f..794cb9301d 100644 --- a/services/core/java/com/android/server/IpSecService.java +++ b/services/core/java/com/android/server/IpSecService.java @@ -1651,7 +1651,7 @@ public class IpSecService extends IIpSecService.Stub { c.getMode(), c.getSourceAddress(), c.getDestinationAddress(), - (c.getNetwork() != null) ? c.getNetwork().netId : 0, + (c.getNetwork() != null) ? c.getNetwork().getNetId() : 0, spiRecord.getSpi(), c.getMarkValue(), c.getMarkMask(), From 1dc565df716ca1b376d4846271905d48586db4ea Mon Sep 17 00:00:00 2001 From: lucaslin Date: Fri, 19 Mar 2021 23:08:33 +0800 Subject: [PATCH 37/64] Use getAllInterfaceNames to get all interface names The current design is using hidden API - getStackedLinks() to get LinkProperties then call getInterfaceName() to get the interface name. In fact, this behavior could be replaced by system API - getAllInterfaceNames(). Bug: 182963397 Test: atest FrameworksNetTests Test: atest CtsNetTestCases Change-Id: Id2b19dc5099355af69d23a6d99d2b7e6c0e1e88a --- .../server/net/NetworkStatsService.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 7b376847fd..fe43c311da 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -92,7 +92,6 @@ import android.net.DataUsageRequest; import android.net.INetworkManagementEventObserver; import android.net.INetworkStatsService; import android.net.INetworkStatsSession; -import android.net.LinkProperties; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkIdentity; @@ -131,6 +130,7 @@ import android.service.NetworkInterfaceProto; import android.service.NetworkStatsServiceDumpProto; import android.telephony.PhoneStateListener; import android.telephony.SubscriptionPlan; +import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; @@ -1358,17 +1358,18 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // (or non eBPF offloaded) TX they would appear on both, however egress interface // accounting is explicitly bypassed for traffic from the clat uid. // - final List stackedLinks = snapshot.linkProperties.getStackedLinks(); - for (LinkProperties stackedLink : stackedLinks) { - final String stackedIface = stackedLink.getInterfaceName(); - if (stackedIface != null) { - findOrCreateNetworkIdentitySet(mActiveIfaces, stackedIface).add(ident); - findOrCreateNetworkIdentitySet(mActiveUidIfaces, stackedIface).add(ident); + // TODO: This code might be combined to above code. + for (String iface : snapshot.linkProperties.getAllInterfaceNames()) { + // baseIface has been handled, so ignore it. + if (TextUtils.equals(baseIface, iface)) continue; + if (iface != null) { + findOrCreateNetworkIdentitySet(mActiveIfaces, iface).add(ident); + findOrCreateNetworkIdentitySet(mActiveUidIfaces, iface).add(ident); if (isMobile) { - mobileIfaces.add(stackedIface); + mobileIfaces.add(iface); } - mStatsFactory.noteStackedIface(stackedIface, baseIface); + mStatsFactory.noteStackedIface(iface, baseIface); } } } From f19fea861cbc9c76c2a328059db850066729a376 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Wed, 3 Feb 2021 00:51:29 +0800 Subject: [PATCH 38/64] Migrate hidden API in IpConfigStore to formal API IpConfiguration and StaticIpConfiguration are included in framework-connectivity which cannot have external hidden API usages dependencies on them. IpConfiguration and StaticIpConfiguration provide builder and getter methods for the fields of the objects which are formal APIs. So, replace the usages in IpConfigStore with those formal APIs to remove the dependencies. Bug: 178777253 Test: FrameworksServicesTests:IpConfigStoreTest Change-Id: Ie9e6af0efe2c39667bb8faa1e3a498b1f61e1432 --- .../com/android/server/net/IpConfigStore.java | 87 ++++++++++--------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java index cc3a002adc..512d2192b9 100644 --- a/services/core/java/com/android/server/net/IpConfigStore.java +++ b/services/core/java/com/android/server/net/IpConfigStore.java @@ -42,6 +42,8 @@ import java.io.IOException; import java.io.InputStream; import java.net.Inet4Address; import java.net.InetAddress; +import java.util.ArrayList; +import java.util.List; public class IpConfigStore { private static final String TAG = "IpConfigStore"; @@ -83,25 +85,25 @@ public class IpConfigStore { boolean written = false; try { - switch (config.ipAssignment) { + switch (config.getIpAssignment()) { case STATIC: out.writeUTF(IP_ASSIGNMENT_KEY); - out.writeUTF(config.ipAssignment.toString()); - StaticIpConfiguration staticIpConfiguration = config.staticIpConfiguration; + out.writeUTF(config.getIpAssignment().toString()); + StaticIpConfiguration staticIpConfiguration = config.getStaticIpConfiguration(); if (staticIpConfiguration != null) { - if (staticIpConfiguration.ipAddress != null) { - LinkAddress ipAddress = staticIpConfiguration.ipAddress; + if (staticIpConfiguration.getIpAddress() != null) { + LinkAddress ipAddress = staticIpConfiguration.getIpAddress(); out.writeUTF(LINK_ADDRESS_KEY); out.writeUTF(ipAddress.getAddress().getHostAddress()); out.writeInt(ipAddress.getPrefixLength()); } - if (staticIpConfiguration.gateway != null) { + if (staticIpConfiguration.getGateway() != null) { out.writeUTF(GATEWAY_KEY); out.writeInt(0); // Default route. out.writeInt(1); // Have a gateway. - out.writeUTF(staticIpConfiguration.gateway.getHostAddress()); + out.writeUTF(staticIpConfiguration.getGateway().getHostAddress()); } - for (InetAddress inetAddr : staticIpConfiguration.dnsServers) { + for (InetAddress inetAddr : staticIpConfiguration.getDnsServers()) { out.writeUTF(DNS_KEY); out.writeUTF(inetAddr.getHostAddress()); } @@ -110,7 +112,7 @@ public class IpConfigStore { break; case DHCP: out.writeUTF(IP_ASSIGNMENT_KEY); - out.writeUTF(config.ipAssignment.toString()); + out.writeUTF(config.getIpAssignment().toString()); written = true; break; case UNASSIGNED: @@ -121,13 +123,13 @@ public class IpConfigStore { break; } - switch (config.proxySettings) { + switch (config.getProxySettings()) { case STATIC: - ProxyInfo proxyProperties = config.httpProxy; + ProxyInfo proxyProperties = config.getHttpProxy(); String exclusionList = ProxyUtils.exclusionListAsString( proxyProperties.getExclusionList()); out.writeUTF(PROXY_SETTINGS_KEY); - out.writeUTF(config.proxySettings.toString()); + out.writeUTF(config.getProxySettings().toString()); out.writeUTF(PROXY_HOST_KEY); out.writeUTF(proxyProperties.getHost()); out.writeUTF(PROXY_PORT_KEY); @@ -139,16 +141,16 @@ public class IpConfigStore { written = true; break; case PAC: - ProxyInfo proxyPacProperties = config.httpProxy; + ProxyInfo proxyPacProperties = config.getHttpProxy(); out.writeUTF(PROXY_SETTINGS_KEY); - out.writeUTF(config.proxySettings.toString()); + out.writeUTF(config.getProxySettings().toString()); out.writeUTF(PROXY_PAC_FILE); out.writeUTF(proxyPacProperties.getPacFileUrl().toString()); written = true; break; case NONE: out.writeUTF(PROXY_SETTINGS_KEY); - out.writeUTF(config.proxySettings.toString()); + out.writeUTF(config.getProxySettings().toString()); written = true; break; case UNASSIGNED: @@ -267,11 +269,14 @@ public class IpConfigStore { IpAssignment ipAssignment = IpAssignment.DHCP; ProxySettings proxySettings = ProxySettings.NONE; StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration(); + LinkAddress linkAddress = null; + InetAddress gatewayAddress = null; String proxyHost = null; String pacFileUrl = null; int proxyPort = -1; String exclusionList = null; String key; + final List dnsServers = new ArrayList<>(); do { key = in.readUTF(); @@ -286,15 +291,15 @@ public class IpConfigStore { } else if (key.equals(IP_ASSIGNMENT_KEY)) { ipAssignment = IpAssignment.valueOf(in.readUTF()); } else if (key.equals(LINK_ADDRESS_KEY)) { - LinkAddress linkAddr = + LinkAddress parsedLinkAddress = new LinkAddress( InetAddresses.parseNumericAddress(in.readUTF()), in.readInt()); - if (linkAddr.getAddress() instanceof Inet4Address && - staticIpConfiguration.ipAddress == null) { - staticIpConfiguration.ipAddress = linkAddr; + if (parsedLinkAddress.getAddress() instanceof Inet4Address + && linkAddress == null) { + linkAddress = parsedLinkAddress; } else { - loge("Non-IPv4 or duplicate address: " + linkAddr); + loge("Non-IPv4 or duplicate address: " + parsedLinkAddress); } } else if (key.equals(GATEWAY_KEY)) { LinkAddress dest = null; @@ -302,8 +307,8 @@ public class IpConfigStore { if (version == 1) { // only supported default gateways - leave the dest/prefix empty gateway = InetAddresses.parseNumericAddress(in.readUTF()); - if (staticIpConfiguration.gateway == null) { - staticIpConfiguration.gateway = gateway; + if (gatewayAddress == null) { + gatewayAddress = gateway; } else { loge("Duplicate gateway: " + gateway.getHostAddress()); } @@ -318,16 +323,14 @@ public class IpConfigStore { gateway = InetAddresses.parseNumericAddress(in.readUTF()); } RouteInfo route = new RouteInfo(dest, gateway); - if (route.isIPv4Default() && - staticIpConfiguration.gateway == null) { - staticIpConfiguration.gateway = gateway; + if (route.isIPv4Default() && gatewayAddress == null) { + gatewayAddress = gateway; } else { loge("Non-IPv4 default or duplicate route: " + route); } } } else if (key.equals(DNS_KEY)) { - staticIpConfiguration.dnsServers.add( - InetAddresses.parseNumericAddress(in.readUTF())); + dnsServers.add(InetAddresses.parseNumericAddress(in.readUTF())); } else if (key.equals(PROXY_SETTINGS_KEY)) { proxySettings = ProxySettings.valueOf(in.readUTF()); } else if (key.equals(PROXY_HOST_KEY)) { @@ -348,25 +351,31 @@ public class IpConfigStore { } } while (true); + staticIpConfiguration = new StaticIpConfiguration.Builder() + .setIpAddress(linkAddress) + .setGateway(gatewayAddress) + .setDnsServers(dnsServers) + .build(); + if (uniqueToken != null) { IpConfiguration config = new IpConfiguration(); networks.put(uniqueToken, config); switch (ipAssignment) { case STATIC: - config.staticIpConfiguration = staticIpConfiguration; - config.ipAssignment = ipAssignment; + config.setStaticIpConfiguration(staticIpConfiguration); + config.setIpAssignment(ipAssignment); break; case DHCP: - config.ipAssignment = ipAssignment; + config.setIpAssignment(ipAssignment); break; case UNASSIGNED: loge("BUG: Found UNASSIGNED IP on file, use DHCP"); - config.ipAssignment = IpAssignment.DHCP; + config.setIpAssignment(IpAssignment.DHCP); break; default: loge("Ignore invalid ip assignment while reading."); - config.ipAssignment = IpAssignment.UNASSIGNED; + config.setIpAssignment(IpAssignment.UNASSIGNED); break; } @@ -374,25 +383,25 @@ public class IpConfigStore { case STATIC: ProxyInfo proxyInfo = ProxyInfo.buildDirectProxy(proxyHost, proxyPort, ProxyUtils.exclusionStringAsList(exclusionList)); - config.proxySettings = proxySettings; - config.httpProxy = proxyInfo; + config.setProxySettings(proxySettings); + config.setHttpProxy(proxyInfo); break; case PAC: ProxyInfo proxyPacProperties = ProxyInfo.buildPacProxy(Uri.parse(pacFileUrl)); - config.proxySettings = proxySettings; - config.httpProxy = proxyPacProperties; + config.setProxySettings(proxySettings); + config.setHttpProxy(proxyPacProperties); break; case NONE: - config.proxySettings = proxySettings; + config.setProxySettings(proxySettings); break; case UNASSIGNED: loge("BUG: Found UNASSIGNED proxy on file, use NONE"); - config.proxySettings = ProxySettings.NONE; + config.setProxySettings(ProxySettings.NONE); break; default: loge("Ignore invalid proxy settings while reading"); - config.proxySettings = ProxySettings.UNASSIGNED; + config.setProxySettings(ProxySettings.UNASSIGNED); break; } } else { From cbe8076a2366462acb25f0a34dee15086f9165c2 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Thu, 18 Mar 2021 21:35:45 +0800 Subject: [PATCH 39/64] Fix IpConfigStore dependencies on framework-connectivity This change fixes IpConfigStore dependencies on framework-connectivity hidden APIs. - Use the version of SystemApi to new RouteInfo. - Inline the implementation of isIPv4Default() directly because isDefaultRoute() is a public API so it can be used in this class. Bug: 178777253 Test: FrameworksServicesTests:IpConfigStoreTest Change-Id: I5ed1bc8bc8bee5b0c795fd8577a2d64628998e51 --- .../java/com/android/server/net/IpConfigStore.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/net/IpConfigStore.java b/services/core/java/com/android/server/net/IpConfigStore.java index 512d2192b9..df1eb6d9fe 100644 --- a/services/core/java/com/android/server/net/IpConfigStore.java +++ b/services/core/java/com/android/server/net/IpConfigStore.java @@ -22,7 +22,6 @@ import android.net.IpConfiguration.IpAssignment; import android.net.IpConfiguration.ProxySettings; import android.net.LinkAddress; import android.net.ProxyInfo; -import android.net.RouteInfo; import android.net.StaticIpConfiguration; import android.net.Uri; import android.util.ArrayMap; @@ -322,11 +321,14 @@ public class IpConfigStore { if (in.readInt() == 1) { gateway = InetAddresses.parseNumericAddress(in.readUTF()); } - RouteInfo route = new RouteInfo(dest, gateway); - if (route.isIPv4Default() && gatewayAddress == null) { + // If the destination is a default IPv4 route, use the gateway + // address unless already set. + if (dest.getAddress() instanceof Inet4Address + && dest.getPrefixLength() == 0 && gatewayAddress == null) { gatewayAddress = gateway; } else { - loge("Non-IPv4 default or duplicate route: " + route); + loge("Non-IPv4 default or duplicate route: " + + dest.getAddress()); } } } else if (key.equals(DNS_KEY)) { From cc6bc70bbf36b11698680ff59d18267775bf46ae Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 10 Mar 2021 10:33:16 +0800 Subject: [PATCH 40/64] [SP28] Add API for set data warning To have better control and race-free of set data warning to tether offload hardware, an interface of set warning and limit at the same time in the NetworkStatsProvider is needed. This is a no-op change which expose such interface with minimum changes in service side to get build pass. The implementation would be included in follow-up patches. Test: atest NetworkStatsServiceTest Test: atest NetworkPolicyManagerServiceTest Test: atest GtsNetworkStackHostTestCases Test: m doc-comment-check-docs Bug: 149467454 Bug: 170699770 Bug: 170179169 Ignore-AOSP-First: avoid long automerger delay Change-Id: I6ee661497f7dedb871c85786d1950cab951d8aa2 --- .../provider/INetworkStatsProvider.aidl | 2 +- .../INetworkStatsProviderCallback.aidl | 2 +- .../provider/NetworkStatsProvider.java | 58 ++++++++++++++++--- .../server/net/NetworkStatsService.java | 10 ++-- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl index 4078b24921..74c3ba44b6 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl @@ -23,6 +23,6 @@ package android.net.netstats.provider; */ oneway interface INetworkStatsProvider { void onRequestStatsUpdate(int token); - void onSetLimit(String iface, long quotaBytes); void onSetAlert(long quotaBytes); + void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes); } diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl index bd336dd348..7eaa01e262 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl @@ -26,6 +26,6 @@ import android.net.NetworkStats; oneway interface INetworkStatsProviderCallback { void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); void notifyAlertReached(); - void notifyLimitReached(); + void notifyWarningOrLimitReached(); void unregister(); } diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java index 7639d2244c..65b336ad6f 100644 --- a/core/java/android/net/netstats/provider/NetworkStatsProvider.java +++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java @@ -29,7 +29,8 @@ import android.os.RemoteException; @SystemApi public abstract class NetworkStatsProvider { /** - * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit. + * A value used by {@link #onSetLimit}, {@link #onSetAlert} and {@link #onSetWarningAndLimit} + * indicates there is no limit. */ public static final int QUOTA_UNLIMITED = -1; @@ -42,13 +43,13 @@ public abstract class NetworkStatsProvider { } @Override - public void onSetLimit(String iface, long quotaBytes) { - NetworkStatsProvider.this.onSetLimit(iface, quotaBytes); + public void onSetAlert(long quotaBytes) { + NetworkStatsProvider.this.onSetAlert(quotaBytes); } @Override - public void onSetAlert(long quotaBytes) { - NetworkStatsProvider.this.onSetAlert(quotaBytes); + public void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes) { + NetworkStatsProvider.this.onSetWarningAndLimit(iface, warningBytes, limitBytes); } }; @@ -145,11 +146,28 @@ public abstract class NetworkStatsProvider { } /** - * Notify system that the quota set by {@code onSetLimit} has been reached. + * Notify system that the warning set by {@link #onSetWarningAndLimit} has been reached. + * + * @hide + */ + // TODO: Expose as system API. + public void notifyWarningReached() { + try { + // Reuse the code path to notify warning reached with limit reached + // since framework handles them in the same way. + getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@link #onSetLimit} or limit set by + * {@link #onSetWarningAndLimit} has been reached. */ public void notifyLimitReached() { try { - getProviderCallbackBinderOrThrow().notifyLimitReached(); + getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached(); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } @@ -180,8 +198,34 @@ public abstract class NetworkStatsProvider { * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. */ + // TODO: deprecate this once onSetWarningAndLimit is ready. public abstract void onSetLimit(@NonNull String iface, long quotaBytes); + /** + * Called by {@code NetworkStatsService} when setting the interface quotas for the specified + * upstream interface. If a provider implements {@link #onSetWarningAndLimit}, the system + * will not call {@link #onSetLimit}. When this method is called, the implementation + * should behave as follows: + * 1. If {@code warningBytes} is reached on {@code iface}, block all further traffic on + * {@code iface} and call {@link NetworkStatsProvider@notifyWarningReached()}. + * 2. If {@code limitBytes} is reached on {@code iface}, block all further traffic on + * {@code iface} and call {@link NetworkStatsProvider#notifyLimitReached()}. + * + * @param iface the interface requiring the operation. + * @param warningBytes the warning defined as the number of bytes, starting from zero and + * counting from now. A value of {@link #QUOTA_UNLIMITED} indicates + * there is no warning. + * @param limitBytes the limit defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. + * + * @hide + */ + // TODO: Expose as system API. + public void onSetWarningAndLimit(@NonNull String iface, long warningBytes, long limitBytes) { + // Backward compatibility for those who didn't override this function. + onSetLimit(iface, limitBytes); + } + /** * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index fe43c311da..785e487ed1 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -1676,7 +1676,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public void setStatsProviderLimitAsync(@NonNull String iface, long quota) { if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")"); - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota)); + // TODO: Set warning accordingly. + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface, + NetworkStatsProvider.QUOTA_UNLIMITED, quota)); } } @@ -2071,10 +2073,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void notifyLimitReached() { - Log.d(TAG, mTag + ": onLimitReached"); + public void notifyWarningOrLimitReached() { + Log.d(TAG, mTag + ": notifyWarningOrLimitReached"); LocalServices.getService(NetworkPolicyManagerInternal.class) - .onStatsProviderLimitReached(mTag); + .onStatsProviderWarningOrLimitReached(mTag); } @Override From df6726cac74d6145f0cfa7a213b2e8dc8180a95d Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 24 Mar 2021 14:17:19 +0800 Subject: [PATCH 41/64] [SP29] Send interface warning bytes to NetworkStatsProvider This change contains necessary modification in NPMS and NSS to send warning bytes to NetworkStatsProvider. But since no any provider has been upgraded to handle such parameter. Thus, no behavior change is made in this patch. Test: atest NetworkPolicyManagerServiceTest NetworkStatsServiceTest Test: atest NetworkPolicyManagerServiceTest#testStatsProviderWarningAndLimitReached Bug: 149467454 Bug: 170699770 Bug: 170179169 Ignore-AOSP-First: avoid long automerger delay Change-Id: I6c4863030c36328db571294fd12a40e59864def5 --- .../com/android/server/net/NetworkStatsService.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 785e487ed1..de5aae07d6 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -1674,11 +1674,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void setStatsProviderLimitAsync(@NonNull String iface, long quota) { - if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")"); - // TODO: Set warning accordingly. + public void setStatsProviderWarningAndLimitAsync( + @NonNull String iface, long warning, long limit) { + if (LOGV) { + Slog.v(TAG, "setStatsProviderWarningAndLimitAsync(" + + iface + "," + warning + "," + limit + ")"); + } invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface, - NetworkStatsProvider.QUOTA_UNLIMITED, quota)); + warning, limit)); } } From e6e90d34a2dd4065e25b4e66017a8185a03a6342 Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 10 Mar 2021 19:45:05 +0800 Subject: [PATCH 42/64] [SP31] Expose onSetWarningAndLimit System API Test: atest NetworkPolicyManagerServiceTest NetworkStatsServiceTest Bug: 149467454 CTS-Coverage-Bug: 183598414 Ignore-AOSP-First: avoid long automerger delay Change-Id: I6f5e22e3a7b80a38cae9f3c5d7296a1dff34facf --- .../net/netstats/provider/NetworkStatsProvider.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java index 65b336ad6f..23fc06927e 100644 --- a/core/java/android/net/netstats/provider/NetworkStatsProvider.java +++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java @@ -147,10 +147,7 @@ public abstract class NetworkStatsProvider { /** * Notify system that the warning set by {@link #onSetWarningAndLimit} has been reached. - * - * @hide */ - // TODO: Expose as system API. public void notifyWarningReached() { try { // Reuse the code path to notify warning reached with limit reached @@ -198,7 +195,6 @@ public abstract class NetworkStatsProvider { * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. */ - // TODO: deprecate this once onSetWarningAndLimit is ready. public abstract void onSetLimit(@NonNull String iface, long quotaBytes); /** @@ -217,10 +213,7 @@ public abstract class NetworkStatsProvider { * there is no warning. * @param limitBytes the limit defined as the number of bytes, starting from zero and counting * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. - * - * @hide */ - // TODO: Expose as system API. public void onSetWarningAndLimit(@NonNull String iface, long warningBytes, long limitBytes) { // Backward compatibility for those who didn't override this function. onSetLimit(iface, limitBytes); From f7633ac09c4e91f3968eaf6f29cdefd43b160088 Mon Sep 17 00:00:00 2001 From: paulhu Date: Fri, 9 Apr 2021 15:47:36 +0800 Subject: [PATCH 43/64] Rename FIRST_SDK_INT to DEVICE_INITIAL_SDK_INT As API review feedback, rename Build#VERSION#FIRST_SDK_INT to Build#VERSION#DEVICE_INITIAL_SDK_INT. As well as update all usage in frameworks and tests. Bug: 184735771 Test: m Change-Id: I72660959cb4e638a8e80fcf2f4e96ea172969f44 --- core/java/android/net/IpSecAlgorithm.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java index 8f1e2defd2..7ef5bac092 100644 --- a/core/java/android/net/IpSecAlgorithm.java +++ b/core/java/android/net/IpSecAlgorithm.java @@ -354,7 +354,7 @@ public final class IpSecAlgorithm implements Parcelable { } for (Entry entry : ALGO_TO_REQUIRED_FIRST_SDK.entrySet()) { - if (Build.VERSION.FIRST_SDK_INT >= entry.getValue()) { + if (Build.VERSION.DEVICE_INITIAL_SDK_INT >= entry.getValue()) { enabledAlgos.add(entry.getKey()); } } From 1e384f29b40860ec0c209200ae9fd267dde322d7 Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Thu, 8 Apr 2021 19:42:30 +0800 Subject: [PATCH 44/64] Resolve hidden connectivity methods dependency This commit resolves the dependency under batterystatstests, servicestests and coretests with hidden connectivity module codes. Because of connectivity modularization work, the hidden connectivity methods are not accessible outside modules. Update tests with alternative ways. Bug: 182859030 Test: atest Change-Id: I8294ae4167ee5f95137e0be0f7464429ed3f3322 --- .../android/server/net/IpConfigStoreTest.java | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java index 401d6e30df..2f771260ac 100644 --- a/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java +++ b/services/tests/servicestests/src/com/android/server/net/IpConfigStoreTest.java @@ -39,6 +39,8 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; +import java.net.InetAddress; +import java.util.ArrayList; import java.util.Arrays; /** @@ -53,8 +55,8 @@ public class IpConfigStoreTest { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); DataOutputStream outputStream = new DataOutputStream(byteStream); - IpConfiguration expectedConfig = new IpConfiguration(IpAssignment.DHCP, - ProxySettings.NONE, null, null); + final IpConfiguration expectedConfig = + newIpConfiguration(IpAssignment.DHCP, ProxySettings.NONE, null, null); // Emulate writing to old format. writeDhcpConfigV2(outputStream, KEY_CONFIG, expectedConfig); @@ -78,18 +80,23 @@ public class IpConfigStoreTest { final String DNS_IP_ADDR_1 = "1.2.3.4"; final String DNS_IP_ADDR_2 = "5.6.7.8"; - StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration(); - staticIpConfiguration.ipAddress = new LinkAddress(IP_ADDR_1); - staticIpConfiguration.dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1)); - staticIpConfiguration.dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2)); + final ArrayList dnsServers = new ArrayList<>(); + dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_1)); + dnsServers.add(InetAddresses.parseNumericAddress(DNS_IP_ADDR_2)); + final StaticIpConfiguration staticIpConfiguration1 = new StaticIpConfiguration.Builder() + .setIpAddress(new LinkAddress(IP_ADDR_1)) + .setDnsServers(dnsServers).build(); + final StaticIpConfiguration staticIpConfiguration2 = new StaticIpConfiguration.Builder() + .setIpAddress(new LinkAddress(IP_ADDR_2)) + .setDnsServers(dnsServers).build(); ProxyInfo proxyInfo = ProxyInfo.buildDirectProxy("10.10.10.10", 88, Arrays.asList("host1", "host2")); - IpConfiguration expectedConfig1 = new IpConfiguration(IpAssignment.STATIC, - ProxySettings.STATIC, staticIpConfiguration, proxyInfo); - IpConfiguration expectedConfig2 = new IpConfiguration(expectedConfig1); - expectedConfig2.getStaticIpConfiguration().ipAddress = new LinkAddress(IP_ADDR_2); + IpConfiguration expectedConfig1 = newIpConfiguration(IpAssignment.STATIC, + ProxySettings.STATIC, staticIpConfiguration1, proxyInfo); + IpConfiguration expectedConfig2 = newIpConfiguration(IpAssignment.STATIC, + ProxySettings.STATIC, staticIpConfiguration2, proxyInfo); ArrayMap expectedNetworks = new ArrayMap<>(); expectedNetworks.put(IFACE_1, expectedConfig1); @@ -107,14 +114,24 @@ public class IpConfigStoreTest { assertEquals(expectedNetworks.get(IFACE_2), actualNetworks.get(IFACE_2)); } + private IpConfiguration newIpConfiguration(IpAssignment ipAssignment, + ProxySettings proxySettings, StaticIpConfiguration staticIpConfig, ProxyInfo info) { + final IpConfiguration config = new IpConfiguration(); + config.setIpAssignment(ipAssignment); + config.setProxySettings(proxySettings); + config.setStaticIpConfiguration(staticIpConfig); + config.setHttpProxy(info); + return config; + } + // This is simplified snapshot of code that was used to store values in V2 format (key as int). private static void writeDhcpConfigV2(DataOutputStream out, int configKey, IpConfiguration config) throws IOException { out.writeInt(2); // VERSION 2 - switch (config.ipAssignment) { + switch (config.getIpAssignment()) { case DHCP: out.writeUTF("ipAssignment"); - out.writeUTF(config.ipAssignment.toString()); + out.writeUTF(config.getIpAssignment().toString()); break; default: fail("Not supported in test environment"); From 8a74c1ff1df01ad7f7ea854b52f3b72e20af7f0b Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Fri, 16 Apr 2021 23:20:23 +0800 Subject: [PATCH 45/64] Add getters to UnderlyingNetworkInfo Address API review feedback, add getters to UnderlyingNetworkInfo instead of exposing fields. Instead of wasting memory by converting this into an array, have migrateTun take a List. In turn, tunAdjustmentInit should also take a List. Bug: 183972554 Test: atest android.net.UnderlyingNetworkInfoTest Change-Id: Id59744097208d91298a25ef110ade91a9cf291a1 --- core/java/android/net/NetworkStats.java | 31 +++++----- .../android/net/UnderlyingNetworkInfo.java | 60 ++++++++++++------- .../server/net/NetworkStatsFactory.java | 4 +- 3 files changed, 58 insertions(+), 37 deletions(-) diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index d42beae601..6ccbab7ed8 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -38,6 +38,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Predicate; @@ -1423,11 +1424,11 @@ public final class NetworkStats implements Parcelable { * @hide */ public void migrateTun(int tunUid, @NonNull String tunIface, - @NonNull String[] underlyingIfaces) { + @NonNull List underlyingIfaces) { // Combined usage by all apps using VPN. final Entry tunIfaceTotal = new Entry(); // Usage by VPN, grouped by its {@code underlyingIfaces}. - final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.length]; + final Entry[] perInterfaceTotal = new Entry[underlyingIfaces.size()]; // Usage by VPN, summed across all its {@code underlyingIfaces}. final Entry underlyingIfacesTotal = new Entry(); @@ -1468,7 +1469,7 @@ public final class NetworkStats implements Parcelable { * {@code underlyingIfaces} */ private void tunAdjustmentInit(int tunUid, @NonNull String tunIface, - @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal, + @NonNull List underlyingIfaces, @NonNull Entry tunIfaceTotal, @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) { final Entry recycle = new Entry(); for (int i = 0; i < size; i++) { @@ -1488,8 +1489,8 @@ public final class NetworkStats implements Parcelable { if (recycle.uid == tunUid) { // Add up traffic through tunUid's underlying interfaces. - for (int j = 0; j < underlyingIfaces.length; j++) { - if (Objects.equals(underlyingIfaces[j], recycle.iface)) { + for (int j = 0; j < underlyingIfaces.size(); j++) { + if (Objects.equals(underlyingIfaces.get(j), recycle.iface)) { perInterfaceTotal[j].add(recycle); underlyingIfacesTotal.add(recycle); break; @@ -1515,12 +1516,12 @@ public final class NetworkStats implements Parcelable { * underlyingIfaces} */ private Entry[] addTrafficToApplications(int tunUid, @NonNull String tunIface, - @NonNull String[] underlyingIfaces, @NonNull Entry tunIfaceTotal, + @NonNull List underlyingIfaces, @NonNull Entry tunIfaceTotal, @NonNull Entry[] perInterfaceTotal, @NonNull Entry underlyingIfacesTotal) { // Traffic that should be moved off of each underlying interface for tunUid (see // deductTrafficFromVpnApp below). - final Entry[] moved = new Entry[underlyingIfaces.length]; - for (int i = 0; i < underlyingIfaces.length; i++) { + final Entry[] moved = new Entry[underlyingIfaces.size()]; + for (int i = 0; i < underlyingIfaces.size(); i++) { moved[i] = new Entry(); } @@ -1582,8 +1583,8 @@ public final class NetworkStats implements Parcelable { } // In a second pass, distribute these values across interfaces in the proportion that // each interface represents of the total traffic of the underlying interfaces. - for (int j = 0; j < underlyingIfaces.length; j++) { - tmpEntry.iface = underlyingIfaces[j]; + for (int j = 0; j < underlyingIfaces.size(); j++) { + tmpEntry.iface = underlyingIfaces.get(j); tmpEntry.rxBytes = 0; // Reset 'set' to correct value since it gets updated when adding debug info below. tmpEntry.set = set[i]; @@ -1638,14 +1639,14 @@ public final class NetworkStats implements Parcelable { private void deductTrafficFromVpnApp( int tunUid, - @NonNull String[] underlyingIfaces, + @NonNull List underlyingIfaces, @NonNull Entry[] moved) { - for (int i = 0; i < underlyingIfaces.length; i++) { + for (int i = 0; i < underlyingIfaces.size(); i++) { moved[i].uid = tunUid; // Add debug info moved[i].set = SET_DBG_VPN_OUT; moved[i].tag = TAG_NONE; - moved[i].iface = underlyingIfaces[i]; + moved[i].iface = underlyingIfaces.get(i); moved[i].metered = METERED_ALL; moved[i].roaming = ROAMING_ALL; moved[i].defaultNetwork = DEFAULT_NETWORK_ALL; @@ -1658,7 +1659,7 @@ public final class NetworkStats implements Parcelable { // METERED_NO, which should be the case as it comes directly from the /proc file. // We only blend in the roaming data after applying these adjustments, by checking the // NetworkIdentity of the underlying iface. - final int idxVpnBackground = findIndex(underlyingIfaces[i], tunUid, SET_DEFAULT, + final int idxVpnBackground = findIndex(underlyingIfaces.get(i), tunUid, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO); if (idxVpnBackground != -1) { // Note - tunSubtract also updates moved[i]; whatever traffic that's left is removed @@ -1666,7 +1667,7 @@ public final class NetworkStats implements Parcelable { tunSubtract(idxVpnBackground, this, moved[i]); } - final int idxVpnForeground = findIndex(underlyingIfaces[i], tunUid, SET_FOREGROUND, + final int idxVpnForeground = findIndex(underlyingIfaces.get(i), tunUid, SET_FOREGROUND, TAG_NONE, METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO); if (idxVpnForeground != -1) { tunSubtract(idxVpnForeground, this, moved[i]); diff --git a/core/java/android/net/UnderlyingNetworkInfo.java b/core/java/android/net/UnderlyingNetworkInfo.java index 7bf9231239..459fdacef8 100644 --- a/core/java/android/net/UnderlyingNetworkInfo.java +++ b/core/java/android/net/UnderlyingNetworkInfo.java @@ -37,36 +37,56 @@ import java.util.Objects; @SystemApi(client = MODULE_LIBRARIES) public final class UnderlyingNetworkInfo implements Parcelable { /** The owner of this network. */ - public final int ownerUid; + private final int mOwnerUid; + /** The interface name of this network. */ @NonNull - public final String iface; + private final String mIface; + /** The names of the interfaces underlying this network. */ @NonNull - public final List underlyingIfaces; + private final List mUnderlyingIfaces; public UnderlyingNetworkInfo(int ownerUid, @NonNull String iface, @NonNull List underlyingIfaces) { Objects.requireNonNull(iface); Objects.requireNonNull(underlyingIfaces); - this.ownerUid = ownerUid; - this.iface = iface; - this.underlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces)); + mOwnerUid = ownerUid; + mIface = iface; + mUnderlyingIfaces = Collections.unmodifiableList(new ArrayList<>(underlyingIfaces)); } private UnderlyingNetworkInfo(@NonNull Parcel in) { - this.ownerUid = in.readInt(); - this.iface = in.readString(); - this.underlyingIfaces = new ArrayList<>(); - in.readList(this.underlyingIfaces, null /*classLoader*/); + mOwnerUid = in.readInt(); + mIface = in.readString(); + List underlyingIfaces = new ArrayList<>(); + in.readList(underlyingIfaces, null /*classLoader*/); + mUnderlyingIfaces = Collections.unmodifiableList(underlyingIfaces); + } + + /** Get the owner of this network. */ + public int getOwnerUid() { + return mOwnerUid; + } + + /** Get the interface name of this network. */ + @NonNull + public String getIface() { + return mIface; + } + + /** Get the names of the interfaces underlying this network. */ + @NonNull + public List getUnderlyingIfaces() { + return mUnderlyingIfaces; } @Override public String toString() { return "UnderlyingNetworkInfo{" - + "ownerUid=" + ownerUid - + ", iface='" + iface + '\'' - + ", underlyingIfaces='" + underlyingIfaces.toString() + '\'' + + "ownerUid=" + mOwnerUid + + ", iface='" + mIface + '\'' + + ", underlyingIfaces='" + mUnderlyingIfaces.toString() + '\'' + '}'; } @@ -77,9 +97,9 @@ public final class UnderlyingNetworkInfo implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeInt(ownerUid); - dest.writeString(iface); - dest.writeList(underlyingIfaces); + dest.writeInt(mOwnerUid); + dest.writeString(mIface); + dest.writeList(mUnderlyingIfaces); } @NonNull @@ -103,13 +123,13 @@ public final class UnderlyingNetworkInfo implements Parcelable { if (this == o) return true; if (!(o instanceof UnderlyingNetworkInfo)) return false; final UnderlyingNetworkInfo that = (UnderlyingNetworkInfo) o; - return ownerUid == that.ownerUid - && Objects.equals(iface, that.iface) - && Objects.equals(underlyingIfaces, that.underlyingIfaces); + return mOwnerUid == that.getOwnerUid() + && Objects.equals(mIface, that.getIface()) + && Objects.equals(mUnderlyingIfaces, that.getUnderlyingIfaces()); } @Override public int hashCode() { - return Objects.hash(ownerUid, iface, underlyingIfaces); + return Objects.hash(mOwnerUid, mIface, mUnderlyingIfaces); } } diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java index d042b882fe..e7c0a50163 100644 --- a/services/core/java/com/android/server/net/NetworkStatsFactory.java +++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java @@ -382,8 +382,8 @@ public class NetworkStatsFactory { // Migrate data usage over a VPN to the TUN network. for (UnderlyingNetworkInfo info : vpnArray) { - delta.migrateTun(info.ownerUid, info.iface, - info.underlyingIfaces.toArray(new String[0])); + delta.migrateTun(info.getOwnerUid(), info.getIface(), + info.getUnderlyingIfaces()); // Filter out debug entries as that may lead to over counting. delta.filterDebugEntries(); } From 444fcb9d56beb7a318e832ae827098f1466dd803 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Tue, 20 Apr 2021 17:19:46 +0800 Subject: [PATCH 46/64] Add getters to NetworkStateSnapshot Address API council feedback, add getters to NetworkStateSnapshot instead of exposing the bare fields directly. Bug: 183972826 Test: FrameworksNetTests Change-Id: Id1707753b42ae88d2b95e4bd00a792609434e4f5 --- core/java/android/net/NetworkIdentity.java | 12 +-- .../android/net/NetworkStateSnapshot.java | 92 ++++++++++++------- .../server/net/NetworkStatsService.java | 21 ++--- 3 files changed, 77 insertions(+), 48 deletions(-) diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 1eef7d9a53..3bde6fa691 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -186,19 +186,19 @@ public class NetworkIdentity implements Comparable { */ public static NetworkIdentity buildNetworkIdentity(Context context, NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType) { - final int legacyType = snapshot.legacyType; + final int legacyType = snapshot.getLegacyType(); - final String subscriberId = snapshot.subscriberId; + final String subscriberId = snapshot.getSubscriberId(); String networkId = null; - boolean roaming = !snapshot.networkCapabilities.hasCapability( + boolean roaming = !snapshot.getNetworkCapabilities().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); - boolean metered = !snapshot.networkCapabilities.hasCapability( + boolean metered = !snapshot.getNetworkCapabilities().hasCapability( NetworkCapabilities.NET_CAPABILITY_NOT_METERED); - final int oemManaged = getOemBitfield(snapshot.networkCapabilities); + final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities()); if (legacyType == TYPE_WIFI) { - networkId = snapshot.networkCapabilities.getSsid(); + networkId = snapshot.getNetworkCapabilities().getSsid(); if (networkId == null) { final WifiManager wifi = context.getSystemService(WifiManager.class); final WifiInfo info = wifi.getConnectionInfo(); diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java index 0d26c2de86..9df861a6ff 100644 --- a/core/java/android/net/NetworkStateSnapshot.java +++ b/core/java/android/net/NetworkStateSnapshot.java @@ -37,47 +37,76 @@ import java.util.Objects; public final class NetworkStateSnapshot implements Parcelable { /** The network associated with this snapshot. */ @NonNull - public final Network network; + private final Network mNetwork; /** The {@link NetworkCapabilities} of the network associated with this snapshot. */ @NonNull - public final NetworkCapabilities networkCapabilities; + private final NetworkCapabilities mNetworkCapabilities; /** The {@link LinkProperties} of the network associated with this snapshot. */ @NonNull - public final LinkProperties linkProperties; + private final LinkProperties mLinkProperties; /** * The Subscriber Id of the network associated with this snapshot. See * {@link android.telephony.TelephonyManager#getSubscriberId()}. */ @Nullable - public final String subscriberId; + private final String mSubscriberId; /** * The legacy type of the network associated with this snapshot. See * {@code ConnectivityManager#TYPE_*}. */ - public final int legacyType; + private final int mLegacyType; public NetworkStateSnapshot(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities, @NonNull LinkProperties linkProperties, @Nullable String subscriberId, int legacyType) { - this.network = Objects.requireNonNull(network); - this.networkCapabilities = Objects.requireNonNull(networkCapabilities); - this.linkProperties = Objects.requireNonNull(linkProperties); - this.subscriberId = subscriberId; - this.legacyType = legacyType; + mNetwork = Objects.requireNonNull(network); + mNetworkCapabilities = Objects.requireNonNull(networkCapabilities); + mLinkProperties = Objects.requireNonNull(linkProperties); + mSubscriberId = subscriberId; + mLegacyType = legacyType; } /** @hide */ public NetworkStateSnapshot(@NonNull Parcel in) { - network = in.readParcelable(null); - networkCapabilities = in.readParcelable(null); - linkProperties = in.readParcelable(null); - subscriberId = in.readString(); - legacyType = in.readInt(); + mNetwork = in.readParcelable(null); + mNetworkCapabilities = in.readParcelable(null); + mLinkProperties = in.readParcelable(null); + mSubscriberId = in.readString(); + mLegacyType = in.readInt(); + } + + /** Get the network associated with this snapshot */ + @NonNull + public Network getNetwork() { + return mNetwork; + } + + /** Get {@link NetworkCapabilities} of the network associated with this snapshot. */ + @NonNull + public NetworkCapabilities getNetworkCapabilities() { + return mNetworkCapabilities; + } + + /** Get the {@link LinkProperties} of the network associated with this snapshot. */ + @NonNull + public LinkProperties getLinkProperties() { + return mLinkProperties; + } + + /** Get the Subscriber Id of the network associated with this snapshot. */ + @Nullable + public String getSubscriberId() { + return mSubscriberId; + } + + /** Get the legacy type of the network associated with this snapshot. */ + public int getLegacyType() { + return mLegacyType; } @Override @@ -87,11 +116,11 @@ public final class NetworkStateSnapshot implements Parcelable { @Override public void writeToParcel(@NonNull Parcel out, int flags) { - out.writeParcelable(network, flags); - out.writeParcelable(networkCapabilities, flags); - out.writeParcelable(linkProperties, flags); - out.writeString(subscriberId); - out.writeInt(legacyType); + out.writeParcelable(mNetwork, flags); + out.writeParcelable(mNetworkCapabilities, flags); + out.writeParcelable(mLinkProperties, flags); + out.writeString(mSubscriberId); + out.writeInt(mLegacyType); } @NonNull @@ -115,26 +144,27 @@ public final class NetworkStateSnapshot implements Parcelable { if (this == o) return true; if (!(o instanceof NetworkStateSnapshot)) return false; NetworkStateSnapshot that = (NetworkStateSnapshot) o; - return legacyType == that.legacyType - && Objects.equals(network, that.network) - && Objects.equals(networkCapabilities, that.networkCapabilities) - && Objects.equals(linkProperties, that.linkProperties) - && Objects.equals(subscriberId, that.subscriberId); + return mLegacyType == that.mLegacyType + && Objects.equals(mNetwork, that.mNetwork) + && Objects.equals(mNetworkCapabilities, that.mNetworkCapabilities) + && Objects.equals(mLinkProperties, that.mLinkProperties) + && Objects.equals(mSubscriberId, that.mSubscriberId); } @Override public int hashCode() { - return Objects.hash(network, networkCapabilities, linkProperties, subscriberId, legacyType); + return Objects.hash(mNetwork, + mNetworkCapabilities, mLinkProperties, mSubscriberId, mLegacyType); } @Override public String toString() { return "NetworkStateSnapshot{" - + "network=" + network - + ", networkCapabilities=" + networkCapabilities - + ", linkProperties=" + linkProperties - + ", subscriberId='" + NetworkIdentityUtils.scrubSubscriberId(subscriberId) + '\'' - + ", legacyType=" + legacyType + + "network=" + mNetwork + + ", networkCapabilities=" + mNetworkCapabilities + + ", linkProperties=" + mLinkProperties + + ", subscriberId='" + NetworkIdentityUtils.scrubSubscriberId(mSubscriberId) + '\'' + + ", legacyType=" + mLegacyType + '}'; } } diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 19f5e3cd5d..3c14440c64 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -24,7 +24,6 @@ import static android.content.Intent.ACTION_UID_REMOVED; import static android.content.Intent.ACTION_USER_REMOVED; import static android.content.Intent.EXTRA_UID; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkIdentity.SUBTYPE_COMBINED; import static android.net.NetworkStack.checkNetworkStackPermission; import static android.net.NetworkStats.DEFAULT_NETWORK_ALL; @@ -97,12 +96,12 @@ import android.net.INetworkStatsSession; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkIdentity; +import android.net.NetworkSpecifier; import android.net.NetworkStack; import android.net.NetworkStateSnapshot; import android.net.NetworkStats; import android.net.NetworkStats.NonMonotonicObserver; import android.net.NetworkStatsHistory; -import android.net.NetworkSpecifier; import android.net.NetworkTemplate; import android.net.TelephonyNetworkSpecifier; import android.net.TrafficStats; @@ -1296,9 +1295,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { final ArraySet mobileIfaces = new ArraySet<>(); for (NetworkStateSnapshot snapshot : snapshots) { final int displayTransport = - getDisplayTransport(snapshot.networkCapabilities.getTransportTypes()); + getDisplayTransport(snapshot.getNetworkCapabilities().getTransportTypes()); final boolean isMobile = (NetworkCapabilities.TRANSPORT_CELLULAR == displayTransport); - final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.network); + final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.getNetwork()); final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED : getSubTypeForStateSnapshot(snapshot); final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot, @@ -1306,7 +1305,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // Traffic occurring on the base interface is always counted for // both total usage and UID details. - final String baseIface = snapshot.linkProperties.getInterfaceName(); + final String baseIface = snapshot.getLinkProperties().getInterfaceName(); if (baseIface != null) { findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident); findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident); @@ -1316,7 +1315,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // If IMS is metered, then the IMS network usage has already included VT usage. // VT is considered always metered in framework's layer. If VT is not metered // per carrier's policy, modem will report 0 usage for VT calls. - if (snapshot.networkCapabilities.hasCapability( + if (snapshot.getNetworkCapabilities().hasCapability( NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) { // Copy the identify from IMS one but mark it as metered. @@ -1364,7 +1363,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // accounting is explicitly bypassed for traffic from the clat uid. // // TODO: This code might be combined to above code. - for (String iface : snapshot.linkProperties.getAllInterfaceNames()) { + for (String iface : snapshot.getLinkProperties().getAllInterfaceNames()) { // baseIface has been handled, so ignore it. if (TextUtils.equals(baseIface, iface)) continue; if (iface != null) { @@ -1383,11 +1382,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) { - if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { throw new IllegalArgumentException("Mobile state need capability TRANSPORT_CELLULAR"); } - final NetworkSpecifier spec = state.networkCapabilities.getNetworkSpecifier(); + final NetworkSpecifier spec = state.getNetworkCapabilities().getNetworkSpecifier(); if (spec instanceof TelephonyNetworkSpecifier) { return ((TelephonyNetworkSpecifier) spec).getSubscriptionId(); } else { @@ -1402,11 +1401,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * transport types do not actually fill this value. */ private int getSubTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) { - if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + if (!state.getNetworkCapabilities().hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { return 0; } - return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.subscriberId); + return mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(state.getSubscriberId()); } private static NetworkIdentitySet findOrCreateNetworkIdentitySet( From 6468b0d17ed301be6a57412f96e9ee8c9c410553 Mon Sep 17 00:00:00 2001 From: Nazanin Date: Thu, 15 Apr 2021 14:18:15 -0700 Subject: [PATCH 47/64] Security fix: enforce read privilege permission to check package privileges in TelephonyManager Bug: 180938364 Test: cts Change-Id: I08c346c46b9e87dceaa1faf35fa36b954d88f9b0 --- .../com/android/server/net/NetworkStatsAccess.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsAccess.java b/services/core/java/com/android/server/net/NetworkStatsAccess.java index 7cdc4cc747..d25eae409d 100644 --- a/services/core/java/com/android/server/net/NetworkStatsAccess.java +++ b/services/core/java/com/android/server/net/NetworkStatsAccess.java @@ -27,6 +27,7 @@ import android.app.AppOpsManager; import android.app.admin.DevicePolicyManagerInternal; import android.content.Context; import android.content.pm.PackageManager; +import android.os.Binder; import android.os.Process; import android.os.UserHandle; import android.telephony.TelephonyManager; @@ -108,9 +109,16 @@ public final class NetworkStatsAccess { DevicePolicyManagerInternal.class); final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - boolean hasCarrierPrivileges = tm != null && - tm.checkCarrierPrivilegesForPackageAnyPhone(callingPackage) == - TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; + boolean hasCarrierPrivileges; + final long token = Binder.clearCallingIdentity(); + try { + hasCarrierPrivileges = tm != null + && tm.checkCarrierPrivilegesForPackageAnyPhone(callingPackage) + == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; + } finally { + Binder.restoreCallingIdentity(token); + } + final boolean isDeviceOwner = dpmi != null && dpmi.isActiveDeviceOwner(callingUid); final int appId = UserHandle.getAppId(callingUid); if (hasCarrierPrivileges || isDeviceOwner From 7ead7c510101375b13b7c8cef04ba70b3236d4a2 Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 10 Mar 2021 10:33:16 +0800 Subject: [PATCH 48/64] [SP28] Add API for set data warning To have better control and race-free of set data warning to tether offload hardware, an interface of set warning and limit at the same time in the NetworkStatsProvider is needed. This is a no-op change which expose such interface with minimum changes in service side to get build pass. The implementation would be included in follow-up patches. Test: atest NetworkStatsServiceTest Test: atest NetworkPolicyManagerServiceTest Test: atest GtsNetworkStackHostTestCases Test: m doc-comment-check-docs Bug: 149467454 Bug: 170699770 Bug: 170179169 Merged-In: I6ee661497f7dedb871c85786d1950cab951d8aa2 Change-Id: I6ee661497f7dedb871c85786d1950cab951d8aa2 (cherry-picked from ag/13959436) --- .../provider/INetworkStatsProvider.aidl | 2 +- .../INetworkStatsProviderCallback.aidl | 2 +- .../provider/NetworkStatsProvider.java | 58 ++++++++++++++++--- .../server/net/NetworkStatsService.java | 10 ++-- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl index 4078b24921..74c3ba44b6 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl @@ -23,6 +23,6 @@ package android.net.netstats.provider; */ oneway interface INetworkStatsProvider { void onRequestStatsUpdate(int token); - void onSetLimit(String iface, long quotaBytes); void onSetAlert(long quotaBytes); + void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes); } diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl index bd336dd348..7eaa01e262 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl @@ -26,6 +26,6 @@ import android.net.NetworkStats; oneway interface INetworkStatsProviderCallback { void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); void notifyAlertReached(); - void notifyLimitReached(); + void notifyWarningOrLimitReached(); void unregister(); } diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java index 7639d2244c..65b336ad6f 100644 --- a/core/java/android/net/netstats/provider/NetworkStatsProvider.java +++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java @@ -29,7 +29,8 @@ import android.os.RemoteException; @SystemApi public abstract class NetworkStatsProvider { /** - * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit. + * A value used by {@link #onSetLimit}, {@link #onSetAlert} and {@link #onSetWarningAndLimit} + * indicates there is no limit. */ public static final int QUOTA_UNLIMITED = -1; @@ -42,13 +43,13 @@ public abstract class NetworkStatsProvider { } @Override - public void onSetLimit(String iface, long quotaBytes) { - NetworkStatsProvider.this.onSetLimit(iface, quotaBytes); + public void onSetAlert(long quotaBytes) { + NetworkStatsProvider.this.onSetAlert(quotaBytes); } @Override - public void onSetAlert(long quotaBytes) { - NetworkStatsProvider.this.onSetAlert(quotaBytes); + public void onSetWarningAndLimit(String iface, long warningBytes, long limitBytes) { + NetworkStatsProvider.this.onSetWarningAndLimit(iface, warningBytes, limitBytes); } }; @@ -145,11 +146,28 @@ public abstract class NetworkStatsProvider { } /** - * Notify system that the quota set by {@code onSetLimit} has been reached. + * Notify system that the warning set by {@link #onSetWarningAndLimit} has been reached. + * + * @hide + */ + // TODO: Expose as system API. + public void notifyWarningReached() { + try { + // Reuse the code path to notify warning reached with limit reached + // since framework handles them in the same way. + getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@link #onSetLimit} or limit set by + * {@link #onSetWarningAndLimit} has been reached. */ public void notifyLimitReached() { try { - getProviderCallbackBinderOrThrow().notifyLimitReached(); + getProviderCallbackBinderOrThrow().notifyWarningOrLimitReached(); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } @@ -180,8 +198,34 @@ public abstract class NetworkStatsProvider { * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. */ + // TODO: deprecate this once onSetWarningAndLimit is ready. public abstract void onSetLimit(@NonNull String iface, long quotaBytes); + /** + * Called by {@code NetworkStatsService} when setting the interface quotas for the specified + * upstream interface. If a provider implements {@link #onSetWarningAndLimit}, the system + * will not call {@link #onSetLimit}. When this method is called, the implementation + * should behave as follows: + * 1. If {@code warningBytes} is reached on {@code iface}, block all further traffic on + * {@code iface} and call {@link NetworkStatsProvider@notifyWarningReached()}. + * 2. If {@code limitBytes} is reached on {@code iface}, block all further traffic on + * {@code iface} and call {@link NetworkStatsProvider#notifyLimitReached()}. + * + * @param iface the interface requiring the operation. + * @param warningBytes the warning defined as the number of bytes, starting from zero and + * counting from now. A value of {@link #QUOTA_UNLIMITED} indicates + * there is no warning. + * @param limitBytes the limit defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. + * + * @hide + */ + // TODO: Expose as system API. + public void onSetWarningAndLimit(@NonNull String iface, long warningBytes, long limitBytes) { + // Backward compatibility for those who didn't override this function. + onSetLimit(iface, limitBytes); + } + /** * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index ba9f486092..191ff096c8 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -1660,7 +1660,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public void setStatsProviderLimitAsync(@NonNull String iface, long quota) { if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")"); - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota)); + // TODO: Set warning accordingly. + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface, + NetworkStatsProvider.QUOTA_UNLIMITED, quota)); } } @@ -2051,10 +2053,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void notifyLimitReached() { - Log.d(TAG, mTag + ": onLimitReached"); + public void notifyWarningOrLimitReached() { + Log.d(TAG, mTag + ": notifyWarningOrLimitReached"); LocalServices.getService(NetworkPolicyManagerInternal.class) - .onStatsProviderLimitReached(mTag); + .onStatsProviderWarningOrLimitReached(mTag); } @Override From bfce074c44ebb7cdf3f99e902ea632d6af50797a Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 24 Mar 2021 14:17:19 +0800 Subject: [PATCH 49/64] [SP29] Send interface warning bytes to NetworkStatsProvider This change contains necessary modification in NPMS and NSS to send warning bytes to NetworkStatsProvider. But since no any provider has been upgraded to handle such parameter. Thus, no behavior change is made in this patch. Test: atest NetworkPolicyManagerServiceTest NetworkStatsServiceTest Test: atest NetworkPolicyManagerServiceTest#testStatsProviderWarningAndLimitReached Bug: 149467454 Bug: 170699770 Bug: 170179169 Merged-In: I6c4863030c36328db571294fd12a40e59864def5 Change-Id: I6c4863030c36328db571294fd12a40e59864def5 (cherry-picked from ag/13982166) --- .../com/android/server/net/NetworkStatsService.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 191ff096c8..0bc20540a7 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -1658,11 +1658,14 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void setStatsProviderLimitAsync(@NonNull String iface, long quota) { - if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")"); - // TODO: Set warning accordingly. + public void setStatsProviderWarningAndLimitAsync( + @NonNull String iface, long warning, long limit) { + if (LOGV) { + Slog.v(TAG, "setStatsProviderWarningAndLimitAsync(" + + iface + "," + warning + "," + limit + ")"); + } invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetWarningAndLimit(iface, - NetworkStatsProvider.QUOTA_UNLIMITED, quota)); + warning, limit)); } } From 8c6fdf886ed8a9ba47f45dd7187f925249f24aec Mon Sep 17 00:00:00 2001 From: junyulai Date: Wed, 10 Mar 2021 19:45:05 +0800 Subject: [PATCH 50/64] [SP31] Expose onSetWarningAndLimit System API Test: atest NetworkPolicyManagerServiceTest NetworkStatsServiceTest Bug: 149467454 CTS-Coverage-Bug: 183598414 Merged-In: I6f5e22e3a7b80a38cae9f3c5d7296a1dff34facf Change-Id: I6f5e22e3a7b80a38cae9f3c5d7296a1dff34facf (cherry-picked from ag/13981689 with fixed merged conflict) --- .../net/netstats/provider/NetworkStatsProvider.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java index 65b336ad6f..23fc06927e 100644 --- a/core/java/android/net/netstats/provider/NetworkStatsProvider.java +++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java @@ -147,10 +147,7 @@ public abstract class NetworkStatsProvider { /** * Notify system that the warning set by {@link #onSetWarningAndLimit} has been reached. - * - * @hide */ - // TODO: Expose as system API. public void notifyWarningReached() { try { // Reuse the code path to notify warning reached with limit reached @@ -198,7 +195,6 @@ public abstract class NetworkStatsProvider { * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. */ - // TODO: deprecate this once onSetWarningAndLimit is ready. public abstract void onSetLimit(@NonNull String iface, long quotaBytes); /** @@ -217,10 +213,7 @@ public abstract class NetworkStatsProvider { * there is no warning. * @param limitBytes the limit defined as the number of bytes, starting from zero and counting * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. - * - * @hide */ - // TODO: Expose as system API. public void onSetWarningAndLimit(@NonNull String iface, long warningBytes, long limitBytes) { // Backward compatibility for those who didn't override this function. onSetLimit(iface, limitBytes); From c6e149a97787592bfcfeba243aa453758f00322c Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Wed, 28 Apr 2021 17:21:21 +0800 Subject: [PATCH 51/64] Rename *Iface* APIs to *Interface* Address API review feedback, other APIs have been refering to these as "interface" instead of "iface" so migrate the APIs named *Iface* to *Interface*. Bug: 183972554 Test: atest android.net.UnderlyingNetworkInfoTest Change-Id: I38b476e762fb57fa88c4a789092d0af6f5330d80 --- core/java/android/net/UnderlyingNetworkInfo.java | 8 ++++---- .../java/com/android/server/net/NetworkStatsFactory.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/java/android/net/UnderlyingNetworkInfo.java b/core/java/android/net/UnderlyingNetworkInfo.java index 459fdacef8..33f9375c03 100644 --- a/core/java/android/net/UnderlyingNetworkInfo.java +++ b/core/java/android/net/UnderlyingNetworkInfo.java @@ -71,13 +71,13 @@ public final class UnderlyingNetworkInfo implements Parcelable { /** Get the interface name of this network. */ @NonNull - public String getIface() { + public String getInterface() { return mIface; } /** Get the names of the interfaces underlying this network. */ @NonNull - public List getUnderlyingIfaces() { + public List getUnderlyingInterfaces() { return mUnderlyingIfaces; } @@ -124,8 +124,8 @@ public final class UnderlyingNetworkInfo implements Parcelable { if (!(o instanceof UnderlyingNetworkInfo)) return false; final UnderlyingNetworkInfo that = (UnderlyingNetworkInfo) o; return mOwnerUid == that.getOwnerUid() - && Objects.equals(mIface, that.getIface()) - && Objects.equals(mUnderlyingIfaces, that.getUnderlyingIfaces()); + && Objects.equals(mIface, that.getInterface()) + && Objects.equals(mUnderlyingIfaces, that.getUnderlyingInterfaces()); } @Override diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java index e7c0a50163..431b00914f 100644 --- a/services/core/java/com/android/server/net/NetworkStatsFactory.java +++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java @@ -382,8 +382,8 @@ public class NetworkStatsFactory { // Migrate data usage over a VPN to the TUN network. for (UnderlyingNetworkInfo info : vpnArray) { - delta.migrateTun(info.getOwnerUid(), info.getIface(), - info.getUnderlyingIfaces()); + delta.migrateTun(info.getOwnerUid(), info.getInterface(), + info.getUnderlyingInterfaces()); // Filter out debug entries as that may lead to over counting. delta.filterDebugEntries(); } From ba8093a22e7652a5a20646885973d79bbcb294d8 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Mon, 10 May 2021 23:09:44 +0800 Subject: [PATCH 52/64] Add return type javadoc to NetworkStateSnapshot#getLegacyType Add javadoc to document the return type is the legacy network type in getLegacyType. Bug: 183972826 Test: only update javadoc Change-Id: I7757253af5955f7d489d6349c090dcba146cfd7f --- core/java/android/net/NetworkStateSnapshot.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java index 9df861a6ff..3915634392 100644 --- a/core/java/android/net/NetworkStateSnapshot.java +++ b/core/java/android/net/NetworkStateSnapshot.java @@ -104,7 +104,10 @@ public final class NetworkStateSnapshot implements Parcelable { return mSubscriberId; } - /** Get the legacy type of the network associated with this snapshot. */ + /** + * Get the legacy type of the network associated with this snapshot. + * @return the legacy network type. See {@code ConnectivityManager#TYPE_*}. + */ public int getLegacyType() { return mLegacyType; } From d8d50e6c8fa0da8eb8534bb1657c6573b84fb76c Mon Sep 17 00:00:00 2001 From: junyulai Date: Fri, 5 Mar 2021 10:35:11 +0800 Subject: [PATCH 53/64] [FUI27] Fix internal naming of notifyNetworkStatus Test: TH Bug: 174123988 Merged-In: I970ee365ca221956ee85788005d331374b5fa71a Change-Id: I970ee365ca221956ee85788005d331374b5fa71a (cherry-picked from aosp/1620539) --- .../app/usage/NetworkStatsManager.java | 15 ++++---- .../android/net/INetworkStatsService.aidl | 4 +-- .../server/net/NetworkStatsService.java | 36 ++++++++++--------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 9f1132b605..6cb4b5e9b3 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -655,14 +655,14 @@ public class NetworkStatsManager { } /** - * Notify {@code NetworkStatsService} about network status changed. + * Notify {@code NetworkStatsService} about network status changed. * - * Notifies NetworkStatsService of network state changes for data usage accounting purposes. + * Notifies NetworkStatsService of network state changes for data usage accounting purposes. * - * To avoid races that attribute data usage to wrong network, such as new network with - * the same interface after SIM hot-swap, this function will not return until - * {@code NetworkStatsService} finishes its work of retrieving traffic statistics from - * all data sources. + * To avoid races that attribute data usage to wrong network, such as new network with + * the same interface after SIM hot-swap, this function will not return until + * {@code NetworkStatsService} finishes its work of retrieving traffic statistics from + * all data sources. * * @param defaultNetworks the list of all networks that could be used by network traffic that * does not explicitly select a network. @@ -689,8 +689,7 @@ public class NetworkStatsManager { Objects.requireNonNull(defaultNetworks); Objects.requireNonNull(networkStateSnapshots); Objects.requireNonNull(underlyingNetworkInfos); - // TODO: Change internal namings after the name is decided. - mService.forceUpdateIfaces(defaultNetworks.toArray(new Network[0]), + mService.notifyNetworkStatus(defaultNetworks.toArray(new Network[0]), networkStateSnapshots.toArray(new NetworkStateSnapshot[0]), activeIface, underlyingNetworkInfos.toArray(new UnderlyingNetworkInfo[0])); } catch (RemoteException e) { diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl index dc3b88a7c3..12937b5cb2 100644 --- a/core/java/android/net/INetworkStatsService.aidl +++ b/core/java/android/net/INetworkStatsService.aidl @@ -65,8 +65,8 @@ interface INetworkStatsService { /** Increment data layer count of operations performed for UID and tag. */ void incrementOperationCount(int uid, int tag, int operationCount); - /** Force update of ifaces. */ - void forceUpdateIfaces( + /** Notify {@code NetworkStatsService} about network status changed. */ + void notifyNetworkStatus( in Network[] defaultNetworks, in NetworkStateSnapshot[] snapshots, in String activeIface, diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 3c14440c64..4ee867b7d0 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -181,7 +181,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private static final int MSG_PERFORM_POLL = 1; // Perform polling, persist network, and register the global alert again. private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2; - private static final int MSG_UPDATE_IFACES = 3; + private static final int MSG_NOTIFY_NETWORK_STATUS = 3; // A message for broadcasting ACTION_NETWORK_STATS_UPDATED in handler thread to prevent // deadlock. private static final int MSG_BROADCAST_NETWORK_STATS_UPDATED = 4; @@ -379,11 +379,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { performPoll(FLAG_PERSIST_ALL); break; } - case MSG_UPDATE_IFACES: { + case MSG_NOTIFY_NETWORK_STATUS: { // If no cached states, ignore. if (mLastNetworkStateSnapshots == null) break; // TODO (b/181642673): Protect mDefaultNetworks from concurrent accessing. - updateIfaces(mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface); + handleNotifyNetworkStatus( + mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface); break; } case MSG_PERFORM_POLL_REGISTER_ALERT: { @@ -474,7 +475,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @NonNull Looper looper, @NonNull Executor executor, @NonNull NetworkStatsService service) { // TODO: Update RatType passively in NSS, instead of querying into the monitor - // when forceUpdateIface. + // when notifyNetworkStatus. return new NetworkStatsSubscriptionsMonitor(context, looper, executor, (subscriberId, type) -> service.handleOnCollapsedRatTypeChanged()); } @@ -971,16 +972,19 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - public void forceUpdateIfaces( - Network[] defaultNetworks, - NetworkStateSnapshot[] networkStates, - String activeIface, - UnderlyingNetworkInfo[] underlyingNetworkInfos) { + /** + * Notify {@code NetworkStatsService} about network status changed. + */ + public void notifyNetworkStatus( + @NonNull Network[] defaultNetworks, + @NonNull NetworkStateSnapshot[] networkStates, + @Nullable String activeIface, + @NonNull UnderlyingNetworkInfo[] underlyingNetworkInfos) { checkNetworkStackPermission(mContext); final long token = Binder.clearCallingIdentity(); try { - updateIfaces(defaultNetworks, networkStates, activeIface); + handleNotifyNetworkStatus(defaultNetworks, networkStates, activeIface); } finally { Binder.restoreCallingIdentity(token); } @@ -1244,12 +1248,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @VisibleForTesting public void handleOnCollapsedRatTypeChanged() { // Protect service from frequently updating. Remove pending messages if any. - mHandler.removeMessages(MSG_UPDATE_IFACES); + mHandler.removeMessages(MSG_NOTIFY_NETWORK_STATUS); mHandler.sendMessageDelayed( - mHandler.obtainMessage(MSG_UPDATE_IFACES), mSettings.getPollDelay()); + mHandler.obtainMessage(MSG_NOTIFY_NETWORK_STATUS), mSettings.getPollDelay()); } - private void updateIfaces( + private void handleNotifyNetworkStatus( Network[] defaultNetworks, NetworkStateSnapshot[] snapshots, String activeIface) { @@ -1257,7 +1261,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mWakeLock.acquire(); try { mActiveIface = activeIface; - updateIfacesLocked(defaultNetworks, snapshots); + handleNotifyNetworkStatusLocked(defaultNetworks, snapshots); } finally { mWakeLock.release(); } @@ -1270,10 +1274,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * they are combined under a single {@link NetworkIdentitySet}. */ @GuardedBy("mStatsLock") - private void updateIfacesLocked(@NonNull Network[] defaultNetworks, + private void handleNotifyNetworkStatusLocked(@NonNull Network[] defaultNetworks, @NonNull NetworkStateSnapshot[] snapshots) { if (!mSystemReady) return; - if (LOGV) Slog.v(TAG, "updateIfacesLocked()"); + if (LOGV) Slog.v(TAG, "handleNotifyNetworkStatusLocked()"); // take one last stats snapshot before updating iface mapping. this // isn't perfect, since the kernel may already be counting traffic from From 9156aa122f9ae342b72cf105b291045ec846f879 Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 25 Feb 2021 23:15:07 +0800 Subject: [PATCH 54/64] Support to query TYPE_WIFI usage with subscriberId Previous the API ignores subscriberId when network type is WIFI. Allow caller to call querySummaryXXXX with TYPE: WIFI + subscriberId: IMSI to get carrier merged wifi usage which matches the wifi network with the given IMSI. Bug: 176396812 Test: atest -c NetworkStatsServiceTest Change-Id: Ia033521a24e2bb56182d74a41bb2b39710571782 Merged-In: Ia033521a24e2bb56182d74a41bb2b39710571782 --- core/java/android/app/usage/NetworkStatsManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 9f1132b605..65b9facc86 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -644,7 +644,10 @@ public class NetworkStatsManager { : NetworkTemplate.buildTemplateMobileAll(subscriberId); break; case ConnectivityManager.TYPE_WIFI: - template = NetworkTemplate.buildTemplateWifiWildcard(); + template = subscriberId == null + ? NetworkTemplate.buildTemplateWifiWildcard() + : NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL, + subscriberId); break; default: throw new IllegalArgumentException("Cannot create template for network type " From 43e738951b144e315c98742ed05b5df749f43d89 Mon Sep 17 00:00:00 2001 From: lesl Date: Fri, 7 May 2021 18:15:17 +0800 Subject: [PATCH 55/64] Add metered filter for API: buildTemplateCarrier This CL modifies NetworkTemplate#buildTemplateCarrier to force on metered carrier network and rename to buildTemplateCarrierMetered. This method was introduced recently and has no callers. This method will be used in Settings and NetworkPolicyManagerService to display and manage data usage on carrier metered networks. Settings/NetworkPolicyManagerService will use it instead of the existing method buildTemplateMobileAll method, which only matches metered networks. That code will change from matching metered mobile networks to matching metered carrier networks. Note: The carrier metered network includes metered mobile network and metered "merged carrier wifi network" that is a specific cerrier wifi network which provides the same user experience as mobile. Bug: 176396812 Test: atest -c NetworkTemplateTest Change-Id: I7196d62bb60844458a6c4b1d94e2baccb71e15cd Merged-In: I7196d62bb60844458a6c4b1d94e2baccb71e15cd --- core/java/android/net/NetworkTemplate.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index d3c8957494..fd446cdf5c 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -274,11 +274,14 @@ public class NetworkTemplate implements Parcelable { } /** - * Template to match all carrier networks with the given IMSI. + * Template to match all metered carrier networks with the given IMSI. */ - public static NetworkTemplate buildTemplateCarrier(@NonNull String subscriberId) { + public static NetworkTemplate buildTemplateCarrierMetered(@NonNull String subscriberId) { Objects.requireNonNull(subscriberId); - return new NetworkTemplate(MATCH_CARRIER, subscriberId, null); + return new NetworkTemplate(MATCH_CARRIER, subscriberId, + new String[] { subscriberId }, null /* networkId */, METERED_YES, ROAMING_ALL, + DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL, + SUBSCRIBER_ID_MATCH_RULE_EXACT); } private final int mMatchRule; From 683c9918c921f4c147e3e1d4e96858cdd12b4642 Mon Sep 17 00:00:00 2001 From: Treehugger Robot Date: Thu, 20 May 2021 21:47:50 +0000 Subject: [PATCH 56/64] Improve documentation of IpSecTunnelInterface#setUnderlyingNetwork Clarify the consequence of adding IpSecTunnelInterface to the underlying network. Bug: 169855650 Test: builds Change-Id: I2e3c4fe735b3374b2ff6d23850970e36c0aafda5 Merged-In: I2e3c4fe735b3374b2ff6d23850970e36c0aafda5 --- core/java/android/net/IpSecManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java index 01d1aa533a..c10680761f 100644 --- a/core/java/android/net/IpSecManager.java +++ b/core/java/android/net/IpSecManager.java @@ -810,7 +810,9 @@ public final class IpSecManager { * * @param underlyingNetwork the new {@link Network} that will carry traffic for this tunnel. * This network MUST never be the network exposing this IpSecTunnelInterface, otherwise - * this method will throw an {@link IllegalArgumentException}. + * this method will throw an {@link IllegalArgumentException}. If the + * IpSecTunnelInterface is later added to this network, all outbound traffic will be + * blackholed. */ // TODO: b/169171001 Update the documentation when transform migration is supported. // The purpose of making updating network and applying transforms separate is to leave open From 22d53be4f77ed81df067e4128bdef7ac1e340e58 Mon Sep 17 00:00:00 2001 From: lesl Date: Thu, 28 Jan 2021 15:58:23 +0800 Subject: [PATCH 57/64] carrier data usage: Use carrier template as default policy The carrier network means any network which linked with sepcific subscriberId (for instances: merged Wifi or mobile). Update default policy to use carrier network template to replace mobile template. No impact for current AOSP user because no any wifi network is merged wifi. (Because the merged wifi network requires to support from the wifi module). Also this change convert all of the old policies which template is TYEP_MOBILE to TYPE_CARRIER to match the default policy. Bug: 176396812 Test: atest -c NetworkPolicyManagerServiceTest Test: atest -c CtsHostsideNetworkTests Test: Manual Test with test code (Force wifi to merged wifi). The data will limit when using merged wifi. And mobile policy also work normally. Merged-In: I33c10f7549e713c52ce9afd5b8c4cce2abbda616 Change-Id: I33c10f7549e713c52ce9afd5b8c4cce2abbda616 --- core/java/android/net/NetworkTemplate.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index fd446cdf5c..249154aa91 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -514,6 +514,10 @@ public class NetworkTemplate implements Parcelable { return mSubscriberIdMatchRule; } + public int getMeteredness() { + return mMetered; + } + /** * Test if given {@link NetworkIdentity} matches this template. */ From 0529858b9ccf5e91187a9c64df4754f91b5d55f2 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Sun, 13 Jun 2021 16:52:05 +0000 Subject: [PATCH 58/64] Make NsdService only start the native daemon when needed and automatically clean it up. Currently, NsdService starts the native mdnsresponder daemon if any NsdManager connect to it, which results in that when any constant service holds the NsdManager connection, the device would always be in the mdns multicast group whatever the connection is not used or not. This is because mdnsresponder will join the multicast group when it starts. To solve this problem, start the native daemon only when needed, and clean it up after the given idle timeout. 1. Start the native daemon when a new request come. 2. If there is no pending request, clean up the daemon after 3 seconds of idle time. Bug: 181810560 Test: atest NsdManagerTest NsdServiceTest Original-Change: https://android-review.googlesource.com/1717479 Merged-In: I3eb04552f6cf6c0c68c07abffe751bb4d0669215 Change-Id: I3eb04552f6cf6c0c68c07abffe751bb4d0669215 --- core/java/android/net/nsd/NsdManager.java | 3 + .../java/com/android/server/NsdService.java | 82 ++++++++++++++----- 2 files changed, 66 insertions(+), 19 deletions(-) diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java index 64f20b839a..5a25cfc00c 100644 --- a/core/java/android/net/nsd/NsdManager.java +++ b/core/java/android/net/nsd/NsdManager.java @@ -199,6 +199,9 @@ public final class NsdManager { /** @hide */ public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 20; + /** @hide */ + public static final int DAEMON_CLEANUP = BASE + 21; + /** @hide */ public static final int ENABLE = BASE + 24; /** @hide */ diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index 84f40cb4b8..a481a6a5d3 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -61,6 +61,7 @@ public class NsdService extends INsdManager.Stub { private static final String MDNS_TAG = "mDnsConnector"; private static final boolean DBG = true; + private static final long CLEANUP_DELAY_MS = 3000; private final Context mContext; private final NsdSettings mNsdSettings; @@ -77,6 +78,7 @@ public class NsdService extends INsdManager.Stub { private final SparseArray mIdToClientInfoMap= new SparseArray<>(); private final AsyncChannel mReplyChannel = new AsyncChannel(); + private final long mCleanupDelayMs; private static final int INVALID_ID = 0; private int mUniqueId = 1; @@ -92,6 +94,22 @@ public class NsdService extends INsdManager.Stub { return NsdManager.nameOf(what); } + void maybeStartDaemon() { + mDaemon.maybeStart(); + maybeScheduleStop(); + } + + void maybeScheduleStop() { + if (!isAnyRequestActive()) { + cancelStop(); + sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs); + } + } + + void cancelStop() { + this.removeMessages(NsdManager.DAEMON_CLEANUP); + } + /** * Observes the NSD on/off setting, and takes action when changed. */ @@ -151,10 +169,6 @@ public class NsdService extends INsdManager.Stub { cInfo.expungeAllRequests(); mClients.remove(msg.replyTo); } - //Last client - if (mClients.size() == 0) { - mDaemon.stop(); - } break; case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: AsyncChannel ac = new AsyncChannel(); @@ -180,6 +194,9 @@ public class NsdService extends INsdManager.Stub { replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED, NsdManager.FAILURE_INTERNAL_ERROR); break; + case NsdManager.DAEMON_CLEANUP: + mDaemon.maybeStop(); + break; case NsdManager.NATIVE_DAEMON_EVENT: default: Slog.e(TAG, "Unhandled " + msg); @@ -212,16 +229,13 @@ public class NsdService extends INsdManager.Stub { @Override public void enter() { sendNsdStateChangeBroadcast(true); - if (mClients.size() > 0) { - mDaemon.start(); - } } @Override public void exit() { - if (mClients.size() > 0) { - mDaemon.stop(); - } + // TODO: it is incorrect to stop the daemon without expunging all requests + // and sending error callbacks to clients. + maybeScheduleStop(); } private boolean requestLimitReached(ClientInfo clientInfo) { @@ -236,12 +250,15 @@ public class NsdService extends INsdManager.Stub { clientInfo.mClientIds.put(clientId, globalId); clientInfo.mClientRequests.put(clientId, what); mIdToClientInfoMap.put(globalId, clientInfo); + // Remove the cleanup event because here comes a new request. + cancelStop(); } private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) { clientInfo.mClientIds.delete(clientId); clientInfo.mClientRequests.delete(clientId); mIdToClientInfoMap.remove(globalId); + maybeScheduleStop(); } @Override @@ -251,14 +268,12 @@ public class NsdService extends INsdManager.Stub { int id; switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: - //First client - if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL && - mClients.size() == 0) { - mDaemon.start(); - } return NOT_HANDLED; case AsyncChannel.CMD_CHANNEL_DISCONNECTED: return NOT_HANDLED; + } + + switch (msg.what) { case NsdManager.DISABLE: //TODO: cleanup clients transitionTo(mDisabledState); @@ -274,6 +289,7 @@ public class NsdService extends INsdManager.Stub { break; } + maybeStartDaemon(); id = getUniqueId(); if (discoverServices(id, servInfo.getServiceType())) { if (DBG) { @@ -316,6 +332,7 @@ public class NsdService extends INsdManager.Stub { break; } + maybeStartDaemon(); id = getUniqueId(); if (registerService(id, (NsdServiceInfo) msg.obj)) { if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id); @@ -357,6 +374,7 @@ public class NsdService extends INsdManager.Stub { break; } + maybeStartDaemon(); id = getUniqueId(); if (resolveService(id, servInfo)) { clientInfo.mResolvedService = new NsdServiceInfo(); @@ -513,6 +531,10 @@ public class NsdService extends INsdManager.Stub { } } + private boolean isAnyRequestActive() { + return mIdToClientInfoMap.size() != 0; + } + private String unescape(String s) { StringBuilder sb = new StringBuilder(s.length()); for (int i = 0; i < s.length(); ++i) { @@ -538,7 +560,9 @@ public class NsdService extends INsdManager.Stub { } @VisibleForTesting - NsdService(Context ctx, NsdSettings settings, Handler handler, DaemonConnectionSupplier fn) { + NsdService(Context ctx, NsdSettings settings, Handler handler, + DaemonConnectionSupplier fn, long cleanupDelayMs) { + mCleanupDelayMs = cleanupDelayMs; mContext = ctx; mNsdSettings = settings; mNsdStateMachine = new NsdStateMachine(TAG, handler); @@ -552,7 +576,8 @@ public class NsdService extends INsdManager.Stub { HandlerThread thread = new HandlerThread(TAG); thread.start(); Handler handler = new Handler(thread.getLooper()); - NsdService service = new NsdService(context, settings, handler, DaemonConnection::new); + NsdService service = new NsdService(context, settings, handler, + DaemonConnection::new, CLEANUP_DELAY_MS); service.mDaemonCallback.awaitConnection(); return service; } @@ -681,12 +706,16 @@ public class NsdService extends INsdManager.Stub { @VisibleForTesting public static class DaemonConnection { final NativeDaemonConnector mNativeConnector; + boolean mIsStarted = false; DaemonConnection(NativeCallbackReceiver callback) { mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null); new Thread(mNativeConnector, MDNS_TAG).start(); } + /** + * Executes the specified cmd on the daemon. + */ public boolean execute(Object... args) { if (DBG) { Slog.d(TAG, "mdnssd " + Arrays.toString(args)); @@ -700,12 +729,26 @@ public class NsdService extends INsdManager.Stub { return true; } - public void start() { + /** + * Starts the daemon if it is not already started. + */ + public void maybeStart() { + if (mIsStarted) { + return; + } execute("start-service"); + mIsStarted = true; } - public void stop() { + /** + * Stops the daemon if it is started. + */ + public void maybeStop() { + if (!mIsStarted) { + return; + } execute("stop-service"); + mIsStarted = false; } } @@ -864,6 +907,7 @@ public class NsdService extends INsdManager.Stub { } mClientIds.clear(); mClientRequests.clear(); + mNsdStateMachine.maybeScheduleStop(); } // mClientIds is a sparse array of listener id -> mDnsClient id. For a given mDnsClient id, From fee2cf470d3ed7de714b70781b2fec4a8e6ca067 Mon Sep 17 00:00:00 2001 From: Les Lee Date: Fri, 4 Jun 2021 18:31:42 +0800 Subject: [PATCH 59/64] Fix: query TYPE_WIFI usage with empty string Starting with API level 31, the subscriberId is applicable for the wifi network. Considering applications may use null or an empty string as subscriberId (for instance, cts), frameworks create MATCH_WIFI_WILDCARD NetworkTemplate when querying wifi network with null or an empty string which is the behavior before API level 31. Bug: 188915450 Test: atest -c NetworkStatsManagerTest Test: atest -c NetworkUsageStatsTest Merged-In: I084b69903f8ba7a6225b312560752e8508938714 Change-Id: I084b69903f8ba7a6225b312560752e8508938714 --- .../app/usage/NetworkStatsManager.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index fe99f8532a..8a6c85d548 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -48,6 +48,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.telephony.TelephonyManager; +import android.text.TextUtils; import android.util.DataUnit; import android.util.Log; @@ -214,6 +215,10 @@ public class NetworkStatsManager { * null} value when querying for the mobile network type to receive usage * for all mobile networks. For additional details see {@link * TelephonyManager#getSubscriberId()}. + *

Starting with API level 31, calling apps can provide a + * {@code subscriberId} with wifi network type to receive usage for + * wifi networks which is under the given subscription if applicable. + * Otherwise, pass {@code null} when querying all wifi networks. * @param startTime Start of period. Defined in terms of "Unix time", see * {@link java.lang.System#currentTimeMillis}. * @param endTime End of period. Defined in terms of "Unix time", see @@ -255,6 +260,10 @@ public class NetworkStatsManager { * null} value when querying for the mobile network type to receive usage * for all mobile networks. For additional details see {@link * TelephonyManager#getSubscriberId()}. + *

Starting with API level 31, calling apps can provide a + * {@code subscriberId} with wifi network type to receive usage for + * wifi networks which is under the given subscription if applicable. + * Otherwise, pass {@code null} when querying all wifi networks. * @param startTime Start of period. Defined in terms of "Unix time", see * {@link java.lang.System#currentTimeMillis}. * @param endTime End of period. Defined in terms of "Unix time", see @@ -300,6 +309,10 @@ public class NetworkStatsManager { * null} value when querying for the mobile network type to receive usage * for all mobile networks. For additional details see {@link * TelephonyManager#getSubscriberId()}. + *

Starting with API level 31, calling apps can provide a + * {@code subscriberId} with wifi network type to receive usage for + * wifi networks which is under the given subscription if applicable. + * Otherwise, pass {@code null} when querying all wifi networks. * @param startTime Start of period. Defined in terms of "Unix time", see * {@link java.lang.System#currentTimeMillis}. * @param endTime End of period. Defined in terms of "Unix time", see @@ -388,6 +401,10 @@ public class NetworkStatsManager { * null} value when querying for the mobile network type to receive usage * for all mobile networks. For additional details see {@link * TelephonyManager#getSubscriberId()}. + *

Starting with API level 31, calling apps can provide a + * {@code subscriberId} with wifi network type to receive usage for + * wifi networks which is under the given subscription if applicable. + * Otherwise, pass {@code null} when querying all wifi networks. * @param startTime Start of period. Defined in terms of "Unix time", see * {@link java.lang.System#currentTimeMillis}. * @param endTime End of period. Defined in terms of "Unix time", see @@ -450,6 +467,10 @@ public class NetworkStatsManager { * null} value when querying for the mobile network type to receive usage * for all mobile networks. For additional details see {@link * TelephonyManager#getSubscriberId()}. + *

Starting with API level 31, calling apps can provide a + * {@code subscriberId} with wifi network type to receive usage for + * wifi networks which is under the given subscription if applicable. + * Otherwise, pass {@code null} when querying all wifi networks. * @param startTime Start of period. Defined in terms of "Unix time", see * {@link java.lang.System#currentTimeMillis}. * @param endTime End of period. Defined in terms of "Unix time", see @@ -531,6 +552,10 @@ public class NetworkStatsManager { * null} value when registering for the mobile network type to receive * notifications for all mobile networks. For additional details see {@link * TelephonyManager#getSubscriberId()}. + *

Starting with API level 31, calling apps can provide a + * {@code subscriberId} with wifi network type to receive usage for + * wifi networks which is under the given subscription if applicable. + * Otherwise, pass {@code null} when querying all wifi networks. * @param thresholdBytes Threshold in bytes to be notified on. * @param callback The {@link UsageCallback} that the system will call when data usage * has exceeded the specified threshold. @@ -644,7 +669,7 @@ public class NetworkStatsManager { : NetworkTemplate.buildTemplateMobileAll(subscriberId); break; case ConnectivityManager.TYPE_WIFI: - template = subscriberId == null + template = TextUtils.isEmpty(subscriberId) ? NetworkTemplate.buildTemplateWifiWildcard() : NetworkTemplate.buildTemplateWifi(NetworkTemplate.WIFI_NETWORKID_ALL, subscriberId); From 92860f9ea0437132c761113769cdf60c63b99a33 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Wed, 23 Jun 2021 06:29:30 +0000 Subject: [PATCH 60/64] Fix the comments from aosp/1717479. 1. Increase the cleanup delay from 3s to 10s. 2. Fix the comments from aosp/1717479. Bug: 181810560 Test: atest NsdManagerTest NsdServiceTest Original-Change: https://android-review.googlesource.com/1730170 Merged-In: I71ebdd011574bd96de16a4248b0e15636418e87c Change-Id: I71ebdd011574bd96de16a4248b0e15636418e87c --- .../java/com/android/server/NsdService.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java index a481a6a5d3..f440ee8c4e 100644 --- a/services/core/java/com/android/server/NsdService.java +++ b/services/core/java/com/android/server/NsdService.java @@ -61,7 +61,7 @@ public class NsdService extends INsdManager.Stub { private static final String MDNS_TAG = "mDnsConnector"; private static final boolean DBG = true; - private static final long CLEANUP_DELAY_MS = 3000; + private static final long CLEANUP_DELAY_MS = 10000; private final Context mContext; private final NsdSettings mNsdSettings; @@ -94,19 +94,25 @@ public class NsdService extends INsdManager.Stub { return NsdManager.nameOf(what); } - void maybeStartDaemon() { + private void maybeStartDaemon() { mDaemon.maybeStart(); maybeScheduleStop(); } - void maybeScheduleStop() { + private boolean isAnyRequestActive() { + return mIdToClientInfoMap.size() != 0; + } + + private void scheduleStop() { + sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs); + } + private void maybeScheduleStop() { if (!isAnyRequestActive()) { - cancelStop(); - sendMessageDelayed(NsdManager.DAEMON_CLEANUP, mCleanupDelayMs); + scheduleStop(); } } - void cancelStop() { + private void cancelStop() { this.removeMessages(NsdManager.DAEMON_CLEANUP); } @@ -164,11 +170,16 @@ public class NsdService extends INsdManager.Stub { if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1); break; } + cInfo = mClients.get(msg.replyTo); if (cInfo != null) { cInfo.expungeAllRequests(); mClients.remove(msg.replyTo); } + //Last client + if (mClients.size() == 0) { + scheduleStop(); + } break; case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: AsyncChannel ac = new AsyncChannel(); @@ -235,7 +246,7 @@ public class NsdService extends INsdManager.Stub { public void exit() { // TODO: it is incorrect to stop the daemon without expunging all requests // and sending error callbacks to clients. - maybeScheduleStop(); + scheduleStop(); } private boolean requestLimitReached(ClientInfo clientInfo) { @@ -271,9 +282,6 @@ public class NsdService extends INsdManager.Stub { return NOT_HANDLED; case AsyncChannel.CMD_CHANNEL_DISCONNECTED: return NOT_HANDLED; - } - - switch (msg.what) { case NsdManager.DISABLE: //TODO: cleanup clients transitionTo(mDisabledState); @@ -531,10 +539,6 @@ public class NsdService extends INsdManager.Stub { } } - private boolean isAnyRequestActive() { - return mIdToClientInfoMap.size() != 0; - } - private String unescape(String s) { StringBuilder sb = new StringBuilder(s.length()); for (int i = 0; i < s.length(); ++i) { @@ -907,7 +911,6 @@ public class NsdService extends INsdManager.Stub { } mClientIds.clear(); mClientRequests.clear(); - mNsdStateMachine.maybeScheduleStop(); } // mClientIds is a sparse array of listener id -> mDnsClient id. For a given mDnsClient id, From 8002fe63f4b7ce44e080ac34f93f7c3c862eabe0 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Fri, 2 Jul 2021 19:12:24 +0000 Subject: [PATCH 61/64] Add support for app data accounting for in-kernel dataplanes This change ensures that app data accounting works correctly within the confines of in-kernel dataplanes, as used by platform VPNs and the VCN. Notably, the VCN MUST NOT specify the IMSI, as that would lead to double counting of the interface statistics. Bug: 175853498 Bug: 190620024 Test: atest NetworkStatsTest FrameworksVcnTests Original-Change: https://android-review.googlesource.com/1749070 Merged-In: I768907cd3dd2028c7040cddd81fc71a5ce69bbdb Change-Id: I768907cd3dd2028c7040cddd81fc71a5ce69bbdb --- core/java/android/net/NetworkStats.java | 42 ++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index 6ccbab7ed8..288b06ee52 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -24,6 +24,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.os.Process; import android.os.SystemClock; import android.util.SparseBooleanArray; @@ -1487,8 +1488,31 @@ public final class NetworkStats implements Parcelable { continue; } - if (recycle.uid == tunUid) { - // Add up traffic through tunUid's underlying interfaces. + if (tunUid == Process.SYSTEM_UID) { + // Kernel-based VPN or VCN, traffic sent by apps on the VPN/VCN network + // + // Since the data is not UID-accounted on underlying networks, just use VPN/VCN + // network usage as ground truth. Encrypted traffic on the underlying networks will + // never be processed here because encrypted traffic on the underlying interfaces + // is not present in UID stats, and this method is only called on UID stats. + if (tunIface.equals(recycle.iface)) { + tunIfaceTotal.add(recycle); + underlyingIfacesTotal.add(recycle); + + // In steady state, there should always be one network, but edge cases may + // result in the network being null (network lost), and thus no underlying + // ifaces is possible. + if (perInterfaceTotal.length > 0) { + // While platform VPNs and VCNs have exactly one underlying network, that + // network may have multiple interfaces (eg for 464xlat). This layer does + // not have the required information to identify which of the interfaces + // were used. Select "any" of the interfaces. Since overhead is already + // lost, this number is an approximation anyways. + perInterfaceTotal[0].add(recycle); + } + } + } else if (recycle.uid == tunUid) { + // VpnService VPN, traffic sent by the VPN app over underlying networks for (int j = 0; j < underlyingIfaces.size(); j++) { if (Objects.equals(underlyingIfaces.get(j), recycle.iface)) { perInterfaceTotal[j].add(recycle); @@ -1497,7 +1521,7 @@ public final class NetworkStats implements Parcelable { } } } else if (tunIface.equals(recycle.iface)) { - // Add up all tunIface traffic excluding traffic from the vpn app itself. + // VpnService VPN; traffic sent by apps on the VPN network tunIfaceTotal.add(recycle); } } @@ -1532,9 +1556,13 @@ public final class NetworkStats implements Parcelable { // Consider only entries that go onto the VPN interface. continue; } - if (uid[i] == tunUid) { + + if (uid[i] == tunUid && tunUid != Process.SYSTEM_UID) { // Exclude VPN app from the redistribution, as it can choose to create packet // streams by writing to itself. + // + // However, for platform VPNs, do not exclude the system's usage of the VPN network, + // since it is never local-only, and never double counted continue; } tmpEntry.uid = uid[i]; @@ -1641,6 +1669,12 @@ public final class NetworkStats implements Parcelable { int tunUid, @NonNull List underlyingIfaces, @NonNull Entry[] moved) { + if (tunUid == Process.SYSTEM_UID) { + // No traffic recorded on a per-UID basis for in-kernel VPN/VCNs over underlying + // networks; thus no traffic to deduct. + return; + } + for (int i = 0; i < underlyingIfaces.size(); i++) { moved[i].uid = tunUid; // Add debug info From f7277ed3c45e3fb587f18c8de5edc82d83968544 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Mon, 12 Jul 2021 21:15:10 +0800 Subject: [PATCH 62/64] Keep the native mdns daemon alive for pre-S application Roll back the behavior changes by checking the target SDK to ensure that there are no compatibility issues with the pre-S application. If the target SDK of the application Date: Fri, 30 Jul 2021 02:31:26 +0000 Subject: [PATCH 63/64] Fix mMobileIfaces is not protected by lock Currently, mMobileIfaces is accessed from multiple threads, and should be protected from concurrent accessing. However, since the variable could be accessed frequently, holding the mStatsLock would make this be blocked by network stats I/O operations. Thus, protect the variable by making it volatile. Test: Wifi on/off stress test Bug: 192758557 Original-Change: https://android-review.googlesource.com/1765686 Merged-In: Ie7694a63f5203ee7c83830ca13d97219b7949fd7 Change-Id: Ie7694a63f5203ee7c83830ca13d97219b7949fd7 --- .../server/net/NetworkStatsService.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 4ee867b7d0..097b0711ef 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -289,8 +289,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private String mActiveIface; /** Set of any ifaces associated with mobile networks since boot. */ - @GuardedBy("mStatsLock") - private String[] mMobileIfaces = new String[0]; + private volatile String[] mMobileIfaces = new String[0]; /** Set of all ifaces currently used by traffic that does not explicitly specify a Network. */ @GuardedBy("mStatsLock") @@ -935,7 +934,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public String[] getMobileIfaces() { - return mMobileIfaces; + // TODO (b/192758557): Remove debug log. + if (ArrayUtils.contains(mMobileIfaces, null)) { + throw new NullPointerException( + "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces)); + } + return mMobileIfaces.clone(); } @Override @@ -1084,7 +1088,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public long getIfaceStats(String iface, int type) { + public long getIfaceStats(@NonNull String iface, int type) { + Objects.requireNonNull(iface); long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable()); if (nativeIfaceStats == -1) { return nativeIfaceStats; @@ -1382,7 +1387,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - mMobileIfaces = mobileIfaces.toArray(new String[mobileIfaces.size()]); + mMobileIfaces = mobileIfaces.toArray(new String[0]); + // TODO (b/192758557): Remove debug log. + if (ArrayUtils.contains(mMobileIfaces, null)) { + throw new NullPointerException( + "null element in mMobileIfaces: " + Arrays.toString(mMobileIfaces)); + } } private static int getSubIdForMobile(@NonNull NetworkStateSnapshot state) { From 9ec09dce9499b65ea3eccae2508ba939869cfe89 Mon Sep 17 00:00:00 2001 From: Junyu Lai Date: Fri, 30 Jul 2021 02:31:26 +0000 Subject: [PATCH 64/64] Add debug log for tracking NPE of mMobileIfaces Test: TH Bug: 192758557 Original-Change: https://android-review.googlesource.com/1777887 Merged-In: Ib048c18b1c64627de5a9d2b04d10e084a014ff64 Change-Id: Ib048c18b1c64627de5a9d2b04d10e084a014ff64