SipEditor.java revision bb5fb3fa71c9b9ab678f5cf5f2a9cc69ceea3445
1/* 2 * Copyright (C) 2010 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 17package com.android.phone.sip; 18 19import com.android.phone.R; 20 21import android.app.AlertDialog; 22import android.content.DialogInterface; 23import android.content.Intent; 24import android.net.sip.SipProfile; 25import android.os.Bundle; 26import android.os.Parcel; 27import android.os.Parcelable; 28import android.preference.CheckBoxPreference; 29import android.preference.EditTextPreference; 30import android.preference.ListPreference; 31import android.preference.Preference; 32import android.preference.PreferenceActivity; 33import android.preference.PreferenceGroup; 34import android.text.TextUtils; 35import android.util.Log; 36import android.view.KeyEvent; 37import android.view.Menu; 38import android.view.MenuItem; 39import android.view.View; 40import android.widget.Button; 41 42import java.lang.reflect.Constructor; 43import java.lang.reflect.InvocationTargetException; 44import java.lang.reflect.Method; 45 46/** 47 * The activity class for editing a new or existing SIP profile. 48 */ 49public class SipEditor extends PreferenceActivity 50 implements Preference.OnPreferenceChangeListener { 51 private static final int MENU_SAVE = Menu.FIRST; 52 private static final int MENU_DISCARD = Menu.FIRST + 1; 53 54 private static final String TAG = SipEditor.class.getSimpleName(); 55 private static final String KEY_PROFILE = "profile"; 56 private static final String SCRAMBLED = "****"; 57 private static final String EMPTY = ""; 58 private static final String DEFAULT_SIP_PORT = "5060"; 59 private static final String DEFAULT_PROTOCOL = "UDP"; 60 private static final String GET_METHOD_PREFIX = "get"; 61 62 private boolean mAddingProfile; 63 64 enum PreferenceKey { 65 ProfileName(R.string.profile_name, 0, EMPTY), 66 DomainAddress(R.string.domain_address, 1, EMPTY), 67 Username(R.string.username, 2, EMPTY), 68 Password(R.string.password, 3, EMPTY), 69 DisplayName(R.string.display_name, 4, EMPTY), 70 ProxyAddress(R.string.proxy_address, 5, EMPTY), 71 Port(R.string.port, 6, DEFAULT_SIP_PORT), 72 Transport(R.string.transport, 7, DEFAULT_PROTOCOL), 73 SendKeepAlive(R.string.send_keepalive, 8, EMPTY), 74 AutoRegistration(R.string.auto_registration, 9, EMPTY); 75 76 /** 77 * @param key The key name of the preference. 78 * @param index The index of the preference in the view. 79 * @param defaultValue The default value of the preference. 80 */ 81 PreferenceKey(int text, int index, String defaultValue) { 82 this.text = text; 83 this.index = index; 84 this.defaultValue = defaultValue; 85 } 86 87 public final int text; 88 public final int index; 89 public final String defaultValue; 90 } 91 92 private Preference[] mPreferences = 93 new Preference[PreferenceKey.values().length]; 94 95 @Override 96 public void onCreate(Bundle savedInstanceState) { 97 Log.v(TAG, "start profile editor"); 98 super.onCreate(savedInstanceState); 99 100 setContentView(R.layout.sip_settings_ui); 101 addPreferencesFromResource(R.xml.sip_edit); 102 final SipProfile p = (SipProfile) ((savedInstanceState == null) 103 ? getIntent().getParcelableExtra(SipSettings.KEY_SIP_PROFILE) 104 : savedInstanceState.getParcelable(KEY_PROFILE)); 105 106 for (PreferenceKey key : PreferenceKey.values()) { 107 mPreferences[key.index] = setupPreference(getString(key.text)); 108 } 109 if (p == null) { 110 findViewById(R.id.add_remove_account_bar) 111 .setVisibility(View.GONE); 112 } else { 113 Button removeButton = 114 (Button)findViewById(R.id.add_remove_account_button); 115 removeButton.setText(getString(R.string.remove_sip_account)); 116 removeButton.setOnClickListener( 117 new android.view.View.OnClickListener() { 118 public void onClick(View v) { 119 setRemovedProfileAndFinish(p); 120 } 121 }); 122 } 123 loadPreferencesFromProfile(p); 124 } 125 126 @Override 127 public boolean onCreateOptionsMenu(Menu menu) { 128 super.onCreateOptionsMenu(menu); 129 menu.add(0, MENU_SAVE, 0, R.string.sip_menu_save) 130 .setIcon(android.R.drawable.ic_menu_save); 131 menu.add(0, MENU_DISCARD, 0, R.string.sip_menu_discard) 132 .setIcon(android.R.drawable.ic_menu_close_clear_cancel); 133 return true; 134 } 135 136 @Override 137 public boolean onOptionsItemSelected(MenuItem item) { 138 switch (item.getItemId()) { 139 case MENU_SAVE: 140 if (validateAndSetResult()) { 141 finish(); 142 } 143 return true; 144 145 case MENU_DISCARD: 146 finish(); 147 return true; 148 } 149 return super.onOptionsItemSelected(item); 150 } 151 152 @Override 153 public boolean onKeyDown(int keyCode, KeyEvent event) { 154 switch (keyCode) { 155 case KeyEvent.KEYCODE_BACK: 156 if (validateAndSetResult()) finish(); 157 return true; 158 } 159 return super.onKeyDown(keyCode, event); 160 } 161 162 private void setRemovedProfileAndFinish(SipProfile p) { 163 try { 164 Intent intent = new Intent(this, SipSettings.class); 165 intent.putExtra(SipSettings.KEY_SIP_PROFILE, (Parcelable) p); 166 setResult(RESULT_FIRST_USER, intent); 167 finish(); 168 } catch (Exception e) { 169 showAlert(e.getMessage()); 170 } 171 } 172 173 private void showAlert(String message) { 174 new AlertDialog.Builder(this) 175 .setTitle(android.R.string.dialog_alert_title) 176 .setIcon(android.R.drawable.ic_dialog_alert) 177 .setMessage(message) 178 .setPositiveButton(R.string.alert_dialog_ok, 179 new DialogInterface.OnClickListener() { 180 public void onClick(DialogInterface dialog, int w) { 181 } 182 }) 183 .show(); 184 } 185 186 private boolean validateAndSetResult() { 187 for(Preference pref : mPreferences) { 188 String value = EMPTY; 189 if (pref instanceof ListPreference) { 190 value = ((ListPreference)pref).getValue(); 191 } else if (pref instanceof EditTextPreference) { 192 value = ((EditTextPreference)pref).getText(); 193 } else if (pref instanceof CheckBoxPreference) { 194 continue; 195 } 196 if (TextUtils.isEmpty(value) && 197 (pref != mPreferences[PreferenceKey.ProxyAddress.index])) { 198 showAlert(pref.getTitle() + " " 199 + getString(R.string.empty_alert)); 200 return false; 201 } 202 } 203 try { 204 Intent intent = new Intent(this, SipSettings.class); 205 intent.putExtra(SipSettings.KEY_SIP_PROFILE, 206 (Parcelable) createSipProfile()); 207 setResult(RESULT_OK, intent); 208 return true; 209 } catch (Exception e) { 210 Log.e(TAG, "Can not create new SipProfile : " + e.getMessage()); 211 showAlert(e.getMessage()); 212 return false; 213 } 214 } 215 216 private SipProfile createSipProfile() throws Exception { 217 return new SipProfile.Builder( 218 getValue(PreferenceKey.Username), 219 getValue(PreferenceKey.DomainAddress)) 220 .setProfileName(getValue(PreferenceKey.ProfileName)) 221 .setPassword(getValue(PreferenceKey.Password)) 222 .setOutboundProxy(getValue(PreferenceKey.ProxyAddress)) 223 .setProtocol(getValue(PreferenceKey.Transport)) 224 .setDisplayName(getValue(PreferenceKey.DisplayName)) 225 .setPort(Integer.parseInt(getValue(PreferenceKey.Port))) 226 .setSendKeepAlive(isChecked(PreferenceKey.SendKeepAlive)) 227 .setAutoRegistration( 228 isChecked(PreferenceKey.AutoRegistration)) 229 .build(); 230 } 231 232 public boolean onPreferenceChange(Preference pref, Object newValue) { 233 if (pref instanceof CheckBoxPreference) return true; 234 String value = (String) newValue; 235 if (value == null) value = EMPTY; 236 if (pref != mPreferences[PreferenceKey.Password.index]) { 237 pref.setSummary(value); 238 } else { 239 pref.setSummary(SCRAMBLED); 240 } 241 return true; 242 } 243 244 private void loadPreferencesFromProfile(SipProfile p) { 245 if (p != null) { 246 Log.v(TAG, "Edit the existing profile : " + p.getProfileName()); 247 try { 248 Class profileClass = SipProfile.class; 249 for (PreferenceKey key : PreferenceKey.values()) { 250 Method meth = profileClass.getMethod(GET_METHOD_PREFIX + 251 getString(key.text), (Class[])null); 252 if (key == PreferenceKey.Port) { 253 setValue(key, 254 String.valueOf(meth.invoke(p, (Object[])null))); 255 } else if (key == PreferenceKey.SendKeepAlive 256 || key == PreferenceKey.AutoRegistration) { 257 setCheckBox(key, ((Boolean) 258 meth.invoke(p, (Object[])null)).booleanValue()); 259 } else { 260 setValue(key, (String) meth.invoke(p, (Object[])null)); 261 } 262 } 263 } catch (Exception e) { 264 Log.e(TAG, "Can not load pref from profile:" + e.getMessage()); 265 } 266 } else { 267 Log.v(TAG, "Edit a new profile"); 268 for (PreferenceKey key : PreferenceKey.values()) { 269 Preference pref = mPreferences[key.index]; 270 pref.setOnPreferenceChangeListener(this); 271 if (pref instanceof EditTextPreference) { 272 ((EditTextPreference)pref).setText(key.defaultValue); 273 } else if (pref instanceof ListPreference) { 274 ((ListPreference)pref).setValue(key.defaultValue); 275 } else { 276 continue; 277 } 278 pref.setSummary(EMPTY.equals(key.defaultValue) 279 ? getString(R.string.initial_preference_summary) : key.defaultValue); 280 } 281 } 282 } 283 284 private boolean isChecked(PreferenceKey key) { 285 CheckBoxPreference pref = (CheckBoxPreference)mPreferences[key.index]; 286 return pref.isChecked(); 287 } 288 289 private String getValue(PreferenceKey key) { 290 Preference pref = mPreferences[key.index]; 291 if (pref instanceof EditTextPreference) { 292 return ((EditTextPreference)pref).getText(); 293 } else if (pref instanceof ListPreference) { 294 return ((ListPreference)pref).getValue(); 295 } 296 throw new RuntimeException("getValue() for the preference " + key.text); 297 } 298 299 private void setCheckBox(PreferenceKey key, boolean checked) { 300 CheckBoxPreference pref = (CheckBoxPreference) mPreferences[key.index]; 301 pref.setChecked(checked); 302 } 303 304 private void setValue(PreferenceKey key, String value) { 305 Preference pref = mPreferences[key.index]; 306 if (pref instanceof EditTextPreference) { 307 ((EditTextPreference)pref).setText(value); 308 } else if (pref instanceof ListPreference) { 309 ((ListPreference)pref).setValue(value); 310 } 311 312 if (TextUtils.isEmpty(value)) { 313 value = getString(R.string.initial_preference_summary); 314 } else { 315 if (key == PreferenceKey.Password) value = SCRAMBLED; 316 } 317 pref.setSummary(value); 318 } 319 320 private Preference setupPreference(String key) { 321 Preference pref = getPreferenceScreen().findPreference(key); 322 pref.setOnPreferenceChangeListener(this); 323 return pref; 324 } 325} 326