2 * Copyright (C) 2009 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.vpn;
19 import com.android.settings.R;
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;
33 * The common class for editing {@link VpnProfile}.
35 class VpnProfileEditor {
36 private static final String KEY_VPN_NAME = "vpn_name";
38 private EditTextPreference mName;
39 private EditTextPreference mServerName;
40 private EditTextPreference mDomainSuffices;
41 private VpnProfile mProfile;
43 public VpnProfileEditor(VpnProfile p) {
48 public VpnProfile getProfile() {
53 * Adds the preferences to the panel. Subclasses should override
54 * {@link #loadExtraPreferencesTo(PreferenceGroup)} instead of this method.
56 public void loadPreferencesTo(PreferenceGroup subpanel) {
57 Context c = subpanel.getContext();
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);
68 setName(getProfile().getName());
70 subpanel.addPreference(createServerNamePreference(c));
71 loadExtraPreferencesTo(subpanel);
72 subpanel.addPreference(createDomainSufficesPreference(c));
76 * Adds the extra preferences to the panel. Subclasses should add
77 * additional preferences in this method.
79 protected void loadExtraPreferencesTo(PreferenceGroup subpanel) {
83 * Validates the inputs in the preferences.
85 * @return an error message that is ready to be displayed in a dialog; or
86 * null if all the inputs are valid
88 public String validate() {
89 String result = validate(mName, R.string.vpn_a_name);
90 return ((result != null)
92 : validate(mServerName, R.string.vpn_a_vpn_server));
96 * Creates a preference for users to input domain suffices.
98 protected EditTextPreference createDomainSufficesPreference(Context c) {
99 EditTextPreference pref = mDomainSuffices = createEditTextPreference(c,
100 R.string.vpn_dns_search_list_title,
101 R.string.vpn_dns_search_list,
102 mProfile.getDomainSuffices(),
103 new Preference.OnPreferenceChangeListener() {
104 public boolean onPreferenceChange(
105 Preference pref, Object newValue) {
106 String v = ((String) newValue).trim();
107 mProfile.setDomainSuffices(v);
108 setSummary(pref, R.string.vpn_dns_search_list, v, false);
112 pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI);
116 private Preference createServerNamePreference(Context c) {
117 EditTextPreference pref = mServerName = createEditTextPreference(c,
118 R.string.vpn_vpn_server_title,
119 R.string.vpn_vpn_server,
120 mProfile.getServerName(),
121 new Preference.OnPreferenceChangeListener() {
122 public boolean onPreferenceChange(
123 Preference pref, Object newValue) {
124 String v = ((String) newValue).trim();
125 mProfile.setServerName(v);
126 setSummary(pref, R.string.vpn_vpn_server, v);
130 pref.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI);
134 protected EditTextPreference createEditTextPreference(Context c, int titleId,
135 int prefNameId, String value,
136 Preference.OnPreferenceChangeListener listener) {
137 EditTextPreference pref = new EditTextPreference(c);
138 pref.setTitle(titleId);
139 pref.setDialogTitle(titleId);
140 setSummary(pref, prefNameId, value);
142 pref.setPersistent(true);
143 pref.setOnPreferenceChangeListener(listener);
147 protected String validate(Preference pref, int fieldNameId) {
148 Context c = pref.getContext();
149 String value = (pref instanceof EditTextPreference)
150 ? ((EditTextPreference) pref).getText()
151 : ((ListPreference) pref).getValue();
152 String formatString = (pref instanceof EditTextPreference)
153 ? c.getString(R.string.vpn_error_miss_entering)
154 : c.getString(R.string.vpn_error_miss_selecting);
155 return (TextUtils.isEmpty(value)
156 ? String.format(formatString, c.getString(fieldNameId))
160 protected void setSummary(Preference pref, int fieldNameId, String v) {
161 setSummary(pref, fieldNameId, v, true);
164 protected void setSummary(Preference pref, int fieldNameId, String v,
166 Context c = pref.getContext();
167 String formatString = required
168 ? c.getString(R.string.vpn_field_not_set)
169 : c.getString(R.string.vpn_field_not_set_optional);
170 pref.setSummary(TextUtils.isEmpty(v)
171 ? String.format(formatString, c.getString(fieldNameId))
175 protected void setSecretTitle(
176 CheckBoxPreference pref, int fieldNameId, boolean enabled) {
177 Context c = pref.getContext();
178 String formatString = enabled
179 ? c.getString(R.string.vpn_disable_field)
180 : c.getString(R.string.vpn_enable_field);
181 pref.setTitle(String.format(formatString, c.getString(fieldNameId)));
184 private void setName(String newName) {
185 newName = (newName == null) ? "" : newName.trim();
186 mName.setText(newName);
187 getProfile().setName(newName);
188 setSummary(mName, R.string.vpn_name, newName);
191 // Secret is tricky to handle because empty field may mean "not set" or
192 // "unchanged". This class hides that logic from callers.
193 protected static abstract class SecretHandler {
194 private EditTextPreference mPref;
195 private int mFieldNameId;
196 private boolean mHadSecret;
198 protected SecretHandler(Context c, int titleId, int fieldNameId) {
199 String value = getSecretFromProfile();
200 mHadSecret = !TextUtils.isEmpty(value);
201 mFieldNameId = fieldNameId;
203 EditTextPreference pref = mPref = new EditTextPreference(c);
204 pref.setTitle(titleId);
205 pref.setDialogTitle(titleId);
206 pref.getEditText().setInputType(
207 InputType.TYPE_TEXT_VARIATION_PASSWORD);
208 pref.getEditText().setTransformationMethod(
209 new PasswordTransformationMethod());
211 pref.getEditText().setHint(mHadSecret
212 ? R.string.vpn_secret_unchanged
213 : R.string.vpn_secret_not_set);
214 setSecretSummary(value);
215 pref.setPersistent(true);
216 saveSecretToProfile("");
217 pref.setOnPreferenceChangeListener(
218 new Preference.OnPreferenceChangeListener() {
219 public boolean onPreferenceChange(
220 Preference pref, Object newValue) {
221 saveSecretToProfile((String) newValue);
222 setSecretSummary((String) newValue);
228 protected EditTextPreference getPreference() {
232 protected String validate() {
233 Context c = mPref.getContext();
234 String value = mPref.getText();
235 return ((TextUtils.isEmpty(value) && !mHadSecret)
237 c.getString(R.string.vpn_error_miss_entering),
238 c.getString(mFieldNameId))
242 private void setSecretSummary(String value) {
243 EditTextPreference pref = mPref;
244 Context c = pref.getContext();
245 String formatString = (TextUtils.isEmpty(value) && !mHadSecret)
246 ? c.getString(R.string.vpn_field_not_set)
247 : c.getString(R.string.vpn_field_is_set);
249 String.format(formatString, c.getString(mFieldNameId)));
252 protected abstract String getSecretFromProfile();
253 protected abstract void saveSecretToProfile(String secret);