Merge "Update Settings UI for IKEv2/IPsec VPNs"

This commit is contained in:
Benedict Wong
2020-02-19 07:39:41 +00:00
committed by Gerrit Code Review
2 changed files with 133 additions and 47 deletions

View File

@@ -65,7 +65,7 @@
android:hint="@string/vpn_not_used"/>
</LinearLayout>
<LinearLayout android:id="@+id/ipsec_psk"
<LinearLayout android:id="@+id/options_ipsec_identity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -75,7 +75,13 @@
android:labelFor="@+id/ipsec_identifier"/>
<EditText style="@style/vpn_value" android:id="@+id/ipsec_identifier"
android:hint="@string/vpn_not_used"/>
</LinearLayout>
<LinearLayout android:id="@+id/ipsec_psk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<TextView style="@style/vpn_label"
android:text="@string/vpn_ipsec_secret"
android:labelFor="@+id/ipsec_secret"/>
@@ -123,23 +129,28 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<TextView style="@style/vpn_label"
android:text="@string/vpn_search_domains"
android:labelFor="@+id/search_domains"/>
<EditText style="@style/vpn_value" android:id="@+id/search_domains"
android:hint="@string/vpn_not_used"/>
<LinearLayout android:id="@+id/network_options"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView style="@style/vpn_label"
android:text="@string/vpn_search_domains"
android:labelFor="@+id/search_domains"/>
<EditText style="@style/vpn_value" android:id="@+id/search_domains"
android:hint="@string/vpn_not_used"/>
<TextView style="@style/vpn_label"
android:text="@string/vpn_dns_servers"
android:labelFor="@+id/dns_servers"/>
<EditText style="@style/vpn_value" android:id="@+id/dns_servers"
android:hint="@string/vpn_not_used"/>
<TextView style="@style/vpn_label"
android:text="@string/vpn_dns_servers"
android:labelFor="@+id/dns_servers"/>
<EditText style="@style/vpn_value" android:id="@+id/dns_servers"
android:hint="@string/vpn_not_used"/>
<TextView style="@style/vpn_label"
android:text="@string/vpn_routes"
android:labelFor="@+id/routes"/>
<EditText style="@style/vpn_value" android:id="@+id/routes"
android:hint="@string/vpn_not_used"/>
<TextView style="@style/vpn_label"
android:text="@string/vpn_routes"
android:labelFor="@+id/routes"/>
<EditText style="@style/vpn_value" android:id="@+id/routes"
android:hint="@string/vpn_not_used"/>
</LinearLayout>
<TextView android:id="@+id/vpn_proxy_settings_title"
style="@style/vpn_label"
@@ -182,11 +193,10 @@
</LinearLayout>
</LinearLayout>
<LinearLayout android:id="@+id/login"
<LinearLayout android:id="@+id/userpass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:animateLayoutChanges="true">
android:orientation="vertical">
<TextView style="@style/vpn_label"
android:text="@string/vpn_username"
@@ -202,6 +212,13 @@
<CheckBox style="@style/vpn_value" android:id="@+id/save_login"
android:singleLine="false"
android:text="@string/vpn_save_login"/>
</LinearLayout>
<LinearLayout android:id="@+id/connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:animateLayoutChanges="true">
<CheckBox style="@style/vpn_value" android:id="@+id/always_on_vpn"
android:singleLine="false"
android:text="@string/vpn_menu_lockdown"/>

View File

@@ -16,6 +16,8 @@
package com.android.settings.vpn2;
import static com.android.internal.net.VpnProfile.isLegacyType;
import android.content.Context;
import android.content.DialogInterface;
import android.net.Proxy;
@@ -191,12 +193,7 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
// Hide 'save login' when we are editing.
mSaveLogin.setVisibility(View.GONE);
// Switch to advanced view immediately if any advanced options are on
if (!mProfile.searchDomains.isEmpty() || !mProfile.dnsServers.isEmpty() ||
!mProfile.routes.isEmpty() || (mProfile.proxy != null &&
(!mProfile.proxy.getHost().isEmpty() || mProfile.proxy.getPort() != 0))) {
showAdvancedOptions();
}
configureAdvancedOptionsVisibility();
// Create a button to forget the profile if it has already been saved..
if (mExists) {
@@ -210,6 +207,8 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
} else {
setTitle(context.getString(R.string.vpn_connect_to, mProfile.name));
setUsernamePasswordVisibility(mProfile.type);
// Create a button to connect the network.
setButton(DialogInterface.BUTTON_POSITIVE,
context.getString(R.string.vpn_connect), mListener);
@@ -236,9 +235,7 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
// Visibility isn't restored by super.onRestoreInstanceState, so re-show the advanced
// options here if they were already revealed or set.
if (mShowOptions.isChecked()) {
showAdvancedOptions();
}
configureAdvancedOptionsVisibility();
}
@Override
@@ -257,7 +254,7 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
@Override
public void onClick(View view) {
if (view == mShowOptions) {
showAdvancedOptions();
configureAdvancedOptionsVisibility();
}
}
@@ -308,11 +305,11 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
mAlwaysOnVpn.setEnabled(false);
if (!profile.isTypeValidForLockdown()) {
mAlwaysOnInvalidReason.setText(R.string.vpn_always_on_invalid_reason_type);
} else if (!profile.isServerAddressNumeric()) {
} else if (isLegacyType(profile.type) && !profile.isServerAddressNumeric()) {
mAlwaysOnInvalidReason.setText(R.string.vpn_always_on_invalid_reason_server);
} else if (!profile.hasDns()) {
} else if (isLegacyType(profile.type) && !profile.hasDns()) {
mAlwaysOnInvalidReason.setText(R.string.vpn_always_on_invalid_reason_no_dns);
} else if (!profile.areDnsAddressesNumeric()) {
} else if (isLegacyType(profile.type) && !profile.areDnsAddressesNumeric()) {
mAlwaysOnInvalidReason.setText(R.string.vpn_always_on_invalid_reason_dns);
} else {
mAlwaysOnInvalidReason.setText(R.string.vpn_always_on_invalid_reason_other);
@@ -345,9 +342,26 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
mView.findViewById(R.id.vpn_proxy_fields).setVisibility(visible);
}
private void showAdvancedOptions() {
mView.findViewById(R.id.options).setVisibility(View.VISIBLE);
mShowOptions.setVisibility(View.GONE);
private boolean hasAdvancedOptionsEnabled() {
return mSearchDomains.getText().length() > 0 || mDnsServers.getText().length() > 0 ||
mRoutes.getText().length() > 0 || mProxyHost.getText().length() > 0
|| mProxyPort.getText().length() > 0;
}
private void configureAdvancedOptionsVisibility() {
if (mShowOptions.isChecked() || hasAdvancedOptionsEnabled()) {
mView.findViewById(R.id.options).setVisibility(View.VISIBLE);
mShowOptions.setVisibility(View.GONE);
// Configure networking option visibility
// TODO(b/149070123): Add ability for platform VPNs to support DNS & routes
final int visibility =
isLegacyType(mType.getSelectedItemPosition()) ? View.VISIBLE : View.GONE;
mView.findViewById(R.id.network_options).setVisibility(visibility);
} else {
mView.findViewById(R.id.options).setVisibility(View.GONE);
mShowOptions.setVisibility(View.VISIBLE);
}
}
private void changeType(int type) {
@@ -357,6 +371,14 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
mView.findViewById(R.id.ipsec_psk).setVisibility(View.GONE);
mView.findViewById(R.id.ipsec_user).setVisibility(View.GONE);
mView.findViewById(R.id.ipsec_peer).setVisibility(View.GONE);
mView.findViewById(R.id.options_ipsec_identity).setVisibility(View.GONE);
setUsernamePasswordVisibility(type);
// Always enable identity for IKEv2/IPsec profiles.
if (!isLegacyType(type)) {
mView.findViewById(R.id.options_ipsec_identity).setVisibility(View.VISIBLE);
}
// Then, unhide type-specific fields.
switch (type) {
@@ -367,32 +389,50 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
case VpnProfile.TYPE_L2TP_IPSEC_PSK:
mView.findViewById(R.id.l2tp).setVisibility(View.VISIBLE);
// fall through
case VpnProfile.TYPE_IKEV2_IPSEC_PSK: // fall through
case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
mView.findViewById(R.id.ipsec_psk).setVisibility(View.VISIBLE);
mView.findViewById(R.id.options_ipsec_identity).setVisibility(View.VISIBLE);
break;
case VpnProfile.TYPE_L2TP_IPSEC_RSA:
mView.findViewById(R.id.l2tp).setVisibility(View.VISIBLE);
// fall through
case VpnProfile.TYPE_IKEV2_IPSEC_RSA: // fall through
case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
mView.findViewById(R.id.ipsec_user).setVisibility(View.VISIBLE);
// fall through
case VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS: // fall through
case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
mView.findViewById(R.id.ipsec_peer).setVisibility(View.VISIBLE);
break;
}
configureAdvancedOptionsVisibility();
}
private boolean validate(boolean editing) {
if (mAlwaysOnVpn.isChecked() && !getProfile().isValidLockdownProfile()) {
return false;
}
if (!editing) {
final int type = mType.getSelectedItemPosition();
if (!editing && requiresUsernamePassword(type)) {
return mUsername.getText().length() != 0 && mPassword.getText().length() != 0;
}
if (mName.getText().length() == 0 || mServer.getText().length() == 0 ||
!validateAddresses(mDnsServers.getText().toString(), false) ||
!validateAddresses(mRoutes.getText().toString(), true)) {
if (mName.getText().length() == 0 || mServer.getText().length() == 0) {
return false;
}
// TODO(b/149070123): Add ability for platform VPNs to support DNS & routes
if (isLegacyType(mProfile.type)
&& (!validateAddresses(mDnsServers.getText().toString(), false)
|| !validateAddresses(mRoutes.getText().toString(), true))) {
return false;
}
// All IKEv2 methods require an identifier
if (!isLegacyType(mProfile.type) && mIpsecIdentifier.getText().length() == 0) {
return false;
}
@@ -400,16 +440,19 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
return false;
}
switch (mType.getSelectedItemPosition()) {
case VpnProfile.TYPE_PPTP:
case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
switch (type) {
case VpnProfile.TYPE_PPTP: // fall through
case VpnProfile.TYPE_IPSEC_HYBRID_RSA: // fall through
case VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS:
return true;
case VpnProfile.TYPE_L2TP_IPSEC_PSK:
case VpnProfile.TYPE_IKEV2_IPSEC_PSK: // fall through
case VpnProfile.TYPE_L2TP_IPSEC_PSK: // fall through
case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
return mIpsecSecret.getText().length() != 0;
case VpnProfile.TYPE_L2TP_IPSEC_RSA:
case VpnProfile.TYPE_IKEV2_IPSEC_RSA: // fall through
case VpnProfile.TYPE_L2TP_IPSEC_RSA: // fall through
case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
return mIpsecUserCert.getSelectedItemPosition() != 0;
}
@@ -470,6 +513,21 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
}
}
private void setUsernamePasswordVisibility(int type) {
mView.findViewById(R.id.userpass).setVisibility(
requiresUsernamePassword(type) ? View.VISIBLE : View.GONE);
}
private boolean requiresUsernamePassword(int type) {
switch (type) {
case VpnProfile.TYPE_IKEV2_IPSEC_RSA: // fall through
case VpnProfile.TYPE_IKEV2_IPSEC_PSK:
return false;
default:
return true;
}
}
boolean isEditing() {
return mEditing;
}
@@ -486,9 +544,17 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
profile.server = mServer.getText().toString().trim();
profile.username = mUsername.getText().toString();
profile.password = mPassword.getText().toString();
profile.searchDomains = mSearchDomains.getText().toString().trim();
profile.dnsServers = mDnsServers.getText().toString().trim();
profile.routes = mRoutes.getText().toString().trim();
// Save fields based on VPN type.
if (isLegacyType(profile.type)) {
// TODO(b/149070123): Add ability for platform VPNs to support DNS & routes
profile.searchDomains = mSearchDomains.getText().toString().trim();
profile.dnsServers = mDnsServers.getText().toString().trim();
profile.routes = mRoutes.getText().toString().trim();
} else {
profile.ipsecIdentifier = mIpsecIdentifier.getText().toString();
}
if (hasProxy()) {
String proxyHost = mProxyHost.getText().toString().trim();
String proxyPort = mProxyPort.getText().toString().trim();
@@ -508,6 +574,7 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
case VpnProfile.TYPE_L2TP_IPSEC_PSK:
profile.l2tpSecret = mL2tpSecret.getText().toString();
// fall through
case VpnProfile.TYPE_IKEV2_IPSEC_PSK: // fall through
case VpnProfile.TYPE_IPSEC_XAUTH_PSK:
profile.ipsecIdentifier = mIpsecIdentifier.getText().toString();
profile.ipsecSecret = mIpsecSecret.getText().toString();
@@ -516,11 +583,13 @@ class ConfigDialog extends AlertDialog implements TextWatcher,
case VpnProfile.TYPE_L2TP_IPSEC_RSA:
profile.l2tpSecret = mL2tpSecret.getText().toString();
// fall through
case VpnProfile.TYPE_IKEV2_IPSEC_RSA: // fall through
case VpnProfile.TYPE_IPSEC_XAUTH_RSA:
if (mIpsecUserCert.getSelectedItemPosition() != 0) {
profile.ipsecUserCert = (String) mIpsecUserCert.getSelectedItem();
}
// fall through
case VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS: // fall through
case VpnProfile.TYPE_IPSEC_HYBRID_RSA:
if (mIpsecCaCert.getSelectedItemPosition() != 0) {
profile.ipsecCaCert = (String) mIpsecCaCert.getSelectedItem();