Loading res/layout/vpn_dialog.xml +17 −5 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ --> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" Loading Loading @@ -96,15 +96,27 @@ android:prompt="@string/vpn_ipsec_ca_cert" /> </LinearLayout> <CheckBox style="@style/vpn_value" android:id="@+id/show_options" android:singleLine="false" android:text="@string/vpn_show_options"/> </LinearLayout> <LinearLayout android:id="@+id/options" 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_search_domains"/> <EditText style="@style/vpn_value" android:id="@+id/search_domains" android:hint="@string/vpn_not_used"/> <!-- Not sure if we have time to make it. --> <TextView style="@style/vpn_label" android:text="@string/vpn_routes" android:visibility="gone"/> <TextView style="@style/vpn_label" android:text="@string/vpn_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"/> <EditText style="@style/vpn_value" android:id="@+id/routes" android:visibility="gone"/> android:hint="@string/vpn_not_used"/> </LinearLayout> <LinearLayout android:id="@+id/login" Loading res/values/strings.xml +6 −3 Original line number Diff line number Diff line Loading @@ -3492,18 +3492,21 @@ found in the list of installed applications.</string> <string name="vpn_ipsec_user_cert">IPSec user certificate</string> <!-- Selection label for the IPSec CA certificate of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_ipsec_ca_cert">IPSec CA certificate</string> <!-- Checkbox label to show advanced options of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_show_options">Show advanced options</string> <!-- Input label for the DNS search domains of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_search_domains">DNS search domains</string> <!-- Input label for the DNS servers of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_dns_servers">DNS servers (e.g. 8.8.8.8)</string> <!-- Input label for the forwarding routes of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_routes">Forwarding routes</string> <string name="vpn_routes">Forwarding routes (e.g. 10.0.0.0/8)</string> <!-- Input label for the username of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_username">Username</string> <!-- Input label for the password of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_password">Password</string> <!-- Checkbox label to save the username and the password for a VPN network. [CHAR LIMIT=40] --> <string name="vpn_save_login">Save account information</string> <!-- Hint for not filling an optional field in a VPN configuration. [CHAR LIMIT=40] --> <!-- Hint for not using an optional feature of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_not_used">(not used)</string> <!-- Option to not use a CA certificate to verify the VPN server. [CHAR LIMIT=40] --> <string name="vpn_no_ca_cert">(do not verify server)</string> Loading res/values/styles.xml +2 −3 Original line number Diff line number Diff line Loading @@ -143,15 +143,14 @@ <style name="vpn_label"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textSize">16sp</item> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> </style> <style name="vpn_value"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textSize">18sp</item> <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> <item name="android:singleLine">true</item> <item name="android:paddingBottom">1mm</item> </style> <style name="InputMethodPreferenceStyle"> Loading src/com/android/settings/vpn2/VpnDialog.java +60 −3 Original line number Diff line number Diff line Loading @@ -27,15 +27,18 @@ import android.security.KeyStore; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.Spinner; import android.widget.TextView; class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListener { import java.net.InetAddress; class VpnDialog extends AlertDialog implements TextWatcher, View.OnClickListener, AdapterView.OnItemSelectedListener { private final KeyStore mKeyStore = KeyStore.getInstance(); private final DialogInterface.OnClickListener mListener; private final VpnProfile mProfile; Loading @@ -50,6 +53,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen private TextView mUsername; private TextView mPassword; private TextView mSearchDomains; private TextView mDnsServers; private TextView mRoutes; private CheckBox mMppe; private TextView mL2tpSecret; Loading Loading @@ -82,6 +86,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen mUsername = (TextView) mView.findViewById(R.id.username); mPassword = (TextView) mView.findViewById(R.id.password); mSearchDomains = (TextView) mView.findViewById(R.id.search_domains); mDnsServers = (TextView) mView.findViewById(R.id.dns_servers); mRoutes = (TextView) mView.findViewById(R.id.routes); mMppe = (CheckBox) mView.findViewById(R.id.mppe); mL2tpSecret = (TextView) mView.findViewById(R.id.l2tp_secret); Loading @@ -98,6 +103,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen mUsername.setText(mProfile.username); mPassword.setText(mProfile.password); mSearchDomains.setText(mProfile.searchDomains); mDnsServers.setText(mProfile.dnsServers); mRoutes.setText(mProfile.routes); mMppe.setChecked(mProfile.mppe); mL2tpSecret.setText(mProfile.l2tpSecret); Loading @@ -115,6 +121,8 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen mServer.addTextChangedListener(this); mUsername.addTextChangedListener(this); mPassword.addTextChangedListener(this); mDnsServers.addTextChangedListener(this); mRoutes.addTextChangedListener(this); mIpsecSecret.addTextChangedListener(this); mIpsecUserCert.setOnItemSelectedListener(this); Loading @@ -131,6 +139,15 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen // Show type-specific fields. changeType(mProfile.type); // Show advanced options directly if any of them is set. View showOptions = mView.findViewById(R.id.show_options); if (mProfile.searchDomains.isEmpty() && mProfile.dnsServers.isEmpty() && mProfile.routes.isEmpty()) { showOptions.setOnClickListener(this); } else { onClick(showOptions); } // Create a button to save the profile. setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.vpn_save), mListener); Loading @@ -155,6 +172,10 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen // Disable the action button if necessary. getButton(DialogInterface.BUTTON_POSITIVE) .setEnabled(mEditing ? valid : validate(false)); // Workaround to resize the dialog for the input method. getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); } @Override Loading @@ -170,6 +191,12 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void onClick(View showOptions) { showOptions.setVisibility(View.GONE); mView.findViewById(R.id.options).setVisibility(View.VISIBLE); } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (parent == mType) { Loading Loading @@ -221,7 +248,9 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen if (!editing) { return mUsername.getText().length() != 0 && mPassword.getText().length() != 0; } if (mName.getText().length() == 0 || mServer.getText().length() == 0) { if (mName.getText().length() == 0 || mServer.getText().length() == 0 || !validateAddresses(mDnsServers.getText().toString(), false) || !validateAddresses(mRoutes.getText().toString(), true)) { return false; } switch (mType.getSelectedItemPosition()) { Loading @@ -239,6 +268,33 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen return false; } private boolean validateAddresses(String addresses, boolean cidr) { try { for (String address : addresses.split(" ")) { if (address.isEmpty()) { continue; } // Legacy VPN currently only supports IPv4. int prefixLength = 32; if (cidr) { String[] parts = address.split("/", 2); address = parts[0]; prefixLength = Integer.parseInt(parts[1]); } byte[] bytes = InetAddress.parseNumericAddress(address).getAddress(); int integer = (bytes[3] & 0xFF) | (bytes[2] & 0xFF) << 8 | (bytes[1] & 0xFF) << 16 | (bytes[0] & 0xFF) << 24; if (bytes.length != 4 || prefixLength < 0 || prefixLength > 32 || (prefixLength < 32 && (integer << prefixLength) != 0)) { return false; } } } catch (Exception e) { return false; } return true; } private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) { Context context = getContext(); String first = (firstId == 0) ? "" : context.getString(firstId); Loading Loading @@ -279,6 +335,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen 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(); // Then, save type-specific fields. Loading src/com/android/settings/vpn2/VpnSettings.java +5 −2 Original line number Diff line number Diff line Loading @@ -108,7 +108,7 @@ public class VpnSettings extends SettingsPreferenceFragment implements Credentials.getInstance().unlock(getActivity()); } else { // We already tried, but it is still not working! getActivity().getFragmentManager().popBackStack(); finishFragment(); } mUnlocking = !mUnlocking; return; Loading Loading @@ -429,8 +429,11 @@ public class VpnSettings extends SettingsPreferenceFragment implements config.interfaze = interfaze; config.session = profile.name; config.routes = profile.routes; if (!profile.dnsServers.isEmpty()) { config.dnsServers = Arrays.asList(profile.dnsServers.split(" +")); } if (!profile.searchDomains.isEmpty()) { config.searchDomains = Arrays.asList(profile.searchDomains.split(" ")); config.searchDomains = Arrays.asList(profile.searchDomains.split(" +")); } mService.startLegacyVpn(config, racoon, mtpd); Loading Loading
res/layout/vpn_dialog.xml +17 −5 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ --> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" Loading Loading @@ -96,15 +96,27 @@ android:prompt="@string/vpn_ipsec_ca_cert" /> </LinearLayout> <CheckBox style="@style/vpn_value" android:id="@+id/show_options" android:singleLine="false" android:text="@string/vpn_show_options"/> </LinearLayout> <LinearLayout android:id="@+id/options" 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_search_domains"/> <EditText style="@style/vpn_value" android:id="@+id/search_domains" android:hint="@string/vpn_not_used"/> <!-- Not sure if we have time to make it. --> <TextView style="@style/vpn_label" android:text="@string/vpn_routes" android:visibility="gone"/> <TextView style="@style/vpn_label" android:text="@string/vpn_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"/> <EditText style="@style/vpn_value" android:id="@+id/routes" android:visibility="gone"/> android:hint="@string/vpn_not_used"/> </LinearLayout> <LinearLayout android:id="@+id/login" Loading
res/values/strings.xml +6 −3 Original line number Diff line number Diff line Loading @@ -3492,18 +3492,21 @@ found in the list of installed applications.</string> <string name="vpn_ipsec_user_cert">IPSec user certificate</string> <!-- Selection label for the IPSec CA certificate of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_ipsec_ca_cert">IPSec CA certificate</string> <!-- Checkbox label to show advanced options of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_show_options">Show advanced options</string> <!-- Input label for the DNS search domains of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_search_domains">DNS search domains</string> <!-- Input label for the DNS servers of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_dns_servers">DNS servers (e.g. 8.8.8.8)</string> <!-- Input label for the forwarding routes of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_routes">Forwarding routes</string> <string name="vpn_routes">Forwarding routes (e.g. 10.0.0.0/8)</string> <!-- Input label for the username of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_username">Username</string> <!-- Input label for the password of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_password">Password</string> <!-- Checkbox label to save the username and the password for a VPN network. [CHAR LIMIT=40] --> <string name="vpn_save_login">Save account information</string> <!-- Hint for not filling an optional field in a VPN configuration. [CHAR LIMIT=40] --> <!-- Hint for not using an optional feature of a VPN network. [CHAR LIMIT=40] --> <string name="vpn_not_used">(not used)</string> <!-- Option to not use a CA certificate to verify the VPN server. [CHAR LIMIT=40] --> <string name="vpn_no_ca_cert">(do not verify server)</string> Loading
res/values/styles.xml +2 −3 Original line number Diff line number Diff line Loading @@ -143,15 +143,14 @@ <style name="vpn_label"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textSize">16sp</item> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> </style> <style name="vpn_value"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:textSize">18sp</item> <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> <item name="android:singleLine">true</item> <item name="android:paddingBottom">1mm</item> </style> <style name="InputMethodPreferenceStyle"> Loading
src/com/android/settings/vpn2/VpnDialog.java +60 −3 Original line number Diff line number Diff line Loading @@ -27,15 +27,18 @@ import android.security.KeyStore; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.Spinner; import android.widget.TextView; class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListener { import java.net.InetAddress; class VpnDialog extends AlertDialog implements TextWatcher, View.OnClickListener, AdapterView.OnItemSelectedListener { private final KeyStore mKeyStore = KeyStore.getInstance(); private final DialogInterface.OnClickListener mListener; private final VpnProfile mProfile; Loading @@ -50,6 +53,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen private TextView mUsername; private TextView mPassword; private TextView mSearchDomains; private TextView mDnsServers; private TextView mRoutes; private CheckBox mMppe; private TextView mL2tpSecret; Loading Loading @@ -82,6 +86,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen mUsername = (TextView) mView.findViewById(R.id.username); mPassword = (TextView) mView.findViewById(R.id.password); mSearchDomains = (TextView) mView.findViewById(R.id.search_domains); mDnsServers = (TextView) mView.findViewById(R.id.dns_servers); mRoutes = (TextView) mView.findViewById(R.id.routes); mMppe = (CheckBox) mView.findViewById(R.id.mppe); mL2tpSecret = (TextView) mView.findViewById(R.id.l2tp_secret); Loading @@ -98,6 +103,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen mUsername.setText(mProfile.username); mPassword.setText(mProfile.password); mSearchDomains.setText(mProfile.searchDomains); mDnsServers.setText(mProfile.dnsServers); mRoutes.setText(mProfile.routes); mMppe.setChecked(mProfile.mppe); mL2tpSecret.setText(mProfile.l2tpSecret); Loading @@ -115,6 +121,8 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen mServer.addTextChangedListener(this); mUsername.addTextChangedListener(this); mPassword.addTextChangedListener(this); mDnsServers.addTextChangedListener(this); mRoutes.addTextChangedListener(this); mIpsecSecret.addTextChangedListener(this); mIpsecUserCert.setOnItemSelectedListener(this); Loading @@ -131,6 +139,15 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen // Show type-specific fields. changeType(mProfile.type); // Show advanced options directly if any of them is set. View showOptions = mView.findViewById(R.id.show_options); if (mProfile.searchDomains.isEmpty() && mProfile.dnsServers.isEmpty() && mProfile.routes.isEmpty()) { showOptions.setOnClickListener(this); } else { onClick(showOptions); } // Create a button to save the profile. setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.vpn_save), mListener); Loading @@ -155,6 +172,10 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen // Disable the action button if necessary. getButton(DialogInterface.BUTTON_POSITIVE) .setEnabled(mEditing ? valid : validate(false)); // Workaround to resize the dialog for the input method. getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); } @Override Loading @@ -170,6 +191,12 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void onClick(View showOptions) { showOptions.setVisibility(View.GONE); mView.findViewById(R.id.options).setVisibility(View.VISIBLE); } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (parent == mType) { Loading Loading @@ -221,7 +248,9 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen if (!editing) { return mUsername.getText().length() != 0 && mPassword.getText().length() != 0; } if (mName.getText().length() == 0 || mServer.getText().length() == 0) { if (mName.getText().length() == 0 || mServer.getText().length() == 0 || !validateAddresses(mDnsServers.getText().toString(), false) || !validateAddresses(mRoutes.getText().toString(), true)) { return false; } switch (mType.getSelectedItemPosition()) { Loading @@ -239,6 +268,33 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen return false; } private boolean validateAddresses(String addresses, boolean cidr) { try { for (String address : addresses.split(" ")) { if (address.isEmpty()) { continue; } // Legacy VPN currently only supports IPv4. int prefixLength = 32; if (cidr) { String[] parts = address.split("/", 2); address = parts[0]; prefixLength = Integer.parseInt(parts[1]); } byte[] bytes = InetAddress.parseNumericAddress(address).getAddress(); int integer = (bytes[3] & 0xFF) | (bytes[2] & 0xFF) << 8 | (bytes[1] & 0xFF) << 16 | (bytes[0] & 0xFF) << 24; if (bytes.length != 4 || prefixLength < 0 || prefixLength > 32 || (prefixLength < 32 && (integer << prefixLength) != 0)) { return false; } } } catch (Exception e) { return false; } return true; } private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) { Context context = getContext(); String first = (firstId == 0) ? "" : context.getString(firstId); Loading Loading @@ -279,6 +335,7 @@ class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListen 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(); // Then, save type-specific fields. Loading
src/com/android/settings/vpn2/VpnSettings.java +5 −2 Original line number Diff line number Diff line Loading @@ -108,7 +108,7 @@ public class VpnSettings extends SettingsPreferenceFragment implements Credentials.getInstance().unlock(getActivity()); } else { // We already tried, but it is still not working! getActivity().getFragmentManager().popBackStack(); finishFragment(); } mUnlocking = !mUnlocking; return; Loading Loading @@ -429,8 +429,11 @@ public class VpnSettings extends SettingsPreferenceFragment implements config.interfaze = interfaze; config.session = profile.name; config.routes = profile.routes; if (!profile.dnsServers.isEmpty()) { config.dnsServers = Arrays.asList(profile.dnsServers.split(" +")); } if (!profile.searchDomains.isEmpty()) { config.searchDomains = Arrays.asList(profile.searchDomains.split(" ")); config.searchDomains = Arrays.asList(profile.searchDomains.split(" +")); } mService.startLegacyVpn(config, racoon, mtpd); Loading