AutoFillSettingsFragment.java revision 366824d00030e6a0a0db5a0cc44f1ab7ac672303
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.browser; 18 19import android.app.Fragment; 20import android.content.Context; 21import android.os.Bundle; 22import android.os.Handler; 23import android.os.Message; 24import android.text.Editable; 25import android.text.TextWatcher; 26import android.util.Log; 27import android.view.View; 28import android.view.ViewGroup; 29import android.view.View.OnClickListener; 30import android.view.LayoutInflater; 31import android.view.inputmethod.InputMethodManager; 32import android.webkit.WebSettings.AutoFillProfile; 33import android.widget.Button; 34import android.widget.EditText; 35import android.widget.Toast; 36 37public class AutoFillSettingsFragment extends Fragment { 38 39 private static final String LOGTAG = "AutoFillSettingsFragment"; 40 41 private EditText mFullNameEdit; 42 private EditText mEmailEdit; 43 private EditText mCompanyEdit; 44 private EditText mAddressLine1Edit; 45 private EditText mAddressLine2Edit; 46 private EditText mCityEdit; 47 private EditText mStateEdit; 48 private EditText mZipEdit; 49 private EditText mCountryEdit; 50 private EditText mPhoneEdit; 51 52 private Button mSaveButton; 53 54 // Used to display toast after DB interactions complete. 55 private Handler mHandler; 56 57 private final static int PROFILE_SAVED_MSG = 100; 58 private final static int PROFILE_DELETED_MSG = 101; 59 60 // For now we support just one profile so it's safe to hardcode the 61 // id to 1 here. In the future this unique identifier will be set 62 // dynamically. 63 private int mUniqueId = 1; 64 65 private class PhoneNumberValidator implements TextWatcher { 66 // Keep in sync with kPhoneNumberLength in chrome/browser/autofill/phone_number.cc 67 private static final int PHONE_NUMBER_LENGTH = 7; 68 private static final String PHONE_NUMBER_SEPARATORS_REGEX = "[\\s\\.\\(\\)-]"; 69 70 public void afterTextChanged(Editable s) { 71 String phoneNumber = s.toString(); 72 int phoneNumberLength = phoneNumber.length(); 73 74 // Strip out any phone number separators. 75 phoneNumber = phoneNumber.replaceAll(PHONE_NUMBER_SEPARATORS_REGEX, ""); 76 77 int strippedPhoneNumberLength = phoneNumber.length(); 78 79 if (phoneNumberLength > 0 && strippedPhoneNumberLength < PHONE_NUMBER_LENGTH) { 80 mPhoneEdit.setError(getResources().getText( 81 R.string.autofill_profile_editor_phone_number_invalid)); 82 } else { 83 mPhoneEdit.setError(null); 84 } 85 86 updateButtonState(); 87 } 88 89 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 90 } 91 92 public void onTextChanged(CharSequence s, int start, int before, int count) { 93 } 94 } 95 96 private class FieldChangedListener implements TextWatcher { 97 public void afterTextChanged(Editable s) { 98 updateButtonState(); 99 } 100 101 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 102 } 103 104 public void onTextChanged(CharSequence s, int start, int before, int count) { 105 } 106 107 } 108 109 private TextWatcher mFieldChangedListener = new FieldChangedListener(); 110 111 public AutoFillSettingsFragment() { 112 mHandler = new Handler() { 113 @Override 114 public void handleMessage(Message msg) { 115 switch (msg.what) { 116 case PROFILE_SAVED_MSG: 117 Toast.makeText(getActivity(), R.string.autofill_profile_successful_save, 118 Toast.LENGTH_SHORT).show(); 119 break; 120 121 case PROFILE_DELETED_MSG: 122 Toast.makeText(getActivity(), R.string.autofill_profile_successful_delete, 123 Toast.LENGTH_SHORT).show(); 124 break; 125 } 126 } 127 }; 128 } 129 130 @Override 131 public void onCreate(Bundle savedState) { 132 super.onCreate(savedState); 133 } 134 135 @Override 136 public View onCreateView(LayoutInflater inflater, ViewGroup container, 137 Bundle savedInstanceState) { 138 View v = inflater.inflate(R.layout.autofill_settings_fragment, container, false); 139 140 mFullNameEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_name_edit); 141 mEmailEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_email_address_edit); 142 mCompanyEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_company_name_edit); 143 mAddressLine1Edit = (EditText)v.findViewById( 144 R.id.autofill_profile_editor_address_line_1_edit); 145 mAddressLine2Edit = (EditText)v.findViewById( 146 R.id.autofill_profile_editor_address_line_2_edit); 147 mCityEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_city_edit); 148 mStateEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_state_edit); 149 mZipEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_zip_code_edit); 150 mCountryEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_country_edit); 151 mPhoneEdit = (EditText)v.findViewById(R.id.autofill_profile_editor_phone_number_edit); 152 153 mFullNameEdit.addTextChangedListener(mFieldChangedListener); 154 mEmailEdit.addTextChangedListener(mFieldChangedListener); 155 mCompanyEdit.addTextChangedListener(mFieldChangedListener); 156 mAddressLine1Edit.addTextChangedListener(mFieldChangedListener); 157 mAddressLine2Edit.addTextChangedListener(mFieldChangedListener); 158 mCityEdit.addTextChangedListener(mFieldChangedListener); 159 mStateEdit.addTextChangedListener(mFieldChangedListener); 160 mZipEdit.addTextChangedListener(mFieldChangedListener); 161 mCountryEdit.addTextChangedListener(mFieldChangedListener); 162 mPhoneEdit.addTextChangedListener(new PhoneNumberValidator()); 163 164 mSaveButton = (Button)v.findViewById(R.id.autofill_profile_editor_save_button); 165 mSaveButton.setOnClickListener(new OnClickListener() { 166 public void onClick(View button) { 167 AutoFillProfile newProfile = new AutoFillProfile( 168 mUniqueId, 169 mFullNameEdit.getText().toString(), 170 mEmailEdit.getText().toString(), 171 mCompanyEdit.getText().toString(), 172 mAddressLine1Edit.getText().toString(), 173 mAddressLine2Edit.getText().toString(), 174 mCityEdit.getText().toString(), 175 mStateEdit.getText().toString(), 176 mZipEdit.getText().toString(), 177 mCountryEdit.getText().toString(), 178 mPhoneEdit.getText().toString()); 179 180 BrowserSettings.getInstance().setAutoFillProfile(getActivity(), newProfile, 181 mHandler.obtainMessage(PROFILE_SAVED_MSG)); 182 closeEditor(); 183 } 184 }); 185 186 Button deleteButton = (Button)v.findViewById(R.id.autofill_profile_editor_delete_button); 187 deleteButton.setOnClickListener(new OnClickListener() { 188 public void onClick(View button) { 189 // Clear the UI. 190 mFullNameEdit.setText(""); 191 mEmailEdit.setText(""); 192 mCompanyEdit.setText(""); 193 mAddressLine1Edit.setText(""); 194 mAddressLine2Edit.setText(""); 195 mCityEdit.setText(""); 196 mStateEdit.setText(""); 197 mZipEdit.setText(""); 198 mCountryEdit.setText(""); 199 mPhoneEdit.setText(""); 200 201 // Update browser settings and native with a null profile. This will 202 // trigger the current profile to get deleted from the DB. 203 BrowserSettings.getInstance().setAutoFillProfile(getActivity(), null, 204 mHandler.obtainMessage(PROFILE_DELETED_MSG)); 205 206 updateButtonState(); 207 } 208 }); 209 210 Button cancelButton = (Button)v.findViewById(R.id.autofill_profile_editor_cancel_button); 211 cancelButton.setOnClickListener(new OnClickListener() { 212 public void onClick(View button) { 213 closeEditor(); 214 } 215 }); 216 217 // Populate the text boxes with any pre existing AutoFill data. 218 AutoFillProfile activeProfile = BrowserSettings.getInstance().getAutoFillProfile(); 219 if (activeProfile != null) { 220 mFullNameEdit.setText(activeProfile.getFullName()); 221 mEmailEdit.setText(activeProfile.getEmailAddress()); 222 mCompanyEdit.setText(activeProfile.getCompanyName()); 223 mAddressLine1Edit.setText(activeProfile.getAddressLine1()); 224 mAddressLine2Edit.setText(activeProfile.getAddressLine2()); 225 mCityEdit.setText(activeProfile.getCity()); 226 mStateEdit.setText(activeProfile.getState()); 227 mZipEdit.setText(activeProfile.getZipCode()); 228 mCountryEdit.setText(activeProfile.getCountry()); 229 mPhoneEdit.setText(activeProfile.getPhoneNumber()); 230 } 231 232 updateButtonState(); 233 234 return v; 235 } 236 237 public void updateButtonState() { 238 239 boolean valid = (mFullNameEdit.getText().toString().length() > 0 || 240 mEmailEdit.getText().toString().length() > 0 || 241 mCompanyEdit.getText().toString().length() > 0 || 242 mAddressLine1Edit.getText().toString().length() > 0 || 243 mAddressLine2Edit.getText().toString().length() > 0 || 244 mCityEdit.getText().toString().length() > 0 || 245 mStateEdit.getText().toString().length() > 0 || 246 mZipEdit.getText().toString().length() > 0 || 247 mCountryEdit.getText().toString().length() > 0) && 248 mPhoneEdit.getError() == null; 249 250 // Only enable the save buttons if we have at least one field completed 251 // and the phone number (if present is valid). 252 mSaveButton.setEnabled(valid); 253 } 254 255 private void closeEditor() { 256 // Hide the IME if the user wants to close while an EditText has focus 257 InputMethodManager imm = (InputMethodManager) getActivity().getSystemService( 258 Context.INPUT_METHOD_SERVICE); 259 imm.hideSoftInputFromWindow(getView().getWindowToken(), 0); 260 if (getFragmentManager().getBackStackEntryCount() > 0) { 261 getFragmentManager().popBackStack(); 262 } else { 263 getActivity().finish(); 264 } 265 } 266} 267