Merge changes I28e39400,Ibada8b42
* changes:
UserManager restricted profile SystemApis
Improve testing of CONNECTIVITY_ACTION broadcasts.
diff --git a/core/java/android/net/CaptivePortalData.java b/core/java/android/net/CaptivePortalData.java
index c443c75..18467fa 100644
--- a/core/java/android/net/CaptivePortalData.java
+++ b/core/java/android/net/CaptivePortalData.java
@@ -39,9 +39,11 @@
private final long mByteLimit;
private final long mExpiryTimeMillis;
private final boolean mCaptive;
+ private final String mVenueFriendlyName;
private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl,
- boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive) {
+ boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive,
+ String venueFriendlyName) {
mRefreshTimeMillis = refreshTimeMillis;
mUserPortalUrl = userPortalUrl;
mVenueInfoUrl = venueInfoUrl;
@@ -49,11 +51,12 @@
mByteLimit = byteLimit;
mExpiryTimeMillis = expiryTimeMillis;
mCaptive = captive;
+ mVenueFriendlyName = venueFriendlyName;
}
private CaptivePortalData(Parcel p) {
this(p.readLong(), p.readParcelable(null), p.readParcelable(null), p.readBoolean(),
- p.readLong(), p.readLong(), p.readBoolean());
+ p.readLong(), p.readLong(), p.readBoolean(), p.readString());
}
@Override
@@ -70,6 +73,7 @@
dest.writeLong(mByteLimit);
dest.writeLong(mExpiryTimeMillis);
dest.writeBoolean(mCaptive);
+ dest.writeString(mVenueFriendlyName);
}
/**
@@ -83,6 +87,7 @@
private long mBytesRemaining = -1;
private long mExpiryTime = -1;
private boolean mCaptive;
+ private String mVenueFriendlyName;
/**
* Create an empty builder.
@@ -100,7 +105,8 @@
.setSessionExtendable(data.mIsSessionExtendable)
.setBytesRemaining(data.mByteLimit)
.setExpiryTime(data.mExpiryTimeMillis)
- .setCaptive(data.mCaptive);
+ .setCaptive(data.mCaptive)
+ .setVenueFriendlyName(data.mVenueFriendlyName);
}
/**
@@ -167,12 +173,22 @@
}
/**
+ * Set the venue friendly name.
+ */
+ @NonNull
+ public Builder setVenueFriendlyName(@Nullable String venueFriendlyName) {
+ mVenueFriendlyName = venueFriendlyName;
+ return this;
+ }
+
+ /**
* Create a new {@link CaptivePortalData}.
*/
@NonNull
public CaptivePortalData build() {
return new CaptivePortalData(mRefreshTime, mUserPortalUrl, mVenueInfoUrl,
- mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive);
+ mIsSessionExtendable, mBytesRemaining, mExpiryTime, mCaptive,
+ mVenueFriendlyName);
}
}
@@ -232,6 +248,14 @@
return mCaptive;
}
+ /**
+ * Get the venue friendly name
+ */
+ @Nullable
+ public String getVenueFriendlyName() {
+ return mVenueFriendlyName;
+ }
+
@NonNull
public static final Creator<CaptivePortalData> CREATOR = new Creator<CaptivePortalData>() {
@Override
@@ -248,7 +272,7 @@
@Override
public int hashCode() {
return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl,
- mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive);
+ mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive, mVenueFriendlyName);
}
@Override
@@ -261,7 +285,8 @@
&& mIsSessionExtendable == other.mIsSessionExtendable
&& mByteLimit == other.mByteLimit
&& mExpiryTimeMillis == other.mExpiryTimeMillis
- && mCaptive == other.mCaptive;
+ && mCaptive == other.mCaptive
+ && Objects.equals(mVenueFriendlyName, other.mVenueFriendlyName);
}
@Override
@@ -274,6 +299,7 @@
+ ", byteLimit: " + mByteLimit
+ ", expiryTime: " + mExpiryTimeMillis
+ ", captive: " + mCaptive
+ + ", venueFriendlyName: " + mVenueFriendlyName
+ "}";
}
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 06c1598..8742ecb 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -16,6 +16,9 @@
package android.net;
import static android.net.IpSecManager.INVALID_RESOURCE_ID;
+import static android.net.NetworkRequest.Type.LISTEN;
+import static android.net.NetworkRequest.Type.REQUEST;
+import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -3730,14 +3733,12 @@
private static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
private static CallbackHandler sCallbackHandler;
- private static final int LISTEN = 1;
- private static final int REQUEST = 2;
-
private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
- int timeoutMs, int action, int legacyType, CallbackHandler handler) {
+ int timeoutMs, NetworkRequest.Type reqType, int legacyType, CallbackHandler handler) {
printStackTrace();
checkCallbackNotNull(callback);
- Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities");
+ Preconditions.checkArgument(
+ reqType == TRACK_DEFAULT || need != null, "null NetworkCapabilities");
final NetworkRequest request;
final String callingPackageName = mContext.getOpPackageName();
try {
@@ -3750,13 +3751,13 @@
}
Messenger messenger = new Messenger(handler);
Binder binder = new Binder();
- if (action == LISTEN) {
+ if (reqType == LISTEN) {
request = mService.listenForNetwork(
need, messenger, binder, callingPackageName);
} else {
request = mService.requestNetwork(
- need, messenger, timeoutMs, binder, legacyType, callingPackageName,
- getAttributionTag());
+ need, reqType.ordinal(), messenger, timeoutMs, binder, legacyType,
+ callingPackageName, getAttributionTag());
}
if (request != null) {
sCallbacks.put(request, callback);
@@ -4260,7 +4261,7 @@
// request, i.e., the system default network.
CallbackHandler cbHandler = new CallbackHandler(handler);
sendRequestForNetwork(null /* NetworkCapabilities need */, networkCallback, 0,
- REQUEST, TYPE_NONE, cbHandler);
+ TRACK_DEFAULT, TYPE_NONE, cbHandler);
}
/**
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b32c98b..5e925b6 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -167,7 +167,7 @@
in NetworkCapabilities nc, int score, in NetworkAgentConfig config,
in int factorySerialNumber);
- NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
+ NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, int reqType,
in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
String callingPackageName, String callingAttributionTag);
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 286cdf9..48c4832 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -436,10 +436,10 @@
*/
@VisibleForTesting
/* package */ static final long UNRESTRICTED_CAPABILITIES =
- (1 << NET_CAPABILITY_INTERNET) |
- (1 << NET_CAPABILITY_MMS) |
- (1 << NET_CAPABILITY_SUPL) |
- (1 << NET_CAPABILITY_WIFI_P2P);
+ (1 << NET_CAPABILITY_INTERNET)
+ | (1 << NET_CAPABILITY_MMS)
+ | (1 << NET_CAPABILITY_SUPL)
+ | (1 << NET_CAPABILITY_WIFI_P2P);
/**
* Capabilities that are managed by ConnectivityService.
@@ -907,8 +907,8 @@
}
private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
- return ((this.mTransportTypes == 0) ||
- ((this.mTransportTypes & nc.mTransportTypes) != 0));
+ return ((this.mTransportTypes == 0)
+ || ((this.mTransportTypes & nc.mTransportTypes) != 0));
}
/** @hide */
@@ -1162,12 +1162,12 @@
Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
}
private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
- return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
- this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
+ return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps
+ || this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
}
private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
- return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
- this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
+ return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps
+ && this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
}
/** @hide */
public static int minBandwidth(int a, int b) {
@@ -1682,9 +1682,9 @@
*/
public boolean equalRequestableCapabilities(@Nullable NetworkCapabilities nc) {
if (nc == null) return false;
- return (equalsNetCapabilitiesRequestable(nc) &&
- equalsTransportTypes(nc) &&
- equalsSpecifier(nc));
+ return (equalsNetCapabilitiesRequestable(nc)
+ && equalsTransportTypes(nc)
+ && equalsSpecifier(nc));
}
@Override
diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java
index a32b41f..a202d77 100644
--- a/core/java/android/net/ProxyInfo.java
+++ b/core/java/android/net/ProxyInfo.java
@@ -127,7 +127,7 @@
}
/**
- * Only used in PacManager after Local Proxy is bound.
+ * Only used in PacProxyInstaller after Local Proxy is bound.
* @hide
*/
public ProxyInfo(@NonNull Uri pacFileUrl, int localProxyPort) {
diff --git a/core/java/android/net/util/MultinetworkPolicyTracker.java b/core/java/android/net/util/MultinetworkPolicyTracker.java
index aa0f622..8dfd4e1 100644
--- a/core/java/android/net/util/MultinetworkPolicyTracker.java
+++ b/core/java/android/net/util/MultinetworkPolicyTracker.java
@@ -34,7 +34,7 @@
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.util.Slog;
+import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
@@ -204,13 +204,13 @@
@Override
public void onChange(boolean selfChange) {
- Slog.wtf(TAG, "Should never be reached.");
+ Log.wtf(TAG, "Should never be reached.");
}
@Override
public void onChange(boolean selfChange, Uri uri) {
if (!mSettingsUris.contains(uri)) {
- Slog.wtf(TAG, "Unexpected settings observation: " + uri);
+ Log.wtf(TAG, "Unexpected settings observation: " + uri);
}
reevaluate();
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d8dc933..1b7912e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1791,12 +1791,28 @@
private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
@Override
- public void interfaceClassDataActivityChanged(int networkType, boolean active, long tsNanos,
- int uid) {
- sendDataActivityBroadcast(networkType, active, tsNanos);
+ public void interfaceClassDataActivityChanged(int transportType, boolean active,
+ long tsNanos, int uid) {
+ sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos);
}
};
+ // This is deprecated and only to support legacy use cases.
+ private int transportTypeToLegacyType(int type) {
+ switch (type) {
+ case NetworkCapabilities.TRANSPORT_CELLULAR:
+ return ConnectivityManager.TYPE_MOBILE;
+ case NetworkCapabilities.TRANSPORT_WIFI:
+ return ConnectivityManager.TYPE_WIFI;
+ case NetworkCapabilities.TRANSPORT_BLUETOOTH:
+ return ConnectivityManager.TYPE_BLUETOOTH;
+ case NetworkCapabilities.TRANSPORT_ETHERNET:
+ return ConnectivityManager.TYPE_ETHERNET;
+ default:
+ loge("Unexpected transport in transportTypeToLegacyType: " + type);
+ }
+ return ConnectivityManager.TYPE_NONE;
+ }
/**
* Ensures that the system cannot call a particular method.
*/
@@ -2380,13 +2396,13 @@
timeout = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
10);
- type = ConnectivityManager.TYPE_MOBILE;
+ type = NetworkCapabilities.TRANSPORT_CELLULAR;
} else if (networkAgent.networkCapabilities.hasTransport(
NetworkCapabilities.TRANSPORT_WIFI)) {
timeout = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI,
15);
- type = ConnectivityManager.TYPE_WIFI;
+ type = NetworkCapabilities.TRANSPORT_WIFI;
} else {
return; // do not track any other networks
}
@@ -2961,7 +2977,7 @@
case EVENT_CAPPORT_DATA_CHANGED: {
final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
if (nai == null) break;
- handleCaptivePortalDataUpdate(nai, (CaptivePortalData) msg.obj);
+ handleCapportApiDataUpdate(nai, (CaptivePortalData) msg.obj);
break;
}
}
@@ -3299,9 +3315,9 @@
handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
}
- private void handleCaptivePortalDataUpdate(@NonNull final NetworkAgentInfo nai,
+ private void handleCapportApiDataUpdate(@NonNull final NetworkAgentInfo nai,
@Nullable final CaptivePortalData data) {
- nai.captivePortalData = data;
+ nai.capportApiData = data;
// CaptivePortalData will be merged into LinkProperties from NetworkAgentInfo
handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
}
@@ -5626,31 +5642,40 @@
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, int timeoutMs, IBinder binder, int legacyType,
- @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
+ int reqTypeInt, Messenger messenger, int timeoutMs, IBinder binder,
+ int legacyType, @NonNull String callingPackageName,
+ @Nullable String callingAttributionTag) {
if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
throw new SecurityException("Insufficient permissions to specify legacy type");
}
}
final int callingUid = mDeps.getCallingUid();
- final NetworkRequest.Type type = (networkCapabilities == null)
- ? NetworkRequest.Type.TRACK_DEFAULT
- : NetworkRequest.Type.REQUEST;
- // If the requested networkCapabilities is null, take them instead from
- // the default network request. This allows callers to keep track of
- // the system default network.
- if (type == NetworkRequest.Type.TRACK_DEFAULT) {
- networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid);
- enforceAccessPermission();
- } else {
- networkCapabilities = new NetworkCapabilities(networkCapabilities);
- enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
- callingAttributionTag);
- // TODO: this is incorrect. We mark the request as metered or not depending on the state
- // of the app when the request is filed, but we never change the request if the app
- // changes network state. http://b/29964605
- enforceMeteredApnPolicy(networkCapabilities);
+ final NetworkRequest.Type reqType;
+ try {
+ reqType = NetworkRequest.Type.values()[reqTypeInt];
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new IllegalArgumentException("Unsupported request type " + reqTypeInt);
+ }
+ switch (reqType) {
+ case TRACK_DEFAULT:
+ // If the request type is TRACK_DEFAULT, the passed {@code networkCapabilities}
+ // is unused and will be replaced by the one from the default network request.
+ // This allows callers to keep track of the system default network.
+ networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid);
+ enforceAccessPermission();
+ break;
+ case REQUEST:
+ networkCapabilities = new NetworkCapabilities(networkCapabilities);
+ enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
+ callingAttributionTag);
+ // TODO: this is incorrect. We mark the request as metered or not depending on
+ // the state of the app when the request is filed, but we never change the
+ // request if the app changes network state. http://b/29964605
+ enforceMeteredApnPolicy(networkCapabilities);
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported request type " + reqType);
}
ensureRequestableCapabilities(networkCapabilities);
ensureSufficientPermissionsForRequest(networkCapabilities,
@@ -5669,7 +5694,7 @@
ensureValid(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
- nextNetworkRequestId(), type);
+ nextNetworkRequestId(), reqType);
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
if (DBG) log("requestNetwork for " + nri);
@@ -6111,6 +6136,7 @@
private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
lp.ensureDirectlyConnectedRoutes();
nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
+ nai.networkAgentPortalData = lp.getCaptivePortalData();
}
private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
@@ -6154,9 +6180,11 @@
updateWakeOnLan(newLp);
- // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo,
- // it is not contained in LinkProperties sent from NetworkAgents so needs to be merged here.
- newLp.setCaptivePortalData(networkAgent.captivePortalData);
+ // Captive portal data is obtained from NetworkMonitor and stored in NetworkAgentInfo.
+ // It is not always contained in the LinkProperties sent from NetworkAgents, and if it
+ // does, it needs to be merged here.
+ newLp.setCaptivePortalData(mergeCaptivePortalData(networkAgent.networkAgentPortalData,
+ networkAgent.capportApiData));
// TODO - move this check to cover the whole function
if (!Objects.equals(newLp, oldLp)) {
@@ -6176,6 +6204,57 @@
mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
}
+ /**
+ * @param naData captive portal data from NetworkAgent
+ * @param apiData captive portal data from capport API
+ */
+ @Nullable
+ private CaptivePortalData mergeCaptivePortalData(CaptivePortalData naData,
+ CaptivePortalData apiData) {
+ if (naData == null || apiData == null) {
+ return naData == null ? apiData : naData;
+ }
+ final CaptivePortalData.Builder captivePortalBuilder =
+ new CaptivePortalData.Builder(naData);
+
+ if (apiData.isCaptive()) {
+ captivePortalBuilder.setCaptive(true);
+ }
+ if (apiData.isSessionExtendable()) {
+ captivePortalBuilder.setSessionExtendable(true);
+ }
+ if (apiData.getExpiryTimeMillis() >= 0 || apiData.getByteLimit() >= 0) {
+ // Expiry time, bytes remaining, refresh time all need to come from the same source,
+ // otherwise data would be inconsistent. Prefer the capport API info if present,
+ // as it can generally be refreshed more often.
+ captivePortalBuilder.setExpiryTime(apiData.getExpiryTimeMillis());
+ captivePortalBuilder.setBytesRemaining(apiData.getByteLimit());
+ captivePortalBuilder.setRefreshTime(apiData.getRefreshTimeMillis());
+ } else if (naData.getExpiryTimeMillis() < 0 && naData.getByteLimit() < 0) {
+ // No source has time / bytes remaining information: surface the newest refresh time
+ // for other fields
+ captivePortalBuilder.setRefreshTime(
+ Math.max(naData.getRefreshTimeMillis(), apiData.getRefreshTimeMillis()));
+ }
+
+ // Prioritize the user portal URL from the network agent.
+ if (apiData.getUserPortalUrl() != null && (naData.getUserPortalUrl() == null
+ || TextUtils.isEmpty(naData.getUserPortalUrl().toSafeString()))) {
+ captivePortalBuilder.setUserPortalUrl(apiData.getUserPortalUrl());
+ }
+ // Prioritize the venue information URL from the network agent.
+ if (apiData.getVenueInfoUrl() != null && (naData.getVenueInfoUrl() == null
+ || TextUtils.isEmpty(naData.getVenueInfoUrl().toSafeString()))) {
+ captivePortalBuilder.setVenueInfoUrl(apiData.getVenueInfoUrl());
+
+ // Note that venue friendly name can only come from the network agent because it is not
+ // in use in RFC8908. However, if using the Capport venue URL, make sure that the
+ // friendly name is not set from the network agent.
+ captivePortalBuilder.setVenueFriendlyName(null);
+ }
+ return captivePortalBuilder.build();
+ }
+
private void wakeupModifyInterface(String iface, NetworkCapabilities caps, boolean add) {
// Marks are only available on WiFi interfaces. Checking for
// marks on unsupported interfaces is harmless.
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 55d8279..b0a73f1 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -189,13 +189,18 @@
// Set to true when partial connectivity was detected.
public boolean partialConnectivity;
- // Captive portal info of the network, if any.
+ // Captive portal info of the network from RFC8908, if any.
// Obtained by ConnectivityService and merged into NetworkAgent-provided information.
- public CaptivePortalData captivePortalData;
+ public CaptivePortalData capportApiData;
// The UID of the remote entity that created this Network.
public final int creatorUid;
+ // Network agent portal info of the network, if any. This information is provided from
+ // non-RFC8908 sources, such as Wi-Fi Passpoint, which can provide information such as Venue
+ // URL, Terms & Conditions URL, and network friendly name.
+ public CaptivePortalData networkAgentPortalData;
+
// Networks are lingered when they become unneeded as a result of their NetworkRequests being
// satisfied by a higher-scoring network. so as to allow communication to wrap up before the
// network is taken down. This usually only happens to the default network. Lingering ends with
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index f6ca152..d83ff83 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2018, The Android Open Source Project
+ * 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.
@@ -67,7 +67,7 @@
// is not set. Individual networks have their own settings that override this. This member
// is set through setDefaultProxy, which is called when the default network changes proxies
// in its LinkProperties, or when ConnectivityService switches to a new default network, or
- // when PacManager resolves the proxy.
+ // when PacProxyInstaller resolves the proxy.
@Nullable
@GuardedBy("mProxyLock")
private volatile ProxyInfo mDefaultProxy = null;
@@ -79,13 +79,14 @@
// The object responsible for Proxy Auto Configuration (PAC).
@NonNull
- private final PacManager mPacManager;
+ private final PacProxyInstaller mPacProxyInstaller;
public ProxyTracker(@NonNull final Context context,
@NonNull final Handler connectivityServiceInternalHandler, final int pacChangedEvent) {
mContext = context;
mConnectivityServiceHandler = connectivityServiceInternalHandler;
- mPacManager = new PacManager(context, connectivityServiceInternalHandler, pacChangedEvent);
+ mPacProxyInstaller = new PacProxyInstaller(
+ context, connectivityServiceInternalHandler, pacChangedEvent);
}
// Convert empty ProxyInfo's to null as null-checks are used to determine if proxies are present
@@ -181,7 +182,7 @@
if (!TextUtils.isEmpty(pacFileUrl)) {
mConnectivityServiceHandler.post(
- () -> mPacManager.setCurrentProxyScriptUrl(proxyProperties));
+ () -> mPacProxyInstaller.setCurrentProxyScriptUrl(proxyProperties));
}
}
}
@@ -225,7 +226,9 @@
final ProxyInfo defaultProxy = getDefaultProxy();
final ProxyInfo proxyInfo = null != defaultProxy ?
defaultProxy : ProxyInfo.buildDirectProxy("", 0, Collections.emptyList());
- if (mPacManager.setCurrentProxyScriptUrl(proxyInfo) == PacManager.DONT_SEND_BROADCAST) {
+
+ if (mPacProxyInstaller.setCurrentProxyScriptUrl(proxyInfo)
+ == PacProxyInstaller.DONT_SEND_BROADCAST) {
return;
}
if (DBG) Log.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
@@ -305,10 +308,10 @@
return;
}
- // This call could be coming from the PacManager, containing the port of the local
- // proxy. If this new proxy matches the global proxy then copy this proxy to the
+ // This call could be coming from the PacProxyInstaller, containing the port of the
+ // local proxy. If this new proxy matches the global proxy then copy this proxy to the
// global (to get the correct local port), and send a broadcast.
- // TODO: Switch PacManager to have its own message to send back rather than
+ // TODO: Switch PacProxyInstaller to have its own message to send back rather than
// reusing EVENT_HAS_CHANGED_PROXY and this call to handleApplyDefaultProxy.
if ((mGlobalProxy != null) && (proxyInfo != null)
&& (!Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))
diff --git a/tests/net/common/java/android/net/CaptivePortalDataTest.kt b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
index bd1847b..8710d23 100644
--- a/tests/net/common/java/android/net/CaptivePortalDataTest.kt
+++ b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
@@ -41,13 +41,14 @@
.setBytesRemaining(456L)
.setExpiryTime(789L)
.setCaptive(true)
+ .setVenueFriendlyName("venue friendly name")
.build()
private fun makeBuilder() = CaptivePortalData.Builder(data)
@Test
fun testParcelUnparcel() {
- assertParcelSane(data, fieldCount = 7)
+ assertParcelSane(data, fieldCount = 8)
assertParcelingIsLossless(makeBuilder().setUserPortalUrl(null).build())
assertParcelingIsLossless(makeBuilder().setVenueInfoUrl(null).build())
@@ -66,6 +67,8 @@
assertNotEqualsAfterChange { it.setBytesRemaining(789L) }
assertNotEqualsAfterChange { it.setExpiryTime(12L) }
assertNotEqualsAfterChange { it.setCaptive(false) }
+ assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") }
+ assertNotEqualsAfterChange { it.setVenueFriendlyName(null) }
}
@Test
@@ -108,6 +111,11 @@
assertFalse(makeBuilder().setCaptive(false).build().isCaptive)
}
+ @Test
+ fun testVenueFriendlyName() {
+ assertEquals("venue friendly name", data.venueFriendlyName)
+ }
+
private fun CaptivePortalData.mutate(mutator: (CaptivePortalData.Builder) -> Unit) =
CaptivePortalData.Builder(this).apply { mutator(this) }.build()
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index d74a621..f2dd27e 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -16,6 +16,7 @@
package android.net;
+import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
@@ -31,16 +32,21 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+import static android.net.NetworkRequest.Type.REQUEST;
+import static android.net.NetworkRequest.Type.TRACK_DEFAULT;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -49,9 +55,7 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
-import android.net.NetworkCapabilities;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
@@ -213,9 +217,8 @@
ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class);
// register callback
- when(mService.requestNetwork(
- any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
- .thenReturn(request);
+ when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
+ any(), nullable(String.class))).thenReturn(request);
manager.requestNetwork(request, callback, handler);
// callback triggers
@@ -242,9 +245,8 @@
ArgumentCaptor<Messenger> captor = ArgumentCaptor.forClass(Messenger.class);
// register callback
- when(mService.requestNetwork(
- any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
- .thenReturn(req1);
+ when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
+ any(), nullable(String.class))).thenReturn(req1);
manager.requestNetwork(req1, callback, handler);
// callback triggers
@@ -261,9 +263,8 @@
verify(callback, timeout(100).times(0)).onLosing(any(), anyInt());
// callback can be registered again
- when(mService.requestNetwork(
- any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
- .thenReturn(req2);
+ when(mService.requestNetwork(any(), anyInt(), captor.capture(), anyInt(), any(), anyInt(),
+ any(), nullable(String.class))).thenReturn(req2);
manager.requestNetwork(req2, callback, handler);
// callback triggers
@@ -286,7 +287,7 @@
info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
when(mCtx.getApplicationInfo()).thenReturn(info);
- when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any(),
+ when(mService.requestNetwork(any(), anyInt(), any(), anyInt(), any(), anyInt(), any(),
nullable(String.class))).thenReturn(request);
Handler handler = new Handler(Looper.getMainLooper());
@@ -340,6 +341,35 @@
}
}
+ @Test
+ public void testRequestType() throws Exception {
+ final String testPkgName = "MyPackage";
+ final ConnectivityManager manager = new ConnectivityManager(mCtx, mService);
+ when(mCtx.getOpPackageName()).thenReturn(testPkgName);
+ final NetworkRequest request = makeRequest(1);
+ final NetworkCallback callback = new ConnectivityManager.NetworkCallback();
+
+ manager.requestNetwork(request, callback);
+ verify(mService).requestNetwork(eq(request.networkCapabilities),
+ eq(REQUEST.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(testPkgName), eq(null));
+ reset(mService);
+
+ // Verify that register network callback does not calls requestNetwork at all.
+ manager.registerNetworkCallback(request, callback);
+ verify(mService, never()).requestNetwork(any(), anyInt(), any(), anyInt(), any(),
+ anyInt(), any(), any());
+ verify(mService).listenForNetwork(eq(request.networkCapabilities), any(), any(),
+ eq(testPkgName));
+ reset(mService);
+
+ manager.registerDefaultNetworkCallback(callback);
+ verify(mService).requestNetwork(eq(null),
+ eq(TRACK_DEFAULT.ordinal()), any(), anyInt(), any(), eq(TYPE_NONE),
+ eq(testPkgName), eq(null));
+ reset(mService);
+ }
+
static Message makeMessage(NetworkRequest req, int messageType) {
Bundle bundle = new Bundle();
bundle.putParcelable(NetworkRequest.class.getSimpleName(), req);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 4ebd6e6..2a0414f 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -346,6 +346,11 @@
private static final String INTERFACE_NAME = "interface";
+ private static final String TEST_VENUE_URL_NA = "https://android.com/";
+ private static final String TEST_VENUE_URL_CAPPORT = "https://android.com/capport/";
+ private static final String TEST_FRIENDLY_NAME = "Network friendly name";
+ private static final String TEST_REDIRECT_URL = "http://example.com/firstPath";
+
private MockContext mServiceContext;
private HandlerThread mCsHandlerThread;
private ConnectivityService.Dependencies mDeps;
@@ -854,7 +859,7 @@
mProbesSucceeded = probesSucceeded;
}
- void notifyCaptivePortalDataChanged(CaptivePortalData data) {
+ void notifyCapportApiDataChanged(CaptivePortalData data) {
try {
mNmCallbacks.notifyCaptivePortalDataChanged(data);
} catch (RemoteException e) {
@@ -2030,7 +2035,7 @@
Objects.equals(expectedCapportUrl, lp.getCaptivePortalApiUrl()));
final CaptivePortalData expectedCapportData = sanitized ? null : capportData;
- mWiFiNetworkAgent.notifyCaptivePortalDataChanged(capportData);
+ mWiFiNetworkAgent.notifyCapportApiDataChanged(capportData);
callback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
Objects.equals(expectedCapportData, lp.getCaptivePortalData()));
defaultCallback.expectLinkPropertiesThat(mWiFiNetworkAgent, lp ->
@@ -3068,7 +3073,7 @@
.setBytesRemaining(12345L)
.build();
- mWiFiNetworkAgent.notifyCaptivePortalDataChanged(testData);
+ mWiFiNetworkAgent.notifyCapportApiDataChanged(testData);
captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
lp -> testData.equals(lp.getCaptivePortalData()));
@@ -3081,6 +3086,136 @@
lp -> testData.equals(lp.getCaptivePortalData()) && lp.getMtu() == 1234);
}
+ private TestNetworkCallback setupNetworkCallbackAndConnectToWifi() throws Exception {
+ // Grant NETWORK_SETTINGS permission to be able to receive LinkProperties change callbacks
+ // with sensitive (captive portal) data
+ mServiceContext.setPermission(
+ android.Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
+
+ final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
+ final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
+ mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
+
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+
+ mWiFiNetworkAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false /* isStrictMode */);
+ captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ return captivePortalCallback;
+ }
+
+ private class CaptivePortalTestData {
+ CaptivePortalTestData(CaptivePortalData naData, CaptivePortalData capportData,
+ CaptivePortalData expectedMergedData) {
+ mNaData = naData;
+ mCapportData = capportData;
+ mExpectedMergedData = expectedMergedData;
+ }
+
+ public final CaptivePortalData mNaData;
+ public final CaptivePortalData mCapportData;
+ public final CaptivePortalData mExpectedMergedData;
+ }
+
+ private CaptivePortalTestData setupCaptivePortalData() {
+ final CaptivePortalData capportData = new CaptivePortalData.Builder()
+ .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL))
+ .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_CAPPORT))
+ .setExpiryTime(1000000L)
+ .setBytesRemaining(12345L)
+ .build();
+
+ final CaptivePortalData naData = new CaptivePortalData.Builder()
+ .setBytesRemaining(80802L)
+ .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA))
+ .setVenueFriendlyName(TEST_FRIENDLY_NAME).build();
+
+ final CaptivePortalData expectedMergedData = new CaptivePortalData.Builder()
+ .setUserPortalUrl(Uri.parse(TEST_REDIRECT_URL))
+ .setBytesRemaining(12345L)
+ .setExpiryTime(1000000L)
+ .setVenueInfoUrl(Uri.parse(TEST_VENUE_URL_NA))
+ .setVenueFriendlyName(TEST_FRIENDLY_NAME).build();
+
+ return new CaptivePortalTestData(naData, capportData, expectedMergedData);
+ }
+
+ @Test
+ public void testMergeCaptivePortalApiWithFriendlyNameAndVenueUrl() throws Exception {
+ final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi();
+ final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData();
+
+ // Baseline capport data
+ mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData);
+
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData()));
+
+ // Venue URL and friendly name from Network agent, confirm that API data gets precedence
+ // on the bytes remaining.
+ final LinkProperties linkProperties = new LinkProperties();
+ linkProperties.setCaptivePortalData(captivePortalTestData.mNaData);
+ mWiFiNetworkAgent.sendLinkProperties(linkProperties);
+
+ // Make sure that the capport data is merged
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> captivePortalTestData.mExpectedMergedData.equals(lp.getCaptivePortalData()));
+
+ // Create a new LP with no Network agent capport data
+ final LinkProperties newLps = new LinkProperties();
+ newLps.setMtu(1234);
+ mWiFiNetworkAgent.sendLinkProperties(newLps);
+ // CaptivePortalData is not lost and has the original values when LPs are received from the
+ // NetworkAgent
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData())
+ && lp.getMtu() == 1234);
+
+ // Now send capport data only from the Network agent
+ mWiFiNetworkAgent.notifyCapportApiDataChanged(null);
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> lp.getCaptivePortalData() == null);
+
+ newLps.setCaptivePortalData(captivePortalTestData.mNaData);
+ mWiFiNetworkAgent.sendLinkProperties(newLps);
+
+ // Make sure that only the network agent capport data is available
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> captivePortalTestData.mNaData.equals(lp.getCaptivePortalData()));
+ }
+
+ @Test
+ public void testMergeCaptivePortalDataFromNetworkAgentFirstThenCapport() throws Exception {
+ final TestNetworkCallback captivePortalCallback = setupNetworkCallbackAndConnectToWifi();
+ final CaptivePortalTestData captivePortalTestData = setupCaptivePortalData();
+
+ // Venue URL and friendly name from Network agent, confirm that API data gets precedence
+ // on the bytes remaining.
+ final LinkProperties linkProperties = new LinkProperties();
+ linkProperties.setCaptivePortalData(captivePortalTestData.mNaData);
+ mWiFiNetworkAgent.sendLinkProperties(linkProperties);
+
+ // Make sure that the data is saved correctly
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> captivePortalTestData.mNaData.equals(lp.getCaptivePortalData()));
+
+ // Expected merged data: Network agent data is preferred, and values that are not used by
+ // it are merged from capport data
+ mWiFiNetworkAgent.notifyCapportApiDataChanged(captivePortalTestData.mCapportData);
+
+ // Make sure that the Capport data is merged correctly
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> captivePortalTestData.mExpectedMergedData.equals(lp.getCaptivePortalData()));
+
+ // Now set the naData to null
+ linkProperties.setCaptivePortalData(null);
+ mWiFiNetworkAgent.sendLinkProperties(linkProperties);
+
+ // Make sure that the Capport data is retained correctly
+ captivePortalCallback.expectLinkPropertiesThat(mWiFiNetworkAgent,
+ lp -> captivePortalTestData.mCapportData.equals(lp.getCaptivePortalData()));
+ }
+
private NetworkRequest.Builder newWifiRequestBuilder() {
return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
}
@@ -3251,8 +3386,8 @@
NetworkCapabilities networkCapabilities = new NetworkCapabilities();
networkCapabilities.addTransportType(TRANSPORT_WIFI)
.setNetworkSpecifier(new MatchAllNetworkSpecifier());
- mService.requestNetwork(networkCapabilities, null, 0, null,
- ConnectivityManager.TYPE_WIFI, mContext.getPackageName(),
+ mService.requestNetwork(networkCapabilities, NetworkRequest.Type.REQUEST.ordinal(),
+ null, 0, null, ConnectivityManager.TYPE_WIFI, mContext.getPackageName(),
getAttributionTag());
});
@@ -7294,7 +7429,7 @@
mCellNetworkAgent.connect(true);
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
- eq(ConnectivityManager.TYPE_MOBILE));
+ eq(NetworkCapabilities.TRANSPORT_CELLULAR));
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
final LinkProperties wifiLp = new LinkProperties();
@@ -7308,7 +7443,7 @@
networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
- eq(ConnectivityManager.TYPE_WIFI));
+ eq(NetworkCapabilities.TRANSPORT_WIFI));
verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));
// Disconnect wifi and switch back to cell
@@ -7318,7 +7453,7 @@
assertNoCallbacks(networkCallback);
verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
- eq(ConnectivityManager.TYPE_MOBILE));
+ eq(NetworkCapabilities.TRANSPORT_CELLULAR));
// reconnect wifi
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);