Merge "[NS04] Introduce Network Offers and their callbacks"

This commit is contained in:
Remi NGUYEN VAN 2021-05-13 15:11:45 +00:00 • committed by Gerrit Code Review
commit 5dd83f217e

View file

@ -15,7 +15,6 @@
*/
package com.android.server;
import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
import static android.content.pm.PackageManager.FEATURE_BLUETOOTH;
import static android.content.pm.PackageManager.FEATURE_WATCH;
@ -125,6 +124,7 @@ import android.net.INetworkActivityListener;
import android.net.INetworkAgent;
import android.net.INetworkMonitor;
import android.net.INetworkMonitorCallbacks;
import android.net.INetworkOfferCallback;
import android.net.IOnCompleteListener;
import android.net.IQosCallback;
import android.net.ISocketKeepaliveCallback;
@ -234,6 +234,7 @@ import com.android.net.module.util.PermissionUtils;
import com.android.server.connectivity.AutodestructReference;
import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
import com.android.server.connectivity.FullScore;
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
@ -241,6 +242,7 @@ import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.NetworkNotificationManager;
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.server.connectivity.NetworkOffer;
import com.android.server.connectivity.NetworkRanker;
import com.android.server.connectivity.PermissionMonitor;
import com.android.server.connectivity.ProfileNetworkPreferences;
@ -603,6 +605,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/
private static final int EVENT_UID_BLOCKED_REASON_CHANGED = 51;
/**
* Event to register a new network offer
* obj = NetworkOffer
*/
private static final int EVENT_REGISTER_NETWORK_OFFER = 52;
/**
* Event to unregister an existing network offer
* obj = INetworkOfferCallback
*/
private static final int EVENT_UNREGISTER_NETWORK_OFFER = 53;
/**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
@ -4684,6 +4698,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleUnregisterNetworkProvider((Messenger) msg.obj);
break;
}
case EVENT_REGISTER_NETWORK_OFFER: {
handleRegisterNetworkOffer((NetworkOffer) msg.obj);
break;
}
case EVENT_UNREGISTER_NETWORK_OFFER: {
final NetworkOfferInfo offer =
findNetworkOfferInfoByCallback((INetworkOfferCallback) msg.obj);
if (null != offer) {
handleUnregisterNetworkOffer(offer);
}
break;
}
case EVENT_REGISTER_NETWORK_AGENT: {
final Pair<NetworkAgentInfo, INetworkMonitor> arg =
(Pair<NetworkAgentInfo, INetworkMonitor>) msg.obj;
@ -6214,12 +6240,37 @@ public class ConnectivityService extends IConnectivityManager.Stub
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_PROVIDER, messenger));
}
@Override
public void offerNetwork(@NonNull final Messenger providerMessenger,
@NonNull final NetworkScore score, @NonNull final NetworkCapabilities caps,
@NonNull final INetworkOfferCallback callback) {
final NetworkOffer offer = new NetworkOffer(
FullScore.makeProspectiveScore(score, caps), caps, callback, providerMessenger);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_OFFER, offer));
}
@Override
public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
}
private void handleUnregisterNetworkProvider(Messenger messenger) {
NetworkProviderInfo npi = mNetworkProviderInfos.remove(messenger);
if (npi == null) {
loge("Failed to find Messenger in unregisterNetworkProvider");
return;
}
// Unregister all the offers from this provider
final ArrayList<NetworkOfferInfo> toRemove = new ArrayList<>();
for (final NetworkOfferInfo noi : mNetworkOffers) {
if (noi.offer.provider == messenger) {
// Can't call handleUnregisterNetworkOffer here because iteration is in progress
toRemove.add(noi);
}
}
for (NetworkOfferInfo noi : toRemove) {
handleUnregisterNetworkOffer(noi);
}
if (DBG) log("unregisterNetworkProvider for " + npi.name);
}
@ -6258,6 +6309,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
// (on the handler thread).
private volatile List<UidRange> mVpnBlockedUidRanges = new ArrayList<>();
// Must only be accessed on the handler thread
@NonNull
private final ArrayList<NetworkOfferInfo> mNetworkOffers = new ArrayList<>();
@GuardedBy("mBlockedAppUids")
private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
@ -6582,6 +6637,65 @@ public class ConnectivityService extends IConnectivityManager.Stub
updateUids(nai, null, nai.networkCapabilities);
}
private class NetworkOfferInfo implements IBinder.DeathRecipient {
@NonNull public final NetworkOffer offer;
NetworkOfferInfo(@NonNull final NetworkOffer offer) {
this.offer = offer;
}
@Override
public void binderDied() {
mHandler.post(() -> handleUnregisterNetworkOffer(this));
}
}
/**
* Register or update a network offer.
* @param newOffer The new offer. If the callback member is the same as an existing
* offer, it is an update of that offer.
*/
private void handleRegisterNetworkOffer(@NonNull final NetworkOffer newOffer) {
ensureRunningOnConnectivityServiceThread();
if (null == mNetworkProviderInfos.get(newOffer.provider)) {
// This may actually happen if a provider updates its score or registers and then
// immediately unregisters. The offer would still be in the handler queue, but the
// provider would have been removed.
if (DBG) log("Received offer from an unregistered provider");
return;
}
final NetworkOfferInfo existingOffer = findNetworkOfferInfoByCallback(newOffer.callback);
if (null != existingOffer) {
handleUnregisterNetworkOffer(existingOffer);
newOffer.migrateFrom(existingOffer.offer);
}
final NetworkOfferInfo noi = new NetworkOfferInfo(newOffer);
try {
noi.offer.provider.getBinder().linkToDeath(noi, 0 /* flags */);
} catch (RemoteException e) {
noi.binderDied();
return;
}
mNetworkOffers.add(noi);
// TODO : send requests to the provider.
}
private void handleUnregisterNetworkOffer(@NonNull final NetworkOfferInfo noi) {
ensureRunningOnConnectivityServiceThread();
mNetworkOffers.remove(noi);
noi.offer.provider.getBinder().unlinkToDeath(noi, 0 /* flags */);
}
@Nullable private NetworkOfferInfo findNetworkOfferInfoByCallback(
@NonNull final INetworkOfferCallback callback) {
ensureRunningOnConnectivityServiceThread();
for (final NetworkOfferInfo noi : mNetworkOffers) {
if (noi.offer.callback.equals(callback)) return noi;
}
return null;
}
/**
* Called when receiving LinkProperties directly from a NetworkAgent.
* Stores into |nai| any data coming from the agent that might also be written to the network's