Merge changes from topics "pans", "pans-permission" am: 1c03df3a3e
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1561317 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I72035b6d5d6504cece1df472ae317e865ceb7882
This commit is contained in:
@@ -18,6 +18,7 @@ package android.net;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.SystemApi;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -29,11 +30,12 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/** @hide */
|
||||
@SystemApi
|
||||
public final class OemNetworkPreferences implements Parcelable {
|
||||
/**
|
||||
* Use default behavior requesting networks. Equivalent to not setting any preference at all.
|
||||
* Default in case this value is not set. Using it will result in an error.
|
||||
*/
|
||||
public static final int OEM_NETWORK_PREFERENCE_DEFAULT = 0;
|
||||
public static final int OEM_NETWORK_PREFERENCE_UNINITIALIZED = 0;
|
||||
|
||||
/**
|
||||
* If an unmetered network is available, use it.
|
||||
@@ -45,17 +47,17 @@ public final class OemNetworkPreferences implements Parcelable {
|
||||
/**
|
||||
* If an unmetered network is available, use it.
|
||||
* Otherwise, if a network with the OEM_PAID capability is available, use it.
|
||||
* Otherwise, the app doesn't get a network.
|
||||
* Otherwise, the app doesn't get a default network.
|
||||
*/
|
||||
public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK = 2;
|
||||
|
||||
/**
|
||||
* Prefer only NET_CAPABILITY_OEM_PAID networks.
|
||||
* Use only NET_CAPABILITY_OEM_PAID networks.
|
||||
*/
|
||||
public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY = 3;
|
||||
|
||||
/**
|
||||
* Prefer only NET_CAPABILITY_OEM_PRIVATE networks.
|
||||
* Use only NET_CAPABILITY_OEM_PRIVATE networks.
|
||||
*/
|
||||
public static final int OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY = 4;
|
||||
|
||||
@@ -95,8 +97,6 @@ public final class OemNetworkPreferences implements Parcelable {
|
||||
/**
|
||||
* Builder used to create {@link OemNetworkPreferences} objects. Specify the preferred Network
|
||||
* to package name mappings.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final class Builder {
|
||||
private final Bundle mNetworkMappings;
|
||||
@@ -135,7 +135,7 @@ public final class OemNetworkPreferences implements Parcelable {
|
||||
* @return The builder to facilitate chaining.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder removeNetworkPreference(@NonNull final String packageName) {
|
||||
public Builder clearNetworkPreference(@NonNull final String packageName) {
|
||||
Objects.requireNonNull(packageName);
|
||||
mNetworkMappings.remove(packageName);
|
||||
return this;
|
||||
@@ -160,7 +160,7 @@ public final class OemNetworkPreferences implements Parcelable {
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = "OEM_NETWORK_PREFERENCE_", value = {
|
||||
OEM_NETWORK_PREFERENCE_DEFAULT,
|
||||
OEM_NETWORK_PREFERENCE_UNINITIALIZED,
|
||||
OEM_NETWORK_PREFERENCE_OEM_PAID,
|
||||
OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK,
|
||||
OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY,
|
||||
@@ -174,12 +174,14 @@ public final class OemNetworkPreferences implements Parcelable {
|
||||
*
|
||||
* @param value int value of OemNetworkPreference
|
||||
* @return string version of OemNetworkPreference
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public static String oemNetworkPreferenceToString(@OemNetworkPreference int value) {
|
||||
switch (value) {
|
||||
case OEM_NETWORK_PREFERENCE_DEFAULT:
|
||||
return "OEM_NETWORK_PREFERENCE_DEFAULT";
|
||||
case OEM_NETWORK_PREFERENCE_UNINITIALIZED:
|
||||
return "OEM_NETWORK_PREFERENCE_UNINITIALIZED";
|
||||
case OEM_NETWORK_PREFERENCE_OEM_PAID:
|
||||
return "OEM_NETWORK_PREFERENCE_OEM_PAID";
|
||||
case OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
|
||||
|
||||
@@ -4886,15 +4886,6 @@ public class ConnectivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void setOemNetworkPreference(@NonNull final OemNetworkPreferences preference) {
|
||||
try {
|
||||
mService.setOemNetworkPreference(preference);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "setOemNetworkPreference() failed for preference: " + preference.toString());
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private final List<QosCallbackConnection> mQosCallbackConnections = new ArrayList<>();
|
||||
|
||||
@@ -5096,4 +5087,60 @@ public class ConnectivityManager {
|
||||
sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST,
|
||||
TYPE_NONE, handler == null ? getDefaultHandler() : new CallbackHandler(handler));
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for {@link #setOemNetworkPreference(OemNetworkPreferences, Executor,
|
||||
* OnSetOemNetworkPreferenceListener)}.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public interface OnSetOemNetworkPreferenceListener {
|
||||
/**
|
||||
* Called when setOemNetworkPreference() successfully completes.
|
||||
*/
|
||||
void onComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by automotive devices to set the network preferences used to direct traffic at an
|
||||
* application level as per the given OemNetworkPreferences. An example use-case would be an
|
||||
* automotive OEM wanting to provide connectivity for applications critical to the usage of a
|
||||
* vehicle via a particular network.
|
||||
*
|
||||
* Calling this will overwrite the existing preference.
|
||||
*
|
||||
* @param preference {@link OemNetworkPreferences} The application network preference to be set.
|
||||
* @param executor the executor on which listener will be invoked.
|
||||
* @param listener {@link OnSetOemNetworkPreferenceListener} optional listener used to
|
||||
* communicate completion of setOemNetworkPreference(). This will only be
|
||||
* called once upon successful completion of setOemNetworkPreference().
|
||||
* @throws IllegalArgumentException if {@code preference} contains invalid preference values.
|
||||
* @throws SecurityException if missing the appropriate permissions.
|
||||
* @throws UnsupportedOperationException if called on a non-automotive device.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE)
|
||||
public void setOemNetworkPreference(@NonNull final OemNetworkPreferences preference,
|
||||
@Nullable @CallbackExecutor final Executor executor,
|
||||
@Nullable final OnSetOemNetworkPreferenceListener listener) {
|
||||
Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
|
||||
if (null != listener) {
|
||||
Objects.requireNonNull(executor, "Executor must be non-null");
|
||||
}
|
||||
final IOnSetOemNetworkPreferenceListener listenerInternal = listener == null ? null :
|
||||
new IOnSetOemNetworkPreferenceListener.Stub() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
executor.execute(listener::onComplete);
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
mService.setOemNetworkPreference(preference, listenerInternal);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "setOemNetworkPreference() failed for preference: " + preference.toString());
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.app.PendingIntent;
|
||||
import android.net.ConnectionInfo;
|
||||
import android.net.ConnectivityDiagnosticsManager;
|
||||
import android.net.IConnectivityDiagnosticsCallback;
|
||||
import android.net.IOnSetOemNetworkPreferenceListener;
|
||||
import android.net.IQosCallback;
|
||||
import android.net.ISocketKeepaliveCallback;
|
||||
import android.net.LinkProperties;
|
||||
@@ -245,5 +246,6 @@ interface IConnectivityManager
|
||||
void registerQosSocketCallback(in QosSocketInfo socketInfo, in IQosCallback callback);
|
||||
void unregisterQosCallback(in IQosCallback callback);
|
||||
|
||||
void setOemNetworkPreference(in OemNetworkPreferences preference);
|
||||
void setOemNetworkPreference(in OemNetworkPreferences preference,
|
||||
in IOnSetOemNetworkPreferenceListener listener);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||
@@ -95,6 +97,7 @@ import android.net.INetworkMonitor;
|
||||
import android.net.INetworkMonitorCallbacks;
|
||||
import android.net.INetworkPolicyListener;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.IOnSetOemNetworkPreferenceListener;
|
||||
import android.net.IQosCallback;
|
||||
import android.net.ISocketKeepaliveCallback;
|
||||
import android.net.InetAddresses;
|
||||
@@ -570,6 +573,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
*/
|
||||
private static final int EVENT_SET_REQUIRE_VPN_FOR_UIDS = 47;
|
||||
|
||||
/**
|
||||
* used internally when setting the default networks for OemNetworkPreferences.
|
||||
* obj = OemNetworkPreferences
|
||||
*/
|
||||
private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
|
||||
|
||||
/**
|
||||
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
|
||||
* should be shown.
|
||||
@@ -1039,10 +1048,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
mMetricsLog = logger;
|
||||
mNetworkRanker = new NetworkRanker();
|
||||
final NetworkRequest defaultInternetRequest = createDefaultInternetRequestForTransport(
|
||||
-1, NetworkRequest.Type.REQUEST);
|
||||
mDefaultRequest = new NetworkRequestInfo(null, defaultInternetRequest, new Binder(),
|
||||
null /* attributionTag */);
|
||||
final NetworkRequest defaultInternetRequest = createDefaultRequest();
|
||||
mDefaultRequest = new NetworkRequestInfo(
|
||||
defaultInternetRequest, null, new Binder(),
|
||||
null /* attributionTags */);
|
||||
mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
|
||||
mDefaultNetworkRequests.add(mDefaultRequest);
|
||||
mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest);
|
||||
@@ -1256,15 +1265,25 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return netCap;
|
||||
}
|
||||
|
||||
private NetworkRequest createDefaultRequest() {
|
||||
return createDefaultInternetRequestForTransport(
|
||||
TYPE_NONE, NetworkRequest.Type.REQUEST);
|
||||
}
|
||||
|
||||
private NetworkRequest createDefaultInternetRequestForTransport(
|
||||
int transportType, NetworkRequest.Type type) {
|
||||
final NetworkCapabilities netCap = new NetworkCapabilities();
|
||||
netCap.addCapability(NET_CAPABILITY_INTERNET);
|
||||
netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
|
||||
netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
|
||||
if (transportType > -1) {
|
||||
if (transportType > TYPE_NONE) {
|
||||
netCap.addTransportType(transportType);
|
||||
}
|
||||
return createNetworkRequest(type, netCap);
|
||||
}
|
||||
|
||||
private NetworkRequest createNetworkRequest(
|
||||
NetworkRequest.Type type, NetworkCapabilities netCap) {
|
||||
return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
|
||||
}
|
||||
|
||||
@@ -1314,7 +1333,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
if (enable) {
|
||||
handleRegisterNetworkRequest(new NetworkRequestInfo(
|
||||
null, networkRequest, new Binder(), null /* attributionTag */));
|
||||
networkRequest, null, new Binder(),
|
||||
null /* attributionTags */));
|
||||
} else {
|
||||
handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
|
||||
/* callOnUnavailable */ false);
|
||||
@@ -2292,6 +2312,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
|
||||
}
|
||||
|
||||
private void enforceOemNetworkPreferencesPermission() {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE,
|
||||
"ConnectivityService");
|
||||
}
|
||||
|
||||
private boolean checkNetworkStackPermission() {
|
||||
return checkAnyPermissionOf(
|
||||
android.Manifest.permission.NETWORK_STACK,
|
||||
@@ -2634,6 +2660,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
pw.println();
|
||||
|
||||
pw.print("Current per-app default networks: ");
|
||||
pw.increaseIndent();
|
||||
dumpPerAppNetworkPreferences(pw);
|
||||
pw.decreaseIndent();
|
||||
pw.println();
|
||||
|
||||
pw.println("Current Networks:");
|
||||
pw.increaseIndent();
|
||||
dumpNetworks(pw);
|
||||
@@ -2754,6 +2786,40 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpPerAppNetworkPreferences(IndentingPrintWriter pw) {
|
||||
pw.println("Per-App Network Preference:");
|
||||
pw.increaseIndent();
|
||||
if (0 == mOemNetworkPreferences.getNetworkPreferences().size()) {
|
||||
pw.println("none");
|
||||
} else {
|
||||
pw.println(mOemNetworkPreferences.toString());
|
||||
}
|
||||
pw.decreaseIndent();
|
||||
|
||||
for (final NetworkRequestInfo defaultRequest : mDefaultNetworkRequests) {
|
||||
if (mDefaultRequest == defaultRequest) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean isActive = null != defaultRequest.getSatisfier();
|
||||
pw.println("Is per-app network active:");
|
||||
pw.increaseIndent();
|
||||
pw.println(isActive);
|
||||
if (isActive) {
|
||||
pw.println("Active network: " + defaultRequest.getSatisfier().network.netId);
|
||||
}
|
||||
pw.println("Tracked UIDs:");
|
||||
pw.increaseIndent();
|
||||
if (0 == defaultRequest.mRequests.size()) {
|
||||
pw.println("none, this should never occur.");
|
||||
} else {
|
||||
pw.println(defaultRequest.mRequests.get(0).networkCapabilities.getUids());
|
||||
}
|
||||
pw.decreaseIndent();
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
}
|
||||
|
||||
private void dumpNetworkRequests(IndentingPrintWriter pw) {
|
||||
for (NetworkRequestInfo nri : requestsSortedById()) {
|
||||
pw.println(nri.toString());
|
||||
@@ -3586,29 +3652,38 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
|
||||
private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) {
|
||||
handleRegisterNetworkRequest(Collections.singletonList(nri));
|
||||
}
|
||||
|
||||
private void handleRegisterNetworkRequest(@NonNull final List<NetworkRequestInfo> nris) {
|
||||
ensureRunningOnConnectivityServiceThread();
|
||||
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
||||
for (final NetworkRequest req : nri.mRequests) {
|
||||
mNetworkRequests.put(req, nri);
|
||||
if (req.isListen()) {
|
||||
for (final NetworkAgentInfo network : mNetworkAgentInfos) {
|
||||
if (req.networkCapabilities.hasSignalStrength()
|
||||
&& network.satisfiesImmutableCapabilitiesOf(req)) {
|
||||
updateSignalStrengthThresholds(network, "REGISTER", req);
|
||||
for (final NetworkRequestInfo nri : nris) {
|
||||
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
||||
for (final NetworkRequest req : nri.mRequests) {
|
||||
mNetworkRequests.put(req, nri);
|
||||
if (req.isListen()) {
|
||||
for (final NetworkAgentInfo network : mNetworkAgentInfos) {
|
||||
if (req.networkCapabilities.hasSignalStrength()
|
||||
&& network.satisfiesImmutableCapabilitiesOf(req)) {
|
||||
updateSignalStrengthThresholds(network, "REGISTER", req);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rematchAllNetworksAndRequests();
|
||||
// If the nri is satisfied, return as its score has already been sent if needed.
|
||||
if (nri.isBeingSatisfied()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// As this request was not satisfied on rematch and thus never had any scores sent to the
|
||||
// factories, send null now for each request of type REQUEST.
|
||||
for (final NetworkRequest req : nri.mRequests) {
|
||||
if (req.isRequest()) sendUpdatedScoreToFactories(req, null);
|
||||
rematchAllNetworksAndRequests();
|
||||
for (final NetworkRequestInfo nri : nris) {
|
||||
// If the nri is satisfied, return as its score has already been sent if needed.
|
||||
if (nri.isBeingSatisfied()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// As this request was not satisfied on rematch and thus never had any scores sent to
|
||||
// the factories, send null now for each request of type REQUEST.
|
||||
for (final NetworkRequest req : nri.mRequests) {
|
||||
if (req.isRequest()) sendUpdatedScoreToFactories(req, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3781,6 +3856,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
removeListenRequestFromNetworks(req);
|
||||
}
|
||||
}
|
||||
mDefaultNetworkRequests.remove(nri);
|
||||
mNetworkRequestCounter.decrementCount(nri.mUid);
|
||||
mNetworkRequestInfoLogs.log("RELEASE " + nri);
|
||||
|
||||
@@ -4419,6 +4495,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
|
||||
handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
|
||||
break;
|
||||
case EVENT_SET_OEM_NETWORK_PREFERENCE:
|
||||
final Pair<OemNetworkPreferences, IOnSetOemNetworkPreferenceListener> arg =
|
||||
(Pair<OemNetworkPreferences,
|
||||
IOnSetOemNetworkPreferenceListener>) msg.obj;
|
||||
try {
|
||||
handleSetOemNetworkPreference(arg.first, arg.second);
|
||||
} catch (RemoteException e) {
|
||||
loge("handleMessage.EVENT_SET_OEM_NETWORK_PREFERENCE failed", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5551,10 +5637,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
final PendingIntent mPendingIntent;
|
||||
boolean mPendingIntentSent;
|
||||
@Nullable
|
||||
final Messenger mMessenger;
|
||||
@Nullable
|
||||
private final IBinder mBinder;
|
||||
final int mPid;
|
||||
final int mUid;
|
||||
final Messenger messenger;
|
||||
@Nullable
|
||||
final String mCallingAttributionTag;
|
||||
|
||||
@@ -5570,12 +5658,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return uids;
|
||||
}
|
||||
|
||||
NetworkRequestInfo(NetworkRequest r, PendingIntent pi,
|
||||
NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final PendingIntent pi,
|
||||
@Nullable String callingAttributionTag) {
|
||||
this(Collections.singletonList(r), pi, callingAttributionTag);
|
||||
}
|
||||
|
||||
NetworkRequestInfo(@NonNull final List<NetworkRequest> r,
|
||||
@Nullable final PendingIntent pi, @Nullable String callingAttributionTag) {
|
||||
mRequests = initializeRequests(r);
|
||||
ensureAllNetworkRequestsHaveType(mRequests);
|
||||
mPendingIntent = pi;
|
||||
messenger = null;
|
||||
mMessenger = null;
|
||||
mBinder = null;
|
||||
mPid = getCallingPid();
|
||||
mUid = mDeps.getCallingUid();
|
||||
@@ -5583,11 +5676,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mCallingAttributionTag = callingAttributionTag;
|
||||
}
|
||||
|
||||
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder,
|
||||
@Nullable String callingAttributionTag) {
|
||||
NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final Messenger m,
|
||||
@Nullable final IBinder binder, @Nullable String callingAttributionTag) {
|
||||
this(Collections.singletonList(r), m, binder, callingAttributionTag);
|
||||
}
|
||||
|
||||
NetworkRequestInfo(@NonNull final List<NetworkRequest> r, @Nullable final Messenger m,
|
||||
@Nullable final IBinder binder, @Nullable String callingAttributionTag) {
|
||||
super();
|
||||
messenger = m;
|
||||
mRequests = initializeRequests(r);
|
||||
mMessenger = m;
|
||||
ensureAllNetworkRequestsHaveType(mRequests);
|
||||
mBinder = binder;
|
||||
mPid = getCallingPid();
|
||||
@@ -5603,7 +5701,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
NetworkRequestInfo(NetworkRequest r) {
|
||||
NetworkRequestInfo(@NonNull final NetworkRequest r) {
|
||||
this(Collections.singletonList(r));
|
||||
}
|
||||
|
||||
NetworkRequestInfo(@NonNull final List<NetworkRequest> r) {
|
||||
this(r, null /* pi */, null /* callingAttributionTag */);
|
||||
}
|
||||
|
||||
@@ -5618,9 +5720,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return mRequests.size() > 1;
|
||||
}
|
||||
|
||||
private List<NetworkRequest> initializeRequests(NetworkRequest r) {
|
||||
final ArrayList<NetworkRequest> tempRequests = new ArrayList<>();
|
||||
tempRequests.add(new NetworkRequest(r));
|
||||
private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) {
|
||||
// Creating a defensive copy to prevent the sender from modifying the list being
|
||||
// reflected in the return value of this method.
|
||||
final List<NetworkRequest> tempRequests = new ArrayList<>(r);
|
||||
return Collections.unmodifiableList(tempRequests);
|
||||
}
|
||||
|
||||
@@ -5804,7 +5907,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
|
||||
nextNetworkRequestId(), reqType);
|
||||
NetworkRequestInfo nri =
|
||||
new NetworkRequestInfo(messenger, networkRequest, binder, callingAttributionTag);
|
||||
new NetworkRequestInfo(networkRequest, messenger, binder, callingAttributionTag);
|
||||
if (DBG) log("requestNetwork for " + nri);
|
||||
|
||||
// For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were
|
||||
@@ -5970,7 +6073,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
|
||||
NetworkRequest.Type.LISTEN);
|
||||
NetworkRequestInfo nri =
|
||||
new NetworkRequestInfo(messenger, networkRequest, binder, callingAttributionTag);
|
||||
new NetworkRequestInfo(networkRequest, messenger, binder, callingAttributionTag);
|
||||
if (VDBG) log("listenForNetwork for " + nri);
|
||||
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
|
||||
@@ -6098,13 +6201,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
@GuardedBy("mBlockedAppUids")
|
||||
private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
|
||||
|
||||
// Current OEM network preferences.
|
||||
@NonNull
|
||||
private OemNetworkPreferences mOemNetworkPreferences =
|
||||
new OemNetworkPreferences.Builder().build();
|
||||
|
||||
// The always-on request for an Internet-capable network that apps without a specific default
|
||||
// fall back to.
|
||||
@VisibleForTesting
|
||||
@NonNull
|
||||
private final NetworkRequestInfo mDefaultRequest;
|
||||
final NetworkRequestInfo mDefaultRequest;
|
||||
// Collection of NetworkRequestInfo's used for default networks.
|
||||
@VisibleForTesting
|
||||
@NonNull
|
||||
private final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>();
|
||||
final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>();
|
||||
|
||||
private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) {
|
||||
return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri);
|
||||
@@ -7181,7 +7291,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri,
|
||||
@NonNull final NetworkAgentInfo networkAgent, final int notificationType,
|
||||
final int arg1) {
|
||||
if (nri.messenger == null) {
|
||||
if (nri.mMessenger == null) {
|
||||
// Default request has no msgr. Also prevents callbacks from being invoked for
|
||||
// NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks
|
||||
// are Type.LISTEN, but should not have NetworkCallbacks invoked.
|
||||
@@ -7250,7 +7360,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
String notification = ConnectivityManager.getCallbackName(notificationType);
|
||||
log("sending notification " + notification + " for " + nrForCallback);
|
||||
}
|
||||
nri.messenger.send(msg);
|
||||
nri.mMessenger.send(msg);
|
||||
} catch (RemoteException e) {
|
||||
// may occur naturally in the race of binder death.
|
||||
loge("RemoteException caught trying to send a callback msg for " + nrForCallback);
|
||||
@@ -9205,9 +9315,212 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mQosCallbackTracker.unregisterCallback(callback);
|
||||
}
|
||||
|
||||
private void enforceAutomotiveDevice() {
|
||||
final boolean isAutomotiveDevice =
|
||||
mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
|
||||
if (!isAutomotiveDevice) {
|
||||
throw new UnsupportedOperationException(
|
||||
"setOemNetworkPreference() is only available on automotive devices.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by automotive devices to set the network preferences used to direct traffic at an
|
||||
* application level as per the given OemNetworkPreferences. An example use-case would be an
|
||||
* automotive OEM wanting to provide connectivity for applications critical to the usage of a
|
||||
* vehicle via a particular network.
|
||||
*
|
||||
* Calling this will overwrite the existing preference.
|
||||
*
|
||||
* @param preference {@link OemNetworkPreferences} The application network preference to be set.
|
||||
* @param listener {@link ConnectivityManager.OnSetOemNetworkPreferenceListener} Listener used
|
||||
* to communicate completion of setOemNetworkPreference();
|
||||
*/
|
||||
@Override
|
||||
public void setOemNetworkPreference(@NonNull final OemNetworkPreferences preference) {
|
||||
// TODO http://b/176495594 track multiple default networks with networkPreferences
|
||||
if (DBG) log("setOemNetworkPreference() called with: " + preference.toString());
|
||||
public void setOemNetworkPreference(
|
||||
@NonNull final OemNetworkPreferences preference,
|
||||
@Nullable final IOnSetOemNetworkPreferenceListener listener) {
|
||||
|
||||
enforceAutomotiveDevice();
|
||||
enforceOemNetworkPreferencesPermission();
|
||||
|
||||
Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
|
||||
validateOemNetworkPreferences(preference);
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE,
|
||||
new Pair<>(preference, listener)));
|
||||
}
|
||||
|
||||
private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) {
|
||||
for (@OemNetworkPreferences.OemNetworkPreference final int pref
|
||||
: preference.getNetworkPreferences().values()) {
|
||||
if (OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED == pref) {
|
||||
final String msg = "OEM_NETWORK_PREFERENCE_UNINITIALIZED is an invalid value.";
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSetOemNetworkPreference(
|
||||
@NonNull final OemNetworkPreferences preference,
|
||||
@NonNull final IOnSetOemNetworkPreferenceListener listener) throws RemoteException {
|
||||
Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
|
||||
if (DBG) {
|
||||
log("set OEM network preferences :" + preference.toString());
|
||||
}
|
||||
final List<NetworkRequestInfo> nris =
|
||||
new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(preference);
|
||||
updateDefaultNetworksForOemNetworkPreference(nris);
|
||||
mOemNetworkPreferences = preference;
|
||||
// TODO http://b/176496396 persist data to shared preferences.
|
||||
|
||||
if (null != listener) {
|
||||
listener.onComplete();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDefaultNetworksForOemNetworkPreference(
|
||||
@NonNull final List<NetworkRequestInfo> nris) {
|
||||
ensureRunningOnConnectivityServiceThread();
|
||||
clearNonDefaultNetworkAgents();
|
||||
addDefaultNetworkRequests(nris);
|
||||
}
|
||||
|
||||
private void clearNonDefaultNetworkAgents() {
|
||||
// Copy mDefaultNetworkRequests to iterate and remove elements from it in
|
||||
// handleRemoveNetworkRequest() without getting a ConcurrentModificationException.
|
||||
final NetworkRequestInfo[] nris =
|
||||
mDefaultNetworkRequests.toArray(new NetworkRequestInfo[0]);
|
||||
for (final NetworkRequestInfo nri : nris) {
|
||||
if (mDefaultRequest != nri) {
|
||||
handleRemoveNetworkRequest(nri);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addDefaultNetworkRequests(@NonNull final List<NetworkRequestInfo> nris) {
|
||||
mDefaultNetworkRequests.addAll(nris);
|
||||
handleRegisterNetworkRequest(nris);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used to generate {@link NetworkRequestInfo} based off of {@link OemNetworkPreferences}.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
final class OemNetworkRequestFactory {
|
||||
List<NetworkRequestInfo> createNrisFromOemNetworkPreferences(
|
||||
@NonNull final OemNetworkPreferences preference) {
|
||||
final List<NetworkRequestInfo> nris = new ArrayList<>();
|
||||
final SparseArray<Set<Integer>> uids =
|
||||
createUidsFromOemNetworkPreferences(preference);
|
||||
for (int i = 0; i < uids.size(); i++) {
|
||||
final int key = uids.keyAt(i);
|
||||
final Set<Integer> value = uids.valueAt(i);
|
||||
final NetworkRequestInfo nri = createNriFromOemNetworkPreferences(key, value);
|
||||
// No need to add an nri without any requests.
|
||||
if (0 == nri.mRequests.size()) {
|
||||
continue;
|
||||
}
|
||||
nris.add(nri);
|
||||
}
|
||||
|
||||
return nris;
|
||||
}
|
||||
|
||||
private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences(
|
||||
@NonNull final OemNetworkPreferences preference) {
|
||||
final SparseArray<Set<Integer>> uids = new SparseArray<>();
|
||||
final PackageManager pm = mContext.getPackageManager();
|
||||
for (final Map.Entry<String, Integer> entry :
|
||||
preference.getNetworkPreferences().entrySet()) {
|
||||
@OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue();
|
||||
try {
|
||||
final int uid = pm.getApplicationInfo(entry.getKey(), 0).uid;
|
||||
if (!uids.contains(pref)) {
|
||||
uids.put(pref, new ArraySet<>());
|
||||
}
|
||||
uids.get(pref).add(uid);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// Although this may seem like an error scenario, it is ok that uninstalled
|
||||
// packages are sent on a network preference as the system will watch for
|
||||
// package installations associated with this network preference and update
|
||||
// accordingly. This is done so as to minimize race conditions on app install.
|
||||
// TODO b/177092163 add app install watching.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return uids;
|
||||
}
|
||||
|
||||
private NetworkRequestInfo createNriFromOemNetworkPreferences(
|
||||
@OemNetworkPreferences.OemNetworkPreference final int preference,
|
||||
@NonNull final Set<Integer> uids) {
|
||||
final List<NetworkRequest> requests = new ArrayList<>();
|
||||
// Requests will ultimately be evaluated by order of insertion therefore it matters.
|
||||
switch (preference) {
|
||||
case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID:
|
||||
requests.add(createUnmeteredNetworkRequest());
|
||||
requests.add(createOemPaidNetworkRequest());
|
||||
requests.add(createDefaultRequest());
|
||||
break;
|
||||
case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:
|
||||
requests.add(createUnmeteredNetworkRequest());
|
||||
requests.add(createOemPaidNetworkRequest());
|
||||
break;
|
||||
case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY:
|
||||
requests.add(createOemPaidNetworkRequest());
|
||||
break;
|
||||
case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
|
||||
requests.add(createOemPrivateNetworkRequest());
|
||||
break;
|
||||
default:
|
||||
// This should never happen.
|
||||
throw new IllegalArgumentException("createNriFromOemNetworkPreferences()"
|
||||
+ " called with invalid preference of " + preference);
|
||||
}
|
||||
|
||||
setOemNetworkRequestUids(requests, uids);
|
||||
return new NetworkRequestInfo(requests);
|
||||
}
|
||||
|
||||
private NetworkRequest createUnmeteredNetworkRequest() {
|
||||
final NetworkCapabilities netcap = createDefaultPerAppNetCap()
|
||||
.addCapability(NET_CAPABILITY_NOT_METERED)
|
||||
.addCapability(NET_CAPABILITY_VALIDATED);
|
||||
return createNetworkRequest(NetworkRequest.Type.LISTEN, netcap);
|
||||
}
|
||||
|
||||
private NetworkRequest createOemPaidNetworkRequest() {
|
||||
// NET_CAPABILITY_OEM_PAID is a restricted capability.
|
||||
final NetworkCapabilities netcap = createDefaultPerAppNetCap()
|
||||
.addCapability(NET_CAPABILITY_OEM_PAID)
|
||||
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
|
||||
return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
|
||||
}
|
||||
|
||||
private NetworkRequest createOemPrivateNetworkRequest() {
|
||||
// NET_CAPABILITY_OEM_PRIVATE is a restricted capability.
|
||||
final NetworkCapabilities netcap = createDefaultPerAppNetCap()
|
||||
.addCapability(NET_CAPABILITY_OEM_PRIVATE)
|
||||
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
|
||||
return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
|
||||
}
|
||||
|
||||
private NetworkCapabilities createDefaultPerAppNetCap() {
|
||||
final NetworkCapabilities netCap = new NetworkCapabilities();
|
||||
netCap.addCapability(NET_CAPABILITY_INTERNET);
|
||||
netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
|
||||
return netCap;
|
||||
}
|
||||
|
||||
private void setOemNetworkRequestUids(@NonNull final List<NetworkRequest> requests,
|
||||
@NonNull final Set<Integer> uids) {
|
||||
final Set<UidRange> ranges = new ArraySet<>();
|
||||
for (final int uid : uids) {
|
||||
ranges.add(new UidRange(uid, uid));
|
||||
}
|
||||
for (final NetworkRequest req : requests) {
|
||||
req.networkCapabilities.setUids(ranges);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ import java.util.Map;
|
||||
@SmallTest
|
||||
public class OemNetworkPreferencesTest {
|
||||
|
||||
private static final int TEST_PREF = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_DEFAULT;
|
||||
private static final int TEST_PREF = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
|
||||
private static final String TEST_PACKAGE = "com.google.apps.contacts";
|
||||
|
||||
private final OemNetworkPreferences.Builder mBuilder = new OemNetworkPreferences.Builder();
|
||||
@@ -54,7 +54,7 @@ public class OemNetworkPreferencesTest {
|
||||
@Test
|
||||
public void testBuilderRemoveNetworkPreferenceRequiresNonNullPackageName() {
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> mBuilder.removeNetworkPreference(null));
|
||||
() -> mBuilder.clearNetworkPreference(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -129,7 +129,7 @@ public class OemNetworkPreferencesTest {
|
||||
|
||||
assertTrue(networkPreferences.containsKey(TEST_PACKAGE));
|
||||
|
||||
mBuilder.removeNetworkPreference(TEST_PACKAGE);
|
||||
mBuilder.clearNetworkPreference(TEST_PACKAGE);
|
||||
networkPreferences = mBuilder.build().getNetworkPreferences();
|
||||
|
||||
assertFalse(networkPreferences.containsKey(TEST_PACKAGE));
|
||||
|
||||
Reference in New Issue
Block a user