Implementation of setOemNetworkPreference
Main implementation of ConnectivityService.setOemNetworkPreference. This covers the main requirements of this method including listener functionality. Bug: 176495594 Bug: 177101287 Bug: 176494815 Test: atest FrameworksNetTests atest NetworkStackTests atest FrameworksNetIntegrationTests atest NetworkStackIntegrationTests atest CtsNetTestCasesLatestSdk Change-Id: I8d318ab07785e52dd84d6261fdea8f318dce9bc5
This commit is contained in:
@@ -31,9 +31,9 @@ import java.util.Objects;
|
|||||||
/** @hide */
|
/** @hide */
|
||||||
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.
|
||||||
@@ -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,
|
||||||
@@ -178,8 +178,8 @@ public final class OemNetworkPreferences implements Parcelable {
|
|||||||
@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:
|
||||||
|
|||||||
@@ -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,55 @@ 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)}.
|
||||||
|
*/
|
||||||
|
private 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.
|
||||||
|
*/
|
||||||
|
private 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.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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -2634,6 +2654,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 +2780,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,7 +3646,12 @@ 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();
|
||||||
|
for (final NetworkRequestInfo nri : nris) {
|
||||||
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
mNetworkRequestInfoLogs.log("REGISTER " + nri);
|
||||||
for (final NetworkRequest req : nri.mRequests) {
|
for (final NetworkRequest req : nri.mRequests) {
|
||||||
mNetworkRequests.put(req, nri);
|
mNetworkRequests.put(req, nri);
|
||||||
@@ -3599,18 +3664,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rematchAllNetworksAndRequests();
|
rematchAllNetworksAndRequests();
|
||||||
|
for (final NetworkRequestInfo nri : nris) {
|
||||||
// If the nri is satisfied, return as its score has already been sent if needed.
|
// If the nri is satisfied, return as its score has already been sent if needed.
|
||||||
if (nri.isBeingSatisfied()) {
|
if (nri.isBeingSatisfied()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// As this request was not satisfied on rematch and thus never had any scores sent to the
|
// As this request was not satisfied on rematch and thus never had any scores sent to
|
||||||
// factories, send null now for each request of type REQUEST.
|
// the factories, send null now for each request of type REQUEST.
|
||||||
for (final NetworkRequest req : nri.mRequests) {
|
for (final NetworkRequest req : nri.mRequests) {
|
||||||
if (req.isRequest()) sendUpdatedScoreToFactories(req, null);
|
if (req.isRequest()) sendUpdatedScoreToFactories(req, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent,
|
private void handleReleaseNetworkRequestWithIntent(@NonNull final PendingIntent pendingIntent,
|
||||||
final int callingUid) {
|
final int callingUid) {
|
||||||
@@ -3781,6 +3850,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 +4489,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 +5631,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 +5652,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 +5670,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 +5695,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 +5714,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 +5901,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 +6067,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 +6195,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 +7285,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 +7354,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 +9309,211 @@ 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 listener {@link ConnectivityManager.OnSetOemNetworkPreferenceListener} Listener used
|
||||||
|
* to communicate completion of setOemNetworkPreference();
|
||||||
|
* @param preference {@link OemNetworkPreferences} The application network preference to be set.
|
||||||
|
*/
|
||||||
@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();
|
||||||
|
// TODO http://b/176496438 add permission check once permissions are added.
|
||||||
|
|
||||||
|
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
|
@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();
|
||||||
|
|||||||
Reference in New Issue
Block a user