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