Merge changes I4bfaf79a,I8711187e

* changes:
  Ensure IkeV2VpnRunnerCallback is always called by the mExecutor thread
  Add equals() & hashCode() for VpnProfileState
This commit is contained in:
Lucas Lin
2022-04-27 15:34:15 +00:00
committed by Gerrit Code Review
3 changed files with 83 additions and 66 deletions

View File

@@ -24,6 +24,7 @@ import android.os.Parcelable;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
import java.util.StringJoiner; import java.util.StringJoiner;
/** /**
@@ -176,4 +177,19 @@ public final class VpnProfileState implements Parcelable {
resultJoiner.add("Lockdown: " + isLockdownEnabled()); resultJoiner.add("Lockdown: " + isLockdownEnabled());
return resultJoiner.toString(); return resultJoiner.toString();
} }
@Override
public boolean equals(@Nullable Object obj) {
if (!(obj instanceof VpnProfileState)) return false;
final VpnProfileState that = (VpnProfileState) obj;
return (getState() == that.getState()
&& Objects.equals(getSessionId(), that.getSessionId())
&& isAlwaysOn() == that.isAlwaysOn()
&& isLockdownEnabled() == that.isLockdownEnabled());
}
@Override
public int hashCode() {
return Objects.hash(getState(), getSessionId(), isAlwaysOn(), isLockdownEnabled());
}
} }

View File

@@ -2527,7 +2527,9 @@ public class Vpn {
super(TAG); super(TAG);
mProfile = profile; mProfile = profile;
mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE); mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this); // Pass mExecutor into Ikev2VpnNetworkCallback and make sure that IkeV2VpnRunnerCallback
// will be called by the mExecutor thread.
mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this, mExecutor);
mSessionKey = UUID.randomUUID().toString(); mSessionKey = UUID.randomUUID().toString();
} }
@@ -2682,16 +2684,12 @@ public class Vpn {
* <p>The Ikev2VpnRunner will unconditionally switch to the new network, killing the old IKE * <p>The Ikev2VpnRunner will unconditionally switch to the new network, killing the old IKE
* state in the process, and starting a new IkeSession instance. * state in the process, and starting a new IkeSession instance.
* *
* <p>This method is called multiple times over the lifetime of the Ikev2VpnRunner, and is * <p>This method MUST always be called on the mExecutor thread in order to ensure
* called on the ConnectivityService thread. Thus, the actual work MUST be proxied to the * consistency of the Ikev2VpnRunner fields.
* mExecutor thread in order to ensure consistency of the Ikev2VpnRunner fields.
*/ */
public void onDefaultNetworkChanged(@NonNull Network network) { public void onDefaultNetworkChanged(@NonNull Network network) {
Log.d(TAG, "Starting IKEv2/IPsec session on new network: " + network); Log.d(TAG, "Starting IKEv2/IPsec session on new network: " + network);
// Proxy to the Ikev2VpnRunner (single-thread) executor to ensure consistency in lieu
// of locking.
mExecutor.execute(() -> {
try { try {
if (!mIsRunning) { if (!mIsRunning) {
Log.d(TAG, "onDefaultNetworkChanged after exit"); Log.d(TAG, "onDefaultNetworkChanged after exit");
@@ -2748,7 +2746,6 @@ public class Vpn {
Log.i(TAG, "Setup failed for network " + network + ". Aborting", e); Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
onSessionLost(network, e); onSessionLost(network, e);
} }
});
} }
/** Marks the state as FAILED, and disconnects. */ /** Marks the state as FAILED, and disconnects. */

View File

@@ -86,6 +86,7 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
/** /**
* Utility class to build and convert IKEv2/IPsec parameters. * Utility class to build and convert IKEv2/IPsec parameters.
@@ -376,22 +377,25 @@ public class VpnIkev2Utils {
static class Ikev2VpnNetworkCallback extends NetworkCallback { static class Ikev2VpnNetworkCallback extends NetworkCallback {
private final String mTag; private final String mTag;
private final Vpn.IkeV2VpnRunnerCallback mCallback; private final Vpn.IkeV2VpnRunnerCallback mCallback;
private final ExecutorService mExecutor;
Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback) { Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback,
ExecutorService executor) {
mTag = tag; mTag = tag;
mCallback = callback; mCallback = callback;
mExecutor = executor;
} }
@Override @Override
public void onAvailable(@NonNull Network network) { public void onAvailable(@NonNull Network network) {
Log.d(mTag, "Starting IKEv2/IPsec session on new network: " + network); Log.d(mTag, "Starting IKEv2/IPsec session on new network: " + network);
mCallback.onDefaultNetworkChanged(network); mExecutor.execute(() -> mCallback.onDefaultNetworkChanged(network));
} }
@Override @Override
public void onLost(@NonNull Network network) { public void onLost(@NonNull Network network) {
Log.d(mTag, "Tearing down; lost network: " + network); Log.d(mTag, "Tearing down; lost network: " + network);
mCallback.onSessionLost(network, null); mExecutor.execute(() -> mCallback.onSessionLost(network, null));
} }
} }