[NS04] Introduce Network Offers and their callbacks
This patch introduces the concept of a network offer that providers send to Connectivity to register for relevant requests. This lets them see only requests that they can hope to satisfy considering their capabilities and score filters. This is meant to replace the filtering mechanism currently implemented by NetworkFactory. The reason for replacing this mechanism is that the old mechanism does caps and score filtering on the factory side, which requires these two filters to be contextless and available system-wide, including in separate processes from the system server. These constraints severely limit and complexify in particular what the score comparisons may look like. In the past the score comparison was only integer-based, making the code duplication not much of a problem, but as this scheme is becoming unsustainable by spreading the complexity of the selection across the entire stack, a centralized mechanism is now necessary. This patch only introduces the new objects and has CS keep track of them, but does not actually use them yet. Followup patches will implement the logic of calling the offer callbacks. Test: FrameworksNetTests NetworkStackTests FrameworksWifiTests Bug: 167544279 Merged-In: Idec1fe8eb4ac6f562bf098e3dd470f11024d04f2 (clean cherry-pick) Change-Id: Idec1fe8eb4ac6f562bf098e3dd470f11024d04f2
This commit is contained in:
parent
87deb0b38a
commit
cdd68bcc3a
1 changed files with 509 additions and 2 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue