Home | History | Annotate | Download | only in vpn
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings.vpn;
     18 
     19 import com.android.settings.R;
     20 
     21 import android.content.Context;
     22 import android.net.vpn.VpnProfile;
     23 import android.preference.CheckBoxPreference;
     24 import android.preference.EditTextPreference;
     25 import android.preference.ListPreference;
     26 import android.preference.Preference;
     27 import android.preference.PreferenceGroup;
     28 import android.text.InputType;
     29 import android.text.TextUtils;
     30 import android.text.method.PasswordTransformationMethod;
     31 
     32 /**
     33  * The common class for editing {@link VpnProfile}.
     34  */
     35 class VpnProfileEditor {
     36     private static final String KEY_VPN_NAME = "vpn_name";
     37 
     38     private EditTextPreference mName;
     39     private EditTextPreference mServerName;
     40     private EditTextPreference mDomainSuffices;
     41     private VpnProfile mProfile;
     42 
     43     public VpnProfileEditor(VpnProfile p) {
     44         mProfile = p;
     45     }
     46 
     47     //@Override
     48     public VpnProfile getProfile() {
     49         return mProfile;
     50     }
     51 
     52     /**
     53      * Adds the preferences to the panel. Subclasses should override
     54      * {@link #loadExtraPreferencesTo(PreferenceGroup)} instead of this method.
     55      */
     56     public void loadPreferencesTo(PreferenceGroup subpanel) {
     57         Context c = subpanel.getContext();
     58 
     59         mName = (EditTextPreference) subpanel.findPreference(KEY_VPN_NAME);
     60         mName.setOnPreferenceChangeListener(
     61                 new Preference.OnPreferenceChangeListener() {
     62                     public boolean onPreferenceChange(
     63                             Preference pref, Object newValue) {
     64                         setName((String) newValue);
     65                         return true;
     66                     }
     67                 });
     68         setName(getProfile().getName());
     69         mName.getEditText().setInputType(InputType.TYPE_CLASS_TEXT
     70                 | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
     71 
     72         subpanel.addPreference(createServerNamePreference(c));
     73         loadExtraPreferencesTo(subpanel);
     74         subpanel.addPreference(createDomainSufficesPreference(c));
     75     }
     76 
     77     /**
     78      * Adds the extra preferences to the panel. Subclasses should add
     79      * additional preferences in this method.
     80      */
     81     protected void loadExtraPreferencesTo(PreferenceGroup subpanel) {
     82     }
     83 
     84     /**
     85      * Validates the inputs in the preferences.
     86      *
     87      * @return an error message that is ready to be displayed in a dialog; or
     88      *      null if all the inputs are valid
     89      */
     90     public String validate() {
     91         String result = validate(mName, R.string.vpn_a_name);
     92         return ((result != null)
     93                 ? result
     94                 : validate(mServerName, R.string.vpn_a_vpn_server));
     95     }
     96 
     97     /**
     98      * Creates a preference for users to input domain suffices.
     99      */
    100     protected EditTextPreference createDomainSufficesPreference(Context c) {
    101         EditTextPreference pref = mDomainSuffices = createEditTextPreference(c,
    102                 R.string.vpn_dns_search_list_title,
    103                 R.string.vpn_dns_search_list,
    104                 mProfile.getDomainSuffices(),
    105                 new Preference.OnPreferenceChangeListener() {
    106                     public boolean onPreferenceChange(
    107                             Preference pref, Object newValue) {
    108                         String v = ((String) newValue).trim();
    109                         mProfile.setDomainSuffices(v);
    110                         setSummary(pref, R.string.vpn_dns_search_list, v, false);
    111                         return true;
    112                     }
    113                 });
    114         pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI);
    115         return pref;
    116     }
    117 
    118     private Preference createServerNamePreference(Context c) {
    119         EditTextPreference pref = mServerName = createEditTextPreference(c,
    120                 R.string.vpn_vpn_server_title,
    121                 R.string.vpn_vpn_server,
    122                 mProfile.getServerName(),
    123                 new Preference.OnPreferenceChangeListener() {
    124                     public boolean onPreferenceChange(
    125                             Preference pref, Object newValue) {
    126                         String v = ((String) newValue).trim();
    127                         mProfile.setServerName(v);
    128                         setSummary(pref, R.string.vpn_vpn_server, v);
    129                         return true;
    130                     }
    131                 });
    132         pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI);
    133         return pref;
    134     }
    135 
    136     protected EditTextPreference createEditTextPreference(Context c, int titleId,
    137             int prefNameId, String value,
    138             Preference.OnPreferenceChangeListener listener) {
    139         EditTextPreference pref = new EditTextPreference(c);
    140         pref.setTitle(titleId);
    141         pref.setDialogTitle(titleId);
    142         setSummary(pref, prefNameId, value);
    143         pref.setText(value);
    144         pref.setPersistent(true);
    145         pref.setOnPreferenceChangeListener(listener);
    146         return pref;
    147     }
    148 
    149     protected String validate(Preference pref, int fieldNameId) {
    150         Context c = pref.getContext();
    151         String value = (pref instanceof EditTextPreference)
    152                 ? ((EditTextPreference) pref).getText()
    153                 : ((ListPreference) pref).getValue();
    154         String formatString = (pref instanceof EditTextPreference)
    155                 ? c.getString(R.string.vpn_error_miss_entering)
    156                 : c.getString(R.string.vpn_error_miss_selecting);
    157         return (TextUtils.isEmpty(value)
    158                 ? String.format(formatString, c.getString(fieldNameId))
    159                 : null);
    160     }
    161 
    162     protected void setSummary(Preference pref, int fieldNameId, String v) {
    163         setSummary(pref, fieldNameId, v, true);
    164     }
    165 
    166     protected void setSummary(Preference pref, int fieldNameId, String v,
    167             boolean required) {
    168         Context c = pref.getContext();
    169         String formatString = required
    170                 ? c.getString(R.string.vpn_field_not_set)
    171                 : c.getString(R.string.vpn_field_not_set_optional);
    172         pref.setSummary(TextUtils.isEmpty(v)
    173                 ? String.format(formatString, c.getString(fieldNameId))
    174                 : v);
    175     }
    176 
    177     protected void setCheckBoxTitle(CheckBoxPreference pref, int fieldNameId) {
    178         Context c = pref.getContext();
    179         String formatString = c.getString(R.string.vpn_enable_field);
    180         pref.setTitle(String.format(formatString, c.getString(fieldNameId)));
    181     }
    182 
    183     private void setName(String newName) {
    184         newName = (newName == null) ? "" : newName.trim();
    185         mName.setText(newName);
    186         getProfile().setName(newName);
    187         setSummary(mName, R.string.vpn_name, newName);
    188     }
    189 
    190     // Secret is tricky to handle because empty field may mean "not set" or
    191     // "unchanged". This class hides that logic from callers.
    192     protected static abstract class SecretHandler {
    193         private EditTextPreference mPref;
    194         private int mFieldNameId;
    195         private boolean mHadSecret;
    196 
    197         protected SecretHandler(Context c, int titleId, int fieldNameId) {
    198             String value = getSecretFromProfile();
    199             mHadSecret = !TextUtils.isEmpty(value);
    200             mFieldNameId = fieldNameId;
    201 
    202             EditTextPreference pref = mPref = new EditTextPreference(c);
    203             pref.setTitle(titleId);
    204             pref.setDialogTitle(titleId);
    205             pref.getEditText().setInputType(
    206                     InputType.TYPE_TEXT_VARIATION_PASSWORD);
    207             pref.getEditText().setTransformationMethod(
    208                     new PasswordTransformationMethod());
    209             pref.setText("");
    210             pref.getEditText().setHint(mHadSecret
    211                     ? R.string.vpn_secret_unchanged
    212                     : R.string.vpn_secret_not_set);
    213             setSecretSummary(value);
    214             pref.setPersistent(true);
    215             saveSecretToProfile("");
    216             pref.setOnPreferenceChangeListener(
    217                     new Preference.OnPreferenceChangeListener() {
    218                         public boolean onPreferenceChange(
    219                                 Preference pref, Object newValue) {
    220                             saveSecretToProfile((String) newValue);
    221                             setSecretSummary((String) newValue);
    222                             return true;
    223                         }
    224                     });
    225         }
    226 
    227         protected EditTextPreference getPreference() {
    228             return mPref;
    229         }
    230 
    231         protected String validate() {
    232             Context c = mPref.getContext();
    233             String value = mPref.getText();
    234             return ((TextUtils.isEmpty(value) && !mHadSecret)
    235                     ? String.format(
    236                             c.getString(R.string.vpn_error_miss_entering),
    237                             c.getString(mFieldNameId))
    238                     : null);
    239         }
    240 
    241         private void setSecretSummary(String value) {
    242             EditTextPreference pref = mPref;
    243             Context c = pref.getContext();
    244             String formatString = (TextUtils.isEmpty(value) && !mHadSecret)
    245                     ? c.getString(R.string.vpn_field_not_set)
    246                     : c.getString(R.string.vpn_field_is_set);
    247             pref.setSummary(
    248                     String.format(formatString, c.getString(mFieldNameId)));
    249         }
    250 
    251         protected abstract String getSecretFromProfile();
    252         protected abstract void saveSecretToProfile(String secret);
    253     }
    254 }
    255