Merge "Migrate away from AsyncChannel in NetworkAgent"

This commit is contained in:
Lorenzo Colitti
2021-01-06 14:10:21 +00:00
committed by Gerrit Code Review
8 changed files with 557 additions and 206 deletions

View File

@@ -61,6 +61,7 @@ import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import com.android.connectivity.aidl.INetworkAgent;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import com.android.internal.util.Protocol; import com.android.internal.util.Protocol;
@@ -3287,9 +3288,9 @@ public class ConnectivityManager {
@RequiresPermission(anyOf = { @RequiresPermission(anyOf = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
android.Manifest.permission.NETWORK_FACTORY}) android.Manifest.permission.NETWORK_FACTORY})
public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkAgentConfig config) { NetworkCapabilities nc, int score, NetworkAgentConfig config) {
return registerNetworkAgent(messenger, ni, lp, nc, score, config, NetworkProvider.ID_NONE); return registerNetworkAgent(na, ni, lp, nc, score, config, NetworkProvider.ID_NONE);
} }
/** /**
@@ -3300,10 +3301,10 @@ public class ConnectivityManager {
@RequiresPermission(anyOf = { @RequiresPermission(anyOf = {
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
android.Manifest.permission.NETWORK_FACTORY}) android.Manifest.permission.NETWORK_FACTORY})
public Network registerNetworkAgent(Messenger messenger, NetworkInfo ni, LinkProperties lp, public Network registerNetworkAgent(INetworkAgent na, NetworkInfo ni, LinkProperties lp,
NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) { NetworkCapabilities nc, int score, NetworkAgentConfig config, int providerId) {
try { try {
return mService.registerNetworkAgent(messenger, ni, lp, nc, score, config, providerId); return mService.registerNetworkAgent(na, ni, lp, nc, score, config, providerId);
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }

View File

@@ -37,6 +37,7 @@ import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.os.ResultReceiver; import android.os.ResultReceiver;
import com.android.connectivity.aidl.INetworkAgent;
import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.LegacyVpnInfo;
import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnInfo; import com.android.internal.net.VpnInfo;
@@ -164,7 +165,7 @@ interface IConnectivityManager
void declareNetworkRequestUnfulfillable(in NetworkRequest request); void declareNetworkRequestUnfulfillable(in NetworkRequest request);
Network registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp, Network registerNetworkAgent(in INetworkAgent na, in NetworkInfo ni, in LinkProperties lp,
in NetworkCapabilities nc, int score, in NetworkAgentConfig config, in NetworkCapabilities nc, int score, in NetworkAgentConfig config,
in int factorySerialNumber); in int factorySerialNumber);

View File

@@ -29,11 +29,12 @@ import android.os.ConditionVariable;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.Message; import android.os.Message;
import android.os.Messenger; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import com.android.connectivity.aidl.INetworkAgent;
import com.android.connectivity.aidl.INetworkAgentRegistry;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol; import com.android.internal.util.Protocol;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
@@ -94,12 +95,18 @@ public abstract class NetworkAgent {
@Nullable @Nullable
private volatile Network mNetwork; private volatile Network mNetwork;
@Nullable
private volatile INetworkAgentRegistry mRegistry;
private interface RegistryAction {
void execute(@NonNull INetworkAgentRegistry registry) throws RemoteException;
}
private final Handler mHandler; private final Handler mHandler;
private volatile AsyncChannel mAsyncChannel;
private final String LOG_TAG; private final String LOG_TAG;
private static final boolean DBG = true; private static final boolean DBG = true;
private static final boolean VDBG = false; private static final boolean VDBG = false;
private final ArrayList<Message> mPreConnectedQueue = new ArrayList<Message>(); private final ArrayList<RegistryAction> mPreConnectedQueue = new ArrayList<>();
private volatile long mLastBwRefreshTime = 0; private volatile long mLastBwRefreshTime = 0;
private static final long BW_REFRESH_MIN_WIN_MS = 500; private static final long BW_REFRESH_MIN_WIN_MS = 500;
private boolean mBandwidthUpdateScheduled = false; private boolean mBandwidthUpdateScheduled = false;
@@ -329,6 +336,17 @@ public abstract class NetworkAgent {
*/ */
public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17; public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
/**
* Sent by ConnectivityService to the NetworkAgent to complete the bidirectional connection.
* obj = INetworkAgentRegistry
*/
private static final int EVENT_AGENT_CONNECTED = BASE + 18;
/**
* Sent by ConnectivityService to the NetworkAgent to inform the agent that it was disconnected.
*/
private static final int EVENT_AGENT_DISCONNECTED = BASE + 19;
private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) { private static NetworkInfo getLegacyNetworkInfo(final NetworkAgentConfig config) {
// The subtype can be changed with (TODO) setLegacySubtype, but it starts // The subtype can be changed with (TODO) setLegacySubtype, but it starts
// with 0 (TelephonyManager.NETWORK_TYPE_UNKNOWN) and an empty description. // with 0 (TelephonyManager.NETWORK_TYPE_UNKNOWN) and an empty description.
@@ -402,36 +420,33 @@ public abstract class NetworkAgent {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
switch (msg.what) { switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: { case EVENT_AGENT_CONNECTED: {
if (mAsyncChannel != null) { if (mRegistry != null) {
log("Received new connection while already connected!"); log("Received new connection while already connected!");
} else { } else {
if (VDBG) log("NetworkAgent fully connected"); if (VDBG) log("NetworkAgent fully connected");
AsyncChannel ac = new AsyncChannel();
ac.connected(null, this, msg.replyTo);
ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
AsyncChannel.STATUS_SUCCESSFUL);
synchronized (mPreConnectedQueue) { synchronized (mPreConnectedQueue) {
mAsyncChannel = ac; final INetworkAgentRegistry registry = (INetworkAgentRegistry) msg.obj;
for (Message m : mPreConnectedQueue) { mRegistry = registry;
ac.sendMessage(m); for (RegistryAction a : mPreConnectedQueue) {
try {
a.execute(registry);
} catch (RemoteException e) {
Log.wtf(LOG_TAG, "Communication error with registry", e);
// Fall through
}
} }
mPreConnectedQueue.clear(); mPreConnectedQueue.clear();
} }
} }
break; break;
} }
case AsyncChannel.CMD_CHANNEL_DISCONNECT: { case EVENT_AGENT_DISCONNECTED: {
if (VDBG) log("CMD_CHANNEL_DISCONNECT");
if (mAsyncChannel != null) mAsyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
if (DBG) log("NetworkAgent channel lost"); if (DBG) log("NetworkAgent channel lost");
// let the client know CS is done with us. // let the client know CS is done with us.
onNetworkUnwanted(); onNetworkUnwanted();
synchronized (mPreConnectedQueue) { synchronized (mPreConnectedQueue) {
mAsyncChannel = null; mRegistry = null;
} }
break; break;
} }
@@ -494,15 +509,7 @@ public abstract class NetworkAgent {
} }
case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: { case CMD_SET_SIGNAL_STRENGTH_THRESHOLDS: {
ArrayList<Integer> thresholds = onSignalStrengthThresholdsUpdated((int[]) msg.obj);
((Bundle) msg.obj).getIntegerArrayList("thresholds");
// TODO: Change signal strength thresholds API to use an ArrayList<Integer>
// rather than convert to int[].
int[] intThresholds = new int[(thresholds != null) ? thresholds.size() : 0];
for (int i = 0; i < intThresholds.length; i++) {
intThresholds[i] = thresholds.get(i);
}
onSignalStrengthThresholdsUpdated(intThresholds);
break; break;
} }
case CMD_PREVENT_AUTOMATIC_RECONNECT: { case CMD_PREVENT_AUTOMATIC_RECONNECT: {
@@ -541,7 +548,7 @@ public abstract class NetworkAgent {
} }
final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context final ConnectivityManager cm = (ConnectivityManager) mInitialConfiguration.context
.getSystemService(Context.CONNECTIVITY_SERVICE); .getSystemService(Context.CONNECTIVITY_SERVICE);
mNetwork = cm.registerNetworkAgent(new Messenger(mHandler), mNetwork = cm.registerNetworkAgent(new NetworkAgentBinder(mHandler),
new NetworkInfo(mInitialConfiguration.info), new NetworkInfo(mInitialConfiguration.info),
mInitialConfiguration.properties, mInitialConfiguration.capabilities, mInitialConfiguration.properties, mInitialConfiguration.capabilities,
mInitialConfiguration.score, mInitialConfiguration.config, providerId); mInitialConfiguration.score, mInitialConfiguration.config, providerId);
@@ -550,6 +557,95 @@ public abstract class NetworkAgent {
return mNetwork; return mNetwork;
} }
private static class NetworkAgentBinder extends INetworkAgent.Stub {
private final Handler mHandler;
private NetworkAgentBinder(Handler handler) {
mHandler = handler;
}
@Override
public void onRegistered(@NonNull INetworkAgentRegistry registry) {
mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_CONNECTED, registry));
}
@Override
public void onDisconnected() {
mHandler.sendMessage(mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED));
}
@Override
public void onBandwidthUpdateRequested() {
mHandler.sendMessage(mHandler.obtainMessage(CMD_REQUEST_BANDWIDTH_UPDATE));
}
@Override
public void onValidationStatusChanged(
int validationStatus, @Nullable String captivePortalUrl) {
// TODO: consider using a parcelable as argument when the interface is structured
Bundle redirectUrlBundle = new Bundle();
redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, captivePortalUrl);
mHandler.sendMessage(mHandler.obtainMessage(CMD_REPORT_NETWORK_STATUS,
validationStatus, 0, redirectUrlBundle));
}
@Override
public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) {
mHandler.sendMessage(mHandler.obtainMessage(CMD_SAVE_ACCEPT_UNVALIDATED,
acceptUnvalidated ? 1 : 0, 0));
}
@Override
public void onStartNattSocketKeepalive(int slot, int intervalDurationMs,
@NonNull NattKeepalivePacketData packetData) {
mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE,
slot, intervalDurationMs, packetData));
}
@Override
public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs,
@NonNull TcpKeepalivePacketData packetData) {
mHandler.sendMessage(mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE,
slot, intervalDurationMs, packetData));
}
@Override
public void onStopSocketKeepalive(int slot) {
mHandler.sendMessage(mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0));
}
@Override
public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
mHandler.sendMessage(mHandler.obtainMessage(
CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, thresholds));
}
@Override
public void onPreventAutomaticReconnect() {
mHandler.sendMessage(mHandler.obtainMessage(CMD_PREVENT_AUTOMATIC_RECONNECT));
}
@Override
public void onAddNattKeepalivePacketFilter(int slot,
@NonNull NattKeepalivePacketData packetData) {
mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER,
slot, 0, packetData));
}
@Override
public void onAddTcpKeepalivePacketFilter(int slot,
@NonNull TcpKeepalivePacketData packetData) {
mHandler.sendMessage(mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER,
slot, 0, packetData));
}
@Override
public void onRemoveKeepalivePacketFilter(int slot) {
mHandler.sendMessage(mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER,
slot, 0));
}
}
/** /**
* Register this network agent with a testing harness. * Register this network agent with a testing harness.
* *
@@ -559,13 +655,13 @@ public abstract class NetworkAgent {
* *
* @hide * @hide
*/ */
public Messenger registerForTest(final Network network) { public INetworkAgent registerForTest(final Network network) {
log("Registering NetworkAgent for test"); log("Registering NetworkAgent for test");
synchronized (mRegisterLock) { synchronized (mRegisterLock) {
mNetwork = network; mNetwork = network;
mInitialConfiguration = null; mInitialConfiguration = null;
} }
return new Messenger(mHandler); return new NetworkAgentBinder(mHandler);
} }
/** /**
@@ -589,29 +685,17 @@ public abstract class NetworkAgent {
return mNetwork; return mNetwork;
} }
private void queueOrSendMessage(int what, Object obj) { private void queueOrSendMessage(@NonNull RegistryAction action) {
queueOrSendMessage(what, 0, 0, obj);
}
private void queueOrSendMessage(int what, int arg1, int arg2) {
queueOrSendMessage(what, arg1, arg2, null);
}
private void queueOrSendMessage(int what, int arg1, int arg2, Object obj) {
Message msg = Message.obtain();
msg.what = what;
msg.arg1 = arg1;
msg.arg2 = arg2;
msg.obj = obj;
queueOrSendMessage(msg);
}
private void queueOrSendMessage(Message msg) {
synchronized (mPreConnectedQueue) { synchronized (mPreConnectedQueue) {
if (mAsyncChannel != null) { if (mRegistry != null) {
mAsyncChannel.sendMessage(msg); try {
action.execute(mRegistry);
} catch (RemoteException e) {
Log.wtf(LOG_TAG, "Error executing registry action", e);
// Fall through: the channel is asynchronous and does not report errors back
}
} else { } else {
mPreConnectedQueue.add(msg); mPreConnectedQueue.add(action);
} }
} }
} }
@@ -622,7 +706,8 @@ public abstract class NetworkAgent {
*/ */
public final void sendLinkProperties(@NonNull LinkProperties linkProperties) { public final void sendLinkProperties(@NonNull LinkProperties linkProperties) {
Objects.requireNonNull(linkProperties); Objects.requireNonNull(linkProperties);
queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties)); final LinkProperties lp = new LinkProperties(linkProperties);
queueOrSendMessage(reg -> reg.sendLinkProperties(lp));
} }
/** /**
@@ -647,9 +732,7 @@ public abstract class NetworkAgent {
public final void setUnderlyingNetworks(@Nullable List<Network> underlyingNetworks) { public final void setUnderlyingNetworks(@Nullable List<Network> underlyingNetworks) {
final ArrayList<Network> underlyingArray = (underlyingNetworks != null) final ArrayList<Network> underlyingArray = (underlyingNetworks != null)
? new ArrayList<>(underlyingNetworks) : null; ? new ArrayList<>(underlyingNetworks) : null;
final Bundle bundle = new Bundle(); queueOrSendMessage(reg -> reg.sendUnderlyingNetworks(underlyingArray));
bundle.putParcelableArrayList(UNDERLYING_NETWORKS_KEY, underlyingArray);
queueOrSendMessage(EVENT_UNDERLYING_NETWORKS_CHANGED, bundle);
} }
/** /**
@@ -659,7 +742,7 @@ public abstract class NetworkAgent {
public void markConnected() { public void markConnected() {
mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null /* reason */, mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null /* reason */,
mNetworkInfo.getExtraInfo()); mNetworkInfo.getExtraInfo());
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo); queueOrSendNetworkInfo(mNetworkInfo);
} }
/** /**
@@ -672,7 +755,7 @@ public abstract class NetworkAgent {
// When unregistering an agent nobody should use the extrainfo (or reason) any more. // When unregistering an agent nobody should use the extrainfo (or reason) any more.
mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null /* reason */, mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null /* reason */,
null /* extraInfo */); null /* extraInfo */);
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo); queueOrSendNetworkInfo(mNetworkInfo);
} }
/** /**
@@ -689,7 +772,7 @@ public abstract class NetworkAgent {
@Deprecated @Deprecated
public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) { public void setLegacySubtype(final int legacySubtype, @NonNull final String legacySubtypeName) {
mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName); mNetworkInfo.setSubtype(legacySubtype, legacySubtypeName);
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo); queueOrSendNetworkInfo(mNetworkInfo);
} }
/** /**
@@ -711,7 +794,7 @@ public abstract class NetworkAgent {
@Deprecated @Deprecated
public void setLegacyExtraInfo(@Nullable final String extraInfo) { public void setLegacyExtraInfo(@Nullable final String extraInfo) {
mNetworkInfo.setExtraInfo(extraInfo); mNetworkInfo.setExtraInfo(extraInfo);
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, mNetworkInfo); queueOrSendNetworkInfo(mNetworkInfo);
} }
/** /**
@@ -720,7 +803,11 @@ public abstract class NetworkAgent {
*/ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public final void sendNetworkInfo(NetworkInfo networkInfo) { public final void sendNetworkInfo(NetworkInfo networkInfo) {
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo)); queueOrSendNetworkInfo(new NetworkInfo(networkInfo));
}
private void queueOrSendNetworkInfo(NetworkInfo networkInfo) {
queueOrSendMessage(reg -> reg.sendNetworkInfo(networkInfo));
} }
/** /**
@@ -731,8 +818,8 @@ public abstract class NetworkAgent {
Objects.requireNonNull(networkCapabilities); Objects.requireNonNull(networkCapabilities);
mBandwidthUpdatePending.set(false); mBandwidthUpdatePending.set(false);
mLastBwRefreshTime = System.currentTimeMillis(); mLastBwRefreshTime = System.currentTimeMillis();
queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
new NetworkCapabilities(networkCapabilities)); queueOrSendMessage(reg -> reg.sendNetworkCapabilities(nc));
} }
/** /**
@@ -744,7 +831,7 @@ public abstract class NetworkAgent {
if (score < 0) { if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0"); throw new IllegalArgumentException("Score must be >= 0");
} }
queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score, 0); queueOrSendMessage(reg -> reg.sendScore(score));
} }
/** /**
@@ -784,9 +871,8 @@ public abstract class NetworkAgent {
* @hide should move to NetworkAgentConfig. * @hide should move to NetworkAgentConfig.
*/ */
public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) { public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED, queueOrSendMessage(reg -> reg.sendExplicitlySelected(
explicitlySelected ? 1 : 0, explicitlySelected, acceptUnvalidated));
acceptUnvalidated ? 1 : 0);
} }
/** /**
@@ -909,7 +995,7 @@ public abstract class NetworkAgent {
*/ */
public final void sendSocketKeepaliveEvent(int slot, public final void sendSocketKeepaliveEvent(int slot,
@SocketKeepalive.KeepaliveEvent int event) { @SocketKeepalive.KeepaliveEvent int event) {
queueOrSendMessage(EVENT_SOCKET_KEEPALIVE, slot, event); queueOrSendMessage(reg -> reg.sendSocketKeepaliveEvent(slot, event));
} }
/** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */ /** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */
public void onSocketKeepaliveEvent(int slot, int reason) { public void onSocketKeepaliveEvent(int slot, int reason) {

View File

@@ -175,6 +175,7 @@ import android.util.SparseArray;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import android.util.Xml; import android.util.Xml;
import com.android.connectivity.aidl.INetworkAgent;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
@@ -2007,7 +2008,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
void handleRestrictBackgroundChanged(boolean restrictBackground) { void handleRestrictBackgroundChanged(boolean restrictBackground) {
if (mRestrictBackground == restrictBackground) return; if (mRestrictBackground == restrictBackground) return;
for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean curMetered = nai.networkCapabilities.isMetered(); final boolean curMetered = nai.networkCapabilities.isMetered();
maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground, maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
restrictBackground); restrictBackground);
@@ -2715,7 +2716,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/ */
private NetworkAgentInfo[] networksSortedById() { private NetworkAgentInfo[] networksSortedById() {
NetworkAgentInfo[] networks = new NetworkAgentInfo[0]; NetworkAgentInfo[] networks = new NetworkAgentInfo[0];
networks = mNetworkAgentInfos.values().toArray(networks); networks = mNetworkAgentInfos.toArray(networks);
Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId())); Arrays.sort(networks, Comparator.comparingInt(nai -> nai.network.getNetId()));
return networks; return networks;
} }
@@ -2761,11 +2762,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
handleAsyncChannelHalfConnect(msg); handleAsyncChannelHalfConnect(msg);
break; break;
} }
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) nai.asyncChannel.disconnect();
break;
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
handleAsyncChannelDisconnected(msg); handleAsyncChannelDisconnected(msg);
break; break;
@@ -2775,8 +2771,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
private void maybeHandleNetworkAgentMessage(Message msg) { private void maybeHandleNetworkAgentMessage(Message msg) {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo); final Pair<NetworkAgentInfo, Object> arg = (Pair<NetworkAgentInfo, Object>) msg.obj;
if (nai == null) { final NetworkAgentInfo nai = arg.first;
if (!mNetworkAgentInfos.contains(nai)) {
if (VDBG) { if (VDBG) {
log(String.format("%s from unknown NetworkAgent", eventName(msg.what))); log(String.format("%s from unknown NetworkAgent", eventName(msg.what)));
} }
@@ -2785,7 +2782,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
switch (msg.what) { switch (msg.what) {
case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: { case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj; NetworkCapabilities networkCapabilities = (NetworkCapabilities) arg.second;
if (networkCapabilities.hasConnectivityManagedCapability()) { if (networkCapabilities.hasConnectivityManagedCapability()) {
Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability."); Log.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
} }
@@ -2802,13 +2799,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
break; break;
} }
case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: { case NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED: {
LinkProperties newLp = (LinkProperties) msg.obj; LinkProperties newLp = (LinkProperties) arg.second;
processLinkPropertiesFromAgent(nai, newLp); processLinkPropertiesFromAgent(nai, newLp);
handleUpdateLinkProperties(nai, newLp); handleUpdateLinkProperties(nai, newLp);
break; break;
} }
case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: { case NetworkAgent.EVENT_NETWORK_INFO_CHANGED: {
NetworkInfo info = (NetworkInfo) msg.obj; NetworkInfo info = (NetworkInfo) arg.second;
updateNetworkInfo(nai, info); updateNetworkInfo(nai, info);
break; break;
} }
@@ -2833,7 +2830,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
break; break;
} }
case NetworkAgent.EVENT_SOCKET_KEEPALIVE: { case NetworkAgent.EVENT_SOCKET_KEEPALIVE: {
mKeepaliveTracker.handleEventSocketKeepalive(nai, msg); mKeepaliveTracker.handleEventSocketKeepalive(nai, msg.arg1, msg.arg2);
break; break;
} }
case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: { case NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED: {
@@ -2844,7 +2841,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
final ArrayList<Network> underlying; final ArrayList<Network> underlying;
try { try {
underlying = ((Bundle) msg.obj).getParcelableArrayList( underlying = ((Bundle) arg.second).getParcelableArrayList(
NetworkAgent.UNDERLYING_NETWORKS_KEY); NetworkAgent.UNDERLYING_NETWORKS_KEY);
} catch (NullPointerException | ClassCastException e) { } catch (NullPointerException | ClassCastException e) {
break; break;
@@ -2923,8 +2920,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (nai.lastCaptivePortalDetected && if (nai.lastCaptivePortalDetected &&
Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) { Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
if (DBG) log("Avoiding captive portal network: " + nai.toShortString()); if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
nai.asyncChannel.sendMessage( nai.onPreventAutomaticReconnect();
NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
teardownUnneededNetwork(nai); teardownUnneededNetwork(nai);
break; break;
} }
@@ -3016,13 +3012,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
updateInetCondition(nai); updateInetCondition(nai);
// Let the NetworkAgent know the state of its network // Let the NetworkAgent know the state of its network
Bundle redirectUrlBundle = new Bundle();
redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, redirectUrl);
// TODO: Evaluate to update partial connectivity to status to NetworkAgent. // TODO: Evaluate to update partial connectivity to status to NetworkAgent.
nai.asyncChannel.sendMessage( nai.onValidationStatusChanged(
NetworkAgent.CMD_REPORT_NETWORK_STATUS, valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK,
(valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK), redirectUrl);
0, redirectUrlBundle);
// If NetworkMonitor detects partial connectivity before // If NetworkMonitor detects partial connectivity before
// EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
@@ -3056,6 +3049,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
break; break;
} }
case NetworkAgentInfo.EVENT_AGENT_REGISTERED: {
handleNetworkAgentRegistered(msg);
break;
}
case NetworkAgentInfo.EVENT_AGENT_DISCONNECTED: {
handleNetworkAgentDisconnected(msg);
break;
}
} }
return true; return true;
} }
@@ -3232,7 +3233,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void handlePrivateDnsSettingsChanged() { private void handlePrivateDnsSettingsChanged() {
final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
handlePerNetworkPrivateDnsConfig(nai, cfg); handlePerNetworkPrivateDnsConfig(nai, cfg);
if (networkRequiresPrivateDnsValidation(nai)) { if (networkRequiresPrivateDnsValidation(nai)) {
handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties)); handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
@@ -3330,7 +3331,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void handleAsyncChannelHalfConnect(Message msg) { private void handleAsyncChannelHalfConnect(Message msg) {
ensureRunningOnConnectivityServiceThread(); ensureRunningOnConnectivityServiceThread();
final AsyncChannel ac = (AsyncChannel) msg.obj;
if (mNetworkProviderInfos.containsKey(msg.replyTo)) { if (mNetworkProviderInfos.containsKey(msg.replyTo)) {
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
if (VDBG) log("NetworkFactory connected"); if (VDBG) log("NetworkFactory connected");
@@ -3342,15 +3342,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
loge("Error connecting NetworkFactory"); loge("Error connecting NetworkFactory");
mNetworkProviderInfos.remove(msg.obj); mNetworkProviderInfos.remove(msg.obj);
} }
} else if (mNetworkAgentInfos.containsKey(msg.replyTo)) { }
if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { }
if (VDBG) log("NetworkAgent connected");
// A network agent has requested a connection. Establish the connection. private void handleNetworkAgentRegistered(Message msg) {
mNetworkAgentInfos.get(msg.replyTo).asyncChannel. final NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); if (!mNetworkAgentInfos.contains(nai)) {
return;
}
if (msg.arg1 == NetworkAgentInfo.ARG_AGENT_SUCCESS) {
if (VDBG) log("NetworkAgent registered");
} else { } else {
loge("Error connecting NetworkAgent"); loge("Error connecting NetworkAgent");
NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo); mNetworkAgentInfos.remove(nai);
if (nai != null) { if (nai != null) {
final boolean wasDefault = isDefaultNetwork(nai); final boolean wasDefault = isDefaultNetwork(nai);
synchronized (mNetworkForNetId) { synchronized (mNetworkForNetId) {
@@ -3362,20 +3367,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
} }
private void handleNetworkAgentDisconnected(Message msg) {
NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
if (mNetworkAgentInfos.contains(nai)) {
disconnectAndDestroyNetwork(nai);
}
} }
// This is a no-op if it's called with a message designating a network that has // This is a no-op if it's called with a message designating a provider that has
// already been destroyed, because its reference will not be found in the relevant // already been destroyed, because its reference will not be found in the relevant
// maps. // maps.
private void handleAsyncChannelDisconnected(Message msg) { private void handleAsyncChannelDisconnected(Message msg) {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) {
disconnectAndDestroyNetwork(nai);
} else {
NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo); NetworkProviderInfo npi = mNetworkProviderInfos.remove(msg.replyTo);
if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name); if (DBG && npi != null) log("unregisterNetworkFactory for " + npi.name);
} }
}
// Destroys a network, remove references to it from the internal state managed by // Destroys a network, remove references to it from the internal state managed by
// ConnectivityService, free its interfaces and clean up. // ConnectivityService, free its interfaces and clean up.
@@ -3418,7 +3424,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
wakeupModifyInterface(iface, nai.networkCapabilities, false); wakeupModifyInterface(iface, nai.networkCapabilities, false);
} }
nai.networkMonitor().notifyNetworkDisconnected(); nai.networkMonitor().notifyNetworkDisconnected();
mNetworkAgentInfos.remove(nai.messenger); mNetworkAgentInfos.remove(nai);
nai.clatd.update(); nai.clatd.update();
synchronized (mNetworkForNetId) { synchronized (mNetworkForNetId) {
// Remove the NetworkAgent, but don't mark the netId as // Remove the NetworkAgent, but don't mark the netId as
@@ -3526,7 +3532,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mNetworkRequests.put(nri.request, nri); mNetworkRequests.put(nri.request, nri);
mNetworkRequestInfoLogs.log("REGISTER " + nri); mNetworkRequestInfoLogs.log("REGISTER " + nri);
if (nri.request.isListen()) { if (nri.request.isListen()) {
for (NetworkAgentInfo network : mNetworkAgentInfos.values()) { for (NetworkAgentInfo network : mNetworkAgentInfos) {
if (nri.request.networkCapabilities.hasSignalStrength() && if (nri.request.networkCapabilities.hasSignalStrength() &&
network.satisfiesImmutableCapabilitiesOf(nri.request)) { network.satisfiesImmutableCapabilitiesOf(nri.request)) {
updateSignalStrengthThresholds(network, "REGISTER", nri.request); updateSignalStrengthThresholds(network, "REGISTER", nri.request);
@@ -3742,7 +3748,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} else { } else {
// listens don't have a singular affectedNetwork. Check all networks to see // listens don't have a singular affectedNetwork. Check all networks to see
// if this listen request applies and remove it. // if this listen request applies and remove it.
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
nai.removeRequest(nri.request.requestId); nai.removeRequest(nri.request.requestId);
if (nri.request.networkCapabilities.hasSignalStrength() && if (nri.request.networkCapabilities.hasSignalStrength() &&
nai.satisfiesImmutableCapabilitiesOf(nri.request)) { nai.satisfiesImmutableCapabilitiesOf(nri.request)) {
@@ -3815,13 +3821,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
if (always) { if (always) {
nai.asyncChannel.sendMessage( nai.onSaveAcceptUnvalidated(accept);
NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept));
} }
if (!accept) { if (!accept) {
// Tell the NetworkAgent to not automatically reconnect to the network. // Tell the NetworkAgent to not automatically reconnect to the network.
nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); nai.onPreventAutomaticReconnect();
// Teardown the network. // Teardown the network.
teardownUnneededNetwork(nai); teardownUnneededNetwork(nai);
} }
@@ -3852,13 +3857,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
// TODO: Use the current design or save the user choice into IpMemoryStore. // TODO: Use the current design or save the user choice into IpMemoryStore.
if (always) { if (always) {
nai.asyncChannel.sendMessage( nai.onSaveAcceptUnvalidated(accept);
NetworkAgent.CMD_SAVE_ACCEPT_UNVALIDATED, encodeBool(accept));
} }
if (!accept) { if (!accept) {
// Tell the NetworkAgent to not automatically reconnect to the network. // Tell the NetworkAgent to not automatically reconnect to the network.
nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); nai.onPreventAutomaticReconnect();
// Tear down the network. // Tear down the network.
teardownUnneededNetwork(nai); teardownUnneededNetwork(nai);
} else { } else {
@@ -3996,7 +4000,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void rematchForAvoidBadWifiUpdate() { private void rematchForAvoidBadWifiUpdate() {
rematchAllNetworksAndRequests(); rematchAllNetworksAndRequests();
for (NetworkAgentInfo nai: mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai: mNetworkAgentInfos) {
if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { if (nai.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
sendUpdatedScoreToFactories(nai); sendUpdatedScoreToFactories(nai);
} }
@@ -4139,7 +4143,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// to a network that provides no or limited connectivity is not useful, because the user // to a network that provides no or limited connectivity is not useful, because the user
// cannot use that network except through the notification shown by this method, and the // cannot use that network except through the notification shown by this method, and the
// notification is only shown if the network is explicitly selected by the user. // notification is only shown if the network is explicitly selected by the user.
nai.asyncChannel.sendMessage(NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT); nai.onPreventAutomaticReconnect();
// TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
// NetworkMonitor detects the network is partial connectivity. Need to change the design to // NetworkMonitor detects the network is partial connectivity. Need to change the design to
@@ -4789,7 +4793,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
return new VpnInfo[0]; return new VpnInfo[0];
} }
List<VpnInfo> infoList = new ArrayList<>(); List<VpnInfo> infoList = new ArrayList<>();
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
VpnInfo info = createVpnInfo(nai); VpnInfo info = createVpnInfo(nai);
if (info != null) { if (info != null) {
infoList.add(info); infoList.add(info);
@@ -4890,7 +4894,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
*/ */
private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) { private void propagateUnderlyingNetworkCapabilities(Network updatedNetwork) {
ensureRunningOnConnectivityServiceThread(); ensureRunningOnConnectivityServiceThread();
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) { if (updatedNetwork == null || hasUnderlyingNetwork(nai, updatedNetwork)) {
updateCapabilitiesForNetwork(nai); updateCapabilitiesForNetwork(nai);
} }
@@ -5591,7 +5595,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mAppOpsManager.checkPackage(callerUid, callerPackageName); mAppOpsManager.checkPackage(callerUid, callerPackageName);
} }
private ArrayList<Integer> getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) { private int[] getSignalStrengthThresholds(@NonNull final NetworkAgentInfo nai) {
final SortedSet<Integer> thresholds = new TreeSet<>(); final SortedSet<Integer> thresholds = new TreeSet<>();
synchronized (nai) { synchronized (nai) {
for (final NetworkRequestInfo nri : mNetworkRequests.values()) { for (final NetworkRequestInfo nri : mNetworkRequests.values()) {
@@ -5603,14 +5607,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
} }
return new ArrayList<>(thresholds); // TODO: use NetworkStackUtils.convertToIntArray after moving it
return ArrayUtils.convertToIntArray(new ArrayList<>(thresholds));
} }
private void updateSignalStrengthThresholds( private void updateSignalStrengthThresholds(
NetworkAgentInfo nai, String reason, NetworkRequest request) { NetworkAgentInfo nai, String reason, NetworkRequest request) {
ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai); final int[] thresholdsArray = getSignalStrengthThresholds(nai);
Bundle thresholds = new Bundle();
thresholds.putIntegerArrayList("thresholds", thresholdsArray);
if (VDBG || (DBG && !"CONNECT".equals(reason))) { if (VDBG || (DBG && !"CONNECT".equals(reason))) {
String detail; String detail;
@@ -5620,12 +5623,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
detail = reason; detail = reason;
} }
log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s",
detail, Arrays.toString(thresholdsArray.toArray()), nai.toShortString())); detail, Arrays.toString(thresholdsArray), nai.toShortString()));
} }
nai.asyncChannel.sendMessage( nai.onSignalStrengthThresholdsUpdated(thresholdsArray);
android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS,
0, 0, thresholds);
} }
private void ensureValidNetworkSpecifier(NetworkCapabilities nc) { private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
@@ -5735,7 +5736,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai = mNetworkForNetId.get(network.getNetId()); nai = mNetworkForNetId.get(network.getNetId());
} }
if (nai != null) { if (nai != null) {
nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE); nai.onBandwidthUpdateRequested();
synchronized (mBandwidthRequests) { synchronized (mBandwidthRequests) {
final int uid = mDeps.getCallingUid(); final int uid = mDeps.getCallingUid();
Integer uidReqs = mBandwidthRequests.get(uid); Integer uidReqs = mBandwidthRequests.get(uid);
@@ -5978,7 +5979,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// NetworkAgentInfo keyed off its connecting messenger // NetworkAgentInfo keyed off its connecting messenger
// TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays // TODO - eval if we can reduce the number of lists/hashmaps/sparsearrays
// NOTE: Only should be accessed on ConnectivityServiceThread, except dump(). // NOTE: Only should be accessed on ConnectivityServiceThread, except dump().
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos = new HashMap<>(); private final ArraySet<NetworkAgentInfo> mNetworkAgentInfos = new ArraySet<>();
@GuardedBy("mBlockedAppUids") @GuardedBy("mBlockedAppUids")
private final HashSet<Integer> mBlockedAppUids = new HashSet<>(); private final HashSet<Integer> mBlockedAppUids = new HashSet<>();
@@ -6026,17 +6027,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
/** /**
* Register a new agent. {@see #registerNetworkAgent} below. * Register a new agent. {@see #registerNetworkAgent} below.
*/ */
public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities, LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig) { int currentScore, NetworkAgentConfig networkAgentConfig) {
return registerNetworkAgent(messenger, networkInfo, linkProperties, networkCapabilities, return registerNetworkAgent(na, networkInfo, linkProperties, networkCapabilities,
currentScore, networkAgentConfig, NetworkProvider.ID_NONE); currentScore, networkAgentConfig, NetworkProvider.ID_NONE);
} }
/** /**
* Register a new agent with ConnectivityService to handle a network. * Register a new agent with ConnectivityService to handle a network.
* *
* @param messenger a messenger for ConnectivityService to contact the agent asynchronously. * @param na a reference for ConnectivityService to contact the agent asynchronously.
* @param networkInfo the initial info associated with this network. It can be updated later : * @param networkInfo the initial info associated with this network. It can be updated later :
* see {@link #updateNetworkInfo}. * see {@link #updateNetworkInfo}.
* @param linkProperties the initial link properties of this network. They can be updated * @param linkProperties the initial link properties of this network. They can be updated
@@ -6049,7 +6050,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @param providerId the ID of the provider owning this NetworkAgent. * @param providerId the ID of the provider owning this NetworkAgent.
* @return the network created for this agent. * @return the network created for this agent.
*/ */
public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo, public Network registerNetworkAgent(INetworkAgent na, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities, LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) { int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
@@ -6061,14 +6062,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
final int uid = mDeps.getCallingUid(); final int uid = mDeps.getCallingUid();
final long token = Binder.clearCallingIdentity(); final long token = Binder.clearCallingIdentity();
try { try {
return registerNetworkAgentInternal(messenger, networkInfo, linkProperties, return registerNetworkAgentInternal(na, networkInfo, linkProperties,
networkCapabilities, currentScore, networkAgentConfig, providerId, uid); networkCapabilities, currentScore, networkAgentConfig, providerId, uid);
} finally { } finally {
Binder.restoreCallingIdentity(token); Binder.restoreCallingIdentity(token);
} }
} }
private Network registerNetworkAgentInternal(Messenger messenger, NetworkInfo networkInfo, private Network registerNetworkAgentInternal(INetworkAgent na, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities, LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid) { int currentScore, NetworkAgentConfig networkAgentConfig, int providerId, int uid) {
if (networkCapabilities.hasTransport(TRANSPORT_TEST)) { if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
@@ -6084,7 +6085,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network // TODO: Instead of passing mDefaultRequest, provide an API to determine whether a Network
// satisfies mDefaultRequest. // satisfies mDefaultRequest.
final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), final NetworkAgentInfo nai = new NetworkAgentInfo(na,
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc, new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig), currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
this, mNetd, mDnsResolver, mNMS, providerId, uid); this, mNetd, mDnsResolver, mNMS, providerId, uid);
@@ -6102,7 +6103,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
nai.network, name, new NetworkMonitorCallbacks(nai)); nai.network, name, new NetworkMonitorCallbacks(nai));
// NetworkAgentInfo registration will finish when the NetworkMonitor is created. // NetworkAgentInfo registration will finish when the NetworkMonitor is created.
// If the network disconnects or sends any other event before that, messages are deferred by // If the network disconnects or sends any other event before that, messages are deferred by
// NetworkAgent until nai.asyncChannel.connect(), which will be called when finalizing the // NetworkAgent until nai.connect(), which will be called when finalizing the
// registration. // registration.
return nai.network; return nai.network;
} }
@@ -6110,7 +6111,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) { private void handleRegisterNetworkAgent(NetworkAgentInfo nai, INetworkMonitor networkMonitor) {
nai.onNetworkMonitorCreated(networkMonitor); nai.onNetworkMonitorCreated(networkMonitor);
if (VDBG) log("Got NetworkAgent Messenger"); if (VDBG) log("Got NetworkAgent Messenger");
mNetworkAgentInfos.put(nai.messenger, nai); mNetworkAgentInfos.add(nai);
synchronized (mNetworkForNetId) { synchronized (mNetworkForNetId) {
mNetworkForNetId.put(nai.network.getNetId(), nai); mNetworkForNetId.put(nai.network.getNetId(), nai);
} }
@@ -6120,7 +6121,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
} catch (RemoteException e) { } catch (RemoteException e) {
e.rethrowAsRuntimeException(); e.rethrowAsRuntimeException();
} }
nai.asyncChannel.connect(mContext, mTrackerHandler, nai.messenger); nai.notifyRegistered();
NetworkInfo networkInfo = nai.networkInfo; NetworkInfo networkInfo = nai.networkInfo;
updateNetworkInfo(nai, networkInfo); updateNetworkInfo(nai, networkInfo);
updateUids(nai, null, nai.networkCapabilities); updateUids(nai, null, nai.networkCapabilities);
@@ -6933,7 +6934,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
break; break;
} }
} }
nai.asyncChannel.disconnect(); nai.disconnect();
} }
private void handleLingerComplete(NetworkAgentInfo oldNetwork) { private void handleLingerComplete(NetworkAgentInfo oldNetwork) {
@@ -7123,7 +7124,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Gather the list of all relevant agents and sort them by score. // Gather the list of all relevant agents and sort them by score.
final ArrayList<NetworkAgentInfo> nais = new ArrayList<>(); final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
if (!nai.everConnected) continue; if (!nai.everConnected) continue;
nais.add(nai); nais.add(nai);
} }
@@ -7158,7 +7159,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void applyNetworkReassignment(@NonNull final NetworkReassignment changes, private void applyNetworkReassignment(@NonNull final NetworkReassignment changes,
final long now) { final long now) {
final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos.values(); final Collection<NetworkAgentInfo> nais = mNetworkAgentInfos;
// Since most of the time there are only 0 or 1 background networks, it would probably // Since most of the time there are only 0 or 1 background networks, it would probably
// be more efficient to just use an ArrayList here. TODO : measure performance // be more efficient to just use an ArrayList here. TODO : measure performance
@@ -7251,7 +7252,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
updateLegacyTypeTrackerAndVpnLockdownForRematch(oldDefaultNetwork, newDefaultNetwork, nais); updateLegacyTypeTrackerAndVpnLockdownForRematch(oldDefaultNetwork, newDefaultNetwork, nais);
// Tear down all unneeded networks. // Tear down all unneeded networks.
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
if (unneeded(nai, UnneededFor.TEARDOWN)) { if (unneeded(nai, UnneededFor.TEARDOWN)) {
if (nai.getLingerExpiry() > 0) { if (nai.getLingerExpiry() > 0) {
// This network has active linger timers and no requests, but is not // This network has active linger timers and no requests, but is not
@@ -7488,7 +7489,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// This has to happen after matching the requests, because callbacks are just requests. // This has to happen after matching the requests, because callbacks are just requests.
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK); notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
} else if (state == NetworkInfo.State.DISCONNECTED) { } else if (state == NetworkInfo.State.DISCONNECTED) {
networkAgent.asyncChannel.disconnect(); networkAgent.disconnect();
if (networkAgent.isVPN()) { if (networkAgent.isVPN()) {
updateUids(networkAgent, networkAgent.networkCapabilities, null); updateUids(networkAgent, networkAgent.networkCapabilities, null);
} }
@@ -7576,7 +7577,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @param newRules The new rules to apply. * @param newRules The new rules to apply.
*/ */
private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) { private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean metered = nai.networkCapabilities.isMetered(); final boolean metered = nai.networkCapabilities.isMetered();
final boolean oldBlocked, newBlocked; final boolean oldBlocked, newBlocked;
// TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid // TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid
@@ -7682,7 +7683,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
ensureRunningOnConnectivityServiceThread(); ensureRunningOnConnectivityServiceThread();
ArrayList<Network> defaultNetworks = new ArrayList<>(); ArrayList<Network> defaultNetworks = new ArrayList<>();
NetworkAgentInfo defaultNetwork = getDefaultNetwork(); NetworkAgentInfo defaultNetwork = getDefaultNetwork();
for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { for (NetworkAgentInfo nai : mNetworkAgentInfos) {
if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) { if (nai.everConnected && (nai == defaultNetwork || nai.isVPN())) {
defaultNetworks.add(nai.network); defaultNetworks.add(nai.network);
} }
@@ -8416,7 +8417,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
return false; return false;
} }
for (NetworkAgentInfo virtual : mNetworkAgentInfos.values()) { for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
if (virtual.supportsUnderlyingNetworks() if (virtual.supportsUnderlyingNetworks()
&& virtual.networkCapabilities.getOwnerUid() == callbackUid && virtual.networkCapabilities.getOwnerUid() == callbackUid
&& ArrayUtils.contains(virtual.declaredUnderlyingNetworks, nai.network)) { && ArrayUtils.contains(virtual.declaredUnderlyingNetworks, nai.network)) {

View File

@@ -18,10 +18,7 @@ package com.android.server.connectivity;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.NattSocketKeepalive.NATT_PORT; import static android.net.NattSocketKeepalive.NATT_PORT;
import static android.net.NetworkAgent.CMD_ADD_KEEPALIVE_PACKET_FILTER;
import static android.net.NetworkAgent.CMD_REMOVE_KEEPALIVE_PACKET_FILTER;
import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE; import static android.net.NetworkAgent.CMD_START_SOCKET_KEEPALIVE;
import static android.net.NetworkAgent.CMD_STOP_SOCKET_KEEPALIVE;
import static android.net.SocketKeepalive.BINDER_DIED; import static android.net.SocketKeepalive.BINDER_DIED;
import static android.net.SocketKeepalive.DATA_RECEIVED; import static android.net.SocketKeepalive.DATA_RECEIVED;
import static android.net.SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES; import static android.net.SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES;
@@ -330,10 +327,9 @@ public class KeepaliveTracker {
Log.d(TAG, "Starting keepalive " + mSlot + " on " + mNai.toShortString()); Log.d(TAG, "Starting keepalive " + mSlot + " on " + mNai.toShortString());
switch (mType) { switch (mType) {
case TYPE_NATT: case TYPE_NATT:
mNai.asyncChannel.sendMessage( final NattKeepalivePacketData nattData = (NattKeepalivePacketData) mPacket;
CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0 /* Unused */, mPacket); mNai.onAddNattKeepalivePacketFilter(slot, nattData);
mNai.asyncChannel mNai.onStartNattSocketKeepalive(slot, mInterval, nattData);
.sendMessage(CMD_START_SOCKET_KEEPALIVE, slot, mInterval, mPacket);
break; break;
case TYPE_TCP: case TYPE_TCP:
try { try {
@@ -342,11 +338,10 @@ public class KeepaliveTracker {
handleStopKeepalive(mNai, mSlot, ERROR_INVALID_SOCKET); handleStopKeepalive(mNai, mSlot, ERROR_INVALID_SOCKET);
return; return;
} }
mNai.asyncChannel.sendMessage( final TcpKeepalivePacketData tcpData = (TcpKeepalivePacketData) mPacket;
CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0 /* Unused */, mPacket); mNai.onAddTcpKeepalivePacketFilter(slot, tcpData);
// TODO: check result from apf and notify of failure as needed. // TODO: check result from apf and notify of failure as needed.
mNai.asyncChannel mNai.onStartTcpSocketKeepalive(slot, mInterval, tcpData);
.sendMessage(CMD_START_SOCKET_KEEPALIVE, slot, mInterval, mPacket);
break; break;
default: default:
Log.wtf(TAG, "Starting keepalive with unknown type: " + mType); Log.wtf(TAG, "Starting keepalive with unknown type: " + mType);
@@ -394,9 +389,8 @@ public class KeepaliveTracker {
mTcpController.stopSocketMonitor(mSlot); mTcpController.stopSocketMonitor(mSlot);
// fall through // fall through
case TYPE_NATT: case TYPE_NATT:
mNai.asyncChannel.sendMessage(CMD_STOP_SOCKET_KEEPALIVE, mSlot); mNai.onStopSocketKeepalive(mSlot);
mNai.asyncChannel.sendMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, mNai.onRemoveKeepalivePacketFilter(mSlot);
mSlot);
break; break;
default: default:
Log.wtf(TAG, "Stopping keepalive with unknown type: " + mType); Log.wtf(TAG, "Stopping keepalive with unknown type: " + mType);
@@ -548,17 +542,13 @@ public class KeepaliveTracker {
} }
/** Handle keepalive events from lower layer. */ /** Handle keepalive events from lower layer. */
public void handleEventSocketKeepalive(@NonNull NetworkAgentInfo nai, public void handleEventSocketKeepalive(@NonNull NetworkAgentInfo nai, int slot, int reason) {
@NonNull Message message) {
int slot = message.arg1;
int reason = message.arg2;
KeepaliveInfo ki = null; KeepaliveInfo ki = null;
try { try {
ki = mKeepalives.get(nai).get(slot); ki = mKeepalives.get(nai).get(slot);
} catch(NullPointerException e) {} } catch(NullPointerException e) {}
if (ki == null) { if (ki == null) {
Log.e(TAG, "Event " + message.what + "," + slot + "," + reason Log.e(TAG, "Event " + NetworkAgent.EVENT_SOCKET_KEEPALIVE + "," + slot + "," + reason
+ " for unknown keepalive " + slot + " on " + nai.toShortString()); + " for unknown keepalive " + slot + " on " + nai.toShortString());
return; return;
} }
@@ -601,7 +591,7 @@ public class KeepaliveTracker {
ki.mStartedState = KeepaliveInfo.NOT_STARTED; ki.mStartedState = KeepaliveInfo.NOT_STARTED;
cleanupStoppedKeepalive(nai, slot); cleanupStoppedKeepalive(nai, slot);
} else { } else {
Log.wtf(TAG, "Event " + message.what + "," + slot + "," + reason Log.wtf(TAG, "Event " + NetworkAgent.EVENT_SOCKET_KEEPALIVE + "," + slot + "," + reason
+ " for keepalive in wrong state: " + ki.toString()); + " for keepalive in wrong state: " + ki.toString());
} }
} }

View File

@@ -27,25 +27,35 @@ import android.net.IDnsResolver;
import android.net.INetd; import android.net.INetd;
import android.net.INetworkMonitor; import android.net.INetworkMonitor;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.net.NattKeepalivePacketData;
import android.net.Network; import android.net.Network;
import android.net.NetworkAgent;
import android.net.NetworkAgentConfig; import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.NetworkMonitorManager; import android.net.NetworkMonitorManager;
import android.net.NetworkRequest; import android.net.NetworkRequest;
import android.net.NetworkState; import android.net.NetworkState;
import android.net.TcpKeepalivePacketData;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.INetworkManagementService; import android.os.INetworkManagementService;
import android.os.Messenger; import android.os.RemoteException;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log; import android.util.Log;
import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import com.android.internal.util.AsyncChannel; import com.android.connectivity.aidl.INetworkAgent;
import com.android.connectivity.aidl.INetworkAgentRegistry;
import com.android.internal.util.WakeupMessage; import com.android.internal.util.WakeupMessage;
import com.android.server.ConnectivityService; import com.android.server.ConnectivityService;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
@@ -221,6 +231,31 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
*/ */
public static final int EVENT_NETWORK_LINGER_COMPLETE = 1001; public static final int EVENT_NETWORK_LINGER_COMPLETE = 1001;
/**
* Inform ConnectivityService that the agent is half-connected.
* arg1 = ARG_AGENT_SUCCESS or ARG_AGENT_FAILURE
* obj = NetworkAgentInfo
* @hide
*/
public static final int EVENT_AGENT_REGISTERED = 1002;
/**
* Inform ConnectivityService that the agent was disconnected.
* obj = NetworkAgentInfo
* @hide
*/
public static final int EVENT_AGENT_DISCONNECTED = 1003;
/**
* Argument for EVENT_AGENT_HALF_CONNECTED indicating failure.
*/
public static final int ARG_AGENT_FAILURE = 0;
/**
* Argument for EVENT_AGENT_HALF_CONNECTED indicating success.
*/
public static final int ARG_AGENT_SUCCESS = 1;
// All linger timers for this network, sorted by expiry time. A linger timer is added whenever // All linger timers for this network, sorted by expiry time. A linger timer is added whenever
// a request is moved to a network with a better score, regardless of whether the network is or // a request is moved to a network with a better score, regardless of whether the network is or
// was lingering or not. // was lingering or not.
@@ -262,8 +297,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
// report is generated. Once non-null, it will never be null again. // report is generated. Once non-null, it will never be null again.
@Nullable private ConnectivityReport mConnectivityReport; @Nullable private ConnectivityReport mConnectivityReport;
public final Messenger messenger; public final INetworkAgent networkAgent;
public final AsyncChannel asyncChannel; // Only accessed from ConnectivityService handler thread
private final AgentDeathMonitor mDeathMonitor = new AgentDeathMonitor();
public final int factorySerialNumber; public final int factorySerialNumber;
@@ -279,13 +315,12 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
private final Context mContext; private final Context mContext;
private final Handler mHandler; private final Handler mHandler;
public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info, public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info,
LinkProperties lp, NetworkCapabilities nc, int score, Context context, LinkProperties lp, NetworkCapabilities nc, int score, Context context,
Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd, Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber, IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber,
int creatorUid) { int creatorUid) {
this.messenger = messenger; networkAgent = na;
asyncChannel = ac;
network = net; network = net;
networkInfo = info; networkInfo = info;
linkProperties = lp; linkProperties = lp;
@@ -300,6 +335,249 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
this.creatorUid = creatorUid; this.creatorUid = creatorUid;
} }
private class AgentDeathMonitor implements IBinder.DeathRecipient {
@Override
public void binderDied() {
notifyDisconnected();
}
}
/**
* Notify the NetworkAgent that it was registered, and should be unregistered if it dies.
*
* Must be called from the ConnectivityService handler thread. A NetworkAgent can only be
* registered once.
*/
public void notifyRegistered() {
try {
networkAgent.asBinder().linkToDeath(mDeathMonitor, 0);
networkAgent.onRegistered(new NetworkAgentMessageHandler(mHandler));
} catch (RemoteException e) {
Log.e(TAG, "Error registering NetworkAgent", e);
maybeUnlinkDeathMonitor();
mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_FAILURE, 0, this)
.sendToTarget();
return;
}
mHandler.obtainMessage(EVENT_AGENT_REGISTERED, ARG_AGENT_SUCCESS, 0, this).sendToTarget();
}
/**
* Disconnect the NetworkAgent. Must be called from the ConnectivityService handler thread.
*/
public void disconnect() {
try {
networkAgent.onDisconnected();
} catch (RemoteException e) {
Log.i(TAG, "Error disconnecting NetworkAgent", e);
// Fall through: it's fine if the remote has died
}
notifyDisconnected();
maybeUnlinkDeathMonitor();
}
private void maybeUnlinkDeathMonitor() {
try {
networkAgent.asBinder().unlinkToDeath(mDeathMonitor, 0);
} catch (NoSuchElementException e) {
// Was not linked: ignore
}
}
private void notifyDisconnected() {
// Note this may be called multiple times if ConnectivityService disconnects while the
// NetworkAgent also dies. ConnectivityService ignores disconnects of already disconnected
// agents.
mHandler.obtainMessage(EVENT_AGENT_DISCONNECTED, this).sendToTarget();
}
/**
* Notify the NetworkAgent that bandwidth update was requested.
*/
public void onBandwidthUpdateRequested() {
try {
networkAgent.onBandwidthUpdateRequested();
} catch (RemoteException e) {
Log.e(TAG, "Error sending bandwidth update request event", e);
}
}
/**
* Notify the NetworkAgent that validation status has changed.
*/
public void onValidationStatusChanged(int validationStatus, @Nullable String captivePortalUrl) {
try {
networkAgent.onValidationStatusChanged(validationStatus, captivePortalUrl);
} catch (RemoteException e) {
Log.e(TAG, "Error sending validation status change event", e);
}
}
/**
* Notify the NetworkAgent that the acceptUnvalidated setting should be saved.
*/
public void onSaveAcceptUnvalidated(boolean acceptUnvalidated) {
try {
networkAgent.onSaveAcceptUnvalidated(acceptUnvalidated);
} catch (RemoteException e) {
Log.e(TAG, "Error sending accept unvalidated event", e);
}
}
/**
* Notify the NetworkAgent that NATT socket keepalive should be started.
*/
public void onStartNattSocketKeepalive(int slot, int intervalDurationMs,
@NonNull NattKeepalivePacketData packetData) {
try {
networkAgent.onStartNattSocketKeepalive(slot, intervalDurationMs, packetData);
} catch (RemoteException e) {
Log.e(TAG, "Error sending NATT socket keepalive start event", e);
}
}
/**
* Notify the NetworkAgent that TCP socket keepalive should be started.
*/
public void onStartTcpSocketKeepalive(int slot, int intervalDurationMs,
@NonNull TcpKeepalivePacketData packetData) {
try {
networkAgent.onStartTcpSocketKeepalive(slot, intervalDurationMs, packetData);
} catch (RemoteException e) {
Log.e(TAG, "Error sending TCP socket keepalive start event", e);
}
}
/**
* Notify the NetworkAgent that socket keepalive should be stopped.
*/
public void onStopSocketKeepalive(int slot) {
try {
networkAgent.onStopSocketKeepalive(slot);
} catch (RemoteException e) {
Log.e(TAG, "Error sending TCP socket keepalive stop event", e);
}
}
/**
* Notify the NetworkAgent that signal strength thresholds should be updated.
*/
public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
try {
networkAgent.onSignalStrengthThresholdsUpdated(thresholds);
} catch (RemoteException e) {
Log.e(TAG, "Error sending signal strength thresholds event", e);
}
}
/**
* Notify the NetworkAgent that automatic reconnect should be prevented.
*/
public void onPreventAutomaticReconnect() {
try {
networkAgent.onPreventAutomaticReconnect();
} catch (RemoteException e) {
Log.e(TAG, "Error sending prevent automatic reconnect event", e);
}
}
/**
* Notify the NetworkAgent that a NATT keepalive packet filter should be added.
*/
public void onAddNattKeepalivePacketFilter(int slot,
@NonNull NattKeepalivePacketData packetData) {
try {
networkAgent.onAddNattKeepalivePacketFilter(slot, packetData);
} catch (RemoteException e) {
Log.e(TAG, "Error sending add NATT keepalive packet filter event", e);
}
}
/**
* Notify the NetworkAgent that a TCP keepalive packet filter should be added.
*/
public void onAddTcpKeepalivePacketFilter(int slot,
@NonNull TcpKeepalivePacketData packetData) {
try {
networkAgent.onAddTcpKeepalivePacketFilter(slot, packetData);
} catch (RemoteException e) {
Log.e(TAG, "Error sending add TCP keepalive packet filter event", e);
}
}
/**
* Notify the NetworkAgent that a keepalive packet filter should be removed.
*/
public void onRemoveKeepalivePacketFilter(int slot) {
try {
networkAgent.onRemoveKeepalivePacketFilter(slot);
} catch (RemoteException e) {
Log.e(TAG, "Error sending remove keepalive packet filter event", e);
}
}
// TODO: consider moving out of NetworkAgentInfo into its own class
private class NetworkAgentMessageHandler extends INetworkAgentRegistry.Stub {
private final Handler mHandler;
private NetworkAgentMessageHandler(Handler handler) {
mHandler = handler;
}
@Override
public void sendNetworkCapabilities(NetworkCapabilities nc) {
mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED,
new Pair<>(NetworkAgentInfo.this, nc)).sendToTarget();
}
@Override
public void sendLinkProperties(LinkProperties lp) {
mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_PROPERTIES_CHANGED,
new Pair<>(NetworkAgentInfo.this, lp)).sendToTarget();
}
@Override
public void sendNetworkInfo(NetworkInfo info) {
mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_INFO_CHANGED,
new Pair<>(NetworkAgentInfo.this, info)).sendToTarget();
}
@Override
public void sendScore(int score) {
mHandler.obtainMessage(NetworkAgent.EVENT_NETWORK_SCORE_CHANGED, score, 0,
new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
}
@Override
public void sendExplicitlySelected(boolean explicitlySelected, boolean acceptPartial) {
mHandler.obtainMessage(NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED,
explicitlySelected ? 1 : 0, acceptPartial ? 1 : 0,
new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
}
@Override
public void sendSocketKeepaliveEvent(int slot, int reason) {
mHandler.obtainMessage(NetworkAgent.EVENT_SOCKET_KEEPALIVE,
slot, reason, new Pair<>(NetworkAgentInfo.this, null)).sendToTarget();
}
@Override
public void sendUnderlyingNetworks(@Nullable List<Network> networks) {
final Bundle args = new Bundle();
if (networks instanceof ArrayList<?>) {
args.putParcelableArrayList(NetworkAgent.UNDERLYING_NETWORKS_KEY,
(ArrayList<Network>) networks);
} else {
args.putParcelableArrayList(NetworkAgent.UNDERLYING_NETWORKS_KEY,
networks == null ? null : new ArrayList<>(networks));
}
mHandler.obtainMessage(NetworkAgent.EVENT_UNDERLYING_NETWORKS_CHANGED,
new Pair<>(NetworkAgentInfo.this, args)).sendToTarget();
}
}
/** /**
* Inform NetworkAgentInfo that a new NetworkMonitor was created. * Inform NetworkAgentInfo that a new NetworkMonitor was created.
*/ */

View File

@@ -7810,8 +7810,7 @@ public class ConnectivityServiceTest {
@Test @Test
public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception { public void testCheckConnectivityDiagnosticsPermissionsNetworkStack() throws Exception {
final NetworkAgentInfo naiWithoutUid = final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo( new NetworkAgentInfo(null, null, null, null, new NetworkCapabilities(), 0,
null, null, null, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
mServiceContext.setPermission( mServiceContext.setPermission(
@@ -7826,8 +7825,7 @@ public class ConnectivityServiceTest {
@Test @Test
public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception { public void testCheckConnectivityDiagnosticsPermissionsWrongUidPackageName() throws Exception {
final NetworkAgentInfo naiWithoutUid = final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo( new NetworkAgentInfo(null, null, null, null, new NetworkCapabilities(), 0,
null, null, null, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
@@ -7842,8 +7840,7 @@ public class ConnectivityServiceTest {
@Test @Test
public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception { public void testCheckConnectivityDiagnosticsPermissionsNoLocationPermission() throws Exception {
final NetworkAgentInfo naiWithoutUid = final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo( new NetworkAgentInfo(null, null, null, null, new NetworkCapabilities(), 0,
null, null, null, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED); mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
@@ -7859,8 +7856,7 @@ public class ConnectivityServiceTest {
public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception { public void testCheckConnectivityDiagnosticsPermissionsActiveVpn() throws Exception {
final Network network = new Network(NET_ID); final Network network = new Network(NET_ID);
final NetworkAgentInfo naiWithoutUid = final NetworkAgentInfo naiWithoutUid =
new NetworkAgentInfo( new NetworkAgentInfo(null, network, null, null, new NetworkCapabilities(), 0,
null, null, network, null, null, new NetworkCapabilities(), 0,
mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID); mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
@@ -7894,8 +7890,7 @@ public class ConnectivityServiceTest {
final NetworkCapabilities nc = new NetworkCapabilities(); final NetworkCapabilities nc = new NetworkCapabilities();
nc.setAdministratorUids(new int[] {Process.myUid()}); nc.setAdministratorUids(new int[] {Process.myUid()});
final NetworkAgentInfo naiWithUid = final NetworkAgentInfo naiWithUid =
new NetworkAgentInfo( new NetworkAgentInfo(null, null, null, null, nc, 0, mServiceContext, null, null,
null, null, null, null, null, nc, 0, mServiceContext, null, null,
mService, null, null, null, 0, INVALID_UID); mService, null, null, null, 0, INVALID_UID);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
@@ -7914,8 +7909,7 @@ public class ConnectivityServiceTest {
nc.setOwnerUid(Process.myUid()); nc.setOwnerUid(Process.myUid());
nc.setAdministratorUids(new int[] {Process.myUid()}); nc.setAdministratorUids(new int[] {Process.myUid()});
final NetworkAgentInfo naiWithUid = final NetworkAgentInfo naiWithUid =
new NetworkAgentInfo( new NetworkAgentInfo(null, null, null, null, nc, 0, mServiceContext, null, null,
null, null, null, null, null, nc, 0, mServiceContext, null, null,
mService, null, null, null, 0, INVALID_UID); mService, null, null, null, 0, INVALID_UID);
setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION, setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,

View File

@@ -353,7 +353,7 @@ public class LingerMonitorTest {
NetworkCapabilities caps = new NetworkCapabilities(); NetworkCapabilities caps = new NetworkCapabilities();
caps.addCapability(0); caps.addCapability(0);
caps.addTransportType(transport); caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null, NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info, null,
caps, 50, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS, caps, 50, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
NetworkProvider.ID_NONE, Binder.getCallingUid()); NetworkProvider.ID_NONE, Binder.getCallingUid());
nai.everValidated = true; nai.everValidated = true;