Add a NetworkProvider class to the SDK.
Bug: 138306002 Test: builds, boots, wifi and telephony work Test: tested by upcoming change that uses this in NetworkFactory Change-Id: I2f61bf323215b7c6feff8acc92e7434346751773
This commit is contained in:
@@ -3107,6 +3107,63 @@ public class ConnectivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the specified {@link NetworkProvider}.
|
||||
* Each listener must only be registered once. The listener can be unregistered with
|
||||
* {@link #unregisterNetworkProvider}.
|
||||
*
|
||||
* @param provider the provider to register
|
||||
* @return the ID of the provider. This ID must be used by the provider when registering
|
||||
* {@link android.net.NetworkAgent}s.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
|
||||
public int registerNetworkProvider(@NonNull NetworkProvider provider) {
|
||||
if (provider.getProviderId() != NetworkProvider.ID_NONE) {
|
||||
// TODO: Provide a better method for checking this by moving NetworkFactory.SerialNumber
|
||||
// out of NetworkFactory.
|
||||
throw new IllegalStateException("NetworkProviders can only be registered once");
|
||||
}
|
||||
|
||||
try {
|
||||
int providerId = mService.registerNetworkProvider(provider.getMessenger(),
|
||||
provider.getName());
|
||||
provider.setProviderId(providerId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
return provider.getProviderId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the specified NetworkProvider.
|
||||
*
|
||||
* @param provider the provider to unregister
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
|
||||
public void unregisterNetworkProvider(@NonNull NetworkProvider provider) {
|
||||
try {
|
||||
mService.unregisterNetworkProvider(provider.getMessenger());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
provider.setProviderId(NetworkProvider.ID_NONE);
|
||||
}
|
||||
|
||||
|
||||
/** @hide exposed via the NetworkProvider class. */
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
|
||||
public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {
|
||||
try {
|
||||
mService.declareNetworkRequestUnfulfillable(request);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO : remove this method. It is a stopgap measure to help sheperding a number
|
||||
// of dependent changes that would conflict throughout the automerger graph. Having this
|
||||
// temporarily helps with the process of going through with all these dependent changes across
|
||||
|
||||
@@ -142,12 +142,16 @@ interface IConnectivityManager
|
||||
|
||||
void setAirplaneMode(boolean enable);
|
||||
|
||||
int registerNetworkFactory(in Messenger messenger, in String name);
|
||||
|
||||
boolean requestBandwidthUpdate(in Network network);
|
||||
|
||||
int registerNetworkFactory(in Messenger messenger, in String name);
|
||||
void unregisterNetworkFactory(in Messenger messenger);
|
||||
|
||||
int registerNetworkProvider(in Messenger messenger, in String name);
|
||||
void unregisterNetworkProvider(in Messenger messenger);
|
||||
|
||||
void declareNetworkRequestUnfulfillable(in NetworkRequest request);
|
||||
|
||||
int registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
|
||||
in NetworkCapabilities nc, int score, in NetworkMisc misc, in int factorySerialNumber);
|
||||
|
||||
|
||||
166
core/java/android/net/NetworkProvider.java
Normal file
166
core/java/android/net/NetworkProvider.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Base class for network providers such as telephony or Wi-Fi. NetworkProviders connect the device
|
||||
* to networks and makes them available to to the core network stack by creating
|
||||
* {@link NetworkAgent}s. The networks can then provide connectivity to apps and can be interacted
|
||||
* with via networking APIs such as {@link ConnectivityManager}.
|
||||
*
|
||||
* Subclasses should implement {@link #onNetworkRequested} and {@link #onRequestWithdrawn} to
|
||||
* receive {@link NetworkRequest}s sent by the system and by apps. A network that is not the
|
||||
* best (highest-scoring) network for any request is generally not used by the system, and torn
|
||||
* down.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public class NetworkProvider {
|
||||
/**
|
||||
* {@code providerId} value that indicates the absence of a provider. It is the providerId of
|
||||
* any NetworkProvider that is not currently registered, and of any NetworkRequest that is not
|
||||
* currently being satisfied by a network.
|
||||
*/
|
||||
public static final int ID_NONE = -1;
|
||||
|
||||
/**
|
||||
* A hardcoded ID for NetworkAgents representing VPNs. These agents are not created by any
|
||||
* provider, so they use this constant for clarity instead of NONE.
|
||||
* @hide only used by ConnectivityService.
|
||||
*/
|
||||
public static final int ID_VPN = -2;
|
||||
|
||||
/**
|
||||
* The first providerId value that will be allocated.
|
||||
* @hide only used by ConnectivityService.
|
||||
*/
|
||||
public static final int FIRST_PROVIDER_ID = 1;
|
||||
|
||||
/** @hide only used by ConnectivityService */
|
||||
public static final int CMD_REQUEST_NETWORK = 1;
|
||||
/** @hide only used by ConnectivityService */
|
||||
public static final int CMD_CANCEL_REQUEST = 2;
|
||||
|
||||
private final Messenger mMessenger;
|
||||
private final String mName;
|
||||
private final ConnectivityManager mCm;
|
||||
|
||||
private int mProviderId = ID_NONE;
|
||||
|
||||
/**
|
||||
* Constructs a new NetworkProvider.
|
||||
*
|
||||
* @param looper the Looper on which to run {@link #onNetworkRequested} and
|
||||
* {@link #onRequestWithdrawn}.
|
||||
* @param name the name of the listener, used only for debugging.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public NetworkProvider(@NonNull Context context, @NonNull Looper looper, @NonNull String name) {
|
||||
mCm = ConnectivityManager.from(context);
|
||||
|
||||
Handler handler = new Handler(looper) {
|
||||
@Override
|
||||
public void handleMessage(Message m) {
|
||||
switch (m.what) {
|
||||
case CMD_REQUEST_NETWORK:
|
||||
onNetworkRequested((NetworkRequest) m.obj, m.arg1, m.arg2);
|
||||
break;
|
||||
case CMD_CANCEL_REQUEST:
|
||||
onRequestWithdrawn((NetworkRequest) m.obj);
|
||||
break;
|
||||
default:
|
||||
Log.e(mName, "Unhandled message: " + m.what);
|
||||
}
|
||||
}
|
||||
};
|
||||
mMessenger = new Messenger(handler);
|
||||
mName = name;
|
||||
}
|
||||
|
||||
// TODO: consider adding a register() method so ConnectivityManager does not need to call this.
|
||||
public @Nullable Messenger getMessenger() {
|
||||
return mMessenger;
|
||||
}
|
||||
|
||||
public @NonNull String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of this provider. This is known only once the provider is registered via
|
||||
* {@link ConnectivityManager#registerNetworkProvider()}, otherwise the ID is {@link #ID_NONE}.
|
||||
* This ID must be used when registering any {@link NetworkAgent}s.
|
||||
*/
|
||||
public int getProviderId() {
|
||||
return mProviderId;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public void setProviderId(int providerId) {
|
||||
mProviderId = providerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a NetworkRequest is received. The request may be a new request or an existing
|
||||
* request with a different score.
|
||||
*
|
||||
* @param request the NetworkRequest being received
|
||||
* @param score the score of the network currently satisfying the request, or 0 if none.
|
||||
* @param providerId the ID of the provider that created the network currently satisfying this
|
||||
* request, or {@link #ID_NONE} if none.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {}
|
||||
|
||||
/**
|
||||
* Called when a NetworkRequest is withdrawn.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public void onRequestWithdrawn(@NonNull NetworkRequest request) {}
|
||||
|
||||
/**
|
||||
* Asserts that no provider will ever be able to satisfy the specified request. The provider
|
||||
* must only call this method if it knows that it is the only provider on the system capable of
|
||||
* satisfying this request, and that the request cannot be satisfied. The application filing the
|
||||
* request will receive an {@link NetworkCallback#onUnavailable()} callback.
|
||||
*
|
||||
* @param request the request that cannot be fulfilled
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
|
||||
public void declareNetworkRequestUnfulfillable(@NonNull NetworkRequest request) {
|
||||
mCm.declareNetworkRequestUnfulfillable(request);
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,7 @@ import android.net.NetworkInfo.DetailedState;
|
||||
import android.net.NetworkMisc;
|
||||
import android.net.NetworkMonitorManager;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkProvider;
|
||||
import android.net.NetworkQuotaInfo;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.NetworkScore;
|
||||
@@ -221,6 +222,7 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -597,6 +599,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
// sequence number of NetworkRequests
|
||||
private int mNextNetworkRequestId = 1;
|
||||
|
||||
// Sequence number for NetworkProvider IDs.
|
||||
private final AtomicInteger mNextNetworkProviderId = new AtomicInteger(
|
||||
NetworkProvider.FIRST_PROVIDER_ID);
|
||||
|
||||
// NetworkRequest activity String log entries.
|
||||
private static final int MAX_NETWORK_REQUEST_LOGS = 20;
|
||||
private final LocalLog mNetworkRequestInfoLogs = new LocalLog(MAX_NETWORK_REQUEST_LOGS);
|
||||
@@ -4904,31 +4910,69 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
public final String name;
|
||||
public final Messenger messenger;
|
||||
private final AsyncChannel mAsyncChannel;
|
||||
private final IBinder.DeathRecipient mDeathRecipient;
|
||||
public final int factorySerialNumber;
|
||||
|
||||
NetworkFactoryInfo(String name, Messenger messenger, AsyncChannel asyncChannel,
|
||||
int factorySerialNumber) {
|
||||
int factorySerialNumber, IBinder.DeathRecipient deathRecipient) {
|
||||
this.name = name;
|
||||
this.messenger = messenger;
|
||||
this.mAsyncChannel = asyncChannel;
|
||||
this.factorySerialNumber = factorySerialNumber;
|
||||
mAsyncChannel = asyncChannel;
|
||||
mDeathRecipient = deathRecipient;
|
||||
|
||||
if ((mAsyncChannel == null) == (mDeathRecipient == null)) {
|
||||
throw new AssertionError("Must pass exactly one of asyncChannel or deathRecipient");
|
||||
}
|
||||
}
|
||||
|
||||
boolean isLegacyNetworkFactory() {
|
||||
return mAsyncChannel != null;
|
||||
}
|
||||
|
||||
void sendMessageToNetworkProvider(int what, int arg1, int arg2, Object obj) {
|
||||
try {
|
||||
messenger.send(Message.obtain(null /* handler */, what, arg1, arg2, obj));
|
||||
} catch (RemoteException e) {
|
||||
// Remote process died. Ignore; the death recipient will remove this
|
||||
// NetworkFactoryInfo from mNetworkFactoryInfos.
|
||||
}
|
||||
}
|
||||
|
||||
void requestNetwork(NetworkRequest request, int score, int servingSerialNumber) {
|
||||
mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
|
||||
servingSerialNumber, request);
|
||||
if (isLegacyNetworkFactory()) {
|
||||
mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
|
||||
servingSerialNumber, request);
|
||||
} else {
|
||||
sendMessageToNetworkProvider(NetworkProvider.CMD_REQUEST_NETWORK, score,
|
||||
servingSerialNumber, request);
|
||||
}
|
||||
}
|
||||
|
||||
void cancelRequest(NetworkRequest request) {
|
||||
mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request);
|
||||
if (isLegacyNetworkFactory()) {
|
||||
mAsyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST, request);
|
||||
} else {
|
||||
sendMessageToNetworkProvider(NetworkProvider.CMD_CANCEL_REQUEST, 0, 0, request);
|
||||
}
|
||||
}
|
||||
|
||||
void connect(Context context, Handler handler) {
|
||||
mAsyncChannel.connect(context, handler, messenger);
|
||||
if (isLegacyNetworkFactory()) {
|
||||
mAsyncChannel.connect(context, handler, messenger);
|
||||
} else {
|
||||
try {
|
||||
messenger.getBinder().linkToDeath(mDeathRecipient, 0);
|
||||
} catch (RemoteException e) {
|
||||
mDeathRecipient.binderDied();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void completeConnection() {
|
||||
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
|
||||
if (isLegacyNetworkFactory()) {
|
||||
mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5299,6 +5343,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_LISTENER, nri));
|
||||
}
|
||||
|
||||
/** Returns the next Network provider ID. */
|
||||
public final int nextNetworkProviderId() {
|
||||
return mNextNetworkProviderId.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseNetworkRequest(NetworkRequest networkRequest) {
|
||||
ensureNetworkRequestHasType(networkRequest);
|
||||
@@ -5310,21 +5359,49 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
public int registerNetworkFactory(Messenger messenger, String name) {
|
||||
enforceNetworkFactoryPermission();
|
||||
NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger, new AsyncChannel(),
|
||||
NetworkFactory.SerialNumber.nextSerialNumber());
|
||||
nextNetworkProviderId(), null /* deathRecipient */);
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
|
||||
return nfi.factorySerialNumber;
|
||||
}
|
||||
|
||||
private void handleRegisterNetworkFactory(NetworkFactoryInfo nfi) {
|
||||
if (mNetworkFactoryInfos.containsKey(nfi.messenger)) {
|
||||
// Avoid creating duplicates. even if an app makes a direct AIDL call.
|
||||
// This will never happen if an app calls ConnectivityManager#registerNetworkProvider,
|
||||
// as that will throw if a duplicate provider is registered.
|
||||
Slog.e(TAG, "Attempt to register existing NetworkFactoryInfo "
|
||||
+ mNetworkFactoryInfos.get(nfi.messenger).name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DBG) log("Got NetworkFactory Messenger for " + nfi.name);
|
||||
mNetworkFactoryInfos.put(nfi.messenger, nfi);
|
||||
nfi.connect(mContext, mTrackerHandler);
|
||||
if (!nfi.isLegacyNetworkFactory()) {
|
||||
// Legacy NetworkFactories get their requests when their AsyncChannel connects.
|
||||
sendAllRequestsToFactory(nfi);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerNetworkProvider(Messenger messenger, String name) {
|
||||
enforceNetworkFactoryPermission();
|
||||
NetworkFactoryInfo nfi = new NetworkFactoryInfo(name, messenger,
|
||||
null /* asyncChannel */, nextNetworkProviderId(),
|
||||
() -> unregisterNetworkProvider(messenger));
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_FACTORY, nfi));
|
||||
return nfi.factorySerialNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterNetworkProvider(Messenger messenger) {
|
||||
enforceNetworkFactoryPermission();
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterNetworkFactory(Messenger messenger) {
|
||||
enforceNetworkFactoryPermission();
|
||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_FACTORY, messenger));
|
||||
unregisterNetworkProvider(messenger);
|
||||
}
|
||||
|
||||
private void handleUnregisterNetworkFactory(Messenger messenger) {
|
||||
@@ -5336,6 +5413,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
if (DBG) log("unregisterNetworkFactory for " + nfi.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void declareNetworkRequestUnfulfillable(NetworkRequest request) {
|
||||
enforceNetworkFactoryPermission();
|
||||
mHandler.post(() -> handleReleaseNetworkRequest(request, Binder.getCallingUid(), true));
|
||||
}
|
||||
|
||||
// NOTE: Accessed on multiple threads, must be synchronized on itself.
|
||||
@GuardedBy("mNetworkForNetId")
|
||||
private final SparseArray<NetworkAgentInfo> mNetworkForNetId = new SparseArray<>();
|
||||
|
||||
Reference in New Issue
Block a user