1310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh/* 2310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * Copyright (C) 2011 The Android Open Source Project 3310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * 4310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 5310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * you may not use this file except in compliance with the License. 6310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * You may obtain a copy of the License at 7310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * 8310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 9310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * 10310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 11310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 12310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * See the License for the specific language governing permissions and 14310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh * limitations under the License. 15310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh */ 16310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 17310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehpackage com.android.settings.vpn2; 18310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 19c6e84c09590ec5e4da287fba32dd53775156ae76Jeff Sharkeyimport com.android.internal.net.VpnProfile; 20310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport com.android.settings.R; 21310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 22310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.app.AlertDialog; 23310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.content.Context; 24310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.content.DialogInterface; 25310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.os.Bundle; 26310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.security.Credentials; 27310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.security.KeyStore; 28310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.text.Editable; 29310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.text.TextWatcher; 30310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.view.View; 31d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yehimport android.view.WindowManager; 32310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.widget.AdapterView; 33310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.widget.ArrayAdapter; 34310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.widget.Button; 35310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.widget.CheckBox; 36310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.widget.Spinner; 37310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yehimport android.widget.TextView; 38310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 39d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yehimport java.net.InetAddress; 40d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh 41d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yehclass VpnDialog extends AlertDialog implements TextWatcher, 42d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh View.OnClickListener, AdapterView.OnItemSelectedListener { 43310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private final KeyStore mKeyStore = KeyStore.getInstance(); 44310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private final DialogInterface.OnClickListener mListener; 45310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private final VpnProfile mProfile; 46310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 47310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private boolean mEditing; 48310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 49310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private View mView; 50310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 51310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mName; 52310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private Spinner mType; 53310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mServer; 54310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mUsername; 55310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mPassword; 562fa9eade41144094ef743cc5a3faf4f1ce7209afChia-chi Yeh private TextView mSearchDomains; 57d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh private TextView mDnsServers; 58310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mRoutes; 59310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private CheckBox mMppe; 60310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mL2tpSecret; 61310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mIpsecIdentifier; 62310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private TextView mIpsecSecret; 63310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private Spinner mIpsecUserCert; 64310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private Spinner mIpsecCaCert; 65f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh private Spinner mIpsecServerCert; 66310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private CheckBox mSaveLogin; 67310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 68310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh VpnDialog(Context context, DialogInterface.OnClickListener listener, 69310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh VpnProfile profile, boolean editing) { 70310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh super(context); 71310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mListener = listener; 72310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mProfile = profile; 73310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mEditing = editing; 74310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 75310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 76310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh @Override 77310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh protected void onCreate(Bundle savedState) { 78310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView = getLayoutInflater().inflate(R.layout.vpn_dialog, null); 79310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh setView(mView); 80310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh setInverseBackgroundForced(true); 81310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 82310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh Context context = getContext(); 83310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 84310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // First, find out all the fields. 85310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mName = (TextView) mView.findViewById(R.id.name); 86310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mType = (Spinner) mView.findViewById(R.id.type); 87310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mServer = (TextView) mView.findViewById(R.id.server); 88310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mUsername = (TextView) mView.findViewById(R.id.username); 89310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mPassword = (TextView) mView.findViewById(R.id.password); 902fa9eade41144094ef743cc5a3faf4f1ce7209afChia-chi Yeh mSearchDomains = (TextView) mView.findViewById(R.id.search_domains); 91d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh mDnsServers = (TextView) mView.findViewById(R.id.dns_servers); 92310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mRoutes = (TextView) mView.findViewById(R.id.routes); 93310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mMppe = (CheckBox) mView.findViewById(R.id.mppe); 94310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mL2tpSecret = (TextView) mView.findViewById(R.id.l2tp_secret); 95310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mIpsecIdentifier = (TextView) mView.findViewById(R.id.ipsec_identifier); 96310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mIpsecSecret = (TextView) mView.findViewById(R.id.ipsec_secret); 97310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mIpsecUserCert = (Spinner) mView.findViewById(R.id.ipsec_user_cert); 98310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mIpsecCaCert = (Spinner) mView.findViewById(R.id.ipsec_ca_cert); 99f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh mIpsecServerCert = (Spinner) mView.findViewById(R.id.ipsec_server_cert); 100310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mSaveLogin = (CheckBox) mView.findViewById(R.id.save_login); 101310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 102310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Second, copy values from the profile. 103310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mName.setText(mProfile.name); 104310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mType.setSelection(mProfile.type); 105310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mServer.setText(mProfile.server); 10694c6cd6c29cb7cc92b4f5377db78df02c769f7c1Chia-chi Yeh if (mProfile.saveLogin) { 10794c6cd6c29cb7cc92b4f5377db78df02c769f7c1Chia-chi Yeh mUsername.setText(mProfile.username); 10894c6cd6c29cb7cc92b4f5377db78df02c769f7c1Chia-chi Yeh mPassword.setText(mProfile.password); 10994c6cd6c29cb7cc92b4f5377db78df02c769f7c1Chia-chi Yeh } 1102fa9eade41144094ef743cc5a3faf4f1ce7209afChia-chi Yeh mSearchDomains.setText(mProfile.searchDomains); 111d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh mDnsServers.setText(mProfile.dnsServers); 112310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mRoutes.setText(mProfile.routes); 113310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mMppe.setChecked(mProfile.mppe); 114aa5b531b0b540488f47ad0414dc77eecbb47cd3aChia-chi Yeh mL2tpSecret.setText(mProfile.l2tpSecret); 115310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mIpsecIdentifier.setText(mProfile.ipsecIdentifier); 116aa5b531b0b540488f47ad0414dc77eecbb47cd3aChia-chi Yeh mIpsecSecret.setText(mProfile.ipsecSecret); 1172340efc9a3fb4ae7b90cf9e7b3eab8c9ff7aeec8Chia-chi Yeh loadCertificates(mIpsecUserCert, Credentials.USER_PRIVATE_KEY, 118310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 0, mProfile.ipsecUserCert); 119bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh loadCertificates(mIpsecCaCert, Credentials.CA_CERTIFICATE, 120310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh R.string.vpn_no_ca_cert, mProfile.ipsecCaCert); 121f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh loadCertificates(mIpsecServerCert, Credentials.USER_CERTIFICATE, 122f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh R.string.vpn_no_server_cert, mProfile.ipsecServerCert); 123310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mSaveLogin.setChecked(mProfile.saveLogin); 124310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 125310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Third, add listeners to required fields. 126310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mName.addTextChangedListener(this); 127310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mType.setOnItemSelectedListener(this); 128310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mServer.addTextChangedListener(this); 129310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mUsername.addTextChangedListener(this); 130310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mPassword.addTextChangedListener(this); 131d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh mDnsServers.addTextChangedListener(this); 132d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh mRoutes.addTextChangedListener(this); 133310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mIpsecSecret.addTextChangedListener(this); 134310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mIpsecUserCert.setOnItemSelectedListener(this); 135310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 136310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Forth, determine to do editing or connecting. 137310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh boolean valid = validate(true); 138310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mEditing = mEditing || !valid; 139310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 140310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh if (mEditing) { 141310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh setTitle(R.string.vpn_edit); 142310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 143310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Show common fields. 144310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.editor).setVisibility(View.VISIBLE); 145310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 146310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Show type-specific fields. 147310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh changeType(mProfile.type); 148310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 149d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh // Show advanced options directly if any of them is set. 150d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh View showOptions = mView.findViewById(R.id.show_options); 151d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh if (mProfile.searchDomains.isEmpty() && mProfile.dnsServers.isEmpty() && 152d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh mProfile.routes.isEmpty()) { 153d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh showOptions.setOnClickListener(this); 154d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } else { 155d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh onClick(showOptions); 156d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 157d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh 158310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Create a button to save the profile. 159310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh setButton(DialogInterface.BUTTON_POSITIVE, 160310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh context.getString(R.string.vpn_save), mListener); 161310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } else { 162310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh setTitle(context.getString(R.string.vpn_connect_to, mProfile.name)); 163310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 164310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Not editing, just show username and password. 165310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.login).setVisibility(View.VISIBLE); 166310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 167310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Create a button to connect the network. 168310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh setButton(DialogInterface.BUTTON_POSITIVE, 169310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh context.getString(R.string.vpn_connect), mListener); 170310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 171310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 172310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Always provide a cancel button. 173310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh setButton(DialogInterface.BUTTON_NEGATIVE, 174310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh context.getString(R.string.vpn_cancel), mListener); 175310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 176310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Let AlertDialog create everything. 177310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh super.onCreate(null); 178310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 179310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Disable the action button if necessary. 180310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh getButton(DialogInterface.BUTTON_POSITIVE) 181310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh .setEnabled(mEditing ? valid : validate(false)); 182d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh 183d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh // Workaround to resize the dialog for the input method. 184d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | 185d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 186310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 187310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 188310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh @Override 189310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh public void afterTextChanged(Editable field) { 190310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validate(mEditing)); 191310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 192310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 193310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh @Override 194310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh public void beforeTextChanged(CharSequence s, int start, int count, int after) { 195310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 196310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 197310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh @Override 198310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh public void onTextChanged(CharSequence s, int start, int before, int count) { 199310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 200310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 201310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh @Override 202d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh public void onClick(View showOptions) { 203d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh showOptions.setVisibility(View.GONE); 204d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh mView.findViewById(R.id.options).setVisibility(View.VISIBLE); 205d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 206d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh 207d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh @Override 208310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 209310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh if (parent == mType) { 210310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh changeType(position); 211310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 212bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(validate(mEditing)); 213310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 214310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 215310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh @Override 216310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh public void onNothingSelected(AdapterView<?> parent) { 217310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 218310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 219310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private void changeType(int type) { 220310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // First, hide everything. 221310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mMppe.setVisibility(View.GONE); 222310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.l2tp).setVisibility(View.GONE); 223310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.ipsec_psk).setVisibility(View.GONE); 224310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.ipsec_user).setVisibility(View.GONE); 225f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh mView.findViewById(R.id.ipsec_peer).setVisibility(View.GONE); 226310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 227310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Then, unhide type-specific fields. 228310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh switch (type) { 229310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_PPTP: 230310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mMppe.setVisibility(View.VISIBLE); 231310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh break; 2326d4334be691815cd9615b0fdebb756999a9c06a3Chia-chi Yeh 233310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_L2TP_IPSEC_PSK: 234310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.l2tp).setVisibility(View.VISIBLE); 2356d4334be691815cd9615b0fdebb756999a9c06a3Chia-chi Yeh // fall through 236310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_XAUTH_PSK: 237310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.ipsec_psk).setVisibility(View.VISIBLE); 238310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh break; 239310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 240310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_L2TP_IPSEC_RSA: 241310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh mView.findViewById(R.id.l2tp).setVisibility(View.VISIBLE); 242310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // fall through 243310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_XAUTH_RSA: 2440082d17ce7ad2f8b3601068e62eda92aa8670a0fChia-chi Yeh mView.findViewById(R.id.ipsec_user).setVisibility(View.VISIBLE); 245310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // fall through 246310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_HYBRID_RSA: 247f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh mView.findViewById(R.id.ipsec_peer).setVisibility(View.VISIBLE); 248310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh break; 249310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 250310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 251310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 252310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private boolean validate(boolean editing) { 253310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh if (!editing) { 254310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return mUsername.getText().length() != 0 && mPassword.getText().length() != 0; 255310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 256d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh if (mName.getText().length() == 0 || mServer.getText().length() == 0 || 257d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh !validateAddresses(mDnsServers.getText().toString(), false) || 258d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh !validateAddresses(mRoutes.getText().toString(), true)) { 259310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return false; 260310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 261310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh switch (mType.getSelectedItemPosition()) { 262310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_PPTP: 2636d4334be691815cd9615b0fdebb756999a9c06a3Chia-chi Yeh case VpnProfile.TYPE_IPSEC_HYBRID_RSA: 264310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return true; 265310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 266310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_L2TP_IPSEC_PSK: 267310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_XAUTH_PSK: 268310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return mIpsecSecret.getText().length() != 0; 269310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 270310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_L2TP_IPSEC_RSA: 271310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_XAUTH_RSA: 272310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return mIpsecUserCert.getSelectedItemPosition() != 0; 273310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 274310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return false; 275310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 276310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 277d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh private boolean validateAddresses(String addresses, boolean cidr) { 278d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh try { 279d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh for (String address : addresses.split(" ")) { 280d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh if (address.isEmpty()) { 281d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh continue; 282d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 283d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh // Legacy VPN currently only supports IPv4. 284d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh int prefixLength = 32; 285d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh if (cidr) { 286d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh String[] parts = address.split("/", 2); 287d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh address = parts[0]; 288d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh prefixLength = Integer.parseInt(parts[1]); 289d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 290d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh byte[] bytes = InetAddress.parseNumericAddress(address).getAddress(); 291d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh int integer = (bytes[3] & 0xFF) | (bytes[2] & 0xFF) << 8 | 292d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh (bytes[1] & 0xFF) << 16 | (bytes[0] & 0xFF) << 24; 293d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh if (bytes.length != 4 || prefixLength < 0 || prefixLength > 32 || 294d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh (prefixLength < 32 && (integer << prefixLength) != 0)) { 295d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh return false; 296d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 297d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 298d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } catch (Exception e) { 299d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh return false; 300d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 301d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh return true; 302d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh } 303d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh 304310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) { 305310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh Context context = getContext(); 306310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh String first = (firstId == 0) ? "" : context.getString(firstId); 307bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh String[] certificates = mKeyStore.saw(prefix); 308310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 309bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh if (certificates == null || certificates.length == 0) { 310bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh certificates = new String[] {first}; 311310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } else { 312bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh String[] array = new String[certificates.length + 1]; 313310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh array[0] = first; 314bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh System.arraycopy(certificates, 0, array, 1, certificates.length); 315bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh certificates = array; 316310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 317310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 318310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh ArrayAdapter<String> adapter = new ArrayAdapter<String>( 319bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh context, android.R.layout.simple_spinner_item, certificates); 320310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 321310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh spinner.setAdapter(adapter); 322310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 323bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh for (int i = 1; i < certificates.length; ++i) { 324bbb5094be6673929bcb808cdeaf748a73be4dbf0Chia-chi Yeh if (certificates[i].equals(selected)) { 325310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh spinner.setSelection(i); 326310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh break; 327310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 328310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 329310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 330310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 331310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh boolean isEditing() { 332310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return mEditing; 333310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 334310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 335310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh VpnProfile getProfile() { 336310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // First, save common fields. 337310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh VpnProfile profile = new VpnProfile(mProfile.key); 338310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh profile.name = mName.getText().toString(); 339310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh profile.type = mType.getSelectedItemPosition(); 340310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh profile.server = mServer.getText().toString().trim(); 341310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh profile.username = mUsername.getText().toString(); 342aa5b531b0b540488f47ad0414dc77eecbb47cd3aChia-chi Yeh profile.password = mPassword.getText().toString(); 3432fa9eade41144094ef743cc5a3faf4f1ce7209afChia-chi Yeh profile.searchDomains = mSearchDomains.getText().toString().trim(); 344d68dbe29bb0a6639bfd95449eb28e7d4b174a3feChia-chi Yeh profile.dnsServers = mDnsServers.getText().toString().trim(); 345310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh profile.routes = mRoutes.getText().toString().trim(); 346310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 347310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // Then, save type-specific fields. 348310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh switch (profile.type) { 349310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_PPTP: 350310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh profile.mppe = mMppe.isChecked(); 351310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh break; 3526d4334be691815cd9615b0fdebb756999a9c06a3Chia-chi Yeh 353310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_L2TP_IPSEC_PSK: 354aa5b531b0b540488f47ad0414dc77eecbb47cd3aChia-chi Yeh profile.l2tpSecret = mL2tpSecret.getText().toString(); 3556d4334be691815cd9615b0fdebb756999a9c06a3Chia-chi Yeh // fall through 356310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_XAUTH_PSK: 357413b171159cec5ad1e7b3cf4f1f842b5f2debc05Chia-chi Yeh profile.ipsecIdentifier = mIpsecIdentifier.getText().toString(); 358aa5b531b0b540488f47ad0414dc77eecbb47cd3aChia-chi Yeh profile.ipsecSecret = mIpsecSecret.getText().toString(); 359310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh break; 360310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 361310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_L2TP_IPSEC_RSA: 362aa5b531b0b540488f47ad0414dc77eecbb47cd3aChia-chi Yeh profile.l2tpSecret = mL2tpSecret.getText().toString(); 363310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // fall through 364310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_XAUTH_RSA: 3650082d17ce7ad2f8b3601068e62eda92aa8670a0fChia-chi Yeh if (mIpsecUserCert.getSelectedItemPosition() != 0) { 3660082d17ce7ad2f8b3601068e62eda92aa8670a0fChia-chi Yeh profile.ipsecUserCert = (String) mIpsecUserCert.getSelectedItem(); 367310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 368310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh // fall through 369310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh case VpnProfile.TYPE_IPSEC_HYBRID_RSA: 3700082d17ce7ad2f8b3601068e62eda92aa8670a0fChia-chi Yeh if (mIpsecCaCert.getSelectedItemPosition() != 0) { 3710082d17ce7ad2f8b3601068e62eda92aa8670a0fChia-chi Yeh profile.ipsecCaCert = (String) mIpsecCaCert.getSelectedItem(); 372310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 373f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh if (mIpsecServerCert.getSelectedItemPosition() != 0) { 374f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh profile.ipsecServerCert = (String) mIpsecServerCert.getSelectedItem(); 375f5317a151bef8d93f7a640fe46c6dcde6baa258dChia-chi Yeh } 376310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh break; 377310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 378310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh 379310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh profile.saveLogin = mSaveLogin.isChecked(); 380310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh return profile; 381310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh } 382310d619acba5cd1f7c8a55aa7906ed4f1c011bd8Chia-chi Yeh} 383