/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings.vpn; import com.android.settings.R; import android.content.Context; import android.content.Intent; import android.net.vpn.VpnProfile; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; import android.text.InputType; import android.text.TextUtils; import android.text.method.PasswordTransformationMethod; import android.view.Menu; import android.view.MenuItem; /** * The common class for editing {@link VpnProfile}. */ class VpnProfileEditor { private static final String KEY_VPN_NAME = "vpn_name"; private EditTextPreference mName; private EditTextPreference mServerName; private EditTextPreference mDomainSuffices; private VpnProfile mProfile; public VpnProfileEditor(VpnProfile p) { mProfile = p; } //@Override public VpnProfile getProfile() { return mProfile; } /** * Adds the preferences to the panel. Subclasses should override * {@link #loadExtraPreferencesTo(PreferenceGroup)} instead of this method. */ public void loadPreferencesTo(PreferenceGroup subpanel) { Context c = subpanel.getContext(); mName = (EditTextPreference) subpanel.findPreference(KEY_VPN_NAME); mName.setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange( Preference pref, Object newValue) { setName((String) newValue); return true; } }); setName(getProfile().getName()); mName.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); subpanel.addPreference(createServerNamePreference(c)); loadExtraPreferencesTo(subpanel); subpanel.addPreference(createDomainSufficesPreference(c)); } /** * Adds the extra preferences to the panel. Subclasses should add * additional preferences in this method. */ protected void loadExtraPreferencesTo(PreferenceGroup subpanel) { } protected void onCreateOptionsMenu(Menu menu, int last_item) { } protected boolean onOptionsItemSelected(PreferenceActivity p, MenuItem item) { return false; } protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { } /** * Validates the inputs in the preferences. * * @return an error message that is ready to be displayed in a dialog; or * null if all the inputs are valid */ public String validate() { String result = validate(mName, R.string.vpn_a_name); return ((result != null) ? result : validate(mServerName, R.string.vpn_a_vpn_server)); } /** * Creates a preference for users to input domain suffices. */ protected EditTextPreference createDomainSufficesPreference(Context c) { EditTextPreference pref = mDomainSuffices = createEditTextPreference(c, R.string.vpn_dns_search_list_title, R.string.vpn_dns_search_list, mProfile.getDomainSuffices(), new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange( Preference pref, Object newValue) { String v = ((String) newValue).trim(); mProfile.setDomainSuffices(v); setSummary(pref, R.string.vpn_dns_search_list, v, false); return true; } }); pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI); return pref; } private Preference createServerNamePreference(Context c) { EditTextPreference pref = mServerName = createEditTextPreference(c, R.string.vpn_vpn_server_title, R.string.vpn_vpn_server, mProfile.getServerName(), new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange( Preference pref, Object newValue) { String v = ((String) newValue).trim(); mProfile.setServerName(v); setSummary(pref, R.string.vpn_vpn_server, v); return true; } }); pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI); return pref; } protected EditTextPreference createEditTextPreference(Context c, int titleId, int prefNameId, String value, Preference.OnPreferenceChangeListener listener) { EditTextPreference pref = new EditTextPreference(c); pref.setTitle(titleId); pref.setDialogTitle(titleId); setSummary(pref, prefNameId, value); pref.setText(value); pref.setPersistent(true); pref.setOnPreferenceChangeListener(listener); return pref; } protected String validate(Preference pref, int fieldNameId) { Context c = pref.getContext(); String value = (pref instanceof EditTextPreference) ? ((EditTextPreference) pref).getText() : ((ListPreference) pref).getValue(); String formatString = (pref instanceof EditTextPreference) ? c.getString(R.string.vpn_error_miss_entering) : c.getString(R.string.vpn_error_miss_selecting); return (TextUtils.isEmpty(value) ? String.format(formatString, c.getString(fieldNameId)) : null); } protected void setSummary(Preference pref, int fieldNameId, String v) { setSummary(pref, fieldNameId, v, true); } protected void setSummary(Preference pref, int fieldNameId, String v, boolean required) { Context c = pref.getContext(); String formatString = required ? c.getString(R.string.vpn_field_not_set) : c.getString(R.string.vpn_field_not_set_optional); pref.setSummary(TextUtils.isEmpty(v) ? String.format(formatString, c.getString(fieldNameId)) : v); } protected void setCheckBoxTitle(CheckBoxPreference pref, int fieldNameId) { Context c = pref.getContext(); String formatString = c.getString(R.string.vpn_enable_field); pref.setTitle(String.format(formatString, c.getString(fieldNameId))); } private void setName(String newName) { newName = (newName == null) ? "" : newName.trim(); mName.setText(newName); getProfile().setName(newName); setSummary(mName, R.string.vpn_name, newName); } // Secret is tricky to handle because empty field may mean "not set" or // "unchanged". This class hides that logic from callers. protected static abstract class SecretHandler { private EditTextPreference mPref; private int mFieldNameId; private boolean mHadSecret; protected SecretHandler(Context c, int titleId, int fieldNameId) { String value = getSecretFromProfile(); mHadSecret = !TextUtils.isEmpty(value); mFieldNameId = fieldNameId; EditTextPreference pref = mPref = new EditTextPreference(c); pref.setTitle(titleId); pref.setDialogTitle(titleId); pref.getEditText().setInputType( InputType.TYPE_TEXT_VARIATION_PASSWORD); pref.getEditText().setTransformationMethod( new PasswordTransformationMethod()); pref.setText(""); pref.getEditText().setHint(mHadSecret ? R.string.vpn_secret_unchanged : R.string.vpn_secret_not_set); setSecretSummary(value); pref.setPersistent(true); saveSecretToProfile(""); pref.setOnPreferenceChangeListener( new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange( Preference pref, Object newValue) { saveSecretToProfile((String) newValue); setSecretSummary((String) newValue); return true; } }); } protected EditTextPreference getPreference() { return mPref; } protected String validate() { Context c = mPref.getContext(); String value = mPref.getText(); return ((TextUtils.isEmpty(value) && !mHadSecret) ? String.format( c.getString(R.string.vpn_error_miss_entering), c.getString(mFieldNameId)) : null); } private void setSecretSummary(String value) { EditTextPreference pref = mPref; Context c = pref.getContext(); String formatString = (TextUtils.isEmpty(value) && !mHadSecret) ? c.getString(R.string.vpn_field_not_set) : c.getString(R.string.vpn_field_is_set); pref.setSummary( String.format(formatString, c.getString(mFieldNameId))); } protected abstract String getSecretFromProfile(); protected abstract void saveSecretToProfile(String secret); } }