Add underpinned Network parameter in SocketKeepalive.start()
Take a Network parameter to have an one-to-one mapping between keepalive and its underpinned network on the automatic keepalive. Existing design could not really tell which network should the automatic keepalive check for the TCP socket status if there are multiple automatic keepalives enabled, e.g. Bothe IWLAN and VPN on WiFi enable the automatic keepalive. The keepalive for IWLAN should check if there are any TCP sockets on the IWLAN network instead of VPN network. Bug: 259000745 Test: atest FrameworksNetTests Test: Cts in the follow up commit Change-Id: I7353f4ef43e8fdad02c4d4a0bb5f6efa7d94c1b4
This commit is contained in:
@@ -470,7 +470,7 @@ package android.net {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract class SocketKeepalive implements java.lang.AutoCloseable {
|
public abstract class SocketKeepalive implements java.lang.AutoCloseable {
|
||||||
method public final void start(@IntRange(from=0xa, to=0xe10) int, int);
|
method public final void start(@IntRange(from=0xa, to=0xe10) int, int, @NonNull android.net.Network);
|
||||||
field public static final int ERROR_NO_SUCH_SLOT = -33; // 0xffffffdf
|
field public static final int ERROR_NO_SUCH_SLOT = -33; // 0xffffffdf
|
||||||
field public static final int FLAG_AUTOMATIC_ON_OFF = 1; // 0x1
|
field public static final int FLAG_AUTOMATIC_ON_OFF = 1; // 0x1
|
||||||
field public static final int SUCCESS = 0; // 0x0
|
field public static final int SUCCESS = 0; // 0x0
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ interface IConnectivityManager
|
|||||||
|
|
||||||
void startNattKeepaliveWithFd(in Network network, in ParcelFileDescriptor pfd, int resourceId,
|
void startNattKeepaliveWithFd(in Network network, in ParcelFileDescriptor pfd, int resourceId,
|
||||||
int intervalSeconds, in ISocketKeepaliveCallback cb, String srcAddr,
|
int intervalSeconds, in ISocketKeepaliveCallback cb, String srcAddr,
|
||||||
String dstAddr, boolean automaticOnOffKeepalives);
|
String dstAddr, boolean automaticOnOffKeepalives, in Network underpinnedNetwork);
|
||||||
|
|
||||||
void startTcpKeepalive(in Network network, in ParcelFileDescriptor pfd, int intervalSeconds,
|
void startTcpKeepalive(in Network network, in ParcelFileDescriptor pfd, int intervalSeconds,
|
||||||
in ISocketKeepaliveCallback cb);
|
in ISocketKeepaliveCallback cb);
|
||||||
|
|||||||
@@ -66,10 +66,12 @@ public final class NattSocketKeepalive extends SocketKeepalive {
|
|||||||
* the supplied {@link Callback} will see a call to
|
* the supplied {@link Callback} will see a call to
|
||||||
* {@link Callback#onError(int)} with {@link #ERROR_INVALID_INTERVAL}.
|
* {@link Callback#onError(int)} with {@link #ERROR_INVALID_INTERVAL}.
|
||||||
* @param flags Flags to enable/disable available options on this keepalive.
|
* @param flags Flags to enable/disable available options on this keepalive.
|
||||||
|
* @param underpinnedNetwork The underpinned network of this keepalive.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void startImpl(int intervalSec, int flags) {
|
protected void startImpl(int intervalSec, int flags, Network underpinnedNetwork) {
|
||||||
if (0 != (flags & ~FLAG_AUTOMATIC_ON_OFF)) {
|
if (0 != (flags & ~FLAG_AUTOMATIC_ON_OFF)) {
|
||||||
throw new IllegalArgumentException("Illegal flag value for "
|
throw new IllegalArgumentException("Illegal flag value for "
|
||||||
+ this.getClass().getSimpleName() + " : " + flags);
|
+ this.getClass().getSimpleName() + " : " + flags);
|
||||||
@@ -79,7 +81,8 @@ public final class NattSocketKeepalive extends SocketKeepalive {
|
|||||||
try {
|
try {
|
||||||
mService.startNattKeepaliveWithFd(mNetwork, mPfd, mResourceId,
|
mService.startNattKeepaliveWithFd(mNetwork, mPfd, mResourceId,
|
||||||
intervalSec, mCallback, mSource.getHostAddress(),
|
intervalSec, mCallback, mSource.getHostAddress(),
|
||||||
mDestination.getHostAddress(), automaticOnOffKeepalives);
|
mDestination.getHostAddress(), automaticOnOffKeepalives,
|
||||||
|
underpinnedNetwork);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Error starting socket keepalive: ", e);
|
Log.e(TAG, "Error starting socket keepalive: ", e);
|
||||||
throw e.rethrowFromSystemServer();
|
throw e.rethrowFromSystemServer();
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ public abstract class SocketKeepalive implements AutoCloseable {
|
|||||||
*/
|
*/
|
||||||
public final void start(@IntRange(from = MIN_INTERVAL_SEC, to = MAX_INTERVAL_SEC)
|
public final void start(@IntRange(from = MIN_INTERVAL_SEC, to = MAX_INTERVAL_SEC)
|
||||||
int intervalSec) {
|
int intervalSec) {
|
||||||
startImpl(intervalSec, 0 /* flags */);
|
startImpl(intervalSec, 0 /* flags */, null /* underpinnedNetwork */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -374,16 +374,18 @@ public abstract class SocketKeepalive implements AutoCloseable {
|
|||||||
* the supplied {@link Callback} will see a call to
|
* the supplied {@link Callback} will see a call to
|
||||||
* {@link Callback#onError(int)} with {@link #ERROR_INVALID_INTERVAL}.
|
* {@link Callback#onError(int)} with {@link #ERROR_INVALID_INTERVAL}.
|
||||||
* @param flags Flags to enable/disable available options on this keepalive.
|
* @param flags Flags to enable/disable available options on this keepalive.
|
||||||
|
* @param underpinnedNetwork The underpinned network of this keepalive.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SystemApi(client = PRIVILEGED_APPS)
|
@SystemApi(client = PRIVILEGED_APPS)
|
||||||
public final void start(@IntRange(from = MIN_INTERVAL_SEC, to = MAX_INTERVAL_SEC)
|
public final void start(@IntRange(from = MIN_INTERVAL_SEC, to = MAX_INTERVAL_SEC)
|
||||||
int intervalSec, @StartFlags int flags) {
|
int intervalSec, @StartFlags int flags, @NonNull Network underpinnedNetwork) {
|
||||||
startImpl(intervalSec, flags);
|
startImpl(intervalSec, flags, underpinnedNetwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
protected abstract void startImpl(int intervalSec, @StartFlags int flags);
|
protected abstract void startImpl(int intervalSec, @StartFlags int flags,
|
||||||
|
Network underpinnedNetwork);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests that keepalive be stopped. The application must wait for {@link Callback#onStopped}
|
* Requests that keepalive be stopped. The application must wait for {@link Callback#onStopped}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public final class TcpSocketKeepalive extends SocketKeepalive {
|
|||||||
* acknowledgement.
|
* acknowledgement.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void startImpl(int intervalSec, int flags) {
|
protected void startImpl(int intervalSec, int flags, Network underpinnedNetwork) {
|
||||||
if (0 != flags) {
|
if (0 != flags) {
|
||||||
throw new IllegalArgumentException("Illegal flag value for "
|
throw new IllegalArgumentException("Illegal flag value for "
|
||||||
+ this.getClass().getSimpleName() + " : " + flags);
|
+ this.getClass().getSimpleName() + " : " + flags);
|
||||||
|
|||||||
@@ -5589,13 +5589,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj);
|
mKeepaliveTracker.getKeepaliveForBinder((IBinder) msg.obj);
|
||||||
if (null == ki) return; // The callback was unregistered before the alarm fired
|
if (null == ki) return; // The callback was unregistered before the alarm fired
|
||||||
|
|
||||||
|
final Network underpinnedNetwork = ki.getUnderpinnedNetwork();
|
||||||
final Network network = ki.getNetwork();
|
final Network network = ki.getNetwork();
|
||||||
boolean networkFound = false;
|
boolean networkFound = false;
|
||||||
final ArrayList<NetworkAgentInfo> vpnsRunningOnThisNetwork = new ArrayList<>();
|
boolean underpinnedNetworkFound = false;
|
||||||
for (NetworkAgentInfo n : mNetworkAgentInfos) {
|
for (NetworkAgentInfo n : mNetworkAgentInfos) {
|
||||||
if (n.network.equals(network)) networkFound = true;
|
if (n.network.equals(network)) networkFound = true;
|
||||||
if (n.isVPN() && n.everConnected() && hasUnderlyingNetwork(n, network)) {
|
if (n.everConnected() && n.network.equals(underpinnedNetwork)) {
|
||||||
vpnsRunningOnThisNetwork.add(n);
|
underpinnedNetworkFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5603,12 +5604,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// cleaned up already. There is no point trying to resume keepalives.
|
// cleaned up already. There is no point trying to resume keepalives.
|
||||||
if (!networkFound) return;
|
if (!networkFound) return;
|
||||||
|
|
||||||
if (!vpnsRunningOnThisNetwork.isEmpty()) {
|
if (underpinnedNetworkFound) {
|
||||||
mKeepaliveTracker.handleMonitorAutomaticKeepalive(ki,
|
mKeepaliveTracker.handleMonitorAutomaticKeepalive(ki,
|
||||||
// TODO: check all the VPNs running on top of this network
|
underpinnedNetwork.netId);
|
||||||
vpnsRunningOnThisNetwork.get(0).network.netId);
|
|
||||||
} else {
|
} else {
|
||||||
// If no VPN, then make sure the keepalive is running.
|
// If no underpinned network, then make sure the keepalive is running.
|
||||||
mKeepaliveTracker.handleMaybeResumeKeepalive(ki);
|
mKeepaliveTracker.handleMaybeResumeKeepalive(ki);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -9868,21 +9868,22 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
getNetworkAgentInfoForNetwork(network), null /* fd */,
|
getNetworkAgentInfoForNetwork(network), null /* fd */,
|
||||||
intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT,
|
intervalSeconds, cb, srcAddr, srcPort, dstAddr, NattSocketKeepalive.NATT_PORT,
|
||||||
// Keep behavior of the deprecated method as it is. Set automaticOnOffKeepalives to
|
// Keep behavior of the deprecated method as it is. Set automaticOnOffKeepalives to
|
||||||
// false because there is no way and no plan to configure automaticOnOffKeepalives
|
// false and set the underpinned network to null because there is no way and no
|
||||||
// in this deprecated method.
|
// plan to configure automaticOnOffKeepalives or underpinnedNetwork in this
|
||||||
false /* automaticOnOffKeepalives */);
|
// deprecated method.
|
||||||
|
false /* automaticOnOffKeepalives */, null /* underpinnedNetwork */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId,
|
public void startNattKeepaliveWithFd(Network network, ParcelFileDescriptor pfd, int resourceId,
|
||||||
int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
|
int intervalSeconds, ISocketKeepaliveCallback cb, String srcAddr,
|
||||||
String dstAddr, boolean automaticOnOffKeepalives) {
|
String dstAddr, boolean automaticOnOffKeepalives, Network underpinnedNetwork) {
|
||||||
try {
|
try {
|
||||||
final FileDescriptor fd = pfd.getFileDescriptor();
|
final FileDescriptor fd = pfd.getFileDescriptor();
|
||||||
mKeepaliveTracker.startNattKeepalive(
|
mKeepaliveTracker.startNattKeepalive(
|
||||||
getNetworkAgentInfoForNetwork(network), fd, resourceId,
|
getNetworkAgentInfoForNetwork(network), fd, resourceId,
|
||||||
intervalSeconds, cb,
|
intervalSeconds, cb, srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT,
|
||||||
srcAddr, dstAddr, NattSocketKeepalive.NATT_PORT, automaticOnOffKeepalives);
|
automaticOnOffKeepalives, underpinnedNetwork);
|
||||||
} finally {
|
} finally {
|
||||||
// FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
|
// FileDescriptors coming from AIDL calls must be manually closed to prevent leaks.
|
||||||
// startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
|
// startNattKeepalive calls Os.dup(fd) before returning, so we can close immediately.
|
||||||
|
|||||||
@@ -196,11 +196,16 @@ public class AutomaticOnOffKeepaliveTracker {
|
|||||||
private final PendingIntent mTcpPollingAlarm;
|
private final PendingIntent mTcpPollingAlarm;
|
||||||
@AutomaticOnOffState
|
@AutomaticOnOffState
|
||||||
private int mAutomaticOnOffState;
|
private int mAutomaticOnOffState;
|
||||||
|
@Nullable
|
||||||
|
private final Network mUnderpinnedNetwork;
|
||||||
|
|
||||||
AutomaticOnOffKeepalive(@NonNull final KeepaliveTracker.KeepaliveInfo ki,
|
AutomaticOnOffKeepalive(@NonNull final KeepaliveTracker.KeepaliveInfo ki,
|
||||||
final boolean autoOnOff, @NonNull Context context) throws InvalidSocketException {
|
final boolean autoOnOff, @NonNull Context context,
|
||||||
|
@Nullable Network underpinnedNetwork)
|
||||||
|
throws InvalidSocketException {
|
||||||
this.mKi = Objects.requireNonNull(ki);
|
this.mKi = Objects.requireNonNull(ki);
|
||||||
mCallback = ki.mCallback;
|
mCallback = ki.mCallback;
|
||||||
|
mUnderpinnedNetwork = underpinnedNetwork;
|
||||||
if (autoOnOff && mDependencies.isFeatureEnabled(AUTOMATIC_ON_OFF_KEEPALIVE_VERSION)) {
|
if (autoOnOff && mDependencies.isFeatureEnabled(AUTOMATIC_ON_OFF_KEEPALIVE_VERSION)) {
|
||||||
mAutomaticOnOffState = STATE_ENABLED;
|
mAutomaticOnOffState = STATE_ENABLED;
|
||||||
if (null == ki.mFd) {
|
if (null == ki.mFd) {
|
||||||
@@ -228,6 +233,11 @@ public class AutomaticOnOffKeepaliveTracker {
|
|||||||
return mKi.getNai().network;
|
return mKi.getNai().network;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Network getUnderpinnedNetwork() {
|
||||||
|
return mUnderpinnedNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean match(Network network, int slot) {
|
public boolean match(Network network, int slot) {
|
||||||
return mKi.getNai().network().equals(network) && mKi.getSlot() == slot;
|
return mKi.getNai().network().equals(network) && mKi.getSlot() == slot;
|
||||||
}
|
}
|
||||||
@@ -475,13 +485,13 @@ public class AutomaticOnOffKeepaliveTracker {
|
|||||||
@NonNull String srcAddrString,
|
@NonNull String srcAddrString,
|
||||||
int srcPort,
|
int srcPort,
|
||||||
@NonNull String dstAddrString,
|
@NonNull String dstAddrString,
|
||||||
int dstPort, boolean automaticOnOffKeepalives) {
|
int dstPort, boolean automaticOnOffKeepalives, @Nullable Network underpinnedNetwork) {
|
||||||
final KeepaliveTracker.KeepaliveInfo ki = mKeepaliveTracker.makeNattKeepaliveInfo(nai, fd,
|
final KeepaliveTracker.KeepaliveInfo ki = mKeepaliveTracker.makeNattKeepaliveInfo(nai, fd,
|
||||||
intervalSeconds, cb, srcAddrString, srcPort, dstAddrString, dstPort);
|
intervalSeconds, cb, srcAddrString, srcPort, dstAddrString, dstPort);
|
||||||
if (null == ki) return;
|
if (null == ki) return;
|
||||||
try {
|
try {
|
||||||
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
|
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
|
||||||
automaticOnOffKeepalives, mContext);
|
automaticOnOffKeepalives, mContext, underpinnedNetwork);
|
||||||
mConnectivityServiceHandler.obtainMessage(NetworkAgent.CMD_START_SOCKET_KEEPALIVE,
|
mConnectivityServiceHandler.obtainMessage(NetworkAgent.CMD_START_SOCKET_KEEPALIVE,
|
||||||
// TODO : move ConnectivityService#encodeBool to a static lib.
|
// TODO : move ConnectivityService#encodeBool to a static lib.
|
||||||
automaticOnOffKeepalives ? 1 : 0, 0, autoKi).sendToTarget();
|
automaticOnOffKeepalives ? 1 : 0, 0, autoKi).sendToTarget();
|
||||||
@@ -504,13 +514,14 @@ public class AutomaticOnOffKeepaliveTracker {
|
|||||||
@NonNull String srcAddrString,
|
@NonNull String srcAddrString,
|
||||||
@NonNull String dstAddrString,
|
@NonNull String dstAddrString,
|
||||||
int dstPort,
|
int dstPort,
|
||||||
boolean automaticOnOffKeepalives) {
|
boolean automaticOnOffKeepalives,
|
||||||
|
@Nullable Network underpinnedNetwork) {
|
||||||
final KeepaliveTracker.KeepaliveInfo ki = mKeepaliveTracker.makeNattKeepaliveInfo(nai, fd,
|
final KeepaliveTracker.KeepaliveInfo ki = mKeepaliveTracker.makeNattKeepaliveInfo(nai, fd,
|
||||||
resourceId, intervalSeconds, cb, srcAddrString, dstAddrString, dstPort);
|
resourceId, intervalSeconds, cb, srcAddrString, dstAddrString, dstPort);
|
||||||
if (null == ki) return;
|
if (null == ki) return;
|
||||||
try {
|
try {
|
||||||
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
|
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
|
||||||
automaticOnOffKeepalives, mContext);
|
automaticOnOffKeepalives, mContext, underpinnedNetwork);
|
||||||
mConnectivityServiceHandler.obtainMessage(NetworkAgent.CMD_START_SOCKET_KEEPALIVE,
|
mConnectivityServiceHandler.obtainMessage(NetworkAgent.CMD_START_SOCKET_KEEPALIVE,
|
||||||
// TODO : move ConnectivityService#encodeBool to a static lib.
|
// TODO : move ConnectivityService#encodeBool to a static lib.
|
||||||
automaticOnOffKeepalives ? 1 : 0, 0, autoKi).sendToTarget();
|
automaticOnOffKeepalives ? 1 : 0, 0, autoKi).sendToTarget();
|
||||||
@@ -539,7 +550,8 @@ public class AutomaticOnOffKeepaliveTracker {
|
|||||||
if (null == ki) return;
|
if (null == ki) return;
|
||||||
try {
|
try {
|
||||||
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
|
final AutomaticOnOffKeepalive autoKi = new AutomaticOnOffKeepalive(ki,
|
||||||
false /* autoOnOff, tcp keepalives are never auto on/off */, mContext);
|
false /* autoOnOff, tcp keepalives are never auto on/off */,
|
||||||
|
mContext, null /* underpinnedNetwork, tcp keepalives do not refer to this */);
|
||||||
mConnectivityServiceHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, autoKi)
|
mConnectivityServiceHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, autoKi)
|
||||||
.sendToTarget();
|
.sendToTarget();
|
||||||
} catch (InvalidSocketException e) {
|
} catch (InvalidSocketException e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user