Merge changes from topics "pans", "pans-permission"

* changes:
  Marking setOemNetworkPreference as @SystemApi
  Adding permission for OEM managed preferences
  Implementation of setOemNetworkPreference
This commit is contained in:
James Mattis
2021-02-13 20:54:57 +00:00
committed by Gerrit Code Review
9 changed files with 486 additions and 66 deletions

View File

@@ -74,6 +74,7 @@ package android {
field public static final String CONTROL_DISPLAY_SATURATION = "android.permission.CONTROL_DISPLAY_SATURATION"; field public static final String CONTROL_DISPLAY_SATURATION = "android.permission.CONTROL_DISPLAY_SATURATION";
field public static final String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE"; field public static final String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
field public static final String CONTROL_KEYGUARD_SECURE_NOTIFICATIONS = "android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS"; field public static final String CONTROL_KEYGUARD_SECURE_NOTIFICATIONS = "android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS";
field public static final String CONTROL_OEM_PAID_NETWORK_PREFERENCE = "android.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE";
field public static final String CONTROL_VPN = "android.permission.CONTROL_VPN"; field public static final String CONTROL_VPN = "android.permission.CONTROL_VPN";
field public static final String CREATE_USERS = "android.permission.CREATE_USERS"; field public static final String CREATE_USERS = "android.permission.CREATE_USERS";
field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER"; field public static final String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER";
@@ -6045,6 +6046,7 @@ package android.net {
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback); method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback); method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
method @RequiresPermission(android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE) public void setOemNetworkPreference(@NonNull android.net.OemNetworkPreferences, @Nullable java.util.concurrent.Executor, @Nullable android.net.ConnectivityManager.OnSetOemNetworkPreferenceListener);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi(); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle); method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback); method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
@@ -6066,6 +6068,10 @@ package android.net {
field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd
} }
public static interface ConnectivityManager.OnSetOemNetworkPreferenceListener {
method public void onComplete();
}
@Deprecated public abstract static class ConnectivityManager.OnStartTetheringCallback { @Deprecated public abstract static class ConnectivityManager.OnStartTetheringCallback {
ctor @Deprecated public ConnectivityManager.OnStartTetheringCallback(); ctor @Deprecated public ConnectivityManager.OnStartTetheringCallback();
method @Deprecated public void onTetheringFailed(); method @Deprecated public void onTetheringFailed();
@@ -6423,6 +6429,26 @@ package android.net {
ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long); ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long);
} }
public final class OemNetworkPreferences implements android.os.Parcelable {
method public int describeContents();
method @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getNetworkPreferences();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.OemNetworkPreferences> CREATOR;
field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID = 1; // 0x1
field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK = 2; // 0x2
field public static final int OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY = 3; // 0x3
field public static final int OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY = 4; // 0x4
field public static final int OEM_NETWORK_PREFERENCE_UNINITIALIZED = 0; // 0x0
}
public static final class OemNetworkPreferences.Builder {
ctor public OemNetworkPreferences.Builder();
ctor public OemNetworkPreferences.Builder(@NonNull android.net.OemNetworkPreferences);
method @NonNull public android.net.OemNetworkPreferences.Builder addNetworkPreference(@NonNull String, int);
method @NonNull public android.net.OemNetworkPreferences build();
method @NonNull public android.net.OemNetworkPreferences.Builder clearNetworkPreference(@NonNull String);
}
public abstract class QosCallback { public abstract class QosCallback {
ctor public QosCallback(); ctor public QosCallback();
method public void onError(@NonNull android.net.QosCallbackException); method public void onError(@NonNull android.net.QosCallbackException);

View File

@@ -0,0 +1,23 @@
/**
*
* 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;
/** @hide */
oneway interface IOnSetOemNetworkPreferenceListener {
void onComplete();
}

View File

@@ -18,6 +18,7 @@ package android.net;
import android.annotation.IntDef; import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
@@ -29,11 +30,12 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
/** @hide */ /** @hide */
@SystemApi
public final class OemNetworkPreferences implements Parcelable { 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. * 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. * If an unmetered network is available, use it.
* Otherwise, if a network with the OEM_PAID capability 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; 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; 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; 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 * Builder used to create {@link OemNetworkPreferences} objects. Specify the preferred Network
* to package name mappings. * to package name mappings.
*
* @hide
*/ */
public static final class Builder { public static final class Builder {
private final Bundle mNetworkMappings; private final Bundle mNetworkMappings;
@@ -135,7 +135,7 @@ public final class OemNetworkPreferences implements Parcelable {
* @return The builder to facilitate chaining. * @return The builder to facilitate chaining.
*/ */
@NonNull @NonNull
public Builder removeNetworkPreference(@NonNull final String packageName) { public Builder clearNetworkPreference(@NonNull final String packageName) {
Objects.requireNonNull(packageName); Objects.requireNonNull(packageName);
mNetworkMappings.remove(packageName); mNetworkMappings.remove(packageName);
return this; return this;
@@ -160,7 +160,7 @@ public final class OemNetworkPreferences implements Parcelable {
/** @hide */ /** @hide */
@IntDef(prefix = "OEM_NETWORK_PREFERENCE_", value = { @IntDef(prefix = "OEM_NETWORK_PREFERENCE_", value = {
OEM_NETWORK_PREFERENCE_DEFAULT, OEM_NETWORK_PREFERENCE_UNINITIALIZED,
OEM_NETWORK_PREFERENCE_OEM_PAID, OEM_NETWORK_PREFERENCE_OEM_PAID,
OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK, OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK,
OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY, OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY,
@@ -174,12 +174,14 @@ public final class OemNetworkPreferences implements Parcelable {
* *
* @param value int value of OemNetworkPreference * @param value int value of OemNetworkPreference
* @return string version of OemNetworkPreference * @return string version of OemNetworkPreference
*
* @hide
*/ */
@NonNull @NonNull
public static String oemNetworkPreferenceToString(@OemNetworkPreference int value) { public static String oemNetworkPreferenceToString(@OemNetworkPreference int value) {
switch (value) { switch (value) {
case OEM_NETWORK_PREFERENCE_DEFAULT: case OEM_NETWORK_PREFERENCE_UNINITIALIZED:
return "OEM_NETWORK_PREFERENCE_DEFAULT"; return "OEM_NETWORK_PREFERENCE_UNINITIALIZED";
case OEM_NETWORK_PREFERENCE_OEM_PAID: case OEM_NETWORK_PREFERENCE_OEM_PAID:
return "OEM_NETWORK_PREFERENCE_OEM_PAID"; return "OEM_NETWORK_PREFERENCE_OEM_PAID";
case OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK: case OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK:

View File

@@ -1790,6 +1790,12 @@
<permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" <permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS"
android:protectionLevel="signature|privileged" /> android:protectionLevel="signature|privileged" />
<!-- @SystemApi @hide Allows an application to manage an automotive device's application network
preference as it relates to OEM_PAID and OEM_PRIVATE capable networks.
<p>Not for use by third-party or privileged applications. -->
<permission android:name="android.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE"
android:protectionLevel="signature" />
<!-- ======================================= --> <!-- ======================================= -->
<!-- Permissions for short range, peripheral networks --> <!-- Permissions for short range, peripheral networks -->
<!-- ======================================= --> <!-- ======================================= -->

View File

@@ -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 @NonNull
private final List<QosCallbackConnection> mQosCallbackConnections = new ArrayList<>(); private final List<QosCallbackConnection> mQosCallbackConnections = new ArrayList<>();
@@ -5096,4 +5087,60 @@ public class ConnectivityManager {
sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST, sendRequestForNetwork(nc, networkCallback, 0, BACKGROUND_REQUEST,
TYPE_NONE, handler == null ? getDefaultHandler() : new CallbackHandler(handler)); 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();
}
}
} }

View File

@@ -20,6 +20,7 @@ import android.app.PendingIntent;
import android.net.ConnectionInfo; import android.net.ConnectionInfo;
import android.net.ConnectivityDiagnosticsManager; import android.net.ConnectivityDiagnosticsManager;
import android.net.IConnectivityDiagnosticsCallback; import android.net.IConnectivityDiagnosticsCallback;
import android.net.IOnSetOemNetworkPreferenceListener;
import android.net.IQosCallback; import android.net.IQosCallback;
import android.net.ISocketKeepaliveCallback; import android.net.ISocketKeepaliveCallback;
import android.net.LinkProperties; import android.net.LinkProperties;
@@ -245,5 +246,6 @@ interface IConnectivityManager
void registerQosSocketCallback(in QosSocketInfo socketInfo, in IQosCallback callback); void registerQosSocketCallback(in QosSocketInfo socketInfo, in IQosCallback callback);
void unregisterQosCallback(in IQosCallback callback); void unregisterQosCallback(in IQosCallback callback);
void setOemNetworkPreference(in OemNetworkPreferences preference); void setOemNetworkPreference(in OemNetworkPreferences preference,
in IOnSetOemNetworkPreferenceListener listener);
} }

View File

@@ -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_SUSPENDED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED; 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_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_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -95,6 +97,7 @@ import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks; import android.net.INetworkMonitorCallbacks;
import android.net.INetworkPolicyListener; import android.net.INetworkPolicyListener;
import android.net.INetworkStatsService; import android.net.INetworkStatsService;
import android.net.IOnSetOemNetworkPreferenceListener;
import android.net.IQosCallback; import android.net.IQosCallback;
import android.net.ISocketKeepaliveCallback; import android.net.ISocketKeepaliveCallback;
import android.net.InetAddresses; 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; 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 * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown. * should be shown.
@@ -1039,10 +1048,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
mMetricsLog = logger; mMetricsLog = logger;
mNetworkRanker = new NetworkRanker(); mNetworkRanker = new NetworkRanker();
final NetworkRequest defaultInternetRequest = createDefaultInternetRequestForTransport( final NetworkRequest defaultInternetRequest = createDefaultRequest();
-1, NetworkRequest.Type.REQUEST); mDefaultRequest = new NetworkRequestInfo(
mDefaultRequest = new NetworkRequestInfo(null, defaultInternetRequest, new Binder(), defaultInternetRequest, null, new Binder(),
null /* attributionTag */); null /* attributionTags */);
mNetworkRequests.put(defaultInternetRequest, mDefaultRequest); mNetworkRequests.put(defaultInternetRequest, mDefaultRequest);
mDefaultNetworkRequests.add(mDefaultRequest); mDefaultNetworkRequests.add(mDefaultRequest);
mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest); mNetworkRequestInfoLogs.log("REGISTER " + mDefaultRequest);
@@ -1256,15 +1265,25 @@ public class ConnectivityService extends IConnectivityManager.Stub
return netCap; return netCap;
} }
private NetworkRequest createDefaultRequest() {
return createDefaultInternetRequestForTransport(
TYPE_NONE, NetworkRequest.Type.REQUEST);
}
private NetworkRequest createDefaultInternetRequestForTransport( private NetworkRequest createDefaultInternetRequestForTransport(
int transportType, NetworkRequest.Type type) { int transportType, NetworkRequest.Type type) {
final NetworkCapabilities netCap = new NetworkCapabilities(); final NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addCapability(NET_CAPABILITY_INTERNET); netCap.addCapability(NET_CAPABILITY_INTERNET);
netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED); netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
if (transportType > -1) { if (transportType > TYPE_NONE) {
netCap.addTransportType(transportType); netCap.addTransportType(transportType);
} }
return createNetworkRequest(type, netCap);
}
private NetworkRequest createNetworkRequest(
NetworkRequest.Type type, NetworkCapabilities netCap) {
return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type); return new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId(), type);
} }
@@ -1314,7 +1333,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (enable) { if (enable) {
handleRegisterNetworkRequest(new NetworkRequestInfo( handleRegisterNetworkRequest(new NetworkRequestInfo(
null, networkRequest, new Binder(), null /* attributionTag */)); networkRequest, null, new Binder(),
null /* attributionTags */));
} else { } else {
handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID, handleReleaseNetworkRequest(networkRequest, Process.SYSTEM_UID,
/* callOnUnavailable */ false); /* callOnUnavailable */ false);
@@ -2292,6 +2312,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
} }
private void enforceOemNetworkPreferencesPermission() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE,
"ConnectivityService");
}
private boolean checkNetworkStackPermission() { private boolean checkNetworkStackPermission() {
return checkAnyPermissionOf( return checkAnyPermissionOf(
android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_STACK,
@@ -2634,6 +2660,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
pw.println(); pw.println();
pw.print("Current per-app default networks: ");
pw.increaseIndent();
dumpPerAppNetworkPreferences(pw);
pw.decreaseIndent();
pw.println();
pw.println("Current Networks:"); pw.println("Current Networks:");
pw.increaseIndent(); pw.increaseIndent();
dumpNetworks(pw); 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) { private void dumpNetworkRequests(IndentingPrintWriter pw) {
for (NetworkRequestInfo nri : requestsSortedById()) { for (NetworkRequestInfo nri : requestsSortedById()) {
pw.println(nri.toString()); pw.println(nri.toString());
@@ -3586,29 +3652,38 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) { private void handleRegisterNetworkRequest(@NonNull final NetworkRequestInfo nri) {
handleRegisterNetworkRequest(Collections.singletonList(nri));
}
private void handleRegisterNetworkRequest(@NonNull final List<NetworkRequestInfo> nris) {
ensureRunningOnConnectivityServiceThread(); ensureRunningOnConnectivityServiceThread();
mNetworkRequestInfoLogs.log("REGISTER " + nri); for (final NetworkRequestInfo nri : nris) {
for (final NetworkRequest req : nri.mRequests) { mNetworkRequestInfoLogs.log("REGISTER " + nri);
mNetworkRequests.put(req, nri); for (final NetworkRequest req : nri.mRequests) {
if (req.isListen()) { mNetworkRequests.put(req, nri);
for (final NetworkAgentInfo network : mNetworkAgentInfos) { if (req.isListen()) {
if (req.networkCapabilities.hasSignalStrength() for (final NetworkAgentInfo network : mNetworkAgentInfos) {
&& network.satisfiesImmutableCapabilitiesOf(req)) { if (req.networkCapabilities.hasSignalStrength()
updateSignalStrengthThresholds(network, "REGISTER", req); && 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 rematchAllNetworksAndRequests();
// factories, send null now for each request of type REQUEST. for (final NetworkRequestInfo nri : nris) {
for (final NetworkRequest req : nri.mRequests) { // If the nri is satisfied, return as its score has already been sent if needed.
if (req.isRequest()) sendUpdatedScoreToFactories(req, null); 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); removeListenRequestFromNetworks(req);
} }
} }
mDefaultNetworkRequests.remove(nri);
mNetworkRequestCounter.decrementCount(nri.mUid); mNetworkRequestCounter.decrementCount(nri.mUid);
mNetworkRequestInfoLogs.log("RELEASE " + nri); mNetworkRequestInfoLogs.log("RELEASE " + nri);
@@ -4419,6 +4495,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
case EVENT_SET_REQUIRE_VPN_FOR_UIDS: case EVENT_SET_REQUIRE_VPN_FOR_UIDS:
handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj); handleSetRequireVpnForUids(toBool(msg.arg1), (UidRange[]) msg.obj);
break; 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; final PendingIntent mPendingIntent;
boolean mPendingIntentSent; boolean mPendingIntentSent;
@Nullable
final Messenger mMessenger;
@Nullable
private final IBinder mBinder; private final IBinder mBinder;
final int mPid; final int mPid;
final int mUid; final int mUid;
final Messenger messenger;
@Nullable @Nullable
final String mCallingAttributionTag; final String mCallingAttributionTag;
@@ -5570,12 +5658,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
return uids; return uids;
} }
NetworkRequestInfo(NetworkRequest r, PendingIntent pi, NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final PendingIntent pi,
@Nullable String callingAttributionTag) { @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); mRequests = initializeRequests(r);
ensureAllNetworkRequestsHaveType(mRequests); ensureAllNetworkRequestsHaveType(mRequests);
mPendingIntent = pi; mPendingIntent = pi;
messenger = null; mMessenger = null;
mBinder = null; mBinder = null;
mPid = getCallingPid(); mPid = getCallingPid();
mUid = mDeps.getCallingUid(); mUid = mDeps.getCallingUid();
@@ -5583,11 +5676,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
mCallingAttributionTag = callingAttributionTag; mCallingAttributionTag = callingAttributionTag;
} }
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestInfo(@NonNull final NetworkRequest r, @Nullable final Messenger m,
@Nullable String callingAttributionTag) { @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(); super();
messenger = m;
mRequests = initializeRequests(r); mRequests = initializeRequests(r);
mMessenger = m;
ensureAllNetworkRequestsHaveType(mRequests); ensureAllNetworkRequestsHaveType(mRequests);
mBinder = binder; mBinder = binder;
mPid = getCallingPid(); 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 */); this(r, null /* pi */, null /* callingAttributionTag */);
} }
@@ -5618,9 +5720,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
return mRequests.size() > 1; return mRequests.size() > 1;
} }
private List<NetworkRequest> initializeRequests(NetworkRequest r) { private List<NetworkRequest> initializeRequests(List<NetworkRequest> r) {
final ArrayList<NetworkRequest> tempRequests = new ArrayList<>(); // Creating a defensive copy to prevent the sender from modifying the list being
tempRequests.add(new NetworkRequest(r)); // reflected in the return value of this method.
final List<NetworkRequest> tempRequests = new ArrayList<>(r);
return Collections.unmodifiableList(tempRequests); return Collections.unmodifiableList(tempRequests);
} }
@@ -5804,7 +5907,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
nextNetworkRequestId(), reqType); nextNetworkRequestId(), reqType);
NetworkRequestInfo nri = NetworkRequestInfo nri =
new NetworkRequestInfo(messenger, networkRequest, binder, callingAttributionTag); new NetworkRequestInfo(networkRequest, messenger, binder, callingAttributionTag);
if (DBG) log("requestNetwork for " + nri); if (DBG) log("requestNetwork for " + nri);
// For TRACK_SYSTEM_DEFAULT callbacks, the capabilities have been modified since they were // 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 networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
NetworkRequest.Type.LISTEN); NetworkRequest.Type.LISTEN);
NetworkRequestInfo nri = NetworkRequestInfo nri =
new NetworkRequestInfo(messenger, networkRequest, binder, callingAttributionTag); new NetworkRequestInfo(networkRequest, messenger, binder, callingAttributionTag);
if (VDBG) log("listenForNetwork for " + nri); if (VDBG) log("listenForNetwork for " + nri);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri)); mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
@@ -6098,13 +6201,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
@GuardedBy("mBlockedAppUids") @GuardedBy("mBlockedAppUids")
private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); 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 // The always-on request for an Internet-capable network that apps without a specific default
// fall back to. // fall back to.
@VisibleForTesting
@NonNull @NonNull
private final NetworkRequestInfo mDefaultRequest; final NetworkRequestInfo mDefaultRequest;
// Collection of NetworkRequestInfo's used for default networks. // Collection of NetworkRequestInfo's used for default networks.
@VisibleForTesting
@NonNull @NonNull
private final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>(); final ArraySet<NetworkRequestInfo> mDefaultNetworkRequests = new ArraySet<>();
private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) { private boolean isPerAppDefaultRequest(@NonNull final NetworkRequestInfo nri) {
return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri); return (mDefaultNetworkRequests.contains(nri) && mDefaultRequest != nri);
@@ -7181,7 +7291,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri, private void callCallbackForRequest(@NonNull final NetworkRequestInfo nri,
@NonNull final NetworkAgentInfo networkAgent, final int notificationType, @NonNull final NetworkAgentInfo networkAgent, final int notificationType,
final int arg1) { final int arg1) {
if (nri.messenger == null) { if (nri.mMessenger == null) {
// Default request has no msgr. Also prevents callbacks from being invoked for // Default request has no msgr. Also prevents callbacks from being invoked for
// NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks // NetworkRequestInfos registered with ConnectivityDiagnostics requests. Those callbacks
// are Type.LISTEN, but should not have NetworkCallbacks invoked. // are Type.LISTEN, but should not have NetworkCallbacks invoked.
@@ -7250,7 +7360,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
String notification = ConnectivityManager.getCallbackName(notificationType); String notification = ConnectivityManager.getCallbackName(notificationType);
log("sending notification " + notification + " for " + nrForCallback); log("sending notification " + notification + " for " + nrForCallback);
} }
nri.messenger.send(msg); nri.mMessenger.send(msg);
} catch (RemoteException e) { } catch (RemoteException e) {
// may occur naturally in the race of binder death. // may occur naturally in the race of binder death.
loge("RemoteException caught trying to send a callback msg for " + nrForCallback); loge("RemoteException caught trying to send a callback msg for " + nrForCallback);
@@ -9205,9 +9315,212 @@ public class ConnectivityService extends IConnectivityManager.Stub
mQosCallbackTracker.unregisterCallback(callback); 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 @Override
public void setOemNetworkPreference(@NonNull final OemNetworkPreferences preference) { public void setOemNetworkPreference(
// TODO http://b/176495594 track multiple default networks with networkPreferences @NonNull final OemNetworkPreferences preference,
if (DBG) log("setOemNetworkPreference() called with: " + preference.toString()); @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);
}
}
} }
} }

View File

@@ -48,6 +48,7 @@
<uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" /> <uses-permission android:name="android.permission.OBSERVE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.NETWORK_FACTORY" /> <uses-permission android:name="android.permission.NETWORK_FACTORY" />
<uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" /> <uses-permission android:name="android.permission.NETWORK_STATS_PROVIDER" />
<uses-permission android:name="android.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE" />
<application> <application>
<uses-library android:name="android.test.runner" /> <uses-library android:name="android.test.runner" />

View File

@@ -40,7 +40,7 @@ import java.util.Map;
@SmallTest @SmallTest
public class OemNetworkPreferencesTest { 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 static final String TEST_PACKAGE = "com.google.apps.contacts";
private final OemNetworkPreferences.Builder mBuilder = new OemNetworkPreferences.Builder(); private final OemNetworkPreferences.Builder mBuilder = new OemNetworkPreferences.Builder();
@@ -54,7 +54,7 @@ public class OemNetworkPreferencesTest {
@Test @Test
public void testBuilderRemoveNetworkPreferenceRequiresNonNullPackageName() { public void testBuilderRemoveNetworkPreferenceRequiresNonNullPackageName() {
assertThrows(NullPointerException.class, assertThrows(NullPointerException.class,
() -> mBuilder.removeNetworkPreference(null)); () -> mBuilder.clearNetworkPreference(null));
} }
@Test @Test
@@ -129,7 +129,7 @@ public class OemNetworkPreferencesTest {
assertTrue(networkPreferences.containsKey(TEST_PACKAGE)); assertTrue(networkPreferences.containsKey(TEST_PACKAGE));
mBuilder.removeNetworkPreference(TEST_PACKAGE); mBuilder.clearNetworkPreference(TEST_PACKAGE);
networkPreferences = mBuilder.build().getNetworkPreferences(); networkPreferences = mBuilder.build().getNetworkPreferences();
assertFalse(networkPreferences.containsKey(TEST_PACKAGE)); assertFalse(networkPreferences.containsKey(TEST_PACKAGE));